From 95bee3e1cb676e462750a8c46cf6439a3e3e6cc0 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sat, 3 May 2014 15:35:29 +0100 Subject: [PATCH] src/setup.c: Check netmask more carefully. [crybaby ~/src/adns/build]RES_CONF_TEXT="sortlist 172.29.199.1/24" RES_OPTIONS="adns_checkc:entex" adnshost -ta www-cache.distorted.org.uk adnshost: ../src/check.c:83: checkc_global: Assertion `!(ads->sortlist[i].base.s_addr & ~ads->sortlist[i].mask.s_addr)' failed. Aborted Unfortunately, `ccf_sortlist' only checked that the free bits of the network address are clear when given a general netmask, so if you give a prefix length or leave it implicit then you hit a consistency check failure later. Check the mask later on, after all of the variants are handled. There's a little bit of variation in the message. Signed-off-by: Mark Wooding --- src/setup.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/setup.c b/src/setup.c index 96a2a21..f73926c 100644 --- a/src/setup.c +++ b/src/setup.c @@ -152,6 +152,7 @@ static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) { const char *word; char tbuf[200], *slash, *ep; + const char *maskwhat; struct in_addr base, mask; int l; unsigned long initial, baselocal; @@ -182,16 +183,13 @@ static void ccf_sortlist(adns_state ads, const char *fn, if (slash) { if (strchr(slash,'.')) { + maskwhat = "mask"; if (!inet_aton(slash,&mask)) { configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash); continue; } - if (base.s_addr & ~mask.s_addr) { - configparseerr(ads,fn,lno, "mask `%s' in sortlist" - " overlaps address `%s'",slash,tbuf); - continue; - } } else { + maskwhat = "prefix length"; initial= strtoul(slash,&ep,10); if (*ep || initial>32) { configparseerr(ads,fn,lno,"mask length `%s' invalid",slash); @@ -200,6 +198,7 @@ static void ccf_sortlist(adns_state ads, const char *fn, mask.s_addr= htonl((0x0ffffffffUL) << (32-initial)); } } else { + maskwhat = "implied mask"; baselocal= ntohl(base.s_addr); if (!(baselocal & 0x080000000UL)) /* class A */ mask.s_addr= htonl(0x0ff000000UL); @@ -215,6 +214,13 @@ static void ccf_sortlist(adns_state ads, const char *fn, } } + if (base.s_addr & ~mask.s_addr) { + configparseerr(ads,fn,lno, "%s `%s' in sortlist" + " overlaps address `%s'",maskwhat, + slash ? slash : inet_ntoa(mask), tbuf); + continue; + } + ads->sortlist[ads->nsortlist].base= base; ads->sortlist[ads->nsortlist].mask= mask; ads->nsortlist++; -- 2.30.2