]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow encoding for foreign options
authorAlan T. DeKok <aland@freeradius.org>
Fri, 26 Jan 2024 02:59:57 +0000 (21:59 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 26 Jan 2024 16:35:46 +0000 (11:35 -0500)
src/protocols/dhcpv4/base.c
src/protocols/dhcpv4/dhcpv4.h
src/protocols/dhcpv4/encode.c

index 90fa55ada55430213e8cc312d2595a8ff991050b..bff36f50b05869fea4b8680d142b16ef6ebb03dc 100644 (file)
@@ -733,4 +733,5 @@ fr_dict_protocol_t libfreeradius_dhcpv4_dict_protocol = {
        .subtype_table = subtype_table,
        .subtype_table_len = NUM_ELEMENTS(subtype_table),
        .attr_valid = attr_valid,
+       .encode         = fr_dhcpv4_encode_foreign,
 };
index 9d575609125b9e971e619ca86512079aafa2412c..965989216e6620690c851059fa04c53f04f15fe9 100644 (file)
@@ -166,6 +166,7 @@ bool                fr_dhcpv4_is_encodable(void const *item, void const *uctx);
 void           *fr_dhcpv4_next_encodable(fr_dlist_head_t *list, void *to_eval, void *uctx);
 ssize_t                fr_dhcpv4_encode(uint8_t *buffer, size_t buflen, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps);
 ssize_t                fr_dhcpv4_encode_dbuff(fr_dbuff_t *dbuff, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps);
+ssize_t                fr_dhcpv4_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list);
 int            fr_dhcpv4_global_init(void);
 void           fr_dhcpv4_global_free(void);
 void           fr_dhcpv4_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len);
index c8c61847ce3a4c04e8519444ebe443477223e4f0..279841346b026c339c44eef82b5b396bcc665e48 100644 (file)
@@ -756,6 +756,36 @@ ssize_t fr_dhcpv4_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *e
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
+ssize_t        fr_dhcpv4_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
+{
+       ssize_t         slen;
+       fr_pair_t       *vp;
+       fr_dcursor_t    cursor;
+       fr_dbuff_t      work_dbuff = FR_DBUFF(dbuff);
+
+       (void) fr_dhcpv4_global_init();
+
+       fr_assert(dict_dhcpv4 != NULL);
+
+       fr_pair_dcursor_iter_init(&cursor, list, fr_dhcpv4_next_encodable, dict_dhcpv4);
+
+       /*
+        *      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 ((vp = fr_dcursor_current(&cursor))) {
+               slen = fr_dhcpv4_encode_option(&work_dbuff, &cursor, &(fr_dhcpv4_ctx_t){ .root = fr_dict_root(dict_dhcpv4) });
+               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 ssize_t fr_dhcpv4_encode_proto(UNUSED TALLOC_CTX *ctx, fr_pair_list_t *vps, uint8_t *data, size_t data_len, UNUSED void *proto_ctx)
 {
        return fr_dhcpv4_encode_dbuff(&FR_DBUFF_TMP(data, data_len), NULL, 0, 0, vps);