28 #include <freeradius-devel/io/test_point.h>
29 #include <freeradius-devel/util/dns.h>
30 #include <freeradius-devel/util/proto.h>
31 #include <freeradius-devel/util/struct.h>
38 uint8_t const *
data,
size_t const data_len,
void *decode_ctx);
42 uint8_t const *
data,
size_t const data_len,
void *decode_ctx);
46 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
54 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
68 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
81 if ((data_len == 0) || (data_len > (1 +
sizeof(
vp->vp_ipv6addr)))) {
91 if (data_len != (1 +
sizeof(
vp->vp_ipv6addr)))
goto raw;
96 vp->vp_ip.af = AF_INET6;
97 vp->vp_ip.prefix =
data[0];
98 memcpy(&
vp->vp_ipv6addr,
data + 1, data_len - 1);
106 if (
data[0] != 0)
goto raw;
111 vp->vp_ip.af = AF_INET6;
115 prefix_len =
data[0];
126 vp->vp_ip.af = AF_INET6;
127 vp->vp_ip.prefix = prefix_len;
128 memcpy(&
vp->vp_ipv6addr,
data + 1, data_len - 1);
137 if (data_len != 0)
goto raw;
146 if (slen < 0)
return slen;
165 vp->vp_tainted =
true;
171 #define DNS_GET_OPTION_NUM(_x) fr_nbo_to_uint16(_x)
172 #define DNS_GET_OPTION_LEN(_x) fr_nbo_to_uint16((_x) + 2)
176 uint8_t const *
data,
size_t const data_len,
void *decode_ctx)
184 #ifdef STATIC_ANALYZER
198 if (len > (data_len - 4)) {
200 "Optional length must be less than %zu bytes, got %zu bytes",
201 __FUNCTION__, data_len - 4, len);
212 FR_PROTO_TRACE(
"decode context changed %s -> %s",da->parent->name, da->name);
217 }
else if (da->flags.array) {
225 if (slen < 0)
return slen;
244 for (i = 0; (i <
count) && (p < end); i++) {
251 if (slen < 0)
return slen;
290 end = packet + packet_len;
299 FR_PROTO_HEX_DUMP(p, end - p,
"fr_dns_decode - after %zd bytes of questions", slen);
304 return slen - (p - packet);
312 return slen - (p - packet);
320 return slen - (p - packet);
322 FR_PROTO_HEX_DUMP(p, end - p,
"fr_dns_decode - after %zd bytes of additional records", slen);
339 uint8_t const *
data,
size_t data_len,
void *decode_ctx)
344 FR_PROTO_TRACE(
"%s called to parse %zu byte(s)", __FUNCTION__, data_len);
346 if (data_len == 0)
return 0;
366 if (slen < 0)
return slen;
368 FR_PROTO_TRACE(
"decoding option complete, returning %zd byte(s)", slen);
420 if (data_len > 65535)
return -1;
#define L(_str)
Helper for initialising arrays of string literals.
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
void fr_dict_attr_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
fr_dict_attr_t const * fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr)
Check if a child attribute exists in a parent using an attribute number.
#define PAIR_DECODE_OOM
Fatal error - Out of memory.
#define PAIR_DECODE_FATAL_ERROR
Fatal error - Failed decoding the packet.
ssize_t fr_pair_tlvs_from_network(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, fr_pair_decode_value_t decode_tlv, fr_pair_tlvs_verify_t verify_tlvs, bool nested)
Decode a list of pairs from the network.
ssize_t fr_pair_dns_labels_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *start, uint8_t const *data, size_t const data_len, fr_dns_labels_t *lb, bool exact)
Decode a DNS label or a list of DNS labels from the network.
ssize_t fr_pair_array_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value)
Decode an array of values from the network.
ssize_t fr_pair_raw_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len)
Create a "raw" pair from the network data.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_GROUP
A grouping of other attributes.
static unsigned int fr_bytes_from_bits(unsigned int bits)
Convert bits (as in prefix length) to bytes, rounding up.
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
HIDDEN fr_dict_attr_t const * attr_dns_ar
HIDDEN fr_dict_attr_t const * attr_dns_ns
HIDDEN fr_dict_attr_t const * attr_dns_packet
HIDDEN fr_dict_attr_t const * attr_dns_question
HIDDEN fr_dict_attr_t const * attr_dns_rr
fr_dns_labels_t * fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark)
bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query, fr_dns_decode_fail_t *reason)
fr_test_point_pair_decode_t dns_tp_decode_pair
static ssize_t decode_option(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)
static ssize_t decode_rr(TALLOC_CTX *ctx, fr_pair_list_t *out, UNUSED fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx)
Decode DNS RR.
#define DNS_GET_OPTION_LEN(_x)
ssize_t fr_dns_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len, fr_dns_ctx_t *packet_ctx)
Decode a DNS packet.
size_t fr_dns_reason_fail_table_len
static int decode_test_ctx(void **out, TALLOC_CTX *ctx)
static ssize_t decode_value(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)
static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
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)
fr_table_num_ordered_t fr_dns_reason_fail_table[]
#define DNS_GET_OPTION_NUM(_x)
static ssize_t decode_record(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *attr, uint8_t const *rr, uint8_t const *end, fr_dns_ctx_t *packet_ctx, uint8_t const *counter)
fr_test_point_proto_decode_t dns_tp_decode_proto
static ssize_t decode_tlv_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)
Implementation of the DNS protocol.
#define fr_dns_flag_dns_label(_da)
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
uint8_t const * packet
DNS labels can point anywhere in the packet :(.
@ FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION
@ FR_DNS_DECODE_FAIL_TOO_MANY_RRS
@ FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET
@ FR_DNS_DECODE_FAIL_INVALID_RR_LABEL
@ FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL
@ FR_DNS_DECODE_FAIL_INVALID_POINTER
@ FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET
@ FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET
@ FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER
@ FR_DNS_DECODE_FAIL_UNEXPECTED
@ FR_DNS_DECODE_FAIL_POINTER_TO_HEADER
@ FR_DNS_DECODE_FAIL_ZERO_RR_LEN
@ FR_DNS_DECODE_FAIL_LABEL_TOO_LONG
@ FR_DNS_DECODE_FAIL_TOO_FEW_RRS
@ FR_DNS_DECODE_FAIL_MISSING_RR_LEN
@ FR_DNS_DECODE_FAIL_MISSING_QD_HEADER
@ FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET
@ FR_DNS_DECODE_FAIL_NS_IN_QUESTION
@ FR_DNS_DECODE_FAIL_NO_QUESTIONS
@ FR_DNS_DECODE_FAIL_NONE
@ FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR
@ FR_DNS_DECODE_FAIL_POINTER_LOOPS
@ FR_DNS_DECODE_FAIL_MISSING_RR_HEADER
@ FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET
ssize_t fr_struct_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx, fr_pair_decode_value_t decode_value, fr_pair_decode_value_t decode_tlv)
Convert a STRUCT to one or more VPs.
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
An element in an arbitrarily ordered array of name to num mappings.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Entry point for pair decoders.
Entry point for protocol decoders.
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
#define FR_PROTO_TRACE(_fmt,...)
char const * fr_strerror(void)
Get the last library error.
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
static size_t char ** out