shithub: front

Download patch

ref: 790a516884e45ee2a3a11b915f5e125a0ccb02ca
parent: a916137c973c6f0d3c3da14eb5a3d8ca735525fc
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Oct 27 05:09:15 EDT 2024

ip/ipconfig: handle dhcpv6 IA options, pass gateway from RA

The IA options where not parsed properly, assuming option 5
is the first option.

For managed networks, we might not get any prefix info
options, but dhcpv6 needs a gateway, so use source address
of the RA.

--- a/sys/src/cmd/ip/ipconfig/dhcpv6.c
+++ b/sys/src/cmd/ip/ipconfig/dhcpv6.c
@@ -189,16 +189,26 @@
 			memmove(sid, p, sidlen);
 			continue;
 		case 0x03:		/* IA for non-temporary address */
-			if(p+12+4+IPaddrlen+2*4 > x)
+			if(p+12 > x)
 				break;
 			/* skip IAID, T1, T2 */
 			p += 12;
+			/* find IA Address option */
+			while(p + 4 <= x) {
+				opt = (int)p[0] << 8 | p[1];
+				len = (int)p[2] << 8 | p[3];
+				p += 4;
+				if(p + len > x)
+					break;
+				if(opt == 5)
+					break;
+				p += len;
+			}
 			/* IA Addresss */
-			if(p[0] != 0x00 || p[1] != 0x05
-			|| p[2] != 0x00 || p[3] != IPaddrlen+2*4)
+			if(opt != 5)
 				break;
-			p += 4;
-			memset(conf.mask, 0xFF, IPaddrlen);
+			if(len < IPaddrlen)
+				break;
 			memmove(conf.laddr, p, IPaddrlen);
 			continue;
 		case 0x17:	/* dns servers */
@@ -221,10 +231,14 @@
 {
 	int fd;
 
-	if(!dodhcp || conf.duidlen <= 0)
-		return;
+	ipmove(conf.laddr, IPnoaddr);
+	memset(conf.mask, 0xFF, IPaddrlen);
 
+	if(conf.duidlen <= 0)
+		return;
 	fd = openlisten();
+	if(fd < 0)
+		return;
 	if(transaction(fd, SOLICIT, 5000) < 0)
 		goto out;
 	if(!validip(conf.laddr))
--- a/sys/src/cmd/ip/ipconfig/ipv6.c
+++ b/sys/src/cmd/ip/ipconfig/ipv6.c
@@ -588,6 +588,8 @@
 	if(!ISIPV6LINKLOCAL(ra->src))
 		return -1;
 
+	DEBUG("got RA from %I on %s; flags %x", ra->src, conf.dev, ra->mor);
+
 	conf.ttl = ra->cttl;
 	conf.mflag = (MFMASK & ra->mor) != 0;
 	conf.oflag = (OCMASK & ra->mor) != 0;
@@ -785,8 +787,8 @@
 		if(conf.preflt == 0)
 			continue;
 
-		DEBUG("got RA from %I on %s; pfx %I %M",
-			ra->src, conf.dev, conf.v6pref, conf.mask);
+		DEBUG("got prefix %I %M via %I on %s",
+			conf.v6pref, conf.mask, conf.gaddr, conf.dev);
 
 		if(noconfig)
 			continue;
@@ -797,6 +799,9 @@
 		putndb(1);
 		refresh();
 	}
+
+	/* pass gateway to dhcpv6 if it is managed network */
+	ipmove(conf.gaddr, conf.mflag? ra->src: IPnoaddr);
 
 	return 0;
 }
--