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 03:29:26.479821000 +0900 @@ -138,9 +138,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); @@ -174,8 +180,8 @@ dnsrbl_check_source(ad, stage, ap, priv) 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(&ss), salen, req, NS_MAXDNAME)) == NULL){ + mg_log(LOG_ERR, "iptorevstr failed: %s", strerror(errno)); goto end; } @@ -277,7 +283,6 @@ end: } -/* XXX this code is probably broken with IPv6 */ void reverse_endian(dst, src) struct sockaddr *src; @@ -317,6 +322,41 @@ reverse_endian(dst, src) return; } +char * +iptorevstr(sa, salen, buf, buflen) + struct sockaddr *sa; + socklen_t salen; + char *buf; + size_t buflen; +{ + void *addr; + char *addr6; + int i; + + switch (sa->sa_family) { + case AF_INET: + addr = (void *)SADDR4(sa); + if (inet_ntop(sa->sa_family, addr, buf, buflen) != NULL) + return buf; + break; +#ifdef AF_INET6 + case AF_INET6: + if (buflen < sizeof(struct in6_addr) * 4) + break; + addr6 = (char *)SADDR6(sa); + sprintf(buf, "%x.%x", addr6[i] & 0x0f, (addr6[i] & 0xf0) >> 4); + for (i = 1; i < sizeof(struct in6_addr); ++i) { + sprintf(buf + i * 4 - 1, ".%x.%x", + addr6[i] & 0x0f, (addr6[i] & 0xf0) >> 4); + } + return buf; +#endif + default: + return NULL; + } + return NULL; +} + void /* acllist must be write locked */ dnsrbl_source_add(name, domain, blacklisted, cidr) char *name; 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 03:26:03.856861429 +0900 @@ -55,6 +55,7 @@ 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);