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;
}
--
⑨