htons(DHCPV6_OPT_DNS_SERVERS),
htons(DHCPV6_OPT_DNS_DOMAIN),
htons(DHCPV6_OPT_NTP_SERVER),
+ htons(DHCPV6_OPT_SIP_SERVER_A),
htons(DHCPV6_OPT_AFTR_NAME),
htons(DHCPV6_OPT_PD_EXCLUDE),
+ htons(DHCPV6_OPT_PREFIX_CLASS),
};
odhcp6c_add_state(STATE_ORO, oro, sizeof(oro));
else if (type == DHCPV6_MSG_UNKNOWN)
timeout = t1;
else if (type == DHCPV6_MSG_RENEW)
- timeout = t2 - t1;
+ timeout = (t2 > t1) ? t2 - t1 : 0;
else if (type == DHCPV6_MSG_REBIND)
- timeout = t3 - t2;
+ timeout = (t3 > t2) ? t3 - t2 : 0;
if (timeout == 0)
return -1;
if (error)
continue;
- // Update times
- if (l_t1 > 0 && t1 > l_t1)
- t1 = l_t1;
-
- if (l_t2 > 0 && t2 > l_t2)
- t2 = l_t2;
-
uint32_t n = dhcpv6_parse_ia(&ia_hdr[1], odata + olen);
- if (n < t1)
- t1 = n;
+ if (!l_t1)
+ l_t1 = 300;
- if (n < t2)
- t2 = n;
+ if (!l_t2)
+ l_t2 = 600;
if (n < t3)
t3 = n;
- if (t2 >= t3)
- t2 = 8 * t3 / 10;
+ // Update times
+ if (l_t1 > 0 && t1 > l_t1)
+ t1 = l_t1;
- if (t1 >= t2)
- t1 = 5 * t2 / 8;
+ if (l_t2 > 0 && t2 > l_t2)
+ t2 = l_t2;
} else if (otype == DHCPV6_OPT_DNS_SERVERS) {
if (olen % 16 == 0)
uint16_t otype, olen;
uint8_t *odata;
- struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT,
- 0, 0, IN6ADDR_ANY_INIT, 0, 0};
-
// Update address IA
dhcpv6_for_each_option(opt, end, otype, olen, odata) {
+ struct odhcp6c_entry entry = {IN6ADDR_ANY_INIT,
+ 0, 0, IN6ADDR_ANY_INIT, 0, 0, 0};
+
if (otype == DHCPV6_OPT_IA_PREFIX) {
struct dhcpv6_ia_prefix *prefix = (void*)&odata[-4];
if (olen + 4U < sizeof(*prefix))
entry.length = prefix->prefix;
entry.target = prefix->addr;
+ uint16_t stype, slen;
+ uint8_t *sdata;
+
+ // Find prefix class, if any
+ dhcpv6_for_each_option(&prefix[1], odata + olen,
+ stype, slen, sdata)
+ if (stype == DHCPV6_OPT_PREFIX_CLASS && slen == 2)
+ entry.prefix_class = ntohs(*((uint16_t*)sdata));
// Parse PD-exclude
bool ok = true;
- uint16_t stype, slen;
- uint8_t *sdata;
dhcpv6_for_each_option(odata + sizeof(*prefix) - 4U,
odata + olen, stype, slen, sdata) {
if (stype != DHCPV6_OPT_PD_EXCLUDE || slen < 2)
entry.length = 128;
entry.target = addr->addr;
+ uint16_t stype, slen;
+ uint8_t *sdata;
+
+ // Find prefix class, if any
+ dhcpv6_for_each_option(&addr[1], odata + olen,
+ stype, slen, sdata)
+ if (stype == DHCPV6_OPT_PREFIX_CLASS && slen == 2)
+ entry.prefix_class = ntohs(*((uint16_t*)sdata));
+
odhcp6c_update_entry(STATE_IA_NA, &entry);
}