[FR_DNS_STATEFUL_OPERATION] = "Stateful-Operation",
};
+FR_DICT_ATTR_FLAG_FUNC(fr_dns_attr_flags_t, dns_label)
+FR_DICT_ATTR_FLAG_FUNC(fr_dns_attr_flags_t, uncompressed)
+
+static fr_dict_flag_parser_t const dns_flags[] = {
+ { L("dns_label"), { .func = dict_flag_dns_label } },
+ { L("uncompressed"), { .func = dict_flag_uncompressed } }
+};
+
#define DECODE_FAIL(_reason) if (reason) *reason = FR_DNS_DECODE_FAIL_ ## _reason
static bool fr_dns_tlv_ok(uint8_t const *p, uint8_t const *end, fr_dns_decode_fail_t *reason)
fr_dict_autofree(dns_dict);
}
-static fr_table_num_ordered_t const subtype_table[] = {
- { L("dns_label"), FLAG_ENCODE_DNS_LABEL },
- { L("uncompressed"), FLAG_ENCODE_DNS_LABEL_UNCOMPRESSED },
-};
-
-
static bool attr_valid(fr_dict_attr_t *da)
{
/*
da->flags.is_known_width = true;
}
- /*
- * "extra" signifies that subtype is being used by the
- * dictionaries itself.
- */
- if (da->flags.extra || !da->flags.subtype) return true;
-
- if (da->type != FR_TYPE_STRING) {
- fr_strerror_const("The 'dns_label' flag can only be used with attributes of type 'string'");
- return false;
+ if (fr_dns_flag_dns_label(da) || fr_dns_flag_uncompressed(da)) {
+ if (da->type != FR_TYPE_STRING) {
+ fr_strerror_const("The 'dns_label' flag can only be used with attributes of type 'string'");
+ return false;
+ }
+ da->flags.is_known_width = true; /* Lie so we don't trip up the main validation checks */
}
- da->flags.is_known_width = true;
-
return true;
}
.name = "dns",
.default_type_size = 2,
.default_type_length = 2,
- .subtype_table = subtype_table,
- .subtype_table_len = NUM_ELEMENTS(subtype_table),
.attr = {
+ .flags_table = dns_flags,
+ .flags_table_len = NUM_ELEMENTS(dns_flags),
+ .flags_len = sizeof(fr_dns_attr_flags_t),
.valid = attr_valid
},
uint16_t arcount;
} CC_HINT(__packed__) fr_dns_packet_t;
-/** subtype values for DHCPv4 and DHCPv6
- *
- */
-enum {
- FLAG_ENCODE_NONE = 0, //!< no particular encoding for DNS strings
- FLAG_ENCODE_DNS_LABEL, //!< encode as DNS label
- FLAG_ENCODE_DNS_LABEL_UNCOMPRESSED, //!< encode as uncompressed DNS label
-};
-
typedef struct {
TALLOC_CTX *tmp_ctx; //!< for temporary things cleaned up during decoding
uint8_t const *packet; //!< DNS labels can point anywhere in the packet :(
#define DNS_HDR_LEN (12)
+typedef struct {
+ bool dns_label;
+ bool uncompressed;
+} fr_dns_attr_flags_t;
+
+static inline fr_dns_attr_flags_t const *fr_dns_attr_flags(fr_dict_attr_t const *da)
+{
+ return fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);
+}
+
+#define fr_dns_flag_dns_label(_da) (fr_dns_attr_flags(_da)->dns_label)
+#define fr_dns_flag_uncompressed(_da) (fr_dns_attr_flags(_da)->uncompressed)
+
extern fr_table_num_ordered_t fr_dns_reason_fail_table[];
extern char const *fr_dns_packet_names[FR_DNS_CODE_MAX];
extern size_t fr_dns_reason_fail_table_len;
if (!da->flags.extra) {
fr_dbuff_marker_t last_byte, src;
- fr_assert((da->flags.subtype == FLAG_ENCODE_DNS_LABEL) ||
- (da->flags.subtype == FLAG_ENCODE_DNS_LABEL_UNCOMPRESSED));
+ fr_assert(fr_dns_flag_dns_label(da) ||
+ fr_dns_flag_uncompressed(da));
fr_dbuff_marker(&last_byte, &work_dbuff);
fr_dbuff_marker(&src, &work_dbuff);
FR_PROTO_TRACE("encode DNS label %s", vp->vp_strvalue);
- slen = fr_dns_label_from_value_box_dbuff(&work_dbuff, (da->flags.subtype == FLAG_ENCODE_DNS_LABEL),
+ slen = fr_dns_label_from_value_box_dbuff(&work_dbuff, fr_dns_flag_dns_label(da),
&vp->data, packet_ctx->lb);
if (slen < 0) return slen;
break;