ref: 1a919327313d87ca7797928b3cbad80cb40d5167
parent: 248634879a9b78f08ddaeda9c7a50ba413fd4804
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Dec 23 11:12:35 EST 2024
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).
--- a/sys/src/cmd/ip/dhcpd/dat.h
+++ b/sys/src/cmd/ip/dhcpd/dat.h
@@ -49,8 +49,6 @@
/* 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 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);
--- a/sys/src/cmd/ip/dhcpd/db.c
+++ b/sys/src/cmd/ip/dhcpd/db.c
@@ -412,3 +412,22 @@
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;
+}
--- a/sys/src/cmd/ip/dhcpd/dhcpd.c
+++ b/sys/src/cmd/ip/dhcpd/dhcpd.c
@@ -191,7 +191,6 @@
void sendoffer(Req*, uchar*, int);
void stringopt(Req*, int, char*);
void termopt(Req*);
-int validip(uchar*);
void vectoropt(Req*, int, uchar*, int);
void
@@ -1387,26 +1386,6 @@
if(p == nil || *p == 0)
return "unknown";
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
--- a/sys/src/cmd/ip/dhcpd/dhcpleases.c
+++ b/sys/src/cmd/ip/dhcpd/dhcpleases.c
@@ -35,7 +35,9 @@
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,
--- a/sys/src/cmd/ip/dhcpd/ndb.c
+++ b/sys/src/cmd/ip/dhcpd/ndb.c
@@ -57,19 +57,19 @@
}
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 */
}
--
⑨