From 1a919327313d87ca7797928b3cbad80cb40d5167 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 23 Dec 2024 16:12:35 +0000 Subject: [PATCH] ip/dhcpd: impvoe validip(), make validipmask() reject ipv6 masks Because isv4() is never true for IPnoaddr, we can skip the check. Make validipmask() ensure that the top IPv4off bytes are all 0xff, then check that the low 4 bytes are a valid mask (must be a power of two minus one). --- sys/src/cmd/ip/dhcpd/dat.h | 4 ++-- sys/src/cmd/ip/dhcpd/db.c | 19 +++++++++++++++++++ sys/src/cmd/ip/dhcpd/dhcpd.c | 21 --------------------- sys/src/cmd/ip/dhcpd/dhcpleases.c | 4 +++- sys/src/cmd/ip/dhcpd/ndb.c | 14 +++++++------- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/sys/src/cmd/ip/dhcpd/dat.h b/sys/src/cmd/ip/dhcpd/dat.h index 80052674b..a2062fc95 100644 --- a/sys/src/cmd/ip/dhcpd/dat.h +++ b/sys/src/cmd/ip/dhcpd/dat.h @@ -49,8 +49,6 @@ struct Info /* from dhcp.c */ -extern int validip(uchar*); -extern int validipmask(uchar*); extern void fatal(char*, ...); extern void warning(char*, ...); #pragma varargck argpos fatal 1 @@ -58,6 +56,8 @@ extern void warning(char*, ...); extern int minlease; /* from db.c */ +extern int validip(uchar*); +extern int validipmask(uchar*); extern char* toid(uchar*, int); extern void initbinding(uchar*, int); extern Binding* iptobinding(uchar*, int); diff --git a/sys/src/cmd/ip/dhcpd/db.c b/sys/src/cmd/ip/dhcpd/db.c index 80d072ed6..d20a5a4bd 100644 --- a/sys/src/cmd/ip/dhcpd/db.c +++ b/sys/src/cmd/ip/dhcpd/db.c @@ -412,3 +412,22 @@ releasebinding(Binding *b, char *id) close(fd); return 0; } + +int +validip(uchar *ip) +{ + if(ipcmp(ip, v4prefix) == 0) + return 0; + return isv4(ip); +} + +int +validipmask(uchar *mask) +{ + unsigned x; + + if(memcmp(mask, IPallbits, IPv4off) != 0) + return 0; + x = ~(mask[IPv4off+0] << 24 | mask[IPv4off+1] << 16 | mask[IPv4off+2] << 8 | mask[IPv4off+3]); + return ((x + 1U) & x) == 0; +} diff --git a/sys/src/cmd/ip/dhcpd/dhcpd.c b/sys/src/cmd/ip/dhcpd/dhcpd.c index 22a60b584..8c6727a6a 100644 --- a/sys/src/cmd/ip/dhcpd/dhcpd.c +++ b/sys/src/cmd/ip/dhcpd/dhcpd.c @@ -191,7 +191,6 @@ void sendnak(Req*, uchar*, char*); void sendoffer(Req*, uchar*, int); void stringopt(Req*, int, char*); void termopt(Req*); -int validip(uchar*); void vectoropt(Req*, int, uchar*, int); void @@ -1389,26 +1388,6 @@ readsysname(void) return p; } -extern int -validip(uchar *ip) -{ - if(ipcmp(ip, IPnoaddr) == 0) - return 0; - if(ipcmp(ip, v4prefix) == 0) - return 0; - return isv4(ip); -} - -extern int -validipmask(uchar *ip) -{ - if(ipcmp(ip, IPnoaddr) == 0) - return 0; - if(ipcmp(ip, v4prefix) == 0) - return 0; - return 1; -} - void longopt(Req *rp, int t, long v) { diff --git a/sys/src/cmd/ip/dhcpd/dhcpleases.c b/sys/src/cmd/ip/dhcpd/dhcpleases.c index 7e027923d..fffcfd39a 100644 --- a/sys/src/cmd/ip/dhcpd/dhcpleases.c +++ b/sys/src/cmd/ip/dhcpd/dhcpleases.c @@ -35,7 +35,9 @@ main(void) b.lease = b.offer = 0; now = time(0); for(i = 0; i < nall; i++){ - if(parseip(b.ip, all[i].name) == -1 || syncbinding(&b, 0) < 0) + if(parseip(b.ip, all[i].name) == -1 + || !validip(b.ip) + || syncbinding(&b, 0) < 0) continue; if(b.lease > now) print("%I leased by %s until %s", b.ip, b.boundto, diff --git a/sys/src/cmd/ip/dhcpd/ndb.c b/sys/src/cmd/ip/dhcpd/ndb.c index da0244868..91fb1751c 100644 --- a/sys/src/cmd/ip/dhcpd/ndb.c +++ b/sys/src/cmd/ip/dhcpd/ndb.c @@ -57,19 +57,19 @@ localip(uchar *laddr, uchar *raddr, Ipifc *ifc) } static void -setipaddr(uchar *addr, char *ip) +setipaddr(uchar *ip, char *s) { - if(ipcmp(addr, IPnoaddr) == 0) - if(parseip(addr, ip) == -1 - || !validip(addr)) - ipmove(addr, IPnoaddr); /* invalid */ + if(ipcmp(ip, IPnoaddr) == 0) + if(parseip(ip, s) == -1 + || !validip(ip)) + ipmove(ip, IPnoaddr); /* invalid */ } static void -setipmask(uchar *mask, char *ip) +setipmask(uchar *mask, char *s) { if(ipcmp(mask, IPnoaddr) == 0) - if(parseipmask(mask, ip, 1) == -1 + if(parseipmask(mask, s, 1) == -1 || !validipmask(mask)) ipmove(mask, IPnoaddr); /* invalid */ }