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.
This commit is contained in:
cinap_lenrek 2024-10-27 09:09:15 +00:00
parent a916137c97
commit 790a516884
2 changed files with 28 additions and 9 deletions

View file

@ -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))

View file

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