[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);
*/
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;
}
.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,
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);
}
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;
/** 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];
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
*/
*
* 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);
* 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));