gchar *c, *new, *tmp, delim = '.';
gsize len = 0, slen = 0, macro_len = 0;
gint state = 0, ndelim = 0;
- gchar ip_buf[INET6_ADDRSTRLEN + 1];
+ gchar ip_buf[INET6_ADDRSTRLEN * 2 + 1];
gboolean need_expand = FALSE, reversed;
struct rspamd_task *task;
switch (g_ascii_tolower (*p)) {
case 'i':
if (task->from_addr) {
- macro_len = rspamd_strlcpy (ip_buf,
- rspamd_inet_address_to_string (task->from_addr),
- sizeof (ip_buf));
- macro_value = ip_buf;
+ if (rspamd_inet_address_get_af (task->from_addr) == AF_INET) {
+ macro_len = rspamd_strlcpy (ip_buf,
+ rspamd_inet_address_to_string (task->from_addr),
+ sizeof (ip_buf));
+ macro_value = ip_buf;
+ }
+ else if (rspamd_inet_address_get_af (task->from_addr) == AF_INET6) {
+ /* See #3625 for details */
+ socklen_t slen;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)
+ rspamd_inet_address_get_sa (task->from_addr, &slen);
+
+ /* Expand IPv6 address */
+#define IPV6_OCTET(x) bytes[(x)] >> 4, bytes[(x)] & 0xF
+ unsigned char *bytes = (unsigned char *)&sin6->sin6_addr;
+ macro_len = rspamd_snprintf (ip_buf, sizeof (ip_buf),
+ "%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd."
+ "%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd.%xd",
+ IPV6_OCTET(0), IPV6_OCTET(1),
+ IPV6_OCTET(2), IPV6_OCTET(3),
+ IPV6_OCTET(4), IPV6_OCTET(5),
+ IPV6_OCTET(6), IPV6_OCTET(7),
+ IPV6_OCTET(8), IPV6_OCTET(9),
+ IPV6_OCTET(10), IPV6_OCTET(11),
+ IPV6_OCTET(12), IPV6_OCTET(13),
+ IPV6_OCTET(14), IPV6_OCTET(15));
+ macro_value = ip_buf;
+#undef IPV6_OCTET
+ }
+ else {
+ macro_len = rspamd_snprintf (ip_buf, sizeof (ip_buf),
+ "127.0.0.1");
+ macro_value = ip_buf;
+ }
}
else {
macro_len = rspamd_snprintf (ip_buf, sizeof (ip_buf),