The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
decode.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: f8bd7389b7aeca8ebb9869b30597f6ce8cb7793c $
19 *
20 * @file protocols/dns/decode.c
21 * @brief Functions to decode DNS packets.
22 *
23 * @author Alan DeKok (aland@freeradius.org)
24 *
25 * @copyright 2021 The FreeRADIUS server project
26 * @copyright 2021 NetworkRADIUS SARL (legal@networkradius.com)
27 */
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>
32
33#include "dns.h"
34#include "attrs.h"
35
36static ssize_t decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
38 uint8_t const *data, size_t const data_len, void *decode_ctx);
39
40static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
42 uint8_t const *data, size_t const data_len, void *decode_ctx);
43
46 uint8_t const *data, size_t const data_len, void *decode_ctx)
47{
48 return fr_pair_tlvs_from_network(ctx, out, parent, data, data_len, decode_ctx, decode_option, NULL, true);
49}
50
51
54 uint8_t const *data, size_t const data_len, void *decode_ctx)
55{
57 fr_dns_ctx_t *packet_ctx = decode_ctx;
58
59 return fr_pair_dns_labels_from_network(ctx, out, parent, packet_ctx->packet, data, data_len, packet_ctx->lb, false);
60 }
61
62 return decode_value(ctx, out, parent, data, data_len, decode_ctx);
63}
64
65
66static ssize_t decode_value(TALLOC_CTX *ctx, fr_pair_list_t *out,
68 uint8_t const *data, size_t const data_len, void *decode_ctx)
69{
70 ssize_t slen;
72
73 FR_PROTO_HEX_DUMP(data, data_len, "decode_value");
74
75 switch (parent->type) {
76 /*
77 * Address MAY be shorter than 16 bytes.
78 */
80 if (data_len == 0) {
81 raw:
82 return fr_pair_raw_from_network(ctx, out, parent, data, data_len);
83 }
84
86 if (!vp) return PAIR_DECODE_OOM;
88
89 /*
90 * Check values of prefix length, data lengths, etc.
91 */
93 data[0], data + 1, data_len - 1,
94 (parent->parent->type == FR_TYPE_STRUCT), true) < 0) {
96 goto raw;
97 }
98 break;
99
100 /*
101 * A bool is encoded as an empty option if it's
102 * true. A bool is omitted entirely if it's
103 * false.
104 */
105 case FR_TYPE_BOOL:
106 if (data_len != 0) goto raw;
107 vp = fr_pair_afrom_da(ctx, parent);
108 if (!vp) return PAIR_DECODE_OOM;
110
111 vp->vp_bool = true;
112 break;
113
114 case FR_TYPE_STRUCT:
115 slen = fr_struct_from_network(ctx, out, parent, data, data_len,
116 decode_ctx, decode_value_trampoline, NULL);
117 if (slen < 0) return slen;
118 return data_len;
119
120 case FR_TYPE_GROUP:
121 return PAIR_DECODE_FATAL_ERROR; /* not supported */
122
123 default:
124 vp = fr_pair_afrom_da(ctx, parent);
125 if (!vp) return PAIR_DECODE_OOM;
127
128 slen = fr_value_box_from_network(vp, &vp->data, vp->vp_type, vp->da,
129 &FR_DBUFF_TMP(data, data_len), data_len, true);
130 if (slen < 0) {
131 FR_PROTO_TRACE("failed decoding?");
133 goto raw;
134 }
135
136 /*
137 * A length-prefixed member (e.g. CAA Tag, string length=uint8) consumes
138 * less than data_len, and the struct decoder needs the true count to
139 * find the next member.
140 */
141 vp->vp_tainted = true;
143 return slen;
144 }
145
146 vp->vp_tainted = true;
148 return data_len;
149}
150
151
152#define DNS_GET_OPTION_NUM(_x) fr_nbo_to_uint16(_x)
153#define DNS_GET_OPTION_LEN(_x) fr_nbo_to_uint16((_x) + 2)
154
155static ssize_t decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out,
156 fr_dict_attr_t const *parent,
157 uint8_t const *data, size_t const data_len, void *decode_ctx)
158{
159 unsigned int option;
160 size_t len;
161 ssize_t slen;
162 fr_dict_attr_t const *da;
163 fr_dns_ctx_t *packet_ctx = decode_ctx;
164
165#ifdef STATIC_ANALYZER
166 if (!packet_ctx || !packet_ctx->tmp_ctx) return PAIR_DECODE_FATAL_ERROR;
167#endif
168
169 /*
170 * Must have at least an option header.
171 */
172 if (data_len < 4) {
173 fr_strerror_printf("%s: Insufficient data", __FUNCTION__);
174 return -(data_len);
175 }
176
177 option = DNS_GET_OPTION_NUM(data);
179 if (len > (data_len - 4)) {
180 fr_strerror_printf("%s: Option overflows input. "
181 "Optional length must be less than %zu bytes, got %zu bytes",
182 __FUNCTION__, data_len - 4, len);
184 }
185
186 FR_PROTO_HEX_DUMP(data, len + 4, "decode_option");
187
188 da = fr_dict_attr_child_by_num(parent, option);
189 if (!da) {
190 da = fr_dict_attr_unknown_raw_afrom_num(packet_ctx->tmp_ctx, parent, option);
191 if (!da) return PAIR_DECODE_FATAL_ERROR;
192 }
193 FR_PROTO_TRACE("decode context changed %s -> %s",da->parent->name, da->name);
194
195 if ((da->type == FR_TYPE_STRING) && fr_dns_flag_dns_label(da)) {
196 slen = fr_pair_dns_labels_from_network(ctx, out, da, packet_ctx->packet, data + 4, len, packet_ctx->lb, true);
197
198 } else {
199 slen = decode_value(ctx, out, da, data + 4, len, decode_ctx);
200 }
202
203 if (slen < 0) return slen;
204
205 return len + 4;
206}
207
209 uint8_t const *rr, uint8_t const *end,
210 fr_dns_ctx_t *packet_ctx, uint8_t const *counter)
211{
212 unsigned int i, count;
213 uint8_t const *p = rr;
214
215 /*
216 * The header has a count of how many records we need to decode.
217 */
218 count = fr_nbo_to_uint16(counter);
219 FR_PROTO_TRACE("Decoding %u of %s", count, attr->name);
220
221 /* coverity[tainted_data] */
222 for (i = 0; (i < count) && (p < end); i++) {
223 ssize_t slen;
224
225 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - %s %u/%u", attr->name, i, count);
226
227 slen = fr_struct_from_network(ctx, out, attr, p, end - p,
229 if (slen < 0) return slen;
230 if (!slen) break;
231
232 fr_assert(slen <= (end - p));
233
234 p += slen;
235 }
236
237 return p - rr;
238}
239
240/** Decode a DNS packet
241 *
242 */
243ssize_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)
244{
245 ssize_t slen;
246 uint8_t const *p, *end;
247
248 if (packet_len < DNS_HDR_LEN) return 0;
249
250 /*
251 * @todo - synthesize Packet-Type from the various fields.
252 */
253
254 FR_PROTO_HEX_DUMP(packet, packet_len, "fr_dns_decode");
255
256 /*
257 * Decode the header.
258 */
260 packet_ctx, decode_value_trampoline, NULL); /* no TLVs in the header */
261 if (slen < 0) {
262 fr_strerror_printf("Failed decoding DNS header - %s", fr_strerror());
263 return slen;
264 }
265 fr_assert(slen == DNS_HDR_LEN);
266
267 p = packet + DNS_HDR_LEN;
268 end = packet + packet_len;
269 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after header");
270
271 slen = decode_record(ctx, out, attr_dns_question, p, end, packet_ctx, packet + 4);
272 if (slen < 0) {
273 fr_strerror_printf("Failed decoding questions - %s", fr_strerror());
274 /* coverity[return_overflow] */
275 return slen - (p - packet);
276 }
277 p += slen;
278 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of questions", slen);
279
280 slen = decode_record(ctx, out, attr_dns_rr, p, end, packet_ctx, packet + 6);
281 if (slen < 0) {
282 fr_strerror_printf("Failed decoding RRs - %s", fr_strerror());
283 /* coverity[return_overflow] */
284 return slen - (p - packet);
285 }
286 p += slen;
287 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of RRs", slen);
288
289 slen = decode_record(ctx, out, attr_dns_ns, p, end, packet_ctx, packet + 8);
290 if (slen < 0) {
291 fr_strerror_printf("Failed decoding NS - %s", fr_strerror());
292 /* coverity[return_overflow] */
293 return slen - (p - packet);
294 }
295 p += slen;
296 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of NS", slen);
297
298 slen = decode_record(ctx, out, attr_dns_ar, p, end, packet_ctx, packet + 10);
299 if (slen < 0) {
300 fr_strerror_printf("Failed decoding additional records - %s", fr_strerror());
301 /* coverity[return_overflow] */
302 return slen - (p - packet);
303 }
304 FR_PROTO_HEX_DUMP(p, end - p, "fr_dns_decode - after %zd bytes of additional records", slen);
305
306// p += slen;
307
308 return packet_len;
309}
310
311/** Decode DNS RR
312 *
313 * @param[in] ctx context to alloc new attributes in.
314 * @param[in,out] out Where to write the decoded options.
315 * @param[in] parent to lookup attributes in.
316 * @param[in] data to parse.
317 * @param[in] data_len of data to parse.
318 * @param[in] decode_ctx Unused.
319 */
321 uint8_t const *data, size_t data_len, void *decode_ctx)
322{
323 ssize_t slen;
324 fr_dns_ctx_t *packet_ctx = (fr_dns_ctx_t *) decode_ctx;
325
326 FR_PROTO_TRACE("%s called to parse %zu byte(s)", __FUNCTION__, data_len);
327
328 if (data_len == 0) return 0;
329
330 /*
331 * This function is only used for testing, so update decode_ctx
332 */
333 packet_ctx->packet = data;
334 packet_ctx->packet_len = data_len;
335
336 FR_PROTO_HEX_DUMP(data, data_len, NULL);
337
338 /*
339 * There should be at least room for the RR header
340 */
341 if (data_len < 9) {
342 fr_strerror_printf("%s: Insufficient data", __FUNCTION__);
343 return -1;
344 }
345
346 slen = fr_struct_from_network(ctx, out, attr_dns_rr, data, data_len,
348 if (slen < 0) return slen;
349
350 FR_PROTO_TRACE("decoding option complete, returning %zd byte(s)", slen);
351 return slen;
352}
353
354/*
355 * Test points
356 */
357static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict,
359{
360 fr_dns_ctx_t *test_ctx;
361
362 test_ctx = talloc_zero(ctx, fr_dns_ctx_t);
363
364 test_ctx->tmp_ctx = talloc(test_ctx, uint8_t);
365 *out = test_ctx;
366
367 return 0;
368}
369
371 { L("none"), FR_DNS_DECODE_FAIL_NONE },
372 { L("unknown opcode"), FR_DNS_DECODE_FAIL_UNKNOWN_OPCODE },
373 { L("packet is smaller than DNS header"), FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET },
374 { L("packet is larger than 65535"), FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET },
375 { L("expected query / answer, got answer / query"), FR_DNS_DECODE_FAIL_UNEXPECTED },
376 { L("no 'questions' in query packet"), FR_DNS_DECODE_FAIL_NO_QUESTIONS },
377 { L("unexpected answers in query packet"), FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION },
378 { L("unexpected NS records in query packet"), FR_DNS_DECODE_FAIL_NS_IN_QUESTION },
379 { L("invalid label for resource record"), FR_DNS_DECODE_FAIL_INVALID_RR_LABEL },
380 { L("missing resource record header"), FR_DNS_DECODE_FAIL_MISSING_RR_HEADER },
381 { L("missing resource record length field"), FR_DNS_DECODE_FAIL_MISSING_RR_LEN },
382 { L("resource record length field is zero"), FR_DNS_DECODE_FAIL_ZERO_RR_LEN },
383 { L("resource record length overflows the packet"), FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET },
384 { L("more resource records than indicated in header"), FR_DNS_DECODE_FAIL_TOO_MANY_RRS },
385 { L("fewer resource records than indicated in header"), FR_DNS_DECODE_FAIL_TOO_FEW_RRS },
386 { L("pointer overflows packet"), FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET },
387 { L("pointer points to packet header"), FR_DNS_DECODE_FAIL_POINTER_TO_HEADER },
388 { L("pointer does not point to a label"), FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL },
389 { L("pointer creates a loop"), FR_DNS_DECODE_FAIL_POINTER_LOOPS },
390 { L("invalid pointer"), FR_DNS_DECODE_FAIL_INVALID_POINTER },
391 { L("label overflows the packet"), FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET },
392 { L("too many characters in label"), FR_DNS_DECODE_FAIL_LABEL_TOO_LONG },
393 { L("query record header is missing"), FR_DNS_DECODE_FAIL_MISSING_QD_HEADER },
394 { L("missing TLV header in OPT RR"), FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER },
395 { L("TLV overflows enclosing RR"), FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR },
396 { L("TC bit indicates truncation"), FR_DNS_DECODE_FAIL_TRUNCATED },
397};
399
400static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
401{
402 fr_dns_ctx_t *packet_ctx = proto_ctx;
404
405 if (data_len > 65535) return -1; /* packet is too big */
406
407 /*
408 * Allow queries or answers
409 */
410 if (!fr_dns_packet_ok(data, data_len, true, &reason)) {
411 if (reason != FR_DNS_DECODE_FAIL_UNEXPECTED) goto fail;
412
413 if (!fr_dns_packet_ok(data, data_len, false, &reason)) {
414 fail:
415 fr_strerror_printf("DNS packet malformed - %s",
416 fr_table_str_by_value(fr_dns_reason_fail_table, reason, "<INVALID>"));
417 return -1;
418 }
419 }
420
421 packet_ctx->packet = data;
422 packet_ctx->packet_len = data_len;
423 packet_ctx->lb = fr_dns_labels_get(data, data_len, true);
424 fr_assert(packet_ctx->lb != NULL);
425
426 return fr_dns_decode(ctx, out, data, data_len, packet_ctx);
427}
428
429/*
430 * Test points
431 */
437
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define UNUSED
Definition build.h:384
#define NUM_ELEMENTS(_t)
Definition build.h:406
fr_dict_attr_t const * root_da
Definition common.c:32
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:522
static fr_dict_attr_t * fr_dict_attr_unknown_raw_afrom_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Definition dict.h:611
void fr_dict_attr_unknown_free(fr_dict_attr_t const **da)
Free dynamically allocated (unknown attributes)
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.
Definition dict_util.c:3585
#define DNS_HDR_LEN
Definition dns_tests.c:29
enum dwarf_attribute name
Definition dwarf.c:426
Definition dwarf.c:424
talloc_free(hp)
#define PAIR_DECODE_OOM
Fatal error - Out of memory.
Definition pair.h:45
#define PAIR_DECODE_FATAL_ERROR
Fatal error - Failed decoding the packet.
Definition pair.h:49
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.
Definition decode.c:156
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.
Definition decode.c:253
ssize_t fr_pair_raw_from_network(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *da, uint8_t const *data, size_t data_len)
Create a "raw" pair from malformed network data.
Definition decode.c:86
@ 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.
long int ssize_t
unsigned char uint8_t
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)
Definition nbo.h:146
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1352
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.
Definition pair.c:290
static int decode_test_ctx(void **out, TALLOC_CTX *ctx, UNUSED fr_dict_t const *dict, UNUSED fr_dict_attr_t const *root_da)
Definition decode.c:102
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)
Definition decode.c:482
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)
Handle arrays of DNS labels for fr_struct_from_network()
Definition decode.c:70
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)
Definition decode.c:57
HIDDEN fr_dict_attr_t const * attr_dns_ar
Definition base.c:56
HIDDEN fr_dict_attr_t const * attr_dns_ns
Definition base.c:55
HIDDEN fr_dict_attr_t const * attr_dns_packet
Definition base.c:52
HIDDEN fr_dict_attr_t const * attr_dns_question
Definition base.c:53
HIDDEN fr_dict_attr_t const * attr_dns_rr
Definition base.c:54
fr_dns_labels_t * fr_dns_labels_get(uint8_t const *packet, size_t packet_len, bool init_mark)
Definition base.c:420
bool fr_dns_packet_ok(uint8_t const *packet, size_t packet_len, bool query, fr_dns_decode_fail_t *reason)
Definition base.c:109
fr_test_point_pair_decode_t dns_tp_decode_pair
Definition decode.c:433
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.
Definition decode.c:320
#define DNS_GET_OPTION_LEN(_x)
Definition decode.c:153
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.
Definition decode.c:243
size_t fr_dns_reason_fail_table_len
Definition decode.c:398
static ssize_t decode_proto(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *proto_ctx)
Definition decode.c:400
fr_table_num_ordered_t fr_dns_reason_fail_table[]
Definition decode.c:370
#define DNS_GET_OPTION_NUM(_x)
Definition decode.c:152
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)
Definition decode.c:208
fr_test_point_proto_decode_t dns_tp_decode_proto
Definition decode.c:439
Implementation of the DNS protocol.
#define fr_dns_flag_dns_label(_da)
Definition dns.h:153
size_t packet_len
Definition dns.h:76
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
Definition dns.h:74
uint8_t const * packet
DNS labels can point anywhere in the packet :(.
Definition dns.h:75
fr_dns_decode_fail_t
Definition dns.h:102
@ FR_DNS_DECODE_FAIL_ANSWERS_IN_QUESTION
Definition dns.h:109
@ FR_DNS_DECODE_FAIL_TOO_MANY_RRS
Definition dns.h:116
@ FR_DNS_DECODE_FAIL_RR_OVERFLOWS_PACKET
Definition dns.h:115
@ FR_DNS_DECODE_FAIL_INVALID_RR_LABEL
Definition dns.h:111
@ FR_DNS_DECODE_FAIL_POINTER_TO_NON_LABEL
Definition dns.h:118
@ FR_DNS_DECODE_FAIL_INVALID_POINTER
Definition dns.h:122
@ FR_DNS_DECODE_FAIL_POINTER_OVERFLOWS_PACKET
Definition dns.h:119
@ FR_DNS_DECODE_FAIL_LABEL_OVERFLOWS_PACKET
Definition dns.h:123
@ FR_DNS_DECODE_FAIL_MISSING_TLV_HEADER
Definition dns.h:126
@ FR_DNS_DECODE_FAIL_UNEXPECTED
Definition dns.h:107
@ FR_DNS_DECODE_FAIL_POINTER_TO_HEADER
Definition dns.h:120
@ FR_DNS_DECODE_FAIL_ZERO_RR_LEN
Definition dns.h:114
@ FR_DNS_DECODE_FAIL_LABEL_TOO_LONG
Definition dns.h:124
@ FR_DNS_DECODE_FAIL_TRUNCATED
Definition dns.h:128
@ FR_DNS_DECODE_FAIL_TOO_FEW_RRS
Definition dns.h:117
@ FR_DNS_DECODE_FAIL_MISSING_RR_LEN
Definition dns.h:113
@ FR_DNS_DECODE_FAIL_MISSING_QD_HEADER
Definition dns.h:125
@ FR_DNS_DECODE_FAIL_MAX_LENGTH_PACKET
Definition dns.h:106
@ FR_DNS_DECODE_FAIL_NS_IN_QUESTION
Definition dns.h:110
@ FR_DNS_DECODE_FAIL_NO_QUESTIONS
Definition dns.h:108
@ FR_DNS_DECODE_FAIL_NONE
Definition dns.h:103
@ FR_DNS_DECODE_FAIL_TLV_OVERFLOWS_RR
Definition dns.h:127
@ FR_DNS_DECODE_FAIL_POINTER_LOOPS
Definition dns.h:121
@ FR_DNS_DECODE_FAIL_MISSING_RR_HEADER
Definition dns.h:112
@ FR_DNS_DECODE_FAIL_MIN_LENGTH_PACKET
Definition dns.h:105
@ FR_DNS_DECODE_FAIL_UNKNOWN_OPCODE
Definition dns.h:104
fr_dns_labels_t * lb
Definition dns.h:77
#define decode_value
Definition decode.c:411
VQP attributes.
#define fr_assert(_expr)
Definition rad_assert.h:37
fr_pair_t * vp
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.
Definition struct.c:32
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:804
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Definition test_point.h:86
fr_test_point_ctx_alloc_t test_ctx
Allocate a test ctx for the encoder.
Definition test_point.h:68
Entry point for pair decoders.
Definition test_point.h:85
Entry point for protocol decoders.
Definition test_point.h:67
static unsigned count
Definition unittest.c:47
#define PAIR_ALLOCED(_x)
Definition pair.h:212
static fr_slen_t parent
Definition pair.h:858
#define FR_PROTO_HEX_DUMP(_data, _data_len, _fmt,...)
Definition proto.h:42
#define FR_PROTO_TRACE(_fmt,...)
Definition proto.h:41
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:558
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
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.
Definition value.c:1906
ssize_t fr_value_box_ipaddr_from_network(fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, int prefix_len, uint8_t const *data, size_t data_len, bool fixed, bool tainted)
Decode a fr_value_box_t of type IP address / prefix.
Definition value.c:2310
static fr_slen_t data
Definition value.h:1340
static size_t char ** out
Definition value.h:1030