]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add foreign handlers for DHCPv6
authorAlan T. DeKok <aland@freeradius.org>
Sun, 28 Jan 2024 16:22:37 +0000 (11:22 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 28 Jan 2024 16:22:37 +0000 (11:22 -0500)
share/dictionary/radius/dictionary.rfc9445
src/protocols/dhcpv6/base.c
src/protocols/dhcpv6/decode.c
src/protocols/dhcpv6/dhcpv6.h
src/protocols/dhcpv6/encode.c
src/tests/unit/protocols/radius/foreign.txt

index e1745e251441309e1fe628b6503c0a8c4d792f8f..efd3ecd3697393ca82a69dba0ca2f6f9a4fccf16 100644 (file)
@@ -8,5 +8,5 @@
 #
 #      $Id$
 #
-ATTRIBUTE      DHCPv6-Options                          245.3   octets # formatted as DHCPv6 options
+ATTRIBUTE      DHCPv6-Options                          245.3   group ref=..DHCPv6
 ATTRIBUTE      DHCPv4-Options                          245.4   group ref=..DHCPv4
index d7d122779cf801ef31410c32b58cb74b251e5da9..514cac97c2b83a3cd90c9829bb52152b7e7f93e4 100644 (file)
@@ -993,4 +993,11 @@ fr_dict_protocol_t libfreeradius_dhcpv6_dict_protocol = {
        .subtype_table = subtype_table,
        .subtype_table_len = NUM_ELEMENTS(subtype_table),
        .attr_valid = attr_valid,
+
+
+       .init = fr_dhcpv6_global_init,
+       .free = fr_dhcpv6_global_free,
+
+       .encode         = fr_dhcpv6_encode_foreign,
+       .decode         = fr_dhcpv6_decode_foreign,
 };
index 5998a10a79965f83b4225e248e175b34f2264015..8ea258b98fa11b2d9da8919c3e3dc9552429953a 100644 (file)
@@ -421,6 +421,43 @@ ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
        return decode_option(ctx, out, fr_dict_root(dict_dhcpv6), data, data_len, decode_ctx);
 }
 
+ssize_t        fr_dhcpv6_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                                uint8_t const *data, size_t data_len)
+{
+       ssize_t slen;
+       uint8_t const *attr, *end;
+
+       fr_dhcpv6_decode_ctx_t decode_ctx = {};
+
+       decode_ctx.tmp_ctx = talloc(ctx, uint8_t);
+
+       attr = data;
+       end = data + data_len;
+
+       while (attr < end) {
+               slen = fr_dhcpv6_decode_option(ctx, out, attr, (end - attr), &decode_ctx);
+               if (slen < 0) {
+                       talloc_free(decode_ctx.tmp_ctx);
+                       return slen;
+               }
+
+               /*
+                *      If slen is larger than the room in the packet,
+                *      all kinds of bad things happen.
+                */
+                if (!fr_cond_assert(slen <= (end - attr))) {
+                       talloc_free(decode_ctx.tmp_ctx);
+                        return -slen - (attr - data);
+                }
+
+               attr += slen;
+               talloc_free_children(decode_ctx.tmp_ctx);
+       }
+
+       talloc_free(decode_ctx.tmp_ctx);
+       return data_len;
+}
+
 /*
  *     Stub functions to enable test context
  */
index 2b880655f07d7f8a7c3d8ca79b2be17c1f177c46..b9484cc5a4e2504dd813a9a2752e75f4a880e9e4 100644 (file)
@@ -171,8 +171,13 @@ void               fr_dhcpv6_global_free(void);
  */
 ssize_t                fr_dhcpv6_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void * encode_ctx);
 
+ssize_t                fr_dhcpv6_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list);
+
 /*
  *     decode.c
  */
 ssize_t                fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
                                        uint8_t const *data, size_t data_len, void *decode_ctx);
+
+ssize_t                fr_dhcpv6_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out,
+                                        uint8_t const *data, size_t data_len);
index 7e95163b117ea61026e973115610fedbf5f70925..2d4f48addb77d0fb0bf9613a8c1e4a0b65d9f14c 100644 (file)
@@ -713,6 +713,34 @@ ssize_t fr_dhcpv6_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
+ssize_t        fr_dhcpv6_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
+{
+       ssize_t         slen;
+       fr_dcursor_t    cursor;
+       fr_dbuff_t      work_dbuff = FR_DBUFF(dbuff);
+
+       fr_assert(dict_dhcpv6 != NULL);
+
+       fr_pair_dcursor_iter_init(&cursor, list, fr_dhcpv6_next_encodable, dict_dhcpv6);
+
+       /*
+        *      Loop over all DHCPv4 options.
+        *
+        *      Unlike fr_dhcpv4_encode_dbuff(), we don't sort the options.  If that causes problems, we will
+        *      deal with it later.
+        */
+       while (fr_dcursor_current(&cursor) != NULL) {
+               slen = fr_dhcpv6_encode_option(&work_dbuff, &cursor, &(fr_dhcpv6_encode_ctx_t){ .root = fr_dict_root(dict_dhcpv6) });
+               if (slen <= 0) return slen - fr_dbuff_used(&work_dbuff);
+       }
+
+       FR_PROTO_TRACE("Foreign option is %zu byte(s)", fr_dbuff_used(&work_dbuff));
+       FR_PROTO_HEX_DUMP(dbuff->p, fr_dbuff_used(&work_dbuff), NULL);
+
+       return fr_dbuff_set(dbuff, &work_dbuff);
+}
+
+
 static int _test_ctx_free(UNUSED fr_dhcpv6_encode_ctx_t *ctx)
 {
        fr_dhcpv6_global_free();
index f79a86bfa88ae74b6f8b9bcaee853a2d7c5dd340..a8ecc50ad0bd9015f262218c20416f248e055c69 100644 (file)
@@ -30,6 +30,17 @@ match 1a ff 00 00 19 7f 66 fa 02 04 00 00 08 40 38 f0 61 61 61 61 61 61 61 61 61
 #  No decode as of yet of concatenated DHCPv4 options
 #
 
+######################################################################
+#
+#  DHCPv6
+#
+encode-pair Extended-Attribute-5 = { DHCPv6-Options = { Rapid-Commit = true, Information-Refresh-Time = 6809 } }
+match f5 10 03 00 00 0e 00 00 00 20 00 04 00 00 1a 99
+
+decode-pair -
+match Extended-Attribute-5 = { DHCPv6-Options = { Rapid-Commit = yes, Information-Refresh-Time = 6809 } }
+
+
 ######################################################################
 #
 #  Various cross-protocol tests taken from fuzzer output.
@@ -46,4 +57,4 @@ decode-proto 04ac00edd604040404040404040404040302d700f30303f5040402f50303f504030
 match Packet-Type = Accounting-Request, Packet-Authentication-Vector = 0xd604040404040404040404040302d700, raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, raw.Extended-Attribute-5 = 0x0303, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, User-Password = "\366\356", raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, raw.Extended-Attribute-5 = 0x0402, User-Password = "\366\356", raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, User-Password = "\366\356", raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, raw.Extended-Attribute-5 = 0x0403, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x02, raw.214 = 0x0402, User-Password = "\366\356", raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, User-Password = "\366\356", raw.Extended-Attribute-3 = 0x03, raw.Extended-Attribute-5 = 0x0402, raw.Extended-Attribute-5 = 0x03, Extended-Attribute-5 = { raw.DHCPv4-Options = 0x2a006004040404040404f30303f5040402f50303040202046000f30303f5040402f50303f5040303f5040402f50303040202046000f30303f5040402f50303f5040402020203023d046000f30303f5040303f5030402040404 }, raw.NAS-IP-Address = 0x0404, raw.NAS-IP-Address = 0x0404
 
 count
-match 19
+match 23