]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp6: do not set T1 and T2 by dhcp6_option_append_ia() in client
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 22 Feb 2021 12:54:32 +0000 (21:54 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 23 Feb 2021 10:36:37 +0000 (19:36 +0900)
src/libsystemd-network/dhcp6-option.c
src/libsystemd-network/test-dhcp6-client.c

index 8a590b9c81ddffeb59bd2598e899eb2675df47ca..0b32acd38a25666c8d2b0c37893b62efa4f07692 100644 (file)
@@ -113,10 +113,13 @@ int dhcp6_option_append_vendor_option(uint8_t **buf, size_t *buflen, OrderedHash
 }
 
 int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
-        uint16_t len;
-        uint8_t *ia_hdr;
-        size_t iaid_offset, ia_buflen, ia_addrlen = 0;
+        size_t ia_buflen, ia_addrlen = 0;
+        struct ia_na ia_na;
+        struct ia_ta ia_ta;
         DHCP6Address *addr;
+        uint8_t *ia_hdr;
+        uint16_t len;
+        void *p;
         int r;
 
         assert_return(buf, -EINVAL);
@@ -124,15 +127,23 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
         assert_return(buflen, -EINVAL);
         assert_return(ia, -EINVAL);
 
+        /* client should not send set T1 and T2. See, RFC 8415, and issue #18090. */
+
         switch (ia->type) {
         case SD_DHCP6_OPTION_IA_NA:
                 len = DHCP6_OPTION_IA_NA_LEN;
-                iaid_offset = offsetof(DHCP6IA, ia_na);
+                ia_na = (struct ia_na) {
+                        .id = ia->ia_na.id,
+                };
+                p = &ia_na;
                 break;
 
         case SD_DHCP6_OPTION_IA_TA:
                 len = DHCP6_OPTION_IA_TA_LEN;
-                iaid_offset = offsetof(DHCP6IA, ia_ta);
+                ia_ta = (struct ia_ta) {
+                        .id = ia->ia_ta.id,
+                };
+                p = &ia_ta;
                 break;
 
         default:
@@ -148,30 +159,29 @@ int dhcp6_option_append_ia(uint8_t **buf, size_t *buflen, const DHCP6IA *ia) {
         *buf += offsetof(DHCP6Option, data);
         *buflen -= offsetof(DHCP6Option, data);
 
-        memcpy(*buf, (char*) ia + iaid_offset, len);
+        memcpy(*buf, p, len);
 
         *buf += len;
         *buflen -= len;
 
         LIST_FOREACH(addresses, addr, ia->addresses) {
-                r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR,
-                                      sizeof(addr->iaaddr));
+                struct iaaddr a = {
+                        .address = addr->iaaddr.address,
+                };
+
+                r = option_append_hdr(buf, buflen, SD_DHCP6_OPTION_IAADDR, sizeof(struct iaaddr));
                 if (r < 0)
                         return r;
 
-                memcpy(*buf, &addr->iaaddr, sizeof(addr->iaaddr));
+                memcpy(*buf, &a, sizeof(struct iaaddr));
 
-                *buf += sizeof(addr->iaaddr);
-                *buflen -= sizeof(addr->iaaddr);
+                *buf += sizeof(struct iaaddr);
+                *buflen -= sizeof(struct iaaddr);
 
-                ia_addrlen += offsetof(DHCP6Option, data) + sizeof(addr->iaaddr);
+                ia_addrlen += offsetof(DHCP6Option, data) + sizeof(struct iaaddr);
         }
 
-        r = option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
-        if (r < 0)
-                return r;
-
-        return 0;
+        return option_append_hdr(&ia_hdr, &ia_buflen, ia->type, len + ia_addrlen);
 }
 
 int dhcp6_option_append_fqdn(uint8_t **buf, size_t *buflen, const char *fqdn) {
index e6a43dcd5eec44d62bade6ccff2515e78cf521c5..cb363b3973ff244dc8050eed8dc819f6435ff185 100644 (file)
@@ -650,12 +650,12 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
                         assert_se(optlen == 40);
                         assert_se(!memcmp(optval, &test_iaid, sizeof(test_iaid)));
 
-                        val = htobe32(80);
+                        /* T1 and T2 should not be set. */
+                        val = 0;
                         assert_se(!memcmp(optval + 4, &val, sizeof(val)));
-
-                        val = htobe32(120);
                         assert_se(!memcmp(optval + 8, &val, sizeof(val)));
 
+                        /* Then, this should refuse all addresses. */
                         assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
 
                         break;
@@ -694,14 +694,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
                   found_elapsed_time);
 
         sd_dhcp6_lease_reset_address_iter(lease);
-        assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
-                                             &lt_valid) >= 0);
-        assert_se(!memcmp(&addr, &msg_advertise[42], sizeof(addr)));
-        assert_se(lt_pref == 150);
-        assert_se(lt_valid == 180);
-
-        assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref,
-                                             &lt_valid) == -ENOMSG);
+        assert_se(sd_dhcp6_lease_get_address(lease, &addr, &lt_pref, &lt_valid) == -ENOMSG);
 
         return 0;
 }