From: Arran Cudbard-Bell Date: Fri, 25 Oct 2024 05:20:36 +0000 (-0600) Subject: Switch DHCPv6 to using custom flag parsers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7693e8454140c70bfee442ef8c607f70ecf066b;p=thirdparty%2Ffreeradius-server.git Switch DHCPv6 to using custom flag parsers --- diff --git a/src/protocols/dhcpv6/base.c b/src/protocols/dhcpv6/base.c index 9c578ba01c3..6a408193941 100644 --- a/src/protocols/dhcpv6/base.c +++ b/src/protocols/dhcpv6/base.c @@ -107,9 +107,12 @@ char const *fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX] = { [FR_PACKET_TYPE_VALUE_CONTACT] = "Contact" }; -static fr_table_num_ordered_t const subtype_table[] = { - { L("dns_label"), FLAG_ENCODE_DNS_LABEL }, - { L("partial_dns_label"), FLAG_ENCODE_PARTIAL_DNS_LABEL } +FR_DICT_ATTR_FLAG_FUNC(fr_dhcpv6_attr_flags_t, dns_label) +FR_DICT_ATTR_FLAG_FUNC(fr_dhcpv6_attr_flags_t, partial_dns_label) + +static fr_dict_flag_parser_t const dhcpv6_flags[] = { + { L("dns_label"), { .func = dict_flag_dns_label } }, + { L("partial_dns_label"), { .func = dict_flag_partial_dns_label } } }; static ssize_t fr_dhcpv6_ok_internal(uint8_t const *packet, uint8_t const *end, size_t max_attributes, int depth); @@ -970,7 +973,7 @@ static bool attr_valid(fr_dict_attr_t *da) */ if (da->flags.extra || !da->flags.subtype) return true; - if ((da->type != FR_TYPE_STRING) && ((da->flags.subtype == FLAG_ENCODE_DNS_LABEL) || (da->flags.subtype == FLAG_ENCODE_PARTIAL_DNS_LABEL))) { + if ((da->type != FR_TYPE_STRING) && fr_dhcpv6_flag_any_dns_label(da)) { fr_strerror_const("The 'dns_label' flag can only be used with attributes of type 'string'"); return false; } @@ -985,10 +988,12 @@ fr_dict_protocol_t libfreeradius_dhcpv6_dict_protocol = { .name = "dhcpv6", .default_type_size = 2, .default_type_length = 2, - .subtype_table = subtype_table, - .subtype_table_len = NUM_ELEMENTS(subtype_table), + .attr = { .valid = attr_valid, + .flags_table = dhcpv6_flags, + .flags_table_len = NUM_ELEMENTS(dhcpv6_flags), + .flags_len = sizeof(fr_dhcpv6_attr_flags_t) }, .init = fr_dhcpv6_global_init, diff --git a/src/protocols/dhcpv6/decode.c b/src/protocols/dhcpv6/decode.c index 5840ef16ade..e7ed490dfb1 100644 --- a/src/protocols/dhcpv6/decode.c +++ b/src/protocols/dhcpv6/decode.c @@ -58,7 +58,7 @@ static ssize_t decode_value_trampoline(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t const data_len, void *decode_ctx) { - if ((parent->type == FR_TYPE_STRING) && da_is_dns_label(parent)) { + if ((parent->type == FR_TYPE_STRING) && fr_dhcpv6_flag_any_dns_label(parent)) { return fr_pair_dns_labels_from_network(ctx, out, parent, data, data, data_len, NULL, false); } @@ -369,7 +369,7 @@ static ssize_t decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_pair_append(out, vp); - } else if ((da->type == FR_TYPE_STRING) && da_is_dns_label(da)) { + } else if ((da->type == FR_TYPE_STRING) && fr_dhcpv6_flag_any_dns_label(da)) { slen = fr_pair_dns_labels_from_network(ctx, out, da, data + 4, data + 4, len, NULL, true); if (slen < 0) return slen; diff --git a/src/protocols/dhcpv6/dhcpv6.h b/src/protocols/dhcpv6/dhcpv6.h index b9484cc5a4e..c8eb3e6c090 100644 --- a/src/protocols/dhcpv6/dhcpv6.h +++ b/src/protocols/dhcpv6/dhcpv6.h @@ -111,14 +111,6 @@ extern char const *fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX]; /** subtype values for DHCPv4 and DHCPv6 * */ -enum { - FLAG_ENCODE_NONE = 0, //!< no particular encoding for DHCPv6 strings - FLAG_ENCODE_DNS_LABEL, //!< encode as DNS label - FLAG_ENCODE_PARTIAL_DNS_LABEL, //!< encode as a partial DNS label -}; - -#define da_is_dns_label(_da) (!(_da)->flags.extra && (((_da)->flags.subtype == FLAG_ENCODE_DNS_LABEL) || ((_da)->flags.subtype == FLAG_ENCODE_PARTIAL_DNS_LABEL))) - typedef struct CC_HINT(__packed__) { uint8_t code; uint8_t transaction_id[3]; @@ -144,6 +136,26 @@ typedef struct { size_t duid_len; //!< length of the expected DUID } fr_dhcpv6_decode_ctx_t; +typedef struct { + bool dns_label; + bool partial_dns_label; +} fr_dhcpv6_attr_flags_t; + +static inline fr_dhcpv6_attr_flags_t const *fr_dhcpv6_attr_flags(fr_dict_attr_t const *da) +{ + return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); +} + +#define fr_dhcpv6_flag_dns_label(_da) (fr_dhcpv6_attr_flags(_da)->dns_label) +#define fr_dhcpv6_flag_partial_dns_label(_da) (fr_dhcpv6_attr_flags(_da)->partial_dns_label) + +static inline bool fr_dhcpv6_flag_any_dns_label(fr_dict_attr_t const *da) +{ + fr_dhcpv6_attr_flags_t const *flags = fr_dhcpv6_attr_flags(da); + + return flags->dns_label || flags->partial_dns_label; +} + /* * base.c */ diff --git a/src/protocols/dhcpv6/encode.c b/src/protocols/dhcpv6/encode.c index 8a502a4c80f..c78dd365d22 100644 --- a/src/protocols/dhcpv6/encode.c +++ b/src/protocols/dhcpv6/encode.c @@ -140,7 +140,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * * https://tools.ietf.org/html/rfc8415#section-10 */ - if (da_is_dns_label(da)) { + if (fr_dhcpv6_flag_any_dns_label(da)) { fr_dbuff_marker_t last_byte, src; fr_dbuff_marker(&last_byte, &work_dbuff); @@ -154,7 +154,7 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * partial name, and we omit the trailing * zero. */ - if ((da->flags.subtype == FLAG_ENCODE_PARTIAL_DNS_LABEL) && slen > 0) { + if (fr_dhcpv6_flag_partial_dns_label(da) && slen > 0) { uint8_t c = 0; fr_dbuff_advance(&last_byte, (size_t)(slen - 1));