From 790a516884e45ee2a3a11b915f5e125a0ccb02ca Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 27 Oct 2024 09:09:15 +0000 Subject: [PATCH] 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. --- sys/src/cmd/ip/ipconfig/dhcpv6.c | 28 +++++++++++++++++++++------- sys/src/cmd/ip/ipconfig/ipv6.c | 9 +++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/sys/src/cmd/ip/ipconfig/dhcpv6.c b/sys/src/cmd/ip/ipconfig/dhcpv6.c index 3dc443fc7..013ea4e10 100644 --- a/sys/src/cmd/ip/ipconfig/dhcpv6.c +++ b/sys/src/cmd/ip/ipconfig/dhcpv6.c @@ -189,16 +189,26 @@ Response: 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; + if(len < IPaddrlen) break; - p += 4; - memset(conf.mask, 0xFF, IPaddrlen); memmove(conf.laddr, p, IPaddrlen); continue; case 0x17: /* dns servers */ @@ -221,10 +231,14 @@ dhcpv6query(void) { 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)) diff --git a/sys/src/cmd/ip/ipconfig/ipv6.c b/sys/src/cmd/ip/ipconfig/ipv6.c index dffc83c37..cdf5ad8e9 100644 --- a/sys/src/cmd/ip/ipconfig/ipv6.c +++ b/sys/src/cmd/ip/ipconfig/ipv6.c @@ -588,6 +588,8 @@ recvrahost(uchar buf[], int pktlen) 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 @@ recvrahost(uchar buf[], int pktlen) 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; @@ -798,6 +800,9 @@ recvrahost(uchar buf[], int pktlen) refresh(); } + /* pass gateway to dhcpv6 if it is managed network */ + ipmove(conf.gaddr, conf.mflag? ra->src: IPnoaddr); + return 0; }