Index: dnsrbl.c diff -u -p dnsrbl.c.orig dnsrbl.c --- dnsrbl.c.orig 2013-01-20 01:01:15.000000000 +0900 +++ dnsrbl.c 2015-12-24 11:17:32.566399930 +0900 @@ -113,7 +113,6 @@ dnsrbl_check_source(ad, stage, ap, priv) #ifdef HAVE_RES_NINIT struct __res_state res; #endif - sockaddr_t ss; char req[NS_MAXDNAME + 1]; unsigned char *ans = NULL; int anslen; @@ -138,9 +137,15 @@ dnsrbl_check_source(ad, stage, ap, priv) if (dnsrbl_matched(priv, source)) return 1; - /* No IPv6 DNSRBL exists right now */ - if (sa->sa_family != AF_INET) + switch (sa->sa_family) { + case AF_INET: +#ifdef AF_INET6 + case AF_INET6: +#endif + break; + default: return 0; + } blacklisted = SA(&source->d_blacklisted); @@ -172,10 +177,8 @@ dnsrbl_check_source(ad, stage, ap, priv) return 0; } - reverse_endian(SA(&ss), sa); - - if ((iptostring(SA(&ss), salen, req, NS_MAXDNAME)) == NULL){ - mg_log(LOG_ERR, "iptostring failed: %s", strerror(errno)); + if ((iptorevstr(sa, salen, req, NS_MAXDNAME)) == NULL){ + mg_log(LOG_ERR, "iptorevstr failed: %s", strerror(errno)); goto end; } @@ -276,45 +279,41 @@ end: return retval; } - -/* XXX this code is probably broken with IPv6 */ -void -reverse_endian(dst, src) - struct sockaddr *src; - struct sockaddr *dst; +char * +iptorevstr(sa, salen, buf, buflen) + struct sockaddr *sa; + socklen_t salen; + char *buf; + size_t buflen; { - int i, len; - char *src_start; - char *dst_start; + struct in_addr abuf; + char *addr; + int i; - switch (src->sa_family) { + switch (sa->sa_family) { case AF_INET: - src_start = (char *)SADDR4(src); - dst_start = (char *)SADDR4(dst); - len = sizeof(*SADDR4(src)); + addr = (char *)SADDR4(sa); + for (i = 0; i < sizeof(abuf); ++i) + ((char *)&abuf)[sizeof(abuf) - 1 - i] = addr[i]; + if (inet_ntop(sa->sa_family, &abuf, buf, buflen) != NULL) + return buf; break; #ifdef AF_INET6 case AF_INET6: - src_start = (char *)SADDR6(src); - dst_start = (char *)SADDR6(dst); - len = sizeof(*SADDR6(src)); - break; + if (buflen < sizeof(struct in6_addr) * 4) + break; + addr = (char *)SADDR6(sa); + i = sizeof(struct in6_addr) - 1; + sprintf(buf, "%x.%x", addr[i] & 0x0f, (addr[i] & 0xf0) >> 4); + for (--i; i >= 0; --i) + sprintf(buf + (sizeof(struct in6_addr) - i) * 4 - 5, + ".%x.%x", addr[i] & 0x0f, (addr[i] & 0xf0) >> 4); + return buf; #endif default: - mg_log(LOG_ERR, "invalid address family %d", src->sa_family); - exit(EX_SOFTWARE); - break; + return NULL; } - - dst->sa_family = src->sa_family; -#ifdef HAVE_SA_LEN - dst->sa_len = src->sa_len; -#endif - - for (i = 0; i < len; i++) - dst_start[len - 1 - i] = src_start[i]; - - return; + return NULL; } void /* acllist must be write locked */ Index: dnsrbl.h diff -u dnsrbl.h.orig dnsrbl.h --- dnsrbl.h.orig 2007-11-07 09:02:27.000000000 +0900 +++ dnsrbl.h 2015-12-24 11:18:01.304930037 +0900 @@ -54,7 +54,7 @@ void dnsrbl_init(void); int dnsrbl_check_source(acl_data_t *, acl_stage_t, struct acl_param *, struct mlfi_priv *); -void reverse_endian(struct sockaddr *, struct sockaddr *); +char *iptorevstr(struct sockaddr *, socklen_t, char *, size_t); void dnsrbl_source_add(char *, char *, struct sockaddr *, int); struct dnsrbl_entry *dnsrbl_byname(char *); void dnsrbl_clear(void);