Coverage Report

Created: 2026-03-12 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/systemd/src/shared/dns-packet.c
Line
Count
Source
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include "alloc-util.h"
4
#include "bitmap.h"
5
#include "dns-answer.h"
6
#include "dns-domain.h"
7
#include "dns-packet.h"
8
#include "dns-question.h"
9
#include "dns-rr.h"
10
#include "escape.h"
11
#include "log.h"
12
#include "memory-util.h"
13
#include "set.h"
14
#include "siphash24.h"
15
#include "stdio-util.h"
16
#include "string-table.h"
17
#include "string-util.h"
18
#include "time-util.h"
19
#include "unaligned.h"
20
#include "utf8.h"
21
22
0
#define EDNS0_OPT_DO (1<<15)
23
24
assert_cc(DNS_PACKET_SIZE_START > DNS_PACKET_HEADER_SIZE);
25
26
typedef struct DnsPacketRewinder {
27
        DnsPacket *packet;
28
        size_t saved_rindex;
29
} DnsPacketRewinder;
30
31
1.36M
static void rewind_dns_packet(DnsPacketRewinder *rewinder) {
32
1.36M
        if (rewinder->packet)
33
15.6k
                dns_packet_rewind(rewinder->packet, rewinder->saved_rindex);
34
1.36M
}
35
36
1.36M
#define REWINDER_INIT(p) {                              \
37
1.36M
                .packet = (p),                          \
38
1.36M
                .saved_rindex = (p)->rindex,            \
39
1.36M
        }
40
1.35M
#define CANCEL_REWINDER(rewinder) do { (rewinder).packet = NULL; } while (0)
41
42
0
uint16_t dns_packet_rcode(DnsPacket *p) {
43
0
        uint16_t rcode;
44
45
0
        assert(p);
46
47
0
        if (p->opt)
48
0
                rcode = (uint16_t) ((p->opt->ttl >> 20) & 0xFF0);
49
0
        else
50
0
                rcode = 0;
51
52
0
        return rcode | (be16toh(DNS_PACKET_HEADER(p)->flags) & 0xF);
53
0
};
54
55
0
uint16_t dns_packet_payload_size_max(DnsPacket *p) {
56
0
        assert(p);
57
58
        /* Returns the advertised maximum size for replies, or the DNS default if there's nothing defined. */
59
60
0
        if (p->ipproto == IPPROTO_TCP) /* we ignore EDNS(0) size data on TCP, like everybody else */
61
0
                return DNS_PACKET_SIZE_MAX;
62
63
0
        if (p->opt)
64
0
                return MAX(DNS_PACKET_UNICAST_SIZE_MAX, p->opt->key->class);
65
66
0
        return DNS_PACKET_UNICAST_SIZE_MAX;
67
0
}
68
69
0
bool dns_packet_do(DnsPacket *p) {
70
0
        assert(p);
71
72
0
        if (!p->opt)
73
0
                return false;
74
75
0
        return !!(p->opt->ttl & (1U << 15));
76
0
}
77
78
0
bool dns_packet_version_supported(DnsPacket *p) {
79
0
        assert(p);
80
81
        /* Returns true if this packet is in a version we support. Which means either non-EDNS or EDNS(0), but not EDNS
82
         * of any newer versions */
83
84
0
        if (!p->opt)
85
0
                return true;
86
87
0
        return DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(p->opt);
88
0
}
89
90
int dns_packet_new(
91
                DnsPacket **ret,
92
                DnsProtocol protocol,
93
                size_t min_alloc_dsize,
94
7.71k
                size_t max_size) {
95
96
7.71k
        DnsPacket *p;
97
7.71k
        size_t a;
98
99
7.71k
        assert(ret);
100
7.71k
        assert(max_size >= DNS_PACKET_HEADER_SIZE);
101
102
7.71k
        if (max_size > DNS_PACKET_SIZE_MAX)
103
0
                max_size = DNS_PACKET_SIZE_MAX;
104
105
        /* The caller may not check what is going to be truly allocated, so do not allow to
106
         * allocate a DNS packet bigger than DNS_PACKET_SIZE_MAX.
107
         */
108
7.71k
        if (min_alloc_dsize > DNS_PACKET_SIZE_MAX)
109
0
                return log_error_errno(SYNTHETIC_ERRNO(EFBIG),
110
7.71k
                                       "Requested packet data size too big: %zu",
111
7.71k
                                       min_alloc_dsize);
112
113
        /* When dns_packet_new() is called with min_alloc_dsize == 0, allocate more than the
114
         * absolute minimum (which is the dns packet header size), to avoid
115
         * resizing immediately again after appending the first data to the packet.
116
         */
117
7.71k
        if (min_alloc_dsize < DNS_PACKET_HEADER_SIZE)
118
7.71k
                a = DNS_PACKET_SIZE_START;
119
0
        else
120
0
                a = min_alloc_dsize;
121
122
        /* round up to next page size */
123
7.71k
        a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
124
125
        /* make sure we never allocate more than useful */
126
7.71k
        if (a > max_size)
127
0
                a = max_size;
128
129
7.71k
        p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
130
7.71k
        if (!p)
131
0
                return -ENOMEM;
132
133
7.71k
        *p = (DnsPacket) {
134
7.71k
                .n_ref = 1,
135
7.71k
                .protocol = protocol,
136
7.71k
                .size = DNS_PACKET_HEADER_SIZE,
137
7.71k
                .rindex = DNS_PACKET_HEADER_SIZE,
138
7.71k
                .allocated = a,
139
7.71k
                .max_size = max_size,
140
7.71k
                .opt_start = SIZE_MAX,
141
7.71k
                .opt_size = SIZE_MAX,
142
7.71k
        };
143
144
7.71k
        *ret = p;
145
146
7.71k
        return 0;
147
7.71k
}
148
149
0
void dns_packet_set_flags(DnsPacket *p, bool dnssec_checking_disabled, bool truncated) {
150
151
0
        DnsPacketHeader *h;
152
153
0
        assert(p);
154
155
0
        h = DNS_PACKET_HEADER(p);
156
157
0
        switch (p->protocol) {
158
0
        case DNS_PROTOCOL_LLMNR:
159
0
                assert(!truncated);
160
161
0
                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
162
0
                                                         0 /* opcode */,
163
0
                                                         0 /* c */,
164
0
                                                         0 /* tc */,
165
0
                                                         0 /* t */,
166
0
                                                         0 /* ra */,
167
0
                                                         0 /* ad */,
168
0
                                                         0 /* cd */,
169
0
                                                         0 /* rcode */));
170
0
                break;
171
172
0
        case DNS_PROTOCOL_MDNS:
173
0
                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0         /* qr */,
174
0
                                                         0         /* opcode */,
175
0
                                                         0         /* aa */,
176
0
                                                         truncated /* tc */,
177
0
                                                         0         /* rd (ask for recursion) */,
178
0
                                                         0         /* ra */,
179
0
                                                         0         /* ad */,
180
0
                                                         0         /* cd */,
181
0
                                                         0         /* rcode */));
182
0
                break;
183
184
0
        default:
185
0
                assert(!truncated);
186
187
0
                h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
188
0
                                                         0 /* opcode */,
189
0
                                                         0 /* aa */,
190
0
                                                         0 /* tc */,
191
0
                                                         1 /* rd (ask for recursion) */,
192
0
                                                         0 /* ra */,
193
0
                                                         0 /* ad */,
194
0
                                                         dnssec_checking_disabled /* cd */,
195
0
                                                         0 /* rcode */));
196
0
        }
197
0
}
198
199
0
int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t min_alloc_dsize, bool dnssec_checking_disabled) {
200
0
        DnsPacket *p;
201
0
        int r;
202
203
0
        assert(ret);
204
205
0
        r = dns_packet_new(&p, protocol, min_alloc_dsize, DNS_PACKET_SIZE_MAX);
206
0
        if (r < 0)
207
0
                return r;
208
209
        /* Always set the TC bit to 0 initially.
210
         * If there are multiple packets later, we'll update the bit shortly before sending.
211
         */
212
0
        dns_packet_set_flags(p, dnssec_checking_disabled, false);
213
214
0
        *ret = p;
215
0
        return 0;
216
0
}
217
218
0
int dns_packet_dup(DnsPacket **ret, DnsPacket *p) {
219
0
        DnsPacket *c;
220
0
        int r;
221
222
0
        assert(ret);
223
0
        assert(p);
224
225
0
        r = dns_packet_validate(p);
226
0
        if (r < 0)
227
0
                return r;
228
229
0
        c = malloc(ALIGN(sizeof(DnsPacket)) + p->size);
230
0
        if (!c)
231
0
                return -ENOMEM;
232
233
0
        *c = (DnsPacket) {
234
0
                .n_ref = 1,
235
0
                .protocol = p->protocol,
236
0
                .size = p->size,
237
0
                .rindex = DNS_PACKET_HEADER_SIZE,
238
0
                .allocated = p->size,
239
0
                .max_size = p->max_size,
240
0
                .opt_start = SIZE_MAX,
241
0
                .opt_size = SIZE_MAX,
242
0
        };
243
244
0
        memcpy(DNS_PACKET_DATA(c), DNS_PACKET_DATA(p), p->size);
245
246
0
        *ret = c;
247
0
        return 0;
248
0
}
249
250
0
DnsPacket *dns_packet_ref(DnsPacket *p) {
251
252
0
        if (!p)
253
0
                return NULL;
254
255
0
        assert(!p->on_stack);
256
257
0
        assert(p->n_ref > 0);
258
0
        p->n_ref++;
259
0
        return p;
260
0
}
261
262
11.8k
static void dns_packet_free(DnsPacket *p) {
263
11.8k
        char *s;
264
265
11.8k
        assert(p);
266
267
11.8k
        dns_question_unref(p->question);
268
11.8k
        dns_answer_unref(p->answer);
269
11.8k
        dns_resource_record_unref(p->opt);
270
271
11.8k
        while ((s = hashmap_steal_first_key(p->names)))
272
0
                free(s);
273
11.8k
        hashmap_free(p->names);
274
275
11.8k
        free(p->_data);
276
277
11.8k
        if (!p->on_stack)
278
7.71k
                free(p);
279
11.8k
}
280
281
23.7k
DnsPacket *dns_packet_unref(DnsPacket *p) {
282
23.7k
        if (!p)
283
11.8k
                return NULL;
284
285
11.8k
        assert(p->n_ref > 0);
286
287
11.8k
        dns_packet_unref(p->more);
288
289
11.8k
        if (p->n_ref == 1)
290
11.8k
                dns_packet_free(p);
291
0
        else
292
0
                p->n_ref--;
293
294
11.8k
        return NULL;
295
23.7k
}
296
297
0
int dns_packet_validate(DnsPacket *p) {
298
0
        assert(p);
299
300
0
        if (p->size < DNS_PACKET_HEADER_SIZE)
301
0
                return -EBADMSG;
302
303
0
        if (p->size > DNS_PACKET_SIZE_MAX)
304
0
                return -EBADMSG;
305
306
0
        return 1;
307
0
}
308
309
0
int dns_packet_validate_reply(DnsPacket *p) {
310
0
        int r;
311
312
0
        assert(p);
313
314
0
        r = dns_packet_validate(p);
315
0
        if (r < 0)
316
0
                return r;
317
318
0
        if (DNS_PACKET_QR(p) != 1)
319
0
                return 0;
320
321
0
        if (DNS_PACKET_OPCODE(p) != 0)
322
0
                return -EBADMSG;
323
324
0
        switch (p->protocol) {
325
326
0
        case DNS_PROTOCOL_LLMNR:
327
                /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
328
0
                if (DNS_PACKET_QDCOUNT(p) != 1)
329
0
                        return -EBADMSG;
330
331
0
                break;
332
333
0
        case DNS_PROTOCOL_MDNS:
334
                /* RFC 6762, Section 18 */
335
0
                if (dns_packet_rcode(p) != 0)
336
0
                        return -EBADMSG;
337
338
0
                break;
339
340
0
        default:
341
0
                ;
342
0
        }
343
344
0
        return 1;
345
0
}
346
347
0
int dns_packet_validate_query(DnsPacket *p) {
348
0
        int r;
349
350
0
        assert(p);
351
352
0
        r = dns_packet_validate(p);
353
0
        if (r < 0)
354
0
                return r;
355
356
0
        if (DNS_PACKET_QR(p) != 0)
357
0
                return 0;
358
359
0
        if (DNS_PACKET_OPCODE(p) != 0)
360
0
                return -EBADMSG;
361
362
0
        switch (p->protocol) {
363
364
0
        case DNS_PROTOCOL_DNS:
365
0
                if (DNS_PACKET_TC(p))
366
0
                        return -EBADMSG;
367
368
0
                if (DNS_PACKET_QDCOUNT(p) != 1)
369
0
                        return -EBADMSG;
370
371
0
                if (DNS_PACKET_ANCOUNT(p) > 0)
372
0
                        return -EBADMSG;
373
374
                /* Note, in most cases, DNS query packet does not have authority section. But some query
375
                 * types, e.g. IXFR, have Authority sections. Hence, unlike the check for LLMNR, we do not
376
                 * check DNS_PACKET_NSCOUNT(p) here. */
377
0
                break;
378
379
0
        case DNS_PROTOCOL_LLMNR:
380
0
                if (DNS_PACKET_TC(p))
381
0
                        return -EBADMSG;
382
383
                /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
384
0
                if (DNS_PACKET_QDCOUNT(p) != 1)
385
0
                        return -EBADMSG;
386
387
                /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
388
0
                if (DNS_PACKET_ANCOUNT(p) > 0)
389
0
                        return -EBADMSG;
390
391
                /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
392
0
                if (DNS_PACKET_NSCOUNT(p) > 0)
393
0
                        return -EBADMSG;
394
395
0
                break;
396
397
0
        case DNS_PROTOCOL_MDNS:
398
                /* Note, mDNS query may have truncation flag. So, unlike the check for DNS and LLMNR,
399
                 * we do not check DNS_PACKET_TC(p) here. */
400
401
                /* RFC 6762, Section 18 specifies that messages with non-zero RCODE
402
                 * must be silently ignored, and that we must ignore the values of
403
                 * AA, RD, RA, AD, and CD bits. */
404
0
                if (dns_packet_rcode(p) != 0)
405
0
                        return -EBADMSG;
406
407
0
                break;
408
409
0
        default:
410
0
                ;
411
0
        }
412
413
0
        return 1;
414
0
}
415
416
1.65M
static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
417
1.65M
        assert(p);
418
419
1.65M
        if (p->size + add > p->allocated) {
420
5.42k
                size_t a, ms;
421
422
5.42k
                a = PAGE_ALIGN((p->size + add) * 2);
423
424
5.42k
                ms = dns_packet_size_max(p);
425
5.42k
                if (a > ms)
426
337
                        a = ms;
427
428
5.42k
                if (p->size + add > a)
429
3
                        return -EMSGSIZE;
430
431
5.42k
                if (p->_data) {
432
450
                        void *d;
433
434
450
                        d = realloc(p->_data, a);
435
450
                        if (!d)
436
0
                                return -ENOMEM;
437
438
450
                        p->_data = d;
439
4.97k
                } else {
440
4.97k
                        p->_data = malloc(a);
441
4.97k
                        if (!p->_data)
442
0
                                return -ENOMEM;
443
444
4.97k
                        memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
445
4.97k
                        memzero((uint8_t*) p->_data + p->size, a - p->size);
446
4.97k
                }
447
448
5.42k
                p->allocated = a;
449
5.42k
        }
450
451
1.65M
        if (start)
452
11.8k
                *start = p->size;
453
454
1.65M
        if (ret)
455
1.65M
                *ret = DNS_PACKET_DATA(p) + p->size;
456
457
1.65M
        p->size += add;
458
1.65M
        return 0;
459
1.65M
}
460
461
0
void dns_packet_truncate(DnsPacket *p, size_t sz) {
462
0
        char *s;
463
0
        void *n;
464
465
0
        assert(p);
466
467
0
        if (p->size <= sz)
468
0
                return;
469
470
0
        HASHMAP_FOREACH_KEY(n, s, p->names) {
471
472
0
                if (PTR_TO_SIZE(n) < sz)
473
0
                        continue;
474
475
0
                hashmap_remove(p->names, s);
476
0
                free(s);
477
0
        }
478
479
0
        p->size = sz;
480
0
}
481
482
13.6k
int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
483
13.6k
        void *q;
484
13.6k
        int r;
485
486
13.6k
        assert(p);
487
488
13.6k
        r = dns_packet_extend(p, l, &q, start);
489
13.6k
        if (r < 0)
490
3
                return r;
491
492
13.6k
        memcpy_safe(q, d, l);
493
13.6k
        return 0;
494
13.6k
}
495
496
13.4k
int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
497
13.4k
        void *d;
498
13.4k
        int r;
499
500
13.4k
        assert(p);
501
502
13.4k
        r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
503
13.4k
        if (r < 0)
504
0
                return r;
505
506
13.4k
        ((uint8_t*) d)[0] = v;
507
508
13.4k
        return 0;
509
13.4k
}
510
511
21.6k
int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
512
21.6k
        void *d;
513
21.6k
        int r;
514
515
21.6k
        assert(p);
516
517
21.6k
        r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
518
21.6k
        if (r < 0)
519
0
                return r;
520
521
21.6k
        unaligned_write_be16(d, v);
522
523
21.6k
        return 0;
524
21.6k
}
525
526
5.24k
int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
527
5.24k
        void *d;
528
5.24k
        int r;
529
530
5.24k
        assert(p);
531
532
5.24k
        r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
533
5.24k
        if (r < 0)
534
0
                return r;
535
536
5.24k
        unaligned_write_be32(d, v);
537
538
5.24k
        return 0;
539
5.24k
}
540
541
470
int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
542
470
        assert(p);
543
470
        assert(s);
544
545
470
        return dns_packet_append_raw_string(p, s, strlen(s), start);
546
470
}
547
548
1.59M
int dns_packet_append_raw_string(DnsPacket *p, const void *s, size_t size, size_t *start) {
549
1.59M
        void *d;
550
1.59M
        int r;
551
552
1.59M
        assert(p);
553
1.59M
        assert(s || size == 0);
554
555
1.59M
        if (size > 255)
556
0
                return -E2BIG;
557
558
1.59M
        r = dns_packet_extend(p, 1 + size, &d, start);
559
1.59M
        if (r < 0)
560
0
                return r;
561
562
1.59M
        ((uint8_t*) d)[0] = (uint8_t) size;
563
564
1.59M
        memcpy_safe(((uint8_t*) d) + 1, s, size);
565
566
1.59M
        return 0;
567
1.59M
}
568
569
7.71k
int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, bool canonical_candidate, size_t *start) {
570
7.71k
        uint8_t *w;
571
7.71k
        int r;
572
573
        /* Append a label to a packet. Optionally, does this in DNSSEC
574
         * canonical form, if this label is marked as a candidate for
575
         * it, and the canonical form logic is enabled for the
576
         * packet */
577
578
7.71k
        assert(p);
579
7.71k
        assert(d);
580
581
7.71k
        if (l > DNS_LABEL_MAX)
582
0
                return -E2BIG;
583
584
7.71k
        r = dns_packet_extend(p, 1 + l, (void**) &w, start);
585
7.71k
        if (r < 0)
586
0
                return r;
587
588
7.71k
        *(w++) = (uint8_t) l;
589
590
7.71k
        if (p->canonical_form && canonical_candidate)
591
                /* Generate in canonical form, as defined by DNSSEC
592
                 * RFC 4034, Section 6.2, i.e. all lower-case. */
593
21.1k
                for (size_t i = 0; i < l; i++)
594
17.8k
                        w[i] = (uint8_t) ascii_tolower(d[i]);
595
4.38k
        else
596
                /* Otherwise, just copy the string unaltered. This is
597
                 * essential for DNS-SD, where the casing of labels
598
                 * matters and needs to be retained. */
599
4.38k
                memcpy(w, d, l);
600
601
7.71k
        return 0;
602
7.71k
}
603
604
int dns_packet_append_name(
605
                DnsPacket *p,
606
                const char *name,
607
                bool allow_compression,
608
                bool canonical_candidate,
609
5.94k
                size_t *start) {
610
611
5.94k
        _cleanup_free_ char **added_entries = NULL; /* doesn't own the strings! this is just regular pointer array, not a NULL-terminated strv! */
612
5.94k
        size_t n_added_entries = 0, saved_size;
613
5.94k
        int r;
614
615
5.94k
        assert(p);
616
5.94k
        assert(name);
617
618
5.94k
        r = dns_name_is_valid(name);
619
5.94k
        if (r < 0)
620
0
                return r;
621
5.94k
        if (r == 0)
622
0
                return -EINVAL;
623
624
5.94k
        if (p->refuse_compression)
625
5.94k
                allow_compression = false;
626
627
5.94k
        saved_size = p->size;
628
629
13.6k
        while (!dns_name_is_root(name)) {
630
7.71k
                const char *z = name;
631
7.71k
                char label[DNS_LABEL_MAX+1];
632
7.71k
                size_t n = 0;
633
634
7.71k
                if (allow_compression)
635
0
                        n = PTR_TO_SIZE(hashmap_get(p->names, name));
636
7.71k
                if (n > 0) {
637
0
                        assert(n < p->size);
638
639
0
                        if (n < 0x4000) {
640
0
                                r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
641
0
                                if (r < 0)
642
0
                                        goto fail;
643
644
0
                                goto done;
645
0
                        }
646
0
                }
647
648
7.71k
                r = dns_label_unescape(&name, label, sizeof label, 0);
649
7.71k
                if (r < 0)
650
0
                        goto fail;
651
652
7.71k
                r = dns_packet_append_label(p, label, r, canonical_candidate, &n);
653
7.71k
                if (r < 0)
654
0
                        goto fail;
655
656
7.71k
                if (allow_compression) {
657
0
                        _cleanup_free_ char *s = NULL;
658
659
0
                        if (!GREEDY_REALLOC(added_entries, n_added_entries + 1)) {
660
0
                                r = -ENOMEM;
661
0
                                goto fail;
662
0
                        }
663
664
0
                        s = strdup(z);
665
0
                        if (!s) {
666
0
                                r = -ENOMEM;
667
0
                                goto fail;
668
0
                        }
669
670
0
                        r = hashmap_ensure_put(&p->names, &dns_name_hash_ops, s, SIZE_TO_PTR(n));
671
0
                        if (r < 0)
672
0
                                goto fail;
673
674
                        /* Keep track of the entries we just added (note that the string is owned by the hashtable, not this array!) */
675
0
                        added_entries[n_added_entries++] = TAKE_PTR(s);
676
0
                }
677
7.71k
        }
678
679
5.94k
        r = dns_packet_append_uint8(p, 0, NULL);
680
5.94k
        if (r < 0)
681
0
                return r;
682
683
5.94k
done:
684
5.94k
        if (start)
685
0
                *start = saved_size;
686
687
5.94k
        return 0;
688
689
0
fail:
690
        /* Remove all label compression names we added again */
691
0
        FOREACH_ARRAY(s, added_entries, n_added_entries) {
692
0
                hashmap_remove(p->names, *s);
693
0
                free(*s);
694
0
        }
695
696
0
        dns_packet_truncate(p, saved_size);
697
0
        return r;
698
5.94k
}
699
700
4.16k
int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, const DnsAnswerFlags flags, size_t *start) {
701
4.16k
        size_t saved_size;
702
4.16k
        uint16_t class;
703
4.16k
        int r;
704
705
4.16k
        assert(p);
706
4.16k
        assert(k);
707
708
4.16k
        saved_size = p->size;
709
710
4.16k
        r = dns_packet_append_name(p, dns_resource_key_name(k), true, true, NULL);
711
4.16k
        if (r < 0)
712
0
                goto fail;
713
714
4.16k
        r = dns_packet_append_uint16(p, k->type, NULL);
715
4.16k
        if (r < 0)
716
0
                goto fail;
717
718
4.16k
        class = flags & DNS_ANSWER_CACHE_FLUSH ? k->class | MDNS_RR_CACHE_FLUSH_OR_QU : k->class;
719
4.16k
        r = dns_packet_append_uint16(p, class, NULL);
720
4.16k
        if (r < 0)
721
0
                goto fail;
722
723
4.16k
        if (start)
724
0
                *start = saved_size;
725
726
4.16k
        return 0;
727
728
0
fail:
729
0
        dns_packet_truncate(p, saved_size);
730
0
        return r;
731
4.16k
}
732
733
2.26k
static int dns_packet_append_type_window(DnsPacket *p, uint8_t window, uint8_t length, const uint8_t *types, size_t *start) {
734
2.26k
        size_t saved_size;
735
2.26k
        int r;
736
737
2.26k
        assert(p);
738
2.26k
        assert(types);
739
2.26k
        assert(length > 0);
740
741
2.26k
        saved_size = p->size;
742
743
2.26k
        r = dns_packet_append_uint8(p, window, NULL);
744
2.26k
        if (r < 0)
745
0
                goto fail;
746
747
2.26k
        r = dns_packet_append_uint8(p, length, NULL);
748
2.26k
        if (r < 0)
749
0
                goto fail;
750
751
2.26k
        r = dns_packet_append_blob(p, types, length, NULL);
752
2.26k
        if (r < 0)
753
0
                goto fail;
754
755
2.26k
        if (start)
756
0
                *start = saved_size;
757
758
2.26k
        return 0;
759
0
fail:
760
0
        dns_packet_truncate(p, saved_size);
761
0
        return r;
762
2.26k
}
763
764
764
static int dns_packet_append_types(DnsPacket *p, Bitmap *types, size_t *start) {
765
764
        uint8_t window = 0;
766
764
        uint8_t entry = 0;
767
764
        uint8_t bitmaps[32] = {};
768
764
        unsigned n;
769
764
        size_t saved_size;
770
764
        int r;
771
772
764
        assert(p);
773
774
764
        saved_size = p->size;
775
776
110k
        BITMAP_FOREACH(n, types) {
777
110k
                assert(n <= 0xffff);
778
779
110k
                if ((n >> 8) != window && bitmaps[entry / 8] != 0) {
780
1.61k
                        r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
781
1.61k
                        if (r < 0)
782
0
                                goto fail;
783
784
1.61k
                        zero(bitmaps);
785
1.61k
                }
786
787
110k
                window = n >> 8;
788
110k
                entry = n & 255;
789
790
110k
                bitmaps[entry / 8] |= 1 << (7 - (entry % 8));
791
110k
        }
792
793
764
        if (bitmaps[entry / 8] != 0) {
794
644
                r = dns_packet_append_type_window(p, window, entry / 8 + 1, bitmaps, NULL);
795
644
                if (r < 0)
796
0
                        goto fail;
797
644
        }
798
799
764
        if (start)
800
0
                *start = saved_size;
801
802
764
        return 0;
803
0
fail:
804
0
        dns_packet_truncate(p, saved_size);
805
0
        return r;
806
764
}
807
808
/* Append the OPT pseudo-RR described in RFC6891 */
809
int dns_packet_append_opt(
810
                DnsPacket *p,
811
                uint16_t max_udp_size,
812
                bool edns0_do,
813
                bool include_rfc6975,
814
                const char *nsid,
815
                int rcode,
816
0
                size_t *ret_start) {
817
818
0
        size_t saved_size;
819
0
        int r;
820
821
0
        assert(p);
822
        /* we must never advertise supported packet size smaller than the legacy max */
823
0
        assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
824
0
        assert(rcode >= 0);
825
0
        assert(rcode <= _DNS_RCODE_MAX);
826
827
0
        if (p->opt_start != SIZE_MAX)
828
0
                return -EBUSY;
829
830
0
        assert(p->opt_size == SIZE_MAX);
831
832
0
        saved_size = p->size;
833
834
        /* empty name */
835
0
        r = dns_packet_append_uint8(p, 0, NULL);
836
0
        if (r < 0)
837
0
                return r;
838
839
        /* type */
840
0
        r = dns_packet_append_uint16(p, DNS_TYPE_OPT, NULL);
841
0
        if (r < 0)
842
0
                goto fail;
843
844
        /* class: maximum udp packet that can be received */
845
0
        r = dns_packet_append_uint16(p, max_udp_size, NULL);
846
0
        if (r < 0)
847
0
                goto fail;
848
849
        /* extended RCODE and VERSION */
850
0
        r = dns_packet_append_uint16(p, ((uint16_t) rcode & 0x0FF0) << 4, NULL);
851
0
        if (r < 0)
852
0
                goto fail;
853
854
        /* flags: DNSSEC OK (DO), see RFC3225 */
855
0
        r = dns_packet_append_uint16(p, edns0_do ? EDNS0_OPT_DO : 0, NULL);
856
0
        if (r < 0)
857
0
                goto fail;
858
859
0
        if (edns0_do && include_rfc6975) {
860
                /* If DO is on and this is requested, also append RFC6975 Algorithm data. This is supposed to
861
                 * be done on queries, not on replies, hencer callers should turn this off when finishing off
862
                 * replies. */
863
864
0
                static const uint8_t rfc6975[] = {
865
866
0
                        0, DNS_EDNS_OPT_DAU, /* OPTION_CODE */
867
#if HAVE_OPENSSL
868
                        0, 7, /* LIST_LENGTH */
869
#else
870
0
                        0, 6, /* LIST_LENGTH */
871
0
#endif
872
0
                        DNSSEC_ALGORITHM_RSASHA1,
873
0
                        DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1,
874
0
                        DNSSEC_ALGORITHM_RSASHA256,
875
0
                        DNSSEC_ALGORITHM_RSASHA512,
876
0
                        DNSSEC_ALGORITHM_ECDSAP256SHA256,
877
0
                        DNSSEC_ALGORITHM_ECDSAP384SHA384,
878
#if HAVE_OPENSSL
879
                        DNSSEC_ALGORITHM_ED25519,
880
#endif
881
882
0
                        0, DNS_EDNS_OPT_DHU, /* OPTION_CODE */
883
0
                        0, 3, /* LIST_LENGTH */
884
0
                        DNSSEC_DIGEST_SHA1,
885
0
                        DNSSEC_DIGEST_SHA256,
886
0
                        DNSSEC_DIGEST_SHA384,
887
888
0
                        0, DNS_EDNS_OPT_N3U, /* OPTION_CODE */
889
0
                        0, 1, /* LIST_LENGTH */
890
0
                        NSEC3_ALGORITHM_SHA1,
891
0
                };
892
893
0
                r = dns_packet_append_uint16(p, sizeof(rfc6975), NULL); /* RDLENGTH */
894
0
                if (r < 0)
895
0
                        goto fail;
896
897
0
                r = dns_packet_append_blob(p, rfc6975, sizeof(rfc6975), NULL); /* the payload, as defined above */
898
899
0
        } else if (nsid) {
900
901
0
                if (strlen(nsid) > UINT16_MAX - 4) {
902
0
                        r = -E2BIG;
903
0
                        goto fail;
904
0
                }
905
906
0
                r = dns_packet_append_uint16(p, 4 + strlen(nsid), NULL); /* RDLENGTH */
907
0
                if (r < 0)
908
0
                        goto fail;
909
910
0
                r = dns_packet_append_uint16(p, 3, NULL); /* OPTION-CODE: NSID */
911
0
                if (r < 0)
912
0
                        goto fail;
913
914
0
                r = dns_packet_append_uint16(p, strlen(nsid), NULL); /* OPTION-LENGTH */
915
0
                if (r < 0)
916
0
                        goto fail;
917
918
0
                r = dns_packet_append_blob(p, nsid, strlen(nsid), NULL);
919
0
        } else
920
0
                r = dns_packet_append_uint16(p, 0, NULL);
921
0
        if (r < 0)
922
0
                goto fail;
923
924
0
        DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) + 1);
925
926
0
        p->opt_start = saved_size;
927
0
        p->opt_size = p->size - saved_size;
928
929
0
        if (ret_start)
930
0
                *ret_start = saved_size;
931
932
0
        return 0;
933
934
0
fail:
935
0
        dns_packet_truncate(p, saved_size);
936
0
        return r;
937
0
}
938
939
0
int dns_packet_truncate_opt(DnsPacket *p) {
940
0
        assert(p);
941
942
0
        if (p->opt_start == SIZE_MAX) {
943
0
                assert(p->opt_size == SIZE_MAX);
944
0
                return 0;
945
0
        }
946
947
0
        assert(p->opt_size != SIZE_MAX);
948
0
        assert(DNS_PACKET_ARCOUNT(p) > 0);
949
950
0
        if (p->opt_start + p->opt_size != p->size)
951
0
                return -EBUSY;
952
953
0
        dns_packet_truncate(p, p->opt_start);
954
0
        DNS_PACKET_HEADER(p)->arcount = htobe16(DNS_PACKET_ARCOUNT(p) - 1);
955
0
        p->opt_start = p->opt_size = SIZE_MAX;
956
957
0
        return 1;
958
0
}
959
960
4.16k
int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAnswerFlags flags, size_t *start, size_t *rdata_start) {
961
962
4.16k
        size_t saved_size, rdlength_offset, end, rdlength, rds;
963
4.16k
        uint32_t ttl;
964
4.16k
        int r;
965
966
4.16k
        assert(p);
967
4.16k
        assert(rr);
968
969
4.16k
        saved_size = p->size;
970
971
4.16k
        r = dns_packet_append_key(p, rr->key, flags, NULL);
972
4.16k
        if (r < 0)
973
0
                goto fail;
974
975
4.16k
        ttl = flags & DNS_ANSWER_GOODBYE ? 0 : rr->ttl;
976
4.16k
        r = dns_packet_append_uint32(p, ttl, NULL);
977
4.16k
        if (r < 0)
978
0
                goto fail;
979
980
        /* Initially we write 0 here */
981
4.16k
        r = dns_packet_append_uint16(p, 0, &rdlength_offset);
982
4.16k
        if (r < 0)
983
0
                goto fail;
984
985
4.16k
        rds = p->size - saved_size;
986
987
4.16k
        switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
988
989
2
        case DNS_TYPE_SRV:
990
2
                r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
991
2
                if (r < 0)
992
0
                        goto fail;
993
994
2
                r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
995
2
                if (r < 0)
996
0
                        goto fail;
997
998
2
                r = dns_packet_append_uint16(p, rr->srv.port, NULL);
999
2
                if (r < 0)
1000
0
                        goto fail;
1001
1002
                /* RFC 2782 states "Unless and until permitted by future standards action, name compression
1003
                 * is not to be used for this field." Hence we turn off compression here. */
1004
2
                r = dns_packet_append_name(p, rr->srv.name, /* allow_compression= */ false, /* canonical_candidate= */ true, NULL);
1005
2
                break;
1006
1007
18
        case DNS_TYPE_PTR:
1008
40
        case DNS_TYPE_NS:
1009
50
        case DNS_TYPE_CNAME:
1010
82
        case DNS_TYPE_DNAME:
1011
82
                r = dns_packet_append_name(p, rr->ptr.name, true, true, NULL);
1012
82
                break;
1013
1014
64
        case DNS_TYPE_HINFO:
1015
64
                r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
1016
64
                if (r < 0)
1017
0
                        goto fail;
1018
1019
64
                r = dns_packet_append_string(p, rr->hinfo.os, NULL);
1020
64
                break;
1021
1022
96
        case DNS_TYPE_SPF: /* exactly the same as TXT */
1023
458
        case DNS_TYPE_TXT:
1024
1025
458
                if (!rr->txt.items) {
1026
                        /* RFC 6763, section 6.1 suggests to generate
1027
                         * single empty string for an empty array. */
1028
1029
0
                        r = dns_packet_append_raw_string(p, NULL, 0, NULL);
1030
0
                        if (r < 0)
1031
0
                                goto fail;
1032
0
                } else
1033
1.59M
                        LIST_FOREACH(items, i, rr->txt.items) {
1034
1.59M
                                r = dns_packet_append_raw_string(p, i->data, i->length, NULL);
1035
1.59M
                                if (r < 0)
1036
0
                                        goto fail;
1037
1.59M
                        }
1038
1039
458
                r = 0;
1040
458
                break;
1041
1042
6
        case DNS_TYPE_A:
1043
6
                r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1044
6
                break;
1045
1046
4
        case DNS_TYPE_AAAA:
1047
4
                r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1048
4
                break;
1049
1050
26
        case DNS_TYPE_SOA:
1051
26
                r = dns_packet_append_name(p, rr->soa.mname, true, true, NULL);
1052
26
                if (r < 0)
1053
0
                        goto fail;
1054
1055
26
                r = dns_packet_append_name(p, rr->soa.rname, true, true, NULL);
1056
26
                if (r < 0)
1057
0
                        goto fail;
1058
1059
26
                r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
1060
26
                if (r < 0)
1061
0
                        goto fail;
1062
1063
26
                r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
1064
26
                if (r < 0)
1065
0
                        goto fail;
1066
1067
26
                r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
1068
26
                if (r < 0)
1069
0
                        goto fail;
1070
1071
26
                r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
1072
26
                if (r < 0)
1073
0
                        goto fail;
1074
1075
26
                r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
1076
26
                break;
1077
1078
32
        case DNS_TYPE_MX:
1079
32
                r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
1080
32
                if (r < 0)
1081
0
                        goto fail;
1082
1083
32
                r = dns_packet_append_name(p, rr->mx.exchange, true, true, NULL);
1084
32
                break;
1085
1086
210
        case DNS_TYPE_LOC:
1087
210
                r = dns_packet_append_uint8(p, rr->loc.version, NULL);
1088
210
                if (r < 0)
1089
0
                        goto fail;
1090
1091
210
                r = dns_packet_append_uint8(p, rr->loc.size, NULL);
1092
210
                if (r < 0)
1093
0
                        goto fail;
1094
1095
210
                r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
1096
210
                if (r < 0)
1097
0
                        goto fail;
1098
1099
210
                r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
1100
210
                if (r < 0)
1101
0
                        goto fail;
1102
1103
210
                r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
1104
210
                if (r < 0)
1105
0
                        goto fail;
1106
1107
210
                r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
1108
210
                if (r < 0)
1109
0
                        goto fail;
1110
1111
210
                r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
1112
210
                break;
1113
1114
66
        case DNS_TYPE_DS:
1115
66
                r = dns_packet_append_uint16(p, rr->ds.key_tag, NULL);
1116
66
                if (r < 0)
1117
0
                        goto fail;
1118
1119
66
                r = dns_packet_append_uint8(p, rr->ds.algorithm, NULL);
1120
66
                if (r < 0)
1121
0
                        goto fail;
1122
1123
66
                r = dns_packet_append_uint8(p, rr->ds.digest_type, NULL);
1124
66
                if (r < 0)
1125
0
                        goto fail;
1126
1127
66
                r = dns_packet_append_blob(p, rr->ds.digest, rr->ds.digest_size, NULL);
1128
66
                break;
1129
1130
104
        case DNS_TYPE_SSHFP:
1131
104
                r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
1132
104
                if (r < 0)
1133
0
                        goto fail;
1134
1135
104
                r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
1136
104
                if (r < 0)
1137
0
                        goto fail;
1138
1139
104
                r = dns_packet_append_blob(p, rr->sshfp.fingerprint, rr->sshfp.fingerprint_size, NULL);
1140
104
                break;
1141
1142
198
        case DNS_TYPE_DNSKEY:
1143
198
                r = dns_packet_append_uint16(p, rr->dnskey.flags, NULL);
1144
198
                if (r < 0)
1145
0
                        goto fail;
1146
1147
198
                r = dns_packet_append_uint8(p, rr->dnskey.protocol, NULL);
1148
198
                if (r < 0)
1149
0
                        goto fail;
1150
1151
198
                r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
1152
198
                if (r < 0)
1153
0
                        goto fail;
1154
1155
198
                r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
1156
198
                break;
1157
1158
108
        case DNS_TYPE_RRSIG:
1159
108
                r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
1160
108
                if (r < 0)
1161
0
                        goto fail;
1162
1163
108
                r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
1164
108
                if (r < 0)
1165
0
                        goto fail;
1166
1167
108
                r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
1168
108
                if (r < 0)
1169
0
                        goto fail;
1170
1171
108
                r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
1172
108
                if (r < 0)
1173
0
                        goto fail;
1174
1175
108
                r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
1176
108
                if (r < 0)
1177
0
                        goto fail;
1178
1179
108
                r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
1180
108
                if (r < 0)
1181
0
                        goto fail;
1182
1183
108
                r = dns_packet_append_uint16(p, rr->rrsig.key_tag, NULL);
1184
108
                if (r < 0)
1185
0
                        goto fail;
1186
1187
108
                r = dns_packet_append_name(p, rr->rrsig.signer, false, true, NULL);
1188
108
                if (r < 0)
1189
0
                        goto fail;
1190
1191
108
                r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
1192
108
                break;
1193
1194
644
        case DNS_TYPE_NSEC:
1195
644
                r = dns_packet_append_name(p, rr->nsec.next_domain_name, false, false, NULL);
1196
644
                if (r < 0)
1197
0
                        goto fail;
1198
1199
644
                r = dns_packet_append_types(p, rr->nsec.types, NULL);
1200
644
                if (r < 0)
1201
0
                        goto fail;
1202
1203
644
                break;
1204
1205
644
        case DNS_TYPE_NSEC3:
1206
120
                r = dns_packet_append_uint8(p, rr->nsec3.algorithm, NULL);
1207
120
                if (r < 0)
1208
0
                        goto fail;
1209
1210
120
                r = dns_packet_append_uint8(p, rr->nsec3.flags, NULL);
1211
120
                if (r < 0)
1212
0
                        goto fail;
1213
1214
120
                r = dns_packet_append_uint16(p, rr->nsec3.iterations, NULL);
1215
120
                if (r < 0)
1216
0
                        goto fail;
1217
1218
120
                r = dns_packet_append_uint8(p, rr->nsec3.salt_size, NULL);
1219
120
                if (r < 0)
1220
0
                        goto fail;
1221
1222
120
                r = dns_packet_append_blob(p, rr->nsec3.salt, rr->nsec3.salt_size, NULL);
1223
120
                if (r < 0)
1224
0
                        goto fail;
1225
1226
120
                r = dns_packet_append_uint8(p, rr->nsec3.next_hashed_name_size, NULL);
1227
120
                if (r < 0)
1228
0
                        goto fail;
1229
1230
120
                r = dns_packet_append_blob(p, rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, NULL);
1231
120
                if (r < 0)
1232
0
                        goto fail;
1233
1234
120
                r = dns_packet_append_types(p, rr->nsec3.types, NULL);
1235
120
                if (r < 0)
1236
0
                        goto fail;
1237
1238
120
                break;
1239
1240
144
        case DNS_TYPE_TLSA:
1241
144
                r = dns_packet_append_uint8(p, rr->tlsa.cert_usage, NULL);
1242
144
                if (r < 0)
1243
0
                        goto fail;
1244
1245
144
                r = dns_packet_append_uint8(p, rr->tlsa.selector, NULL);
1246
144
                if (r < 0)
1247
0
                        goto fail;
1248
1249
144
                r = dns_packet_append_uint8(p, rr->tlsa.matching_type, NULL);
1250
144
                if (r < 0)
1251
0
                        goto fail;
1252
1253
144
                r = dns_packet_append_blob(p, rr->tlsa.data, rr->tlsa.data_size, NULL);
1254
144
                break;
1255
1256
464
        case DNS_TYPE_SVCB:
1257
852
        case DNS_TYPE_HTTPS:
1258
852
                r = dns_packet_append_uint16(p, rr->svcb.priority, NULL);
1259
852
                if (r < 0)
1260
0
                        goto fail;
1261
1262
852
                r = dns_packet_append_name(p, rr->svcb.target_name, false, false, NULL);
1263
852
                if (r < 0)
1264
0
                        goto fail;
1265
1266
1.73k
                LIST_FOREACH(params, i, rr->svcb.params) {
1267
1.73k
                        r = dns_packet_append_uint16(p, i->key, NULL);
1268
1.73k
                        if (r < 0)
1269
0
                                goto fail;
1270
1271
1.73k
                        r = dns_packet_append_uint16(p, i->length, NULL);
1272
1.73k
                        if (r < 0)
1273
0
                                goto fail;
1274
1275
1.73k
                        r = dns_packet_append_blob(p, i->value, i->length, NULL);
1276
1.73k
                        if (r < 0)
1277
0
                                goto fail;
1278
1.73k
                }
1279
852
                break;
1280
1281
852
        case DNS_TYPE_CAA:
1282
306
                r = dns_packet_append_uint8(p, rr->caa.flags, NULL);
1283
306
                if (r < 0)
1284
0
                        goto fail;
1285
1286
306
                r = dns_packet_append_string(p, rr->caa.tag, NULL);
1287
306
                if (r < 0)
1288
0
                        goto fail;
1289
1290
306
                r = dns_packet_append_blob(p, rr->caa.value, rr->caa.value_size, NULL);
1291
306
                break;
1292
1293
12
        case DNS_TYPE_NAPTR:
1294
12
                r = dns_packet_append_uint16(p, rr->naptr.order, NULL);
1295
12
                if (r < 0)
1296
0
                        goto fail;
1297
1298
12
                r = dns_packet_append_uint16(p, rr->naptr.preference, NULL);
1299
12
                if (r < 0)
1300
0
                        goto fail;
1301
1302
12
                r = dns_packet_append_string(p, rr->naptr.flags, NULL);
1303
12
                if (r < 0)
1304
0
                        goto fail;
1305
1306
12
                r = dns_packet_append_string(p, rr->naptr.services, NULL);
1307
12
                if (r < 0)
1308
0
                        goto fail;
1309
1310
12
                r = dns_packet_append_string(p, rr->naptr.regexp, NULL);
1311
12
                if (r < 0)
1312
0
                        goto fail;
1313
1314
12
                r = dns_packet_append_name(p, rr->naptr.replacement, /* allow_compression= */ false, /* canonical_candidate= */ true, NULL);
1315
12
                break;
1316
1317
6
        case DNS_TYPE_OPT:
1318
64
        case DNS_TYPE_OPENPGPKEY:
1319
134
        case _DNS_TYPE_INVALID: /* unparsable */
1320
724
        default:
1321
724
                r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
1322
4.16k
        }
1323
4.16k
        if (r < 0)
1324
0
                goto fail;
1325
1326
        /* Let's calculate the actual data size and update the field */
1327
4.16k
        rdlength = p->size - rdlength_offset - sizeof(uint16_t);
1328
4.16k
        if (rdlength > 0xFFFF) {
1329
0
                r = -ENOSPC;
1330
0
                goto fail;
1331
0
        }
1332
1333
4.16k
        end = p->size;
1334
4.16k
        p->size = rdlength_offset;
1335
4.16k
        r = dns_packet_append_uint16(p, rdlength, NULL);
1336
4.16k
        if (r < 0)
1337
0
                goto fail;
1338
4.16k
        p->size = end;
1339
1340
4.16k
        if (start)
1341
4.16k
                *start = saved_size;
1342
1343
4.16k
        if (rdata_start)
1344
4.16k
                *rdata_start = rds;
1345
1346
4.16k
        return 0;
1347
1348
0
fail:
1349
0
        dns_packet_truncate(p, saved_size);
1350
0
        return r;
1351
4.16k
}
1352
1353
0
int dns_packet_append_question(DnsPacket *p, DnsQuestion *q) {
1354
0
        DnsResourceKey *key;
1355
0
        int r;
1356
1357
0
        assert(p);
1358
1359
0
        DNS_QUESTION_FOREACH(key, q) {
1360
0
                r = dns_packet_append_key(p, key, 0, NULL);
1361
0
                if (r < 0)
1362
0
                        return r;
1363
0
        }
1364
1365
0
        return 0;
1366
0
}
1367
1368
0
int dns_packet_append_answer(DnsPacket *p, DnsAnswer *a, unsigned *completed) {
1369
0
        DnsResourceRecord *rr;
1370
0
        DnsAnswerFlags flags;
1371
0
        int r;
1372
1373
0
        assert(p);
1374
1375
0
        DNS_ANSWER_FOREACH_FLAGS(rr, flags, a) {
1376
0
                r = dns_packet_append_rr(p, rr, flags, NULL, NULL);
1377
0
                if (r < 0)
1378
0
                        return r;
1379
1380
0
                if (completed)
1381
0
                        (*completed)++;
1382
0
        }
1383
1384
0
        return 0;
1385
0
}
1386
1387
3.02M
int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
1388
3.02M
        assert(p);
1389
3.02M
        assert(p->rindex <= p->size);
1390
1391
3.02M
        if (sz > p->size - p->rindex)
1392
3.83k
                return -EMSGSIZE;
1393
1394
3.01M
        if (ret)
1395
3.01M
                *ret = DNS_PACKET_DATA(p) + p->rindex;
1396
1397
3.01M
        if (start)
1398
48.9k
                *start = p->rindex;
1399
1400
3.01M
        p->rindex += sz;
1401
3.01M
        return 0;
1402
3.02M
}
1403
1404
22.1k
void dns_packet_rewind(DnsPacket *p, size_t idx) {
1405
22.1k
        assert(p);
1406
22.1k
        assert(idx <= p->size);
1407
22.1k
        assert(idx >= DNS_PACKET_HEADER_SIZE);
1408
1409
22.1k
        p->rindex = idx;
1410
22.1k
}
1411
1412
11.4k
int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
1413
11.4k
        const void *q;
1414
11.4k
        int r;
1415
1416
11.4k
        assert(p);
1417
11.4k
        assert(d);
1418
1419
11.4k
        r = dns_packet_read(p, sz, &q, start);
1420
11.4k
        if (r < 0)
1421
69
                return r;
1422
1423
11.3k
        memcpy(d, q, sz);
1424
11.3k
        return 0;
1425
11.4k
}
1426
1427
static int dns_packet_read_memdup(
1428
                DnsPacket *p, size_t size,
1429
                void **ret, size_t *ret_size,
1430
44.4k
                size_t *ret_start) {
1431
1432
44.4k
        const void *src;
1433
44.4k
        size_t start;
1434
44.4k
        int r;
1435
1436
44.4k
        assert(p);
1437
44.4k
        assert(ret);
1438
1439
44.4k
        r = dns_packet_read(p, size, &src, &start);
1440
44.4k
        if (r < 0)
1441
43
                return r;
1442
1443
44.4k
        if (size <= 0)
1444
26.4k
                *ret = NULL;
1445
17.9k
        else {
1446
17.9k
                void *copy;
1447
1448
17.9k
                copy = memdup(src, size);
1449
17.9k
                if (!copy)
1450
0
                        return -ENOMEM;
1451
1452
17.9k
                *ret = copy;
1453
17.9k
        }
1454
1455
44.4k
        if (ret_size)
1456
44.4k
                *ret_size = size;
1457
44.4k
        if (ret_start)
1458
0
                *ret_start = start;
1459
1460
44.4k
        return 0;
1461
44.4k
}
1462
1463
1.39M
int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
1464
1.39M
        const void *d;
1465
1.39M
        int r;
1466
1467
1.39M
        assert(p);
1468
1469
1.39M
        r = dns_packet_read(p, sizeof(uint8_t), &d, start);
1470
1.39M
        if (r < 0)
1471
2.56k
                return r;
1472
1473
1.38M
        *ret = ((uint8_t*) d)[0];
1474
1.38M
        return 0;
1475
1.39M
}
1476
1477
343k
int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
1478
343k
        const void *d;
1479
343k
        int r;
1480
1481
343k
        assert(p);
1482
1483
343k
        r = dns_packet_read(p, sizeof(uint16_t), &d, start);
1484
343k
        if (r < 0)
1485
484
                return r;
1486
1487
342k
        if (ret)
1488
342k
                *ret = unaligned_read_be16(d);
1489
1490
342k
        return 0;
1491
343k
}
1492
1493
121k
int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
1494
121k
        const void *d;
1495
121k
        int r;
1496
1497
121k
        assert(p);
1498
1499
121k
        r = dns_packet_read(p, sizeof(uint32_t), &d, start);
1500
121k
        if (r < 0)
1501
406
                return r;
1502
1503
120k
        *ret = unaligned_read_be32(d);
1504
1505
120k
        return 0;
1506
121k
}
1507
1508
10.6k
int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
1509
10.6k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1510
10.6k
        _cleanup_free_ char *t = NULL;
1511
10.6k
        const void *d;
1512
10.6k
        uint8_t c;
1513
10.6k
        int r;
1514
1515
10.6k
        assert(p);
1516
1517
10.6k
        r = dns_packet_read_uint8(p, &c, NULL);
1518
10.6k
        if (r < 0)
1519
204
                return r;
1520
1521
10.3k
        r = dns_packet_read(p, c, &d, NULL);
1522
10.3k
        if (r < 0)
1523
37
                return r;
1524
1525
10.3k
        r = make_cstring(d, c, MAKE_CSTRING_REFUSE_TRAILING_NUL, &t);
1526
10.3k
        if (r < 0)
1527
58
                return r;
1528
1529
10.3k
        if (!utf8_is_valid(t))
1530
276
                return -EBADMSG;
1531
1532
10.0k
        *ret = TAKE_PTR(t);
1533
1534
10.0k
        if (start)
1535
0
                *start = rewinder.saved_rindex;
1536
10.0k
        CANCEL_REWINDER(rewinder);
1537
1538
10.0k
        return 0;
1539
10.3k
}
1540
1541
970k
int dns_packet_read_raw_string(DnsPacket *p, const void **ret, size_t *size, size_t *start) {
1542
970k
        assert(p);
1543
1544
970k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1545
970k
        uint8_t c;
1546
970k
        int r;
1547
1548
970k
        r = dns_packet_read_uint8(p, &c, NULL);
1549
970k
        if (r < 0)
1550
0
                return r;
1551
1552
970k
        r = dns_packet_read(p, c, ret, NULL);
1553
970k
        if (r < 0)
1554
83
                return r;
1555
1556
970k
        if (size)
1557
970k
                *size = c;
1558
970k
        if (start)
1559
0
                *start = rewinder.saved_rindex;
1560
970k
        CANCEL_REWINDER(rewinder);
1561
1562
970k
        return 0;
1563
970k
}
1564
1565
int dns_packet_read_name(
1566
                DnsPacket *p,
1567
                char **ret,
1568
                bool allow_compression,
1569
138k
                size_t *ret_start) {
1570
1571
138k
        assert(p);
1572
1573
138k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1574
138k
        size_t after_rindex = 0, jump_barrier = p->rindex;
1575
138k
        _cleanup_free_ char *name = NULL;
1576
138k
        bool first = true;
1577
138k
        size_t n = 0, m = 0;
1578
138k
        int r;
1579
1580
138k
        if (p->refuse_compression)
1581
4.73k
                allow_compression = false;
1582
1583
263k
        for (;;) {
1584
263k
                uint8_t c, d;
1585
1586
263k
                r = dns_packet_read_uint8(p, &c, NULL);
1587
263k
                if (r < 0)
1588
2.20k
                        return r;
1589
1590
260k
                if (c == 0)
1591
                        /* End of name */
1592
136k
                        break;
1593
124k
                else if (c <= 63) {
1594
93.2k
                        const char *label;
1595
1596
                        /* Literal label */
1597
93.2k
                        r = dns_packet_read(p, c, (const void**) &label, NULL);
1598
93.2k
                        if (r < 0)
1599
118
                                return r;
1600
1601
93.0k
                        if (!GREEDY_REALLOC(name, n + !first + DNS_LABEL_ESCAPED_MAX))
1602
0
                                return -ENOMEM;
1603
1604
93.0k
                        if (first)
1605
26.9k
                                first = false;
1606
66.0k
                        else {
1607
66.0k
                                name[n++] = '.';
1608
66.0k
                                m++;
1609
66.0k
                        }
1610
1611
93.0k
                        r = dns_label_escape(label, c, name + n, DNS_LABEL_ESCAPED_MAX);
1612
93.0k
                        if (r < 0)
1613
0
                                return r;
1614
1615
93.0k
                        n += r;
1616
93.0k
                        m += c;
1617
1618
93.0k
                        if (m > DNS_HOSTNAME_MAX)
1619
23
                                return -EBADMSG;
1620
1621
93.0k
                        continue;
1622
93.0k
                } else if (allow_compression && FLAGS_SET(c, 0xc0)) {
1623
31.4k
                        uint16_t ptr;
1624
1625
                        /* Pointer */
1626
31.4k
                        r = dns_packet_read_uint8(p, &d, NULL);
1627
31.4k
                        if (r < 0)
1628
20
                                return r;
1629
1630
31.4k
                        ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
1631
31.4k
                        if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier)
1632
101
                                return -EBADMSG;
1633
1634
31.3k
                        if (after_rindex == 0)
1635
22.6k
                                after_rindex = p->rindex;
1636
1637
                        /* Jumps are limited to a "prior occurrence" (RFC-1035 4.1.4) */
1638
31.3k
                        jump_barrier = ptr;
1639
31.3k
                        p->rindex = ptr;
1640
31.3k
                } else
1641
163
                        return -EBADMSG;
1642
260k
        }
1643
1644
136k
        if (!GREEDY_REALLOC(name, n + 1))
1645
0
                return -ENOMEM;
1646
1647
136k
        name[n] = 0;
1648
1649
136k
        if (after_rindex != 0)
1650
22.6k
                p->rindex= after_rindex;
1651
1652
136k
        if (ret)
1653
136k
                *ret = TAKE_PTR(name);
1654
136k
        if (ret_start)
1655
0
                *ret_start = rewinder.saved_rindex;
1656
1657
136k
        CANCEL_REWINDER(rewinder);
1658
1659
136k
        return 0;
1660
136k
}
1661
1662
37.1k
static int dns_packet_read_type_window(DnsPacket *p, Bitmap **types, size_t *start) {
1663
37.1k
        assert(p);
1664
37.1k
        assert(types);
1665
1666
37.1k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1667
37.1k
        uint8_t window, length;
1668
37.1k
        const uint8_t *bitmap;
1669
37.1k
        uint8_t bit = 0;
1670
37.1k
        bool found = false;
1671
37.1k
        int r;
1672
1673
37.1k
        r = bitmap_ensure_allocated(types);
1674
37.1k
        if (r < 0)
1675
0
                return r;
1676
1677
37.1k
        r = dns_packet_read_uint8(p, &window, NULL);
1678
37.1k
        if (r < 0)
1679
0
                return r;
1680
1681
37.1k
        r = dns_packet_read_uint8(p, &length, NULL);
1682
37.1k
        if (r < 0)
1683
44
                return r;
1684
1685
37.0k
        if (length == 0 || length > 32)
1686
118
                return -EBADMSG;
1687
1688
36.9k
        r = dns_packet_read(p, length, (const void **)&bitmap, NULL);
1689
36.9k
        if (r < 0)
1690
28
                return r;
1691
1692
345k
        for (uint8_t i = 0; i < length; i++) {
1693
308k
                uint8_t bitmask = 1 << 7;
1694
1695
308k
                if (!bitmap[i]) {
1696
23.3k
                        found = false;
1697
23.3k
                        bit += 8;
1698
23.3k
                        continue;
1699
23.3k
                }
1700
1701
285k
                found = true;
1702
1703
2.56M
                for (; bitmask; bit++, bitmask >>= 1)
1704
2.28M
                        if (bitmap[i] & bitmask) {
1705
702k
                                uint16_t n;
1706
1707
702k
                                n = (uint16_t) window << 8 | (uint16_t) bit;
1708
1709
                                /* Ignore pseudo-types. see RFC4034 section 4.1.2 */
1710
702k
                                if (dns_type_is_pseudo(n))
1711
7.16k
                                        continue;
1712
1713
695k
                                r = bitmap_set(*types, n);
1714
695k
                                if (r < 0)
1715
0
                                        return r;
1716
695k
                        }
1717
285k
        }
1718
1719
36.9k
        if (!found)
1720
48
                return -EBADMSG;
1721
1722
36.9k
        if (start)
1723
0
                *start = rewinder.saved_rindex;
1724
36.9k
        CANCEL_REWINDER(rewinder);
1725
1726
36.9k
        return 0;
1727
36.9k
}
1728
1729
8.44k
static int dns_packet_read_type_windows(DnsPacket *p, Bitmap **types, size_t size, size_t *start) {
1730
8.44k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1731
8.44k
        int r;
1732
1733
45.2k
        while (p->rindex - rewinder.saved_rindex < size) {
1734
37.1k
                r = dns_packet_read_type_window(p, types, NULL);
1735
37.1k
                if (r < 0)
1736
238
                        return r;
1737
1738
36.9k
                assert(p->rindex >= rewinder.saved_rindex);
1739
1740
                /* don't read past end of current RR */
1741
36.9k
                if (p->rindex - rewinder.saved_rindex > size)
1742
85
                        return -EBADMSG;
1743
36.9k
        }
1744
1745
8.12k
        if (p->rindex - rewinder.saved_rindex != size)
1746
0
                return -EBADMSG;
1747
1748
8.12k
        if (start)
1749
0
                *start = rewinder.saved_rindex;
1750
8.12k
        CANCEL_REWINDER(rewinder);
1751
1752
8.12k
        return 0;
1753
8.12k
}
1754
1755
int dns_packet_read_key(
1756
                DnsPacket *p,
1757
                DnsResourceKey **ret,
1758
                bool *ret_cache_flush_or_qu,
1759
106k
                size_t *ret_start) {
1760
1761
106k
        assert(p);
1762
1763
106k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1764
106k
        _cleanup_free_ char *name = NULL;
1765
106k
        bool cache_flush_or_qu = false;
1766
106k
        uint16_t class, type;
1767
106k
        int r;
1768
1769
106k
        r = dns_packet_read_name(p, &name, true, NULL);
1770
106k
        if (r < 0)
1771
2.48k
                return r;
1772
1773
103k
        r = dns_packet_read_uint16(p, &type, NULL);
1774
103k
        if (r < 0)
1775
184
                return r;
1776
1777
103k
        r = dns_packet_read_uint16(p, &class, NULL);
1778
103k
        if (r < 0)
1779
56
                return r;
1780
1781
103k
        if (p->protocol == DNS_PROTOCOL_MDNS) {
1782
                /* See RFC6762, sections 5.4 and 10.2 */
1783
1784
0
                if (type != DNS_TYPE_OPT && (class & MDNS_RR_CACHE_FLUSH_OR_QU)) {
1785
0
                        class &= ~MDNS_RR_CACHE_FLUSH_OR_QU;
1786
0
                        cache_flush_or_qu = true;
1787
0
                }
1788
0
        }
1789
1790
103k
        if (ret) {
1791
103k
                DnsResourceKey *key;
1792
1793
103k
                key = dns_resource_key_new_consume(class, type, name);
1794
103k
                if (!key)
1795
0
                        return -ENOMEM;
1796
1797
103k
                TAKE_PTR(name);
1798
103k
                *ret = key;
1799
103k
        }
1800
1801
103k
        if (ret_cache_flush_or_qu)
1802
103k
                *ret_cache_flush_or_qu = cache_flush_or_qu;
1803
103k
        if (ret_start)
1804
0
                *ret_start = rewinder.saved_rindex;
1805
1806
103k
        CANCEL_REWINDER(rewinder);
1807
103k
        return 0;
1808
103k
}
1809
1810
6.70k
static bool loc_size_ok(uint8_t size) {
1811
6.70k
        uint8_t m = size >> 4, e = size & 0xF;
1812
1813
6.70k
        return m <= 9 && e <= 9 && (m > 0 || e == 0);
1814
6.70k
}
1815
1816
8.95k
static bool dns_svc_param_is_valid(DnsSvcParam *i) {
1817
8.95k
        if (!i)
1818
0
                return false;
1819
1820
8.95k
        switch (i->key) {
1821
        /* RFC 9460, section 7.1.1: alpn-ids must exactly fill SvcParamValue */
1822
584
        case DNS_SVC_PARAM_KEY_ALPN: {
1823
584
                size_t sz = 0;
1824
584
                if (i->length <= 0)
1825
3
                        return false;
1826
75.2k
                while (sz < i->length)
1827
74.6k
                        sz += 1 + i->value[sz]; /* N.B. will not overflow */
1828
581
                return sz == i->length;
1829
584
        }
1830
1831
        /* RFC 9460, section 7.1.1: value must be empty */
1832
383
        case DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN:
1833
383
                return i->length == 0;
1834
1835
        /* RFC 9460, section 7.2 */
1836
262
        case DNS_SVC_PARAM_KEY_PORT:
1837
262
                return i->length == 2;
1838
1839
        /* RFC 9460, section 7.3: addrs must exactly fill SvcParamValue */
1840
354
        case DNS_SVC_PARAM_KEY_IPV4HINT:
1841
354
                return i->length > 0 && i->length % (sizeof (struct in_addr)) == 0;
1842
290
        case DNS_SVC_PARAM_KEY_IPV6HINT:
1843
290
                return i->length > 0 && i->length % (sizeof (struct in6_addr)) == 0;
1844
1845
        /* Otherwise, permit any value */
1846
7.08k
        default:
1847
7.08k
                return true;
1848
8.95k
        }
1849
8.95k
}
1850
1851
int dns_packet_read_rr(
1852
                DnsPacket *p,
1853
                DnsResourceRecord **ret,
1854
                bool *ret_cache_flush,
1855
91.6k
                size_t *ret_start) {
1856
1857
91.6k
        assert(p);
1858
1859
91.6k
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
1860
91.6k
        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1861
91.6k
        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1862
91.6k
        size_t offset;
1863
91.6k
        uint16_t rdlength;
1864
91.6k
        bool cache_flush;
1865
91.6k
        int r;
1866
1867
91.6k
        r = dns_packet_read_key(p, &key, &cache_flush, NULL);
1868
91.6k
        if (r < 0)
1869
2.12k
                return r;
1870
1871
89.5k
        if (!dns_class_is_valid_rr(key->class) || !dns_type_is_valid_rr(key->type))
1872
16
                return -EBADMSG;
1873
1874
89.5k
        rr = dns_resource_record_new(key);
1875
89.5k
        if (!rr)
1876
0
                return -ENOMEM;
1877
1878
89.5k
        r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1879
89.5k
        if (r < 0)
1880
335
                return r;
1881
1882
        /* RFC 2181, Section 8, suggests to treat a TTL with the MSB set as a zero TTL. We avoid doing this
1883
         * for OPT records so that all 8 bits of the extended RCODE may be used. */
1884
89.1k
        if (key->type != DNS_TYPE_OPT && rr->ttl & UINT32_C(0x80000000))
1885
11.9k
                rr->ttl = 0;
1886
1887
89.1k
        r = dns_packet_read_uint16(p, &rdlength, NULL);
1888
89.1k
        if (r < 0)
1889
157
                return r;
1890
1891
89.0k
        if (rdlength > p->size - p->rindex)
1892
173
                return -EBADMSG;
1893
1894
88.8k
        offset = p->rindex;
1895
1896
88.8k
        switch (rr->key->type) {
1897
1898
1.58k
        case DNS_TYPE_SRV:
1899
1.58k
                r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1900
1.58k
                if (r < 0)
1901
3
                        return r;
1902
1.58k
                r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1903
1.58k
                if (r < 0)
1904
3
                        return r;
1905
1.57k
                r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1906
1.57k
                if (r < 0)
1907
2
                        return r;
1908
1909
                /* RFC 2782 states "Unless and until permitted by future standards action, name compression
1910
                 * is not to be used for this field." Nonetheless, we support it here, in the interest of
1911
                 * increasing compatibility with implementations that do not implement this correctly. After
1912
                 * all we didn't do this right once upon a time ourselves (see
1913
                 * https://github.com/systemd/systemd/issues/9793). */
1914
1.57k
                r = dns_packet_read_name(p, &rr->srv.name, /* allow_compression= */ true, NULL);
1915
1.57k
                break;
1916
1917
926
        case DNS_TYPE_PTR:
1918
3.17k
        case DNS_TYPE_NS:
1919
4.10k
        case DNS_TYPE_CNAME:
1920
4.91k
        case DNS_TYPE_DNAME:
1921
4.91k
                r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1922
4.91k
                break;
1923
1924
1.64k
        case DNS_TYPE_HINFO:
1925
1.64k
                r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1926
1.64k
                if (r < 0)
1927
282
                        return r;
1928
1929
1.36k
                r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1930
1.36k
                break;
1931
1932
12.4k
        case DNS_TYPE_SPF: /* exactly the same as TXT */
1933
13.9k
        case DNS_TYPE_TXT:
1934
13.9k
                if (rdlength <= 0) {
1935
2.49k
                        r = dns_txt_item_new_empty(&rr->txt.items);
1936
2.49k
                        if (r < 0)
1937
0
                                return r;
1938
11.4k
                } else {
1939
11.4k
                        DnsTxtItem *last = NULL;
1940
1941
982k
                        while (p->rindex - offset < rdlength) {
1942
970k
                                DnsTxtItem *i;
1943
970k
                                const void *data;
1944
970k
                                size_t sz;
1945
1946
970k
                                r = dns_packet_read_raw_string(p, &data, &sz, NULL);
1947
970k
                                if (r < 0)
1948
83
                                        return r;
1949
1950
970k
                                i = malloc0(offsetof(DnsTxtItem, data) + sz + 1); /* extra NUL byte at the end */
1951
970k
                                if (!i)
1952
0
                                        return -ENOMEM;
1953
1954
970k
                                memcpy(i->data, data, sz);
1955
970k
                                i->length = sz;
1956
1957
970k
                                LIST_INSERT_AFTER(items, rr->txt.items, last, i);
1958
970k
                                last = i;
1959
970k
                        }
1960
11.4k
                }
1961
1962
13.8k
                r = 0;
1963
13.8k
                break;
1964
1965
1.26k
        case DNS_TYPE_A:
1966
1.26k
                r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1967
1.26k
                break;
1968
1969
1.14k
        case DNS_TYPE_AAAA:
1970
1.14k
                r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1971
1.14k
                break;
1972
1973
3.14k
        case DNS_TYPE_SOA:
1974
3.14k
                r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1975
3.14k
                if (r < 0)
1976
5
                        return r;
1977
1978
3.14k
                r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1979
3.14k
                if (r < 0)
1980
8
                        return r;
1981
1982
3.13k
                r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1983
3.13k
                if (r < 0)
1984
9
                        return r;
1985
1986
3.12k
                r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1987
3.12k
                if (r < 0)
1988
5
                        return r;
1989
1990
3.11k
                r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1991
3.11k
                if (r < 0)
1992
7
                        return r;
1993
1994
3.11k
                r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1995
3.11k
                if (r < 0)
1996
4
                        return r;
1997
1998
3.10k
                r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1999
3.10k
                break;
2000
2001
1.05k
        case DNS_TYPE_MX:
2002
1.05k
                r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
2003
1.05k
                if (r < 0)
2004
2
                        return r;
2005
2006
1.05k
                r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
2007
1.05k
                break;
2008
2009
4.46k
        case DNS_TYPE_LOC: {
2010
4.46k
                uint8_t t;
2011
4.46k
                size_t pos;
2012
2013
4.46k
                r = dns_packet_read_uint8(p, &t, &pos);
2014
4.46k
                if (r < 0)
2015
2
                        return r;
2016
2017
4.45k
                if (t == 0) {
2018
2.27k
                        rr->loc.version = t;
2019
2020
2.27k
                        r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
2021
2.27k
                        if (r < 0)
2022
2
                                return r;
2023
2024
2.27k
                        if (!loc_size_ok(rr->loc.size))
2025
13
                                return -EBADMSG;
2026
2027
2.26k
                        r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
2028
2.26k
                        if (r < 0)
2029
22
                                return r;
2030
2031
2.24k
                        if (!loc_size_ok(rr->loc.horiz_pre))
2032
23
                                return -EBADMSG;
2033
2034
2.21k
                        r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
2035
2.21k
                        if (r < 0)
2036
29
                                return r;
2037
2038
2.18k
                        if (!loc_size_ok(rr->loc.vert_pre))
2039
25
                                return -EBADMSG;
2040
2041
2.16k
                        r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
2042
2.16k
                        if (r < 0)
2043
27
                                return r;
2044
2045
2.13k
                        r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
2046
2.13k
                        if (r < 0)
2047
3
                                return r;
2048
2049
2.13k
                        r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
2050
2.13k
                        if (r < 0)
2051
2
                                return r;
2052
2053
2.13k
                        break;
2054
2.18k
                } else {
2055
2.18k
                        dns_packet_rewind(p, pos);
2056
2.18k
                        rr->unparsable = true;
2057
2.18k
                        goto unparsable;
2058
2.18k
                }
2059
4.45k
        }
2060
2061
1.14k
        case DNS_TYPE_DS:
2062
1.14k
                r = dns_packet_read_uint16(p, &rr->ds.key_tag, NULL);
2063
1.14k
                if (r < 0)
2064
2
                        return r;
2065
2066
1.13k
                r = dns_packet_read_uint8(p, &rr->ds.algorithm, NULL);
2067
1.13k
                if (r < 0)
2068
2
                        return r;
2069
2070
1.13k
                r = dns_packet_read_uint8(p, &rr->ds.digest_type, NULL);
2071
1.13k
                if (r < 0)
2072
2
                        return r;
2073
2074
1.13k
                if (rdlength < 4)
2075
8
                        return -EBADMSG;
2076
2077
1.12k
                r = dns_packet_read_memdup(p, rdlength - 4,
2078
1.12k
                                           &rr->ds.digest, &rr->ds.digest_size,
2079
1.12k
                                           NULL);
2080
1.12k
                if (r < 0)
2081
0
                        return r;
2082
2083
1.12k
                if (rr->ds.digest_size <= 0)
2084
                        /* the accepted size depends on the algorithm, but for now
2085
                           just ensure that the value is greater than zero */
2086
2
                        return -EBADMSG;
2087
2088
1.12k
                break;
2089
2090
1.21k
        case DNS_TYPE_SSHFP:
2091
1.21k
                r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
2092
1.21k
                if (r < 0)
2093
2
                        return r;
2094
2095
1.21k
                r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
2096
1.21k
                if (r < 0)
2097
2
                        return r;
2098
2099
1.21k
                if (rdlength < 2)
2100
4
                        return -EBADMSG;
2101
2102
1.20k
                r = dns_packet_read_memdup(p, rdlength - 2,
2103
1.20k
                                           &rr->sshfp.fingerprint, &rr->sshfp.fingerprint_size,
2104
1.20k
                                           NULL);
2105
2106
1.20k
                if (rr->sshfp.fingerprint_size <= 0)
2107
                        /* the accepted size depends on the algorithm, but for now
2108
                           just ensure that the value is greater than zero */
2109
2
                        return -EBADMSG;
2110
2111
1.20k
                break;
2112
2113
1.76k
        case DNS_TYPE_DNSKEY:
2114
1.76k
                r = dns_packet_read_uint16(p, &rr->dnskey.flags, NULL);
2115
1.76k
                if (r < 0)
2116
4
                        return r;
2117
2118
1.75k
                r = dns_packet_read_uint8(p, &rr->dnskey.protocol, NULL);
2119
1.75k
                if (r < 0)
2120
2
                        return r;
2121
2122
1.75k
                r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
2123
1.75k
                if (r < 0)
2124
2
                        return r;
2125
2126
1.75k
                if (rdlength < 4)
2127
6
                        return -EBADMSG;
2128
2129
1.74k
                r = dns_packet_read_memdup(p, rdlength - 4,
2130
1.74k
                                           &rr->dnskey.key, &rr->dnskey.key_size,
2131
1.74k
                                           NULL);
2132
2133
1.74k
                if (rr->dnskey.key_size <= 0)
2134
                        /* the accepted size depends on the algorithm, but for now
2135
                           just ensure that the value is greater than zero */
2136
2
                        return -EBADMSG;
2137
2138
1.74k
                break;
2139
2140
3.24k
        case DNS_TYPE_RRSIG:
2141
3.24k
                r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
2142
3.24k
                if (r < 0)
2143
2
                        return r;
2144
2145
3.23k
                r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
2146
3.23k
                if (r < 0)
2147
2
                        return r;
2148
2149
3.23k
                r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
2150
3.23k
                if (r < 0)
2151
3
                        return r;
2152
2153
3.23k
                r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
2154
3.23k
                if (r < 0)
2155
2
                        return r;
2156
2157
3.23k
                r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
2158
3.23k
                if (r < 0)
2159
2
                        return r;
2160
2161
3.22k
                r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
2162
3.22k
                if (r < 0)
2163
2
                        return r;
2164
2165
3.22k
                r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
2166
3.22k
                if (r < 0)
2167
2
                        return r;
2168
2169
3.22k
                r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
2170
3.22k
                if (r < 0)
2171
32
                        return r;
2172
2173
3.19k
                if (rdlength < p->rindex - offset)
2174
7
                        return -EBADMSG;
2175
2176
3.18k
                r = dns_packet_read_memdup(p, offset + rdlength - p->rindex,
2177
3.18k
                                           &rr->rrsig.signature, &rr->rrsig.signature_size,
2178
3.18k
                                           NULL);
2179
2180
3.18k
                if (rr->rrsig.signature_size <= 0)
2181
                        /* the accepted size depends on the algorithm, but for now
2182
                           just ensure that the value is greater than zero */
2183
2
                        return -EBADMSG;
2184
2185
3.18k
                break;
2186
2187
6.36k
        case DNS_TYPE_NSEC: {
2188
2189
                /*
2190
                 * RFC6762, section 18.14 explicitly states mDNS should use name compression.
2191
                 * This contradicts RFC3845, section 2.1.1
2192
                 */
2193
2194
6.36k
                bool allow_compressed = p->protocol == DNS_PROTOCOL_MDNS;
2195
2196
6.36k
                r = dns_packet_read_name(p, &rr->nsec.next_domain_name, allow_compressed, NULL);
2197
6.36k
                if (r < 0)
2198
10
                        return r;
2199
2200
6.35k
                if (rdlength < p->rindex - offset)
2201
16
                        return -EBADMSG;
2202
2203
6.34k
                r = dns_packet_read_type_windows(p, &rr->nsec.types, offset + rdlength - p->rindex, NULL);
2204
2205
                /* We accept empty NSEC bitmaps. The bit indicating the presence of the NSEC record itself
2206
                 * is redundant and in e.g., RFC4956 this fact is used to define a use for NSEC records
2207
                 * without the NSEC bit set. */
2208
2209
6.34k
                break;
2210
6.35k
        }
2211
2.18k
        case DNS_TYPE_NSEC3: {
2212
2.18k
                uint8_t size;
2213
2214
2.18k
                r = dns_packet_read_uint8(p, &rr->nsec3.algorithm, NULL);
2215
2.18k
                if (r < 0)
2216
2
                        return r;
2217
2218
2.18k
                r = dns_packet_read_uint8(p, &rr->nsec3.flags, NULL);
2219
2.18k
                if (r < 0)
2220
2
                        return r;
2221
2222
2.18k
                r = dns_packet_read_uint16(p, &rr->nsec3.iterations, NULL);
2223
2.18k
                if (r < 0)
2224
3
                        return r;
2225
2226
                /* this may be zero */
2227
2.18k
                r = dns_packet_read_uint8(p, &size, NULL);
2228
2.18k
                if (r < 0)
2229
2
                        return r;
2230
2231
2.18k
                r = dns_packet_read_memdup(p, size, &rr->nsec3.salt, &rr->nsec3.salt_size, NULL);
2232
2.18k
                if (r < 0)
2233
20
                        return r;
2234
2235
2.16k
                r = dns_packet_read_uint8(p, &size, NULL);
2236
2.16k
                if (r < 0)
2237
4
                        return r;
2238
2239
2.15k
                if (size <= 0)
2240
3
                        return -EBADMSG;
2241
2242
2.15k
                r = dns_packet_read_memdup(p, size,
2243
2.15k
                                           &rr->nsec3.next_hashed_name, &rr->nsec3.next_hashed_name_size,
2244
2.15k
                                           NULL);
2245
2.15k
                if (r < 0)
2246
23
                        return r;
2247
2248
2.13k
                if (rdlength < p->rindex - offset)
2249
24
                        return -EBADMSG;
2250
2251
2.10k
                r = dns_packet_read_type_windows(p, &rr->nsec3.types, offset + rdlength - p->rindex, NULL);
2252
2253
                /* empty non-terminals can have NSEC3 records, so empty bitmaps are allowed */
2254
2255
2.10k
                break;
2256
2.13k
        }
2257
2258
1.06k
        case DNS_TYPE_TLSA:
2259
1.06k
                r = dns_packet_read_uint8(p, &rr->tlsa.cert_usage, NULL);
2260
1.06k
                if (r < 0)
2261
2
                        return r;
2262
2263
1.06k
                r = dns_packet_read_uint8(p, &rr->tlsa.selector, NULL);
2264
1.06k
                if (r < 0)
2265
2
                        return r;
2266
2267
1.06k
                r = dns_packet_read_uint8(p, &rr->tlsa.matching_type, NULL);
2268
1.06k
                if (r < 0)
2269
2
                        return r;
2270
2271
1.06k
                if (rdlength < 3)
2272
4
                        return -EBADMSG;
2273
2274
1.05k
                r = dns_packet_read_memdup(p, rdlength - 3,
2275
1.05k
                                           &rr->tlsa.data, &rr->tlsa.data_size,
2276
1.05k
                                           NULL);
2277
2278
1.05k
                if (rr->tlsa.data_size <= 0)
2279
                        /* the accepted size depends on the algorithm, but for now
2280
                           just ensure that the value is greater than zero */
2281
2
                        return -EBADMSG;
2282
2283
1.05k
                break;
2284
2285
4.20k
        case DNS_TYPE_SVCB:
2286
7.24k
        case DNS_TYPE_HTTPS:
2287
7.24k
                r = dns_packet_read_uint16(p, &rr->svcb.priority, NULL);
2288
7.24k
                if (r < 0)
2289
15
                        return r;
2290
2291
7.22k
                r = dns_packet_read_name(p, &rr->svcb.target_name, false /* uncompressed */, NULL);
2292
7.22k
                if (r < 0)
2293
7
                        return r;
2294
2295
7.22k
                DnsSvcParam *last = NULL;
2296
16.0k
                while (p->rindex - offset < rdlength) {
2297
9.09k
                        _cleanup_free_ DnsSvcParam *i = NULL;
2298
9.09k
                        uint16_t svc_param_key;
2299
9.09k
                        uint16_t sz;
2300
2301
9.09k
                        r = dns_packet_read_uint16(p, &svc_param_key, NULL);
2302
9.09k
                        if (r < 0)
2303
20
                                return r;
2304
                        /* RFC 9460, section 2.2 says we must consider an RR malformed if SvcParamKeys are
2305
                         * not in strictly increasing order */
2306
9.07k
                        if (last && last->key >= svc_param_key)
2307
56
                                return -EBADMSG;
2308
2309
9.02k
                        r = dns_packet_read_uint16(p, &sz, NULL);
2310
9.02k
                        if (r < 0)
2311
23
                                return r;
2312
2313
8.99k
                        i = malloc0(offsetof(DnsSvcParam, value) + sz);
2314
8.99k
                        if (!i)
2315
0
                                return -ENOMEM;
2316
2317
8.99k
                        i->key = svc_param_key;
2318
8.99k
                        i->length = sz;
2319
8.99k
                        r = dns_packet_read_blob(p, &i->value, sz, NULL);
2320
8.99k
                        if (r < 0)
2321
45
                                return r;
2322
8.95k
                        if (!dns_svc_param_is_valid(i))
2323
155
                                return -EBADMSG;
2324
2325
8.95k
                        LIST_INSERT_AFTER(params, rr->svcb.params, last, i);
2326
8.79k
                        last = TAKE_PTR(i);
2327
8.79k
                }
2328
2329
6.92k
                break;
2330
2331
6.92k
        case DNS_TYPE_CAA:
2332
2.26k
                r = dns_packet_read_uint8(p, &rr->caa.flags, NULL);
2333
2.26k
                if (r < 0)
2334
2
                        return r;
2335
2336
2.26k
                r = dns_packet_read_string(p, &rr->caa.tag, NULL);
2337
2.26k
                if (r < 0)
2338
25
                        return r;
2339
2340
2.23k
                if (rdlength < p->rindex - offset)
2341
24
                        return -EBADMSG;
2342
2343
2.21k
                r = dns_packet_read_memdup(p,
2344
2.21k
                                           rdlength + offset - p->rindex,
2345
2.21k
                                           &rr->caa.value, &rr->caa.value_size, NULL);
2346
2347
2.21k
                break;
2348
2349
1.79k
        case DNS_TYPE_NAPTR:
2350
1.79k
                r = dns_packet_read_uint16(p, &rr->naptr.order, NULL);
2351
1.79k
                if (r < 0)
2352
3
                        return r;
2353
2354
1.79k
                r = dns_packet_read_uint16(p, &rr->naptr.preference, NULL);
2355
1.79k
                if (r < 0)
2356
3
                        return r;
2357
2358
1.79k
                r = dns_packet_read_string(p, &rr->naptr.flags, NULL);
2359
1.79k
                if (r < 0)
2360
14
                        return r;
2361
2362
1.77k
                r = dns_packet_read_string(p, &rr->naptr.services, NULL);
2363
1.77k
                if (r < 0)
2364
11
                        return r;
2365
2366
1.76k
                r = dns_packet_read_string(p, &rr->naptr.regexp, NULL);
2367
1.76k
                if (r < 0)
2368
29
                        return r;
2369
2370
1.73k
                r = dns_packet_read_name(p, &rr->naptr.replacement, /* allow_compression= */ false, NULL);
2371
1.73k
                break;
2372
2373
1.42k
        case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
2374
1.45k
        case DNS_TYPE_OPENPGPKEY:
2375
27.4k
        default:
2376
29.6k
        unparsable:
2377
29.6k
                r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
2378
88.8k
        }
2379
87.6k
        if (r < 0)
2380
647
                return r;
2381
87.0k
        if (p->rindex - offset != rdlength)
2382
144
                return -EBADMSG;
2383
2384
86.8k
        if (ret)
2385
86.8k
                *ret = TAKE_PTR(rr);
2386
86.8k
        if (ret_cache_flush)
2387
84.7k
                *ret_cache_flush = cache_flush;
2388
86.8k
        if (ret_start)
2389
84.7k
                *ret_start = rewinder.saved_rindex;
2390
2391
86.8k
        CANCEL_REWINDER(rewinder);
2392
86.8k
        return 0;
2393
87.0k
}
2394
2395
193
static bool opt_is_good(DnsResourceRecord *rr, bool *rfc6975) {
2396
193
        const uint8_t* p;
2397
193
        bool found_dau_dhu_n3u = false;
2398
193
        size_t l;
2399
2400
        /* Checks whether the specified OPT RR is well-formed and whether it contains RFC6975 data (which is not OK in
2401
         * a reply). */
2402
2403
193
        assert(rr);
2404
193
        assert(rr->key->type == DNS_TYPE_OPT);
2405
2406
        /* Check that the version is 0 */
2407
193
        if (((rr->ttl >> 16) & UINT32_C(0xFF)) != 0) {
2408
33
                *rfc6975 = false;
2409
33
                return true; /* if it's not version 0, it's OK, but we will ignore the OPT field contents */
2410
33
        }
2411
2412
160
        p = rr->opt.data;
2413
160
        l = rr->opt.data_size;
2414
1.13k
        while (l > 0) {
2415
1.02k
                uint16_t option_code, option_length;
2416
2417
                /* At least four bytes for OPTION-CODE and OPTION-LENGTH are required */
2418
1.02k
                if (l < 4U)
2419
6
                        return false;
2420
2421
1.01k
                option_code = unaligned_read_be16(p);
2422
1.01k
                option_length = unaligned_read_be16(p + 2);
2423
2424
1.01k
                if (l < option_length + 4U)
2425
42
                        return false;
2426
2427
                /* RFC 6975 DAU, DHU or N3U fields found. */
2428
974
                if (IN_SET(option_code, DNS_EDNS_OPT_DAU, DNS_EDNS_OPT_DHU, DNS_EDNS_OPT_N3U))
2429
199
                        found_dau_dhu_n3u = true;
2430
2431
974
                p += option_length + 4U;
2432
974
                l -= option_length + 4U;
2433
974
        }
2434
2435
112
        *rfc6975 = found_dau_dhu_n3u;
2436
112
        return true;
2437
160
}
2438
2439
4.30k
static int dns_packet_extract_question(DnsPacket *p, DnsQuestion **ret_question) {
2440
4.30k
        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2441
4.30k
        unsigned n;
2442
4.30k
        int r;
2443
2444
4.30k
        n = DNS_PACKET_QDCOUNT(p);
2445
4.30k
        if (n > 0) {
2446
786
                question = dns_question_new(n);
2447
786
                if (!question)
2448
0
                        return -ENOMEM;
2449
2450
786
                _cleanup_set_free_ Set *keys = NULL; /* references to keys are kept by Question */
2451
2452
786
                keys = set_new(&dns_resource_key_hash_ops);
2453
786
                if (!keys)
2454
0
                        return log_oom();
2455
2456
786
                r = set_reserve(keys, n * 2); /* Higher multipliers give slightly higher efficiency through
2457
                                               * hash collisions, but the gains quickly drop off after 2. */
2458
786
                if (r < 0)
2459
0
                        return r;
2460
2461
14.8k
                for (unsigned i = 0; i < n; i++) {
2462
14.6k
                        _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
2463
14.6k
                        bool qu;
2464
2465
14.6k
                        r = dns_packet_read_key(p, &key, &qu, NULL);
2466
14.6k
                        if (r < 0)
2467
607
                                return r;
2468
2469
14.0k
                        if (!dns_type_is_valid_query(key->type))
2470
11
                                return -EBADMSG;
2471
2472
14.0k
                        r = set_put(keys, key);
2473
14.0k
                        if (r < 0)
2474
0
                                return r;
2475
14.0k
                        if (r == 0)
2476
                                /* Already in the Question, let's skip */
2477
6.34k
                                continue;
2478
2479
7.71k
                        r = dns_question_add_raw(question, key, qu ? DNS_QUESTION_WANTS_UNICAST_REPLY : 0);
2480
7.71k
                        if (r < 0)
2481
0
                                return r;
2482
7.71k
                }
2483
786
        }
2484
2485
3.68k
        *ret_question = TAKE_PTR(question);
2486
2487
3.68k
        return 0;
2488
4.30k
}
2489
2490
3.68k
static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
2491
3.68k
        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2492
3.68k
        unsigned n;
2493
3.68k
        _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *previous = NULL;
2494
3.68k
        bool bad_opt = false;
2495
3.68k
        int r;
2496
2497
3.68k
        n = DNS_PACKET_RRCOUNT(p);
2498
3.68k
        if (n == 0)
2499
18
                return 0;
2500
2501
3.66k
        answer = dns_answer_new(n);
2502
3.66k
        if (!answer)
2503
0
                return -ENOMEM;
2504
2505
88.4k
        for (unsigned i = 0; i < n; i++) {
2506
88.3k
                _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
2507
88.3k
                bool cache_flush = false;
2508
88.3k
                size_t start;
2509
2510
88.3k
                if (p->rindex == p->size && p->opt) {
2511
                        /* If we reached the end of the packet already, but there are still more RRs
2512
                         * declared, then that's a corrupt packet. Let's accept the packet anyway, since it's
2513
                         * apparently a common bug in routers. Let's however suppress OPT support in this
2514
                         * case, so that we force the rest of the logic into lowest DNS baseline support. Or
2515
                         * to say this differently: if the DNS server doesn't even get the RR counts right,
2516
                         * it's highly unlikely it gets EDNS right. */
2517
52
                        log_debug("More resource records declared in packet than included, suppressing OPT.");
2518
52
                        bad_opt = true;
2519
52
                        break;
2520
52
                }
2521
2522
88.2k
                r = dns_packet_read_rr(p, &rr, &cache_flush, &start);
2523
88.2k
                if (r < 0)
2524
3.47k
                        return r;
2525
2526
                /* Try to reduce memory usage a bit */
2527
84.7k
                if (previous)
2528
81.6k
                        dns_resource_key_reduce(&rr->key, &previous->key);
2529
2530
84.7k
                if (rr->key->type == DNS_TYPE_OPT) {
2531
1.42k
                        bool has_rfc6975;
2532
2533
1.42k
                        if (p->opt || bad_opt) {
2534
                                /* Multiple OPT RRs? if so, let's ignore all, because there's
2535
                                 * something wrong with the server, and if one is valid we wouldn't
2536
                                 * know which one. */
2537
1.17k
                                log_debug("Multiple OPT RRs detected, ignoring all.");
2538
1.17k
                                bad_opt = true;
2539
1.17k
                                continue;
2540
1.17k
                        }
2541
2542
253
                        if (!dns_name_is_root(dns_resource_key_name(rr->key))) {
2543
                                /* If the OPT RR is not owned by the root domain, then it is bad,
2544
                                 * let's ignore it. */
2545
3
                                log_debug("OPT RR is not owned by root domain, ignoring.");
2546
3
                                bad_opt = true;
2547
3
                                continue;
2548
3
                        }
2549
2550
250
                        if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p)) {
2551
                                /* OPT RR is in the wrong section? Some Belkin routers do this. This
2552
                                 * is a hint the EDNS implementation is borked, like the Belkin one
2553
                                 * is, hence ignore it. */
2554
57
                                log_debug("OPT RR in wrong section, ignoring.");
2555
57
                                bad_opt = true;
2556
57
                                continue;
2557
57
                        }
2558
2559
193
                        if (!opt_is_good(rr, &has_rfc6975)) {
2560
48
                                log_debug("Malformed OPT RR, ignoring.");
2561
48
                                bad_opt = true;
2562
48
                                continue;
2563
48
                        }
2564
2565
145
                        if (DNS_PACKET_QR(p)) {
2566
                                /* Additional checks for responses */
2567
2568
79
                                if (!DNS_RESOURCE_RECORD_OPT_VERSION_SUPPORTED(rr))
2569
                                        /* If this is a reply and we don't know the EDNS version
2570
                                         * then something is weird... */
2571
9
                                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2572
70
                                                               "EDNS version newer that our request, bad server.");
2573
2574
70
                                if (has_rfc6975) {
2575
                                        /* If the OPT RR contains RFC6975 algorithm data, then this
2576
                                         * is indication that the server just copied the OPT it got
2577
                                         * from us (which contained that data) back into the reply.
2578
                                         * If so, then it doesn't properly support EDNS, as RFC6975
2579
                                         * makes it very clear that the algorithm data should only
2580
                                         * be contained in questions, never in replies. Crappy
2581
                                         * Belkin routers copy the OPT data for example, hence let's
2582
                                         * detect this so that we downgrade early. */
2583
6
                                        log_debug("OPT RR contains RFC6975 data, ignoring.");
2584
6
                                        bad_opt = true;
2585
6
                                        continue;
2586
6
                                }
2587
70
                        }
2588
2589
130
                        p->opt = dns_resource_record_ref(rr);
2590
130
                        p->opt_start = start;
2591
130
                        assert(p->rindex >= start);
2592
130
                        p->opt_size = p->rindex - start;
2593
83.3k
                } else {
2594
83.3k
                        DnsAnswerFlags flags = 0;
2595
2596
83.3k
                        if (p->protocol == DNS_PROTOCOL_MDNS) {
2597
0
                                flags |= DNS_ANSWER_REFUSE_TTL_NO_MATCH;
2598
0
                                if (!cache_flush)
2599
0
                                        flags |= DNS_ANSWER_SHARED_OWNER;
2600
0
                        }
2601
2602
                        /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be
2603
                         * cached. Hence mark only those RRs as cacheable by default, but not the ones from
2604
                         * the Additional or Authority sections.
2605
                         * This restriction does not apply to mDNS records (RFC 6762). */
2606
83.3k
                        if (i < DNS_PACKET_ANCOUNT(p))
2607
38.8k
                                flags |= DNS_ANSWER_CACHEABLE|DNS_ANSWER_SECTION_ANSWER;
2608
44.4k
                        else if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p))
2609
23.5k
                                flags |= DNS_ANSWER_SECTION_AUTHORITY;
2610
20.9k
                        else {
2611
20.9k
                                flags |= DNS_ANSWER_SECTION_ADDITIONAL;
2612
20.9k
                                if (p->protocol == DNS_PROTOCOL_MDNS)
2613
0
                                        flags |= DNS_ANSWER_CACHEABLE;
2614
20.9k
                        }
2615
2616
83.3k
                        r = dns_answer_add(answer, rr, p->ifindex, flags, NULL);
2617
83.3k
                        if (r < 0)
2618
0
                                return r;
2619
83.3k
                }
2620
2621
                /* Remember this RR, so that we can potentially merge its ->key object with the
2622
                 * next RR. Note that we only do this if we actually decided to keep the RR around.
2623
                 */
2624
83.4k
                DNS_RR_REPLACE(previous, dns_resource_record_ref(rr));
2625
83.4k
        }
2626
2627
182
        if (bad_opt) {
2628
58
                p->opt = dns_resource_record_unref(p->opt);
2629
58
                p->opt_start = p->opt_size = SIZE_MAX;
2630
58
        }
2631
2632
182
        *ret_answer = TAKE_PTR(answer);
2633
2634
182
        return 0;
2635
3.66k
}
2636
2637
4.30k
int dns_packet_extract(DnsPacket *p) {
2638
4.30k
        assert(p);
2639
2640
4.30k
        if (p->extracted)
2641
0
                return 0;
2642
2643
4.30k
        _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2644
4.30k
        _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
2645
4.30k
        _unused_ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
2646
4.30k
        int r;
2647
2648
4.30k
        dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
2649
2650
4.30k
        r = dns_packet_extract_question(p, &question);
2651
4.30k
        if (r < 0)
2652
618
                return r;
2653
2654
3.68k
        r = dns_packet_extract_answer(p, &answer);
2655
3.68k
        if (r < 0)
2656
3.48k
                return r;
2657
2658
200
        if (p->rindex < p->size)  {
2659
26
                log_debug("Trailing garbage in packet, suppressing OPT.");
2660
26
                p->opt = dns_resource_record_unref(p->opt);
2661
26
                p->opt_start = p->opt_size = SIZE_MAX;
2662
26
        }
2663
2664
200
        p->question = TAKE_PTR(question);
2665
200
        p->answer = TAKE_PTR(answer);
2666
200
        p->extracted = true;
2667
2668
        /* no CANCEL, always rewind */
2669
200
        return 0;
2670
3.68k
}
2671
2672
0
int dns_packet_is_reply_for(DnsPacket *p, const DnsResourceKey *key) {
2673
0
        int r;
2674
2675
0
        assert(p);
2676
0
        assert(key);
2677
2678
        /* Checks if the specified packet is a reply for the specified
2679
         * key and the specified key is the only one in the question
2680
         * section. */
2681
2682
0
        if (DNS_PACKET_QR(p) != 1)
2683
0
                return 0;
2684
2685
        /* Let's unpack the packet, if that hasn't happened yet. */
2686
0
        r = dns_packet_extract(p);
2687
0
        if (r < 0)
2688
0
                return r;
2689
2690
0
        if (!p->question)
2691
0
                return 0;
2692
2693
0
        if (p->question->n_keys != 1)
2694
0
                return 0;
2695
2696
0
        return dns_resource_key_equal(dns_question_first_key(p->question), key);
2697
0
}
2698
2699
0
int dns_packet_patch_max_udp_size(DnsPacket *p, uint16_t max_udp_size) {
2700
0
        assert(p);
2701
0
        assert(max_udp_size >= DNS_PACKET_UNICAST_SIZE_MAX);
2702
2703
0
        if (p->opt_start == SIZE_MAX) /* No OPT section, nothing to patch */
2704
0
                return 0;
2705
2706
0
        assert(p->opt_size != SIZE_MAX);
2707
0
        assert(p->opt_size >= 5);
2708
2709
0
        unaligned_write_be16(DNS_PACKET_DATA(p) + p->opt_start + 3, max_udp_size);
2710
0
        return 1;
2711
0
}
2712
2713
0
static int patch_rr(DnsPacket *p, usec_t age) {
2714
0
        _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
2715
0
        size_t ttl_index;
2716
0
        uint32_t ttl;
2717
0
        uint16_t type, rdlength;
2718
0
        int r;
2719
2720
        /* Patches the RR at the current rindex, subtracts the specified time from the TTL */
2721
2722
0
        r = dns_packet_read_name(p, NULL, true, NULL);
2723
0
        if (r < 0)
2724
0
                return r;
2725
2726
0
        r = dns_packet_read_uint16(p, &type, NULL);
2727
0
        if (r < 0)
2728
0
                return r;
2729
2730
0
        r = dns_packet_read_uint16(p, NULL, NULL);
2731
0
        if (r < 0)
2732
0
                return r;
2733
2734
0
        r = dns_packet_read_uint32(p, &ttl, &ttl_index);
2735
0
        if (r < 0)
2736
0
                return r;
2737
2738
0
        if (type != DNS_TYPE_OPT) { /* The TTL of the OPT field is not actually a TTL, skip it */
2739
0
                ttl = LESS_BY(ttl * USEC_PER_SEC, age) / USEC_PER_SEC;
2740
0
                unaligned_write_be32(DNS_PACKET_DATA(p) + ttl_index, ttl);
2741
0
        }
2742
2743
0
        r = dns_packet_read_uint16(p, &rdlength, NULL);
2744
0
        if (r < 0)
2745
0
                return r;
2746
2747
0
        r = dns_packet_read(p, rdlength, NULL, NULL);
2748
0
        if (r < 0)
2749
0
                return r;
2750
2751
0
        CANCEL_REWINDER(rewinder);
2752
0
        return 0;
2753
0
}
2754
2755
0
int dns_packet_patch_ttls(DnsPacket *p, usec_t timestamp) {
2756
0
        assert(p);
2757
0
        assert(timestamp_is_set(timestamp));
2758
2759
        /* Adjusts all TTLs in the packet by subtracting the time difference between now and the specified timestamp */
2760
2761
0
        _unused_ _cleanup_(rewind_dns_packet) DnsPacketRewinder rewinder = REWINDER_INIT(p);
2762
0
        unsigned n;
2763
0
        usec_t k;
2764
0
        int r;
2765
2766
0
        k = now(CLOCK_BOOTTIME);
2767
0
        assert(k >= timestamp);
2768
0
        k -= timestamp;
2769
2770
0
        dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
2771
2772
0
        n = DNS_PACKET_QDCOUNT(p);
2773
0
        for (unsigned i = 0; i < n; i++) {
2774
0
                r = dns_packet_read_key(p, NULL, NULL, NULL);
2775
0
                if (r < 0)
2776
0
                        return r;
2777
0
        }
2778
2779
0
        n = DNS_PACKET_RRCOUNT(p);
2780
0
        for (unsigned i = 0; i < n; i++) {
2781
2782
                /* DNS servers suck, hence the RR count is in many servers off. If we reached the end
2783
                 * prematurely, accept that, exit early */
2784
0
                if (p->rindex == p->size)
2785
0
                        break;
2786
2787
0
                r = patch_rr(p, k);
2788
0
                if (r < 0)
2789
0
                        return r;
2790
0
        }
2791
2792
0
        return 0;
2793
0
}
2794
2795
0
static void dns_packet_hash_func(const DnsPacket *s, struct siphash *state) {
2796
0
        assert(s);
2797
2798
0
        siphash24_compress_typesafe(s->size, state);
2799
0
        siphash24_compress(DNS_PACKET_DATA((DnsPacket*) s), s->size, state);
2800
0
}
2801
2802
0
static int dns_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
2803
0
        int r;
2804
2805
0
        r = CMP(x->size, y->size);
2806
0
        if (r != 0)
2807
0
                return r;
2808
2809
0
        return memcmp(DNS_PACKET_DATA((DnsPacket*) x), DNS_PACKET_DATA((DnsPacket*) y), x->size);
2810
0
}
2811
2812
DEFINE_HASH_OPS(dns_packet_hash_ops, DnsPacket, dns_packet_hash_func, dns_packet_compare_func);
2813
2814
0
bool dns_packet_equal(const DnsPacket *a, const DnsPacket *b) {
2815
0
        return dns_packet_compare_func(a, b) == 0;
2816
0
}
2817
2818
0
int dns_packet_ede_rcode(DnsPacket *p, int *ret_ede_rcode, char **ret_ede_msg) {
2819
0
        const uint8_t *d;
2820
0
        size_t l;
2821
0
        int r;
2822
2823
0
        assert(p);
2824
2825
0
        if (!p->opt)
2826
0
                return -ENOENT;
2827
2828
0
        d = p->opt->opt.data;
2829
0
        l = p->opt->opt.data_size;
2830
2831
0
        while (l > 0) {
2832
0
                uint16_t code, length;
2833
2834
0
                if (l < 4U)
2835
0
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2836
0
                                               "EDNS0 variable part has invalid size.");
2837
2838
0
                code = unaligned_read_be16(d);
2839
0
                length = unaligned_read_be16(d + 2);
2840
2841
0
                if (l < 4U + length)
2842
0
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2843
0
                                               "Truncated option in EDNS0 variable part.");
2844
2845
0
                if (code == DNS_EDNS_OPT_EXT_ERROR) {
2846
0
                        _cleanup_free_ char *msg = NULL;
2847
2848
0
                        if (length < 2U)
2849
0
                                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2850
0
                                                       "EDNS0 truncated EDE info code.");
2851
2852
0
                        r = make_cstring((char *) d + 6, length - 2U, MAKE_CSTRING_ALLOW_TRAILING_NUL, &msg);
2853
0
                        if (r < 0)
2854
0
                                return log_debug_errno(r, "Invalid EDE text in opt.");
2855
2856
0
                        if (ret_ede_msg) {
2857
0
                                if (!utf8_is_valid(msg)) {
2858
0
                                        _cleanup_free_ char *msg_escaped = NULL;
2859
2860
0
                                        msg_escaped = cescape(msg);
2861
0
                                        if (!msg_escaped)
2862
0
                                                return log_oom_debug();
2863
2864
0
                                        *ret_ede_msg = TAKE_PTR(msg_escaped);
2865
0
                                } else
2866
0
                                        *ret_ede_msg = TAKE_PTR(msg);
2867
0
                        }
2868
2869
0
                        if (ret_ede_rcode)
2870
0
                                *ret_ede_rcode = unaligned_read_be16(d + 4);
2871
2872
0
                        return 0;
2873
0
                }
2874
2875
0
                d += 4U + length;
2876
0
                l -= 4U + length;
2877
0
        }
2878
2879
0
        return -ENOENT;
2880
0
}
2881
2882
0
bool dns_ede_rcode_is_dnssec(int ede_rcode) {
2883
0
        return IN_SET(ede_rcode,
2884
0
                        DNS_EDE_RCODE_UNSUPPORTED_DNSKEY_ALG,
2885
0
                        DNS_EDE_RCODE_UNSUPPORTED_DS_DIGEST,
2886
0
                        DNS_EDE_RCODE_DNSSEC_INDETERMINATE,
2887
0
                        DNS_EDE_RCODE_DNSSEC_BOGUS,
2888
0
                        DNS_EDE_RCODE_SIG_EXPIRED,
2889
0
                        DNS_EDE_RCODE_SIG_NOT_YET_VALID,
2890
0
                        DNS_EDE_RCODE_DNSKEY_MISSING,
2891
0
                        DNS_EDE_RCODE_RRSIG_MISSING,
2892
0
                        DNS_EDE_RCODE_NO_ZONE_KEY_BIT,
2893
0
                        DNS_EDE_RCODE_NSEC_MISSING
2894
0
                     );
2895
0
}
2896
2897
0
int dns_packet_has_nsid_request(DnsPacket *p) {
2898
0
        bool has_nsid = false;
2899
0
        const uint8_t *d;
2900
0
        size_t l;
2901
2902
0
        assert(p);
2903
2904
0
        if (!p->opt)
2905
0
                return false;
2906
2907
0
        d = p->opt->opt.data;
2908
0
        l = p->opt->opt.data_size;
2909
2910
0
        while (l > 0) {
2911
0
                uint16_t code, length;
2912
2913
0
                if (l < 4U)
2914
0
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2915
0
                                               "EDNS0 variable part has invalid size.");
2916
2917
0
                code = unaligned_read_be16(d);
2918
0
                length = unaligned_read_be16(d + 2);
2919
2920
0
                if (l < 4U + length)
2921
0
                        return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2922
0
                                               "Truncated option in EDNS0 variable part.");
2923
2924
0
                if (code == DNS_EDNS_OPT_NSID) {
2925
0
                        if (has_nsid)
2926
0
                                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2927
0
                                                       "Duplicate NSID option in EDNS0 variable part.");
2928
2929
0
                        if (length != 0)
2930
0
                                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
2931
0
                                                       "Non-empty NSID option in DNS request.");
2932
2933
0
                        has_nsid = true;
2934
0
                }
2935
2936
0
                d += 4U + length;
2937
0
                l -= 4U + length;
2938
0
        }
2939
2940
0
        return has_nsid;
2941
0
}
2942
2943
0
size_t dns_packet_size_unfragmented(DnsPacket *p) {
2944
0
        assert(p);
2945
2946
0
        if (p->fragsize == 0) /* Wasn't fragmented */
2947
0
                return p->size;
2948
2949
        /* The fragment size (p->fragsize) covers the whole (fragmented) IP packet, while the regular packet
2950
         * size (p->size) only covers the DNS part. Thus, subtract the UDP header from the largest fragment
2951
         * size, in order to determine which size of DNS packet would have gone through without
2952
         * fragmenting. */
2953
2954
0
        return LESS_BY(p->fragsize, udp_header_size(p->family));
2955
0
}
2956
2957
static const char* const dns_svc_param_key_table[_DNS_SVC_PARAM_KEY_MAX_DEFINED] = {
2958
        [DNS_SVC_PARAM_KEY_MANDATORY]       = "mandatory",
2959
        [DNS_SVC_PARAM_KEY_ALPN]            = "alpn",
2960
        [DNS_SVC_PARAM_KEY_NO_DEFAULT_ALPN] = "no-default-alpn",
2961
        [DNS_SVC_PARAM_KEY_PORT]            = "port",
2962
        [DNS_SVC_PARAM_KEY_IPV4HINT]        = "ipv4hint",
2963
        [DNS_SVC_PARAM_KEY_ECH]             = "ech",
2964
        [DNS_SVC_PARAM_KEY_IPV6HINT]        = "ipv6hint",
2965
        [DNS_SVC_PARAM_KEY_DOHPATH]         = "dohpath",
2966
        [DNS_SVC_PARAM_KEY_OHTTP]           = "ohttp",
2967
};
2968
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dns_svc_param_key, int);
2969
2970
1.73k
const char* format_dns_svc_param_key(uint16_t i, char buf[static DECIMAL_STR_MAX(uint16_t)+3]) {
2971
1.73k
        const char *p = dns_svc_param_key_to_string(i);
2972
1.73k
        if (p)
2973
550
                return p;
2974
2975
1.18k
        return snprintf_ok(buf, DECIMAL_STR_MAX(uint16_t)+3, "key%i", i);
2976
1.73k
}
2977
2978
static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
2979
        [DNS_RCODE_SUCCESS]   = "SUCCESS",
2980
        [DNS_RCODE_FORMERR]   = "FORMERR",
2981
        [DNS_RCODE_SERVFAIL]  = "SERVFAIL",
2982
        [DNS_RCODE_NXDOMAIN]  = "NXDOMAIN",
2983
        [DNS_RCODE_NOTIMP]    = "NOTIMP",
2984
        [DNS_RCODE_REFUSED]   = "REFUSED",
2985
        [DNS_RCODE_YXDOMAIN]  = "YXDOMAIN",
2986
        [DNS_RCODE_YXRRSET]   = "YRRSET",
2987
        [DNS_RCODE_NXRRSET]   = "NXRRSET",
2988
        [DNS_RCODE_NOTAUTH]   = "NOTAUTH",
2989
        [DNS_RCODE_NOTZONE]   = "NOTZONE",
2990
        [DNS_RCODE_DSOTYPENI] = "DSOTYPENI",
2991
        [DNS_RCODE_BADVERS]   = "BADVERS",
2992
        [DNS_RCODE_BADKEY]    = "BADKEY",
2993
        [DNS_RCODE_BADTIME]   = "BADTIME",
2994
        [DNS_RCODE_BADMODE]   = "BADMODE",
2995
        [DNS_RCODE_BADNAME]   = "BADNAME",
2996
        [DNS_RCODE_BADALG]    = "BADALG",
2997
        [DNS_RCODE_BADTRUNC]  = "BADTRUNC",
2998
        [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
2999
};
3000
DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
3001
3002
const char* format_dns_rcode(int i, char buf[static DECIMAL_STR_MAX(int)]) {
3003
        const char *p = dns_rcode_to_string(i);
3004
        if (p)
3005
                return p;
3006
3007
        return snprintf_ok(buf, DECIMAL_STR_MAX(int), "%i", i);
3008
}
3009
3010
static const char* const dns_ede_rcode_table[_DNS_EDE_RCODE_MAX_DEFINED] = {
3011
        [DNS_EDE_RCODE_OTHER]                  = "Other",
3012
        [DNS_EDE_RCODE_UNSUPPORTED_DNSKEY_ALG] = "Unsupported DNSKEY Algorithm",
3013
        [DNS_EDE_RCODE_UNSUPPORTED_DS_DIGEST]  = "Unsupported DS Digest Type",
3014
        [DNS_EDE_RCODE_STALE_ANSWER]           = "Stale Answer",
3015
        [DNS_EDE_RCODE_FORGED_ANSWER]          = "Forged Answer",
3016
        [DNS_EDE_RCODE_DNSSEC_INDETERMINATE]   = "DNSSEC Indeterminate",
3017
        [DNS_EDE_RCODE_DNSSEC_BOGUS]           = "DNSSEC Bogus",
3018
        [DNS_EDE_RCODE_SIG_EXPIRED]            = "Signature Expired",
3019
        [DNS_EDE_RCODE_SIG_NOT_YET_VALID]      = "Signature Not Yet Valid",
3020
        [DNS_EDE_RCODE_DNSKEY_MISSING]         = "DNSKEY Missing",
3021
        [DNS_EDE_RCODE_RRSIG_MISSING]          = "RRSIG Missing",
3022
        [DNS_EDE_RCODE_NO_ZONE_KEY_BIT]        = "No Zone Key Bit Set",
3023
        [DNS_EDE_RCODE_NSEC_MISSING]           = "NSEC Missing",
3024
        [DNS_EDE_RCODE_CACHED_ERROR]           = "Cached Error",
3025
        [DNS_EDE_RCODE_NOT_READY]              = "Not Ready",
3026
        [DNS_EDE_RCODE_BLOCKED]                = "Blocked",
3027
        [DNS_EDE_RCODE_CENSORED]               = "Censored",
3028
        [DNS_EDE_RCODE_FILTERED]               = "Filtered",
3029
        [DNS_EDE_RCODE_PROHIBITED]             = "Prohibited",
3030
        [DNS_EDE_RCODE_STALE_NXDOMAIN_ANSWER]  = "Stale NXDOMAIN Answer",
3031
        [DNS_EDE_RCODE_NOT_AUTHORITATIVE]      = "Not Authoritative",
3032
        [DNS_EDE_RCODE_NOT_SUPPORTED]          = "Not Supported",
3033
        [DNS_EDE_RCODE_UNREACH_AUTHORITY]      = "No Reachable Authority",
3034
        [DNS_EDE_RCODE_NET_ERROR]              = "Network Error",
3035
        [DNS_EDE_RCODE_INVALID_DATA]           = "Invalid Data",
3036
        [DNS_EDE_RCODE_SIG_NEVER]              = "Signature Never Valid",
3037
        [DNS_EDE_RCODE_TOO_EARLY]              = "Too Early",
3038
        [DNS_EDE_RCODE_UNSUPPORTED_NSEC3_ITER] = "Unsupported NSEC3 Iterations",
3039
        [DNS_EDE_RCODE_TRANSPORT_POLICY]       = "Impossible Transport Policy",
3040
        [DNS_EDE_RCODE_SYNTHESIZED]            = "Synthesized",
3041
};
3042
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(dns_ede_rcode, int);
3043
3044
const char* format_dns_ede_rcode(int i, char buf[static DECIMAL_STR_MAX(int)]) {
3045
        const char *p = dns_ede_rcode_to_string(i);
3046
        if (p)
3047
                return p;
3048
3049
        return snprintf_ok(buf, DECIMAL_STR_MAX(int), "%i", i);
3050
}
3051
3052
static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
3053
        [DNS_PROTOCOL_DNS]   = "dns",
3054
        [DNS_PROTOCOL_MDNS]  = "mdns",
3055
        [DNS_PROTOCOL_LLMNR] = "llmnr",
3056
};
3057
DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);