diff options
| author | Roy Marples <roy@marples.name> | 2018-05-08 12:27:42 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2018-05-08 12:27:42 +0100 |
| commit | 7e717094d3ad5b9d84941010134e9c7179b253f8 (patch) | |
| tree | 15f21c944084dbd2aeb3f0a428149adc1bf88359 | |
| parent | 766ce48c95982388ad9c23bde67678dde26354f1 (diff) | |
| download | dhcpcd-7e717094d3ad5b9d84941010134e9c7179b253f8.tar.xz | |
dhcp6: match IA type with request
So we don't send IA_NA, IA_TA and IA_PD addresses in the
IA_NA request if they all share the same IAID.
While here, fix a bug where IA_TA addresses would append
the DHCP6 unknown option 0 by mistakenly trying to put T1
and T2 timers in where there should be none.
| -rw-r--r-- | src/dhcp6.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/dhcp6.c b/src/dhcp6.c index 18fb6079..a557632e 100644 --- a/src/dhcp6.c +++ b/src/dhcp6.c @@ -98,6 +98,11 @@ struct dhcp6_ia_na { }; __CTASSERT(sizeof(struct dhcp6_ia_na) == 12); +struct dhcp6_ia_ta { + uint8_t iaid[4]; +}; +__CTASSERT(sizeof(struct dhcp6_ia_ta) == 4); + struct dhcp6_ia_addr { struct in6_addr addr; uint32_t pltime; @@ -629,6 +634,7 @@ dhcp6_makemessage(struct interface *ifp) int fqdn; struct dhcp6_ia_na ia_na; uint16_t ia_na_len; + struct if_ia *ifia; #ifdef AUTH uint16_t auth_len; #endif @@ -899,19 +905,29 @@ dhcp6_makemessage(struct interface *ifp) COPYIN1(D6_OPTION_RAPID_COMMIT, 0); for (l = 0; IA && l < ifo->ia_len; l++) { + ifia = &ifo->ia[l]; o_lenp = NEXTLEN; - ia_na_len = sizeof(ia_na); - memcpy(ia_na.iaid, ifo->ia[l].iaid, sizeof(ia_na.iaid)); + /* TA structure is the same as the others, + * it just lacks the T1 and T2 timers. + * These happen to be at the end of the struct, + * so we just don't copy them in. */ + if (ifia->ia_type == D6_OPTION_IA_TA) + ia_na_len = sizeof(struct dhcp6_ia_ta); + else + ia_na_len = sizeof(ia_na); + memcpy(ia_na.iaid, ifia->iaid, sizeof(ia_na.iaid)); ia_na.t1 = 0; ia_na.t2 = 0; - COPYIN(ifo->ia[l].ia_type, &ia_na, sizeof(ia_na)); + COPYIN(ifia->ia_type, &ia_na, ia_na_len); TAILQ_FOREACH(ap, &state->addrs, next) { if (ap->flags & IPV6_AF_STALE) continue; if (ap->prefix_vltime == 0 && !(ap->flags & IPV6_AF_REQUEST)) continue; - if (memcmp(ifo->ia[l].iaid, ap->iaid, sizeof(uint32_t))) + if (ap->ia_type != ifia->ia_type) + continue; + if (memcmp(ap->iaid, ifia->iaid, sizeof(ap->iaid))) continue; if (ap->ia_type == D6_OPTION_IA_PD) { #ifndef SMALL |
