ref: 98e7f36f706c21d015af5001a643c0bb64a7aa5d
parent: 47d939a26a95b58e189aa1533530920a9fd50c32
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 */
}
--
⑨