X-Git-Url: https://git.decadent.org.uk/gitweb/?p=odhcp6c.git;a=blobdiff_plain;f=src%2Fdhcpv6.c;h=a3e0a18e50ec1644b07110e371ac52bd6283ce27;hp=bc403b9faaae6c65015182ee1b482c7047ff99b3;hb=4a169b02b003fe50b2bccdf6b8c78a4de245669f;hpb=7c604492735809a6571623645a0b2d1f37e12d40 diff --git a/src/dhcpv6.c b/src/dhcpv6.c index bc403b9..a3e0a18 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -216,10 +216,19 @@ enum { IOV_TOTAL }; -void dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd) +int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd) { + int mode = DHCPV6_UNKNOWN; + na_mode = na; pd_mode = pd; + + if (na_mode == IA_MODE_NONE && pd_mode == IA_MODE_NONE) + mode = DHCPV6_STATELESS; + else if (na_mode == IA_MODE_FORCE || pd_mode == IA_MODE_FORCE) + mode = DHCPV6_STATEFUL; + + return mode; } static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) @@ -263,17 +272,21 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs) for (size_t i = 0; i < n_prefixes; i++) { struct dhcpv6_ia_hdr hdr_ia_pd = { htons(DHCPV6_OPT_IA_PD), - htons(sizeof(hdr_ia_pd) - 4 + sizeof(struct dhcpv6_ia_prefix)), + htons(sizeof(hdr_ia_pd) - 4 + + sizeof(struct dhcpv6_ia_prefix) * !!request_prefixes[i].length), request_prefixes[i].iaid, 0, 0 }; struct dhcpv6_ia_prefix pref = { .type = htons(DHCPV6_OPT_IA_PREFIX), - .len = htons(25), .prefix = request_prefixes[i].length + .len = htons(sizeof(pref) - 4), + .prefix = request_prefixes[i].length }; memcpy(ia_pd + ia_pd_len, &hdr_ia_pd, sizeof(hdr_ia_pd)); ia_pd_len += sizeof(hdr_ia_pd); - memcpy(ia_pd + ia_pd_len, &pref, sizeof(pref)); - ia_pd_len += sizeof(pref); + if (request_prefixes[i].length) { + memcpy(ia_pd + ia_pd_len, &pref, sizeof(pref)); + ia_pd_len += sizeof(pref); + } } } else { struct odhcp6c_entry *e = odhcp6c_get_state(STATE_IA_PD, &ia_pd_entries); @@ -547,10 +560,15 @@ int dhcpv6_request(enum dhcpv6_msg type) round_end = timeout * 1000 + start; // Built and send package - if (type != DHCPV6_MSG_UNKNOWN) { - if (type != DHCPV6_MSG_SOLICIT) - syslog(LOG_NOTICE, "Send %s message (elapsed %llums, rc %d)", - retx->name, (unsigned long long)elapsed, rc); + switch (type) { + case DHCPV6_MSG_UNKNOWN: + break; + default: + syslog(LOG_NOTICE, "Send %s message (elapsed %llums, rc %d)", + retx->name, (unsigned long long)elapsed, rc); + // Fall through + case DHCPV6_MSG_SOLICIT: + case DHCPV6_MSG_INFO_REQ: dhcpv6_send(type, trid, elapsed / 10); rc++; } @@ -934,6 +952,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc, odhcp6c_clear_state(STATE_S46_MAPE); odhcp6c_clear_state(STATE_S46_LW); odhcp6c_clear_state(STATE_PASSTHRU); + odhcp6c_clear_state(STATE_CUSTOM_OPTS); // Parse and find all matching IAs dhcpv6_for_each_option(opt, end, otype, olen, odata) {