// Sockets
static int sock = -1;
static int ifindex = -1;
-static time_t t1 = 0, t2 = 0, t3 = 0;
+static int64_t t1 = 0, t2 = 0, t3 = 0;
// IA states
static int request_prefix = -1;
htons(DHCPV6_OPT_DNS_DOMAIN),
htons(DHCPV6_OPT_NTP_SERVER),
htons(DHCPV6_OPT_SIP_SERVER_A),
- htons(DHCPV6_OPT_SIP_SERVER_D)};
+ htons(DHCPV6_OPT_PREFIX_CLASS)
+ };
odhcp6c_add_state(STATE_ORO, oro, sizeof(oro));
for (size_t i = 0; i < ia_pd_entries; ++i) {
p[i].type = htons(DHCPV6_OPT_IA_PREFIX);
p[i].len = htons(sizeof(p[i]) - 4U);
- p[i].preferred = htonl(e[i].preferred);
- p[i].valid = htonl(e[i].valid);
+ p[i].preferred = 0;
+ p[i].valid = 0;
p[i].prefix = e[i].length;
p[i].addr = e[i].target;
}
pa[i].type = htons(DHCPV6_OPT_IA_ADDR);
pa[i].len = htons(sizeof(pa[i]) - 4U);
pa[i].addr = e[i].target;
- pa[i].preferred = htonl(e[i].preferred);
- pa[i].valid = htonl(e[i].valid);
+ pa[i].preferred = 0;
+ pa[i].valid = 0;
}
ia_na = pa;
cand.preference -= 2000;
} else if (otype == DHCPV6_OPT_PREF && olen >= 1 &&
cand.preference >= 0) {
- cand.preference = odata[1];
+ cand.preference = odata[0];
} else if (otype == DHCPV6_OPT_RECONF_ACCEPT) {
cand.wants_reconfigure = true;
} else if (otype == DHCPV6_OPT_IA_PD && request_prefix) {
if (t3 < 0)
t3 = 0;
} else {
- t1 = t2 = t3 = 86400;
+ t1 = t2 = t3 = UINT32_MAX;
}
if (opt) {
if (ia_hdr->iaid != 1 || l_t2 < l_t1)
continue;
+ bool error = false;
uint16_t stype, slen;
uint8_t *sdata;
// Test status and bail if error
stype, slen, sdata)
if (stype == DHCPV6_OPT_STATUS && slen >= 2 &&
(sdata[0] || sdata[1]))
- continue;
+ error = true;
+
+ if (error)
+ continue;
// Update times
if (l_t1 > 0 && t1 > l_t1)
if (n < t3)
t3 = n;
+ if (t2 >= t3)
+ t2 = 8 * t3 / 10;
+
+ if (t1 >= t2)
+ t1 = 5 * t2 / 8;
+
} else if (otype == DHCPV6_OPT_DNS_SERVERS) {
if (olen % 16 == 0)
odhcp6c_add_state(STATE_DNS, odata, olen);
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));
odhcp6c_update_entry(STATE_IA_PD, &entry);
} else if (otype == DHCPV6_OPT_IA_ADDR) {