]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/dhcpv6.c
Fix handling of DHCPv6 replies containing unrequested IA_NA/IA_PD options
[odhcp6c.git] / src / dhcpv6.c
index cb2aa76f7c7ba01de307ca59f991ad2b9baf0bfc..6ae6f7a02fd8d9040fc8b676cd81a73d361d21c6 100644 (file)
@@ -328,6 +328,11 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs)
                                        .addr = e[j].target
                                };
 
+                               if (type == DHCPV6_MSG_REQUEST) {
+                                       p.preferred = htonl(e[j].preferred);
+                                       p.valid = htonl(e[j].valid);
+                               }
+
                                memcpy(ia_pd + ia_pd_len, &p, sizeof(p));
                                ia_pd_len += sizeof(p);
 
@@ -372,8 +377,14 @@ static void dhcpv6_send(enum dhcpv6_msg type, uint8_t trid[3], uint32_t ecs)
                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 = 0;
-               pa[i].valid = 0;
+
+               if (type == DHCPV6_MSG_REQUEST) {
+                       pa[i].preferred = htonl(e[i].preferred);
+                       pa[i].valid = htonl(e[i].valid);
+               } else {
+                       pa[i].preferred = 0;
+                       pa[i].valid = 0;
+               }
        }
 
        ia_na = pa;
@@ -874,7 +885,7 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
 {
        uint8_t *odata;
        uint16_t otype, olen;
-       uint32_t refresh = UINT32_MAX;
+       uint32_t refresh = 86400;
        int ret = 1;
        bool handled_status_codes[_DHCPV6_Status_Max] = { false, };
 
@@ -936,6 +947,10 @@ static int dhcpv6_handle_reply(enum dhcpv6_msg orig, _unused const int rc,
                                && olen > -4 + sizeof(struct dhcpv6_ia_hdr)) {
                        struct dhcpv6_ia_hdr *ia_hdr = (void*)(&odata[-4]);
 
+                       if ((na_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_NA) ||
+                           (pd_mode == IA_MODE_NONE && otype == DHCPV6_OPT_IA_PD))
+                               continue;
+
                        // Test ID
                        if (ia_hdr->iaid != htonl(1) && otype == DHCPV6_OPT_IA_NA)
                                continue;
@@ -1202,7 +1217,7 @@ static int dhcpv6_parse_ia(void *opt, void *end)
                        }
 
                        if (ok) {
-                               odhcp6c_update_entry(STATE_IA_PD, &entry);
+                               odhcp6c_update_entry(STATE_IA_PD, &entry, 0, false);
                                parsed_ia++;
                        }
 
@@ -1237,7 +1252,7 @@ static int dhcpv6_parse_ia(void *opt, void *end)
                                        entry.class = sdata[0] << 8 | sdata[1];
 #endif
 
-                       odhcp6c_update_entry(STATE_IA_NA, &entry);
+                       odhcp6c_update_entry(STATE_IA_NA, &entry, 0, false);
                        parsed_ia++;
                }
        }