From eda1a2a69882c1d53936aada626820260709406a Mon Sep 17 00:00:00 2001 From: "Joseph C. Lehner" Date: Sat, 19 Nov 2016 13:02:29 +0100 Subject: [PATCH] Check subnet mask's sanity --- nmrp.c | 4 +++- nmrpd.h | 2 ++ util.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/nmrp.c b/nmrp.c index da665cf..c1bfb9c 100644 --- a/nmrp.c +++ b/nmrp.c @@ -430,7 +430,9 @@ int nmrp_do(struct nmrpd_args *args) return 1; } - if ((ipconf.mask.s_addr = inet_addr(args->ipmask)) == INADDR_NONE) { + ipconf.mask.s_addr = inet_addr(args->ipmask); + if (ipconf.mask.s_addr == INADDR_NONE + || netmask(bitcount(ipconf.mask.s_addr)) != ipconf.mask.s_addr) { fprintf(stderr, "Invalid subnet mask '%s'.\n", args->ipmask); return 1; } diff --git a/nmrpd.h b/nmrpd.h index e061155..af9699a 100644 --- a/nmrpd.h +++ b/nmrpd.h @@ -133,4 +133,6 @@ int ethsock_ip_del(struct ethsock *sock, struct ethsock_ip_undo **undo); time_t time_monotonic(); char *lltostr(long long ll, int base); +uint32_t bitcount(uint32_t n); +uint32_t netmask(uint32_t count); #endif diff --git a/util.c b/util.c index 4422442..a1b2c52 100644 --- a/util.c +++ b/util.c @@ -35,3 +35,17 @@ char *lltostr(long long ll, int base) snprintf(buf, sizeof(buf) - 1, (base == 16 ? "%llx" : (base == 8 ? "%llo" : "%lld")), ll); return buf; } + +uint32_t bitcount(uint32_t n) +{ + uint32_t c; + for (c = 0; n; ++c) { + n &= n - 1; + } + return c; +} + +uint32_t netmask(uint32_t count) +{ + return htonl(count <= 32 ? 0xffffffff << (32 - count) : 0); +} -- 2.25.1