chiark / gitweb /
resolved: skip IPv6 LLMNR if IPv6 is not available
[elogind.git] / src / resolve / resolved-dns-packet.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20  ***/
21
22 #include "utf8.h"
23 #include "util.h"
24 #include "strv.h"
25 #include "resolved-dns-domain.h"
26 #include "resolved-dns-packet.h"
27
28 int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
29         DnsPacket *p;
30         size_t a;
31
32         assert(ret);
33
34         if (mtu <= 0)
35                 a = DNS_PACKET_SIZE_START;
36         else
37                 a = mtu;
38
39         if (a < DNS_PACKET_HEADER_SIZE)
40                 a = DNS_PACKET_HEADER_SIZE;
41
42         /* round up to next page size */
43         a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
44
45         /* make sure we never allocate more than useful */
46         if (a > DNS_PACKET_SIZE_MAX)
47                 a = DNS_PACKET_SIZE_MAX;
48
49         p = malloc0(ALIGN(sizeof(DnsPacket)) + a);
50         if (!p)
51                 return -ENOMEM;
52
53         p->size = p->rindex = DNS_PACKET_HEADER_SIZE;
54         p->allocated = a;
55         p->protocol = protocol;
56         p->n_ref = 1;
57
58         *ret = p;
59
60         return 0;
61 }
62
63 int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
64         DnsPacket *p;
65         DnsPacketHeader *h;
66         int r;
67
68         assert(ret);
69
70         r = dns_packet_new(&p, protocol, mtu);
71         if (r < 0)
72                 return r;
73
74         h = DNS_PACKET_HEADER(p);
75
76         if (protocol == DNS_PROTOCOL_LLMNR)
77                 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
78                                                          0 /* opcode */,
79                                                          0 /* c */,
80                                                          0 /* tc */,
81                                                          0 /* t */,
82                                                          0 /* ra */,
83                                                          0 /* ad */,
84                                                          0 /* cd */,
85                                                          0 /* rcode */));
86         else
87                 h->flags = htobe16(DNS_PACKET_MAKE_FLAGS(0 /* qr */,
88                                                          0 /* opcode */,
89                                                          0 /* aa */,
90                                                          0 /* tc */,
91                                                          1 /* rd (ask for recursion) */,
92                                                          0 /* ra */,
93                                                          0 /* ad */,
94                                                          0 /* cd */,
95                                                          0 /* rcode */));
96
97         *ret = p;
98         return 0;
99 }
100
101 DnsPacket *dns_packet_ref(DnsPacket *p) {
102
103         if (!p)
104                 return NULL;
105
106         assert(p->n_ref > 0);
107         p->n_ref++;
108         return p;
109 }
110
111 static void dns_packet_free(DnsPacket *p) {
112         char *s;
113
114         assert(p);
115
116         dns_question_unref(p->question);
117         dns_answer_unref(p->answer);
118
119         while ((s = hashmap_steal_first_key(p->names)))
120                 free(s);
121         hashmap_free(p->names);
122
123         free(p->_data);
124         free(p);
125 }
126
127 DnsPacket *dns_packet_unref(DnsPacket *p) {
128         if (!p)
129                 return NULL;
130
131         assert(p->n_ref > 0);
132
133         if (p->n_ref == 1)
134                 dns_packet_free(p);
135         else
136                 p->n_ref--;
137
138         return NULL;
139 }
140
141 int dns_packet_validate(DnsPacket *p) {
142         assert(p);
143
144         if (p->size < DNS_PACKET_HEADER_SIZE)
145                 return -EBADMSG;
146
147         if (p->size > DNS_PACKET_SIZE_MAX)
148                 return -EBADMSG;
149
150         return 1;
151 }
152
153 int dns_packet_validate_reply(DnsPacket *p) {
154         int r;
155
156         assert(p);
157
158         r = dns_packet_validate(p);
159         if (r < 0)
160                 return r;
161
162         if (DNS_PACKET_QR(p) != 1)
163                 return 0;
164
165         if (DNS_PACKET_OPCODE(p) != 0)
166                 return -EBADMSG;
167
168         /* RFC 4795, Section 2.1.1. says to discard all replies with QDCOUNT != 1 */
169         if (p->protocol == DNS_PROTOCOL_LLMNR &&
170             DNS_PACKET_QDCOUNT(p) != 1)
171                 return -EBADMSG;
172
173         return 1;
174 }
175
176 int dns_packet_validate_query(DnsPacket *p) {
177         int r;
178
179         assert(p);
180
181         r = dns_packet_validate(p);
182         if (r < 0)
183                 return r;
184
185         if (DNS_PACKET_QR(p) != 0)
186                 return 0;
187
188         if (DNS_PACKET_OPCODE(p) != 0)
189                 return -EBADMSG;
190
191         if (DNS_PACKET_TC(p))
192                 return -EBADMSG;
193
194         /* RFC 4795, Section 2.1.1. says to discard all queries with QDCOUNT != 1 */
195         if (p->protocol == DNS_PROTOCOL_LLMNR &&
196             DNS_PACKET_QDCOUNT(p) != 1)
197                 return -EBADMSG;
198
199         /* RFC 4795, Section 2.1.1. says to discard all queries with ANCOUNT != 0 */
200         if (DNS_PACKET_ANCOUNT(p) > 0)
201                 return -EBADMSG;
202
203         /* RFC 4795, Section 2.1.1. says to discard all queries with NSCOUNT != 0 */
204         if (DNS_PACKET_NSCOUNT(p) > 0)
205                 return -EBADMSG;
206
207         return 1;
208 }
209
210 static int dns_packet_extend(DnsPacket *p, size_t add, void **ret, size_t *start) {
211         assert(p);
212
213         if (p->size + add > p->allocated) {
214                 size_t a;
215
216                 a = PAGE_ALIGN((p->size + add) * 2);
217                 if (a > DNS_PACKET_SIZE_MAX)
218                         a = DNS_PACKET_SIZE_MAX;
219
220                 if (p->size + add > a)
221                         return -EMSGSIZE;
222
223                 if (p->_data) {
224                         void *d;
225
226                         d = realloc(p->_data, a);
227                         if (!d)
228                                 return -ENOMEM;
229
230                         p->_data = d;
231                 } else {
232                         p->_data = malloc(a);
233                         if (!p->_data)
234                                 return -ENOMEM;
235
236                         memcpy(p->_data, (uint8_t*) p + ALIGN(sizeof(DnsPacket)), p->size);
237                         memzero((uint8_t*) p->_data + p->size, a - p->size);
238                 }
239
240                 p->allocated = a;
241         }
242
243         if (start)
244                 *start = p->size;
245
246         if (ret)
247                 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->size;
248
249         p->size += add;
250         return 0;
251 }
252
253 static void dns_packet_truncate(DnsPacket *p, size_t sz) {
254         Iterator i;
255         char *s;
256         void *n;
257
258         assert(p);
259
260         if (p->size <= sz)
261                 return;
262
263         HASHMAP_FOREACH_KEY(s, n, p->names, i) {
264
265                 if (PTR_TO_SIZE(n) < sz)
266                         continue;
267
268                 hashmap_remove(p->names, s);
269                 free(s);
270         }
271
272         p->size = sz;
273 }
274
275 int dns_packet_append_blob(DnsPacket *p, const void *d, size_t l, size_t *start) {
276         void *q;
277         int r;
278
279         assert(p);
280
281         r = dns_packet_extend(p, l, &q, start);
282         if (r < 0)
283                 return r;
284
285         memcpy(q, d, l);
286         return 0;
287 }
288
289 int dns_packet_append_uint8(DnsPacket *p, uint8_t v, size_t *start) {
290         void *d;
291         int r;
292
293         assert(p);
294
295         r = dns_packet_extend(p, sizeof(uint8_t), &d, start);
296         if (r < 0)
297                 return r;
298
299         ((uint8_t*) d)[0] = v;
300
301         return 0;
302 }
303
304 int dns_packet_append_uint16(DnsPacket *p, uint16_t v, size_t *start) {
305         void *d;
306         int r;
307
308         assert(p);
309
310         r = dns_packet_extend(p, sizeof(uint16_t), &d, start);
311         if (r < 0)
312                 return r;
313
314         ((uint8_t*) d)[0] = (uint8_t) (v >> 8);
315         ((uint8_t*) d)[1] = (uint8_t) v;
316
317         return 0;
318 }
319
320 int dns_packet_append_uint32(DnsPacket *p, uint32_t v, size_t *start) {
321         void *d;
322         int r;
323
324         assert(p);
325
326         r = dns_packet_extend(p, sizeof(uint32_t), &d, start);
327         if (r < 0)
328                 return r;
329
330         ((uint8_t*) d)[0] = (uint8_t) (v >> 24);
331         ((uint8_t*) d)[1] = (uint8_t) (v >> 16);
332         ((uint8_t*) d)[2] = (uint8_t) (v >> 8);
333         ((uint8_t*) d)[3] = (uint8_t) v;
334
335         return 0;
336 }
337
338 int dns_packet_append_string(DnsPacket *p, const char *s, size_t *start) {
339         void *d;
340         size_t l;
341         int r;
342
343         assert(p);
344         assert(s);
345
346         l = strlen(s);
347         if (l > 255)
348                 return -E2BIG;
349
350         r = dns_packet_extend(p, 1 + l, &d, start);
351         if (r < 0)
352                 return r;
353
354         ((uint8_t*) d)[0] = (uint8_t) l;
355         memcpy(((uint8_t*) d) + 1, s, l);
356
357         return 0;
358 }
359
360 int dns_packet_append_label(DnsPacket *p, const char *d, size_t l, size_t *start) {
361         void *w;
362         int r;
363
364         assert(p);
365         assert(d);
366
367         if (l > DNS_LABEL_MAX)
368                 return -E2BIG;
369
370         r = dns_packet_extend(p, 1 + l, &w, start);
371         if (r < 0)
372                 return r;
373
374         ((uint8_t*) w)[0] = (uint8_t) l;
375         memcpy(((uint8_t*) w) + 1, d, l);
376
377         return 0;
378 }
379
380 int dns_packet_append_name(DnsPacket *p, const char *name,
381                            bool allow_compression, size_t *start) {
382         size_t saved_size;
383         int r;
384
385         assert(p);
386         assert(name);
387
388         saved_size = p->size;
389
390         while (*name) {
391                 _cleanup_free_ char *s = NULL;
392                 char label[DNS_LABEL_MAX];
393                 size_t n = 0;
394                 int k;
395
396                 if (allow_compression)
397                         n = PTR_TO_SIZE(hashmap_get(p->names, name));
398                 if (n > 0) {
399                         assert(n < p->size);
400
401                         if (n < 0x4000) {
402                                 r = dns_packet_append_uint16(p, 0xC000 | n, NULL);
403                                 if (r < 0)
404                                         goto fail;
405
406                                 goto done;
407                         }
408                 }
409
410                 s = strdup(name);
411                 if (!s) {
412                         r = -ENOMEM;
413                         goto fail;
414                 }
415
416                 r = dns_label_unescape(&name, label, sizeof(label));
417                 if (r < 0)
418                         goto fail;
419
420                 if (p->protocol == DNS_PROTOCOL_DNS)
421                         k = dns_label_apply_idna(label, r, label, sizeof(label));
422                 else
423                         k = dns_label_undo_idna(label, r, label, sizeof(label));
424                 if (k < 0) {
425                         r = k;
426                         goto fail;
427                 }
428                 if (k > 0)
429                         r = k;
430
431                 r = dns_packet_append_label(p, label, r, &n);
432                 if (r < 0)
433                         goto fail;
434
435                 if (allow_compression) {
436                         r = hashmap_ensure_allocated(&p->names,
437                                                      dns_name_hash_func,
438                                                      dns_name_compare_func);
439                         if (r < 0)
440                                 goto fail;
441
442                         r = hashmap_put(p->names, s, SIZE_TO_PTR(n));
443                         if (r < 0)
444                                 goto fail;
445
446                         s = NULL;
447                 }
448         }
449
450         r = dns_packet_append_uint8(p, 0, NULL);
451         if (r < 0)
452                 return r;
453
454 done:
455         if (start)
456                 *start = saved_size;
457
458         return 0;
459
460 fail:
461         dns_packet_truncate(p, saved_size);
462         return r;
463 }
464
465 int dns_packet_append_key(DnsPacket *p, const DnsResourceKey *k, size_t *start) {
466         size_t saved_size;
467         int r;
468
469         assert(p);
470         assert(k);
471
472         saved_size = p->size;
473
474         r = dns_packet_append_name(p, DNS_RESOURCE_KEY_NAME(k), true, NULL);
475         if (r < 0)
476                 goto fail;
477
478         r = dns_packet_append_uint16(p, k->type, NULL);
479         if (r < 0)
480                 goto fail;
481
482         r = dns_packet_append_uint16(p, k->class, NULL);
483         if (r < 0)
484                 goto fail;
485
486         if (start)
487                 *start = saved_size;
488
489         return 0;
490
491 fail:
492         dns_packet_truncate(p, saved_size);
493         return r;
494 }
495
496 int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, size_t *start) {
497         size_t saved_size, rdlength_offset, end, rdlength;
498         int r;
499
500         assert(p);
501         assert(rr);
502
503         saved_size = p->size;
504
505         r = dns_packet_append_key(p, rr->key, NULL);
506         if (r < 0)
507                 goto fail;
508
509         r = dns_packet_append_uint32(p, rr->ttl, NULL);
510         if (r < 0)
511                 goto fail;
512
513         /* Initially we write 0 here */
514         r = dns_packet_append_uint16(p, 0, &rdlength_offset);
515         if (r < 0)
516                 goto fail;
517
518         switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
519
520         case DNS_TYPE_SRV:
521                 r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
522                 if (r < 0)
523                         goto fail;
524
525                 r = dns_packet_append_uint16(p, rr->srv.weight, NULL);
526                 if (r < 0)
527                         goto fail;
528
529                 r = dns_packet_append_uint16(p, rr->srv.port, NULL);
530                 if (r < 0)
531                         goto fail;
532
533                 r = dns_packet_append_name(p, rr->srv.name, true, NULL);
534                 break;
535
536         case DNS_TYPE_PTR:
537         case DNS_TYPE_NS:
538         case DNS_TYPE_CNAME:
539         case DNS_TYPE_DNAME:
540                 r = dns_packet_append_name(p, rr->ptr.name, true, NULL);
541                 break;
542
543         case DNS_TYPE_HINFO:
544                 r = dns_packet_append_string(p, rr->hinfo.cpu, NULL);
545                 if (r < 0)
546                         goto fail;
547
548                 r = dns_packet_append_string(p, rr->hinfo.os, NULL);
549                 break;
550
551         case DNS_TYPE_SPF: /* exactly the same as TXT */
552         case DNS_TYPE_TXT: {
553                 char **s;
554
555                 STRV_FOREACH(s, rr->txt.strings) {
556                         r = dns_packet_append_string(p, *s, NULL);
557                         if (r < 0)
558                                 goto fail;
559                 }
560
561                 r = 0;
562                 break;
563         }
564
565         case DNS_TYPE_A:
566                 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
567                 break;
568
569         case DNS_TYPE_AAAA:
570                 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
571                 break;
572
573         case DNS_TYPE_SOA:
574                 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
575                 if (r < 0)
576                         goto fail;
577
578                 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
579                 if (r < 0)
580                         goto fail;
581
582                 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
583                 if (r < 0)
584                         goto fail;
585
586                 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
587                 if (r < 0)
588                         goto fail;
589
590                 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
591                 if (r < 0)
592                         goto fail;
593
594                 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
595                 if (r < 0)
596                         goto fail;
597
598                 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
599                 break;
600
601         case DNS_TYPE_MX:
602                 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
603                 if (r < 0)
604                         goto fail;
605
606                 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
607                 break;
608
609         case DNS_TYPE_LOC:
610                 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
611                 if (r < 0)
612                         goto fail;
613
614                 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
615                 if (r < 0)
616                         goto fail;
617
618                 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
619                 if (r < 0)
620                         goto fail;
621
622                 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
623                 if (r < 0)
624                         goto fail;
625
626                 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
627                 if (r < 0)
628                         goto fail;
629
630                 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
631                 if (r < 0)
632                         goto fail;
633
634                 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
635                 break;
636
637         case DNS_TYPE_SSHFP:
638                 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
639                 if (r < 0)
640                         goto fail;
641
642                 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
643                 if (r < 0)
644                         goto fail;
645
646                 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
647                 break;
648
649         case DNS_TYPE_DNSKEY:
650                 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
651                 if (r < 0)
652                         goto fail;
653
654                 r = dns_packet_append_uint8(p, 3u, NULL);
655                 if (r < 0)
656                         goto fail;
657
658                 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
659                 if (r < 0)
660                         goto fail;
661
662                 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
663                 break;
664
665         case DNS_TYPE_RRSIG:
666                 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
667                 if (r < 0)
668                         goto fail;
669
670                 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
671                 if (r < 0)
672                         goto fail;
673
674                 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
675                 if (r < 0)
676                         goto fail;
677
678                 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
679                 if (r < 0)
680                         goto fail;
681
682                 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
683                 if (r < 0)
684                         goto fail;
685
686                 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
687                 if (r < 0)
688                         goto fail;
689
690                 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
691                 if (r < 0)
692                         goto fail;
693
694                 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
695                 if (r < 0)
696                         goto fail;
697
698                 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
699                 break;
700
701         case _DNS_TYPE_INVALID: /* unparseable */
702         default:
703
704                 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
705                 break;
706         }
707         if (r < 0)
708                 goto fail;
709
710         /* Let's calculate the actual data size and update the field */
711         rdlength = p->size - rdlength_offset - sizeof(uint16_t);
712         if (rdlength > 0xFFFF) {
713                 r = ENOSPC;
714                 goto fail;
715         }
716
717         end = p->size;
718         p->size = rdlength_offset;
719         r = dns_packet_append_uint16(p, rdlength, NULL);
720         if (r < 0)
721                 goto fail;
722         p->size = end;
723
724         if (start)
725                 *start = saved_size;
726
727         return 0;
728
729 fail:
730         dns_packet_truncate(p, saved_size);
731         return r;
732 }
733
734
735 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
736         assert(p);
737
738         if (p->rindex + sz > p->size)
739                 return -EMSGSIZE;
740
741         if (ret)
742                 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
743
744         if (start)
745                 *start = p->rindex;
746
747         p->rindex += sz;
748         return 0;
749 }
750
751 void dns_packet_rewind(DnsPacket *p, size_t idx) {
752         assert(p);
753         assert(idx <= p->size);
754         assert(idx >= DNS_PACKET_HEADER_SIZE);
755
756         p->rindex = idx;
757 }
758
759 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
760         const void *q;
761         int r;
762
763         assert(p);
764         assert(d);
765
766         r = dns_packet_read(p, sz, &q, start);
767         if (r < 0)
768                 return r;
769
770         memcpy(d, q, sz);
771         return 0;
772 }
773
774 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
775         const void *d;
776         int r;
777
778         assert(p);
779
780         r = dns_packet_read(p, sizeof(uint8_t), &d, start);
781         if (r < 0)
782                 return r;
783
784         *ret = ((uint8_t*) d)[0];
785         return 0;
786 }
787
788 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
789         const void *d;
790         int r;
791
792         assert(p);
793
794         r = dns_packet_read(p, sizeof(uint16_t), &d, start);
795         if (r < 0)
796                 return r;
797
798         *ret = (((uint16_t) ((uint8_t*) d)[0]) << 8) |
799                 ((uint16_t) ((uint8_t*) d)[1]);
800         return 0;
801 }
802
803 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
804         const void *d;
805         int r;
806
807         assert(p);
808
809         r = dns_packet_read(p, sizeof(uint32_t), &d, start);
810         if (r < 0)
811                 return r;
812
813         *ret = (((uint32_t) ((uint8_t*) d)[0]) << 24) |
814                (((uint32_t) ((uint8_t*) d)[1]) << 16) |
815                (((uint32_t) ((uint8_t*) d)[2]) << 8) |
816                 ((uint32_t) ((uint8_t*) d)[3]);
817
818         return 0;
819 }
820
821 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
822         size_t saved_rindex;
823         const void *d;
824         char *t;
825         uint8_t c;
826         int r;
827
828         assert(p);
829
830         saved_rindex = p->rindex;
831
832         r = dns_packet_read_uint8(p, &c, NULL);
833         if (r < 0)
834                 goto fail;
835
836         r = dns_packet_read(p, c, &d, NULL);
837         if (r < 0)
838                 goto fail;
839
840         if (memchr(d, 0, c)) {
841                 r = -EBADMSG;
842                 goto fail;
843         }
844
845         t = strndup(d, c);
846         if (!t) {
847                 r = -ENOMEM;
848                 goto fail;
849         }
850
851         if (!utf8_is_valid(t)) {
852                 free(t);
853                 r = -EBADMSG;
854                 goto fail;
855         }
856
857         *ret = t;
858
859         if (start)
860                 *start = saved_rindex;
861
862         return 0;
863
864 fail:
865         dns_packet_rewind(p, saved_rindex);
866         return r;
867 }
868
869 int dns_packet_read_name(DnsPacket *p, char **_ret,
870                          bool allow_compression, size_t *start) {
871         size_t saved_rindex, after_rindex = 0;
872         _cleanup_free_ char *ret = NULL;
873         size_t n = 0, allocated = 0;
874         bool first = true;
875         int r;
876
877         assert(p);
878         assert(_ret);
879
880         saved_rindex = p->rindex;
881
882         for (;;) {
883                 uint8_t c, d;
884
885                 r = dns_packet_read_uint8(p, &c, NULL);
886                 if (r < 0)
887                         goto fail;
888
889                 if (c == 0)
890                         /* End of name */
891                         break;
892                 else if (c <= 63) {
893                         _cleanup_free_ char *t = NULL;
894                         const char *label;
895
896                         /* Literal label */
897                         r = dns_packet_read(p, c, (const void**) &label, NULL);
898                         if (r < 0)
899                                 goto fail;
900
901                         r = dns_label_escape(label, c, &t);
902                         if (r < 0)
903                                 goto fail;
904
905                         if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
906                                 r = -ENOMEM;
907                                 goto fail;
908                         }
909
910                         if (!first)
911                                 ret[n++] = '.';
912                         else
913                                 first = false;
914
915                         memcpy(ret + n, t, r);
916                         n += r;
917                         continue;
918                 } else if (allow_compression && (c & 0xc0) == 0xc0) {
919                         uint16_t ptr;
920
921                         /* Pointer */
922                         r = dns_packet_read_uint8(p, &d, NULL);
923                         if (r < 0)
924                                 goto fail;
925
926                         ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
927                         if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= saved_rindex) {
928                                 r = -EBADMSG;
929                                 goto fail;
930                         }
931
932                         if (after_rindex == 0)
933                                 after_rindex = p->rindex;
934
935                         p->rindex = ptr;
936                 } else
937                         goto fail;
938         }
939
940         if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
941                 r = -ENOMEM;
942                 goto fail;
943         }
944
945         ret[n] = 0;
946
947         if (after_rindex != 0)
948                 p->rindex= after_rindex;
949
950         *_ret = ret;
951         ret = NULL;
952
953         if (start)
954                 *start = saved_rindex;
955
956         return 0;
957
958 fail:
959         dns_packet_rewind(p, saved_rindex);
960         return r;
961 }
962
963 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
964         _cleanup_free_ char *name = NULL;
965         uint16_t class, type;
966         DnsResourceKey *key;
967         size_t saved_rindex;
968         int r;
969
970         assert(p);
971         assert(ret);
972
973         saved_rindex = p->rindex;
974
975         r = dns_packet_read_name(p, &name, true, NULL);
976         if (r < 0)
977                 goto fail;
978
979         r = dns_packet_read_uint16(p, &type, NULL);
980         if (r < 0)
981                 goto fail;
982
983         r = dns_packet_read_uint16(p, &class, NULL);
984         if (r < 0)
985                 goto fail;
986
987         key = dns_resource_key_new_consume(class, type, name);
988         if (!key) {
989                 r = -ENOMEM;
990                 goto fail;
991         }
992
993         name = NULL;
994         *ret = key;
995
996         if (start)
997                 *start = saved_rindex;
998
999         return 0;
1000 fail:
1001         dns_packet_rewind(p, saved_rindex);
1002         return r;
1003 }
1004
1005 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1006                                       void **dp, size_t *lengthp,
1007                                       size_t *start) {
1008         int r;
1009         const void *d;
1010         void *d2;
1011
1012         r = dns_packet_read(p, length, &d, NULL);
1013         if (r < 0)
1014                 return r;
1015
1016         d2 = memdup(d, length);
1017         if (!d2)
1018                 return -ENOMEM;
1019
1020         *dp = d2;
1021         *lengthp = length;
1022         return 0;
1023 }
1024
1025 static bool loc_size_ok(uint8_t size) {
1026         uint8_t m = size >> 4, e = size & 0xF;
1027
1028         return m <= 9 && e <= 9 && (m > 0 || e == 0);
1029 }
1030
1031 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1032         assert(rr);
1033
1034         if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1035                 return -EBADMSG;
1036
1037         rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1038         rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1039         return 0;
1040 }
1041
1042 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1043         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1044         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1045         size_t saved_rindex, offset;
1046         uint16_t rdlength;
1047         const void *d;
1048         int r;
1049
1050         assert(p);
1051         assert(ret);
1052
1053         saved_rindex = p->rindex;
1054
1055         r = dns_packet_read_key(p, &key, NULL);
1056         if (r < 0)
1057                 goto fail;
1058
1059         if (key->class == DNS_CLASS_ANY ||
1060             key->type == DNS_TYPE_ANY) {
1061                 r = -EBADMSG;
1062                 goto fail;
1063         }
1064
1065         rr = dns_resource_record_new(key);
1066         if (!rr) {
1067                 r = -ENOMEM;
1068                 goto fail;
1069         }
1070
1071         r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1072         if (r < 0)
1073                 goto fail;
1074
1075         r = dns_packet_read_uint16(p, &rdlength, NULL);
1076         if (r < 0)
1077                 goto fail;
1078
1079         if (p->rindex + rdlength > p->size) {
1080                 r = -EBADMSG;
1081                 goto fail;
1082         }
1083
1084         offset = p->rindex;
1085
1086         switch (rr->key->type) {
1087
1088         case DNS_TYPE_SRV:
1089                 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1090                 if (r < 0)
1091                         goto fail;
1092                 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1093                 if (r < 0)
1094                         goto fail;
1095                 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1096                 if (r < 0)
1097                         goto fail;
1098                 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1099                 break;
1100
1101         case DNS_TYPE_PTR:
1102         case DNS_TYPE_NS:
1103         case DNS_TYPE_CNAME:
1104         case DNS_TYPE_DNAME:
1105                 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1106                 break;
1107
1108         case DNS_TYPE_HINFO:
1109                 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1110                 if (r < 0)
1111                         goto fail;
1112
1113                 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1114                 break;
1115
1116         case DNS_TYPE_SPF: /* exactly the same as TXT */
1117         case DNS_TYPE_TXT: {
1118                 char *s;
1119
1120                 while (p->rindex < offset + rdlength) {
1121                         r = dns_packet_read_string(p, &s, NULL);
1122                         if (r < 0)
1123                                 goto fail;
1124
1125                         r = strv_consume(&rr->txt.strings, s);
1126                         if (r < 0)
1127                                 goto fail;
1128                 }
1129
1130                 r = 0;
1131                 break;
1132         }
1133
1134         case DNS_TYPE_A:
1135                 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1136                 break;
1137
1138         case DNS_TYPE_AAAA:
1139                 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1140                 break;
1141
1142         case DNS_TYPE_SOA:
1143                 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1144                 if (r < 0)
1145                         goto fail;
1146
1147                 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1148                 if (r < 0)
1149                         goto fail;
1150
1151                 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1152                 if (r < 0)
1153                         goto fail;
1154
1155                 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1156                 if (r < 0)
1157                         goto fail;
1158
1159                 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1160                 if (r < 0)
1161                         goto fail;
1162
1163                 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1164                 if (r < 0)
1165                         goto fail;
1166
1167                 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1168                 break;
1169
1170         case DNS_TYPE_MX:
1171                 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1172                 if (r < 0)
1173                         goto fail;
1174
1175                 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1176                 break;
1177
1178         case DNS_TYPE_LOC: {
1179                 uint8_t t;
1180                 size_t pos;
1181
1182                 r = dns_packet_read_uint8(p, &t, &pos);
1183                 if (r < 0)
1184                         goto fail;
1185
1186                 if (t == 0) {
1187                         rr->loc.version = t;
1188
1189                         r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1190                         if (r < 0)
1191                                 goto fail;
1192
1193                         if (!loc_size_ok(rr->loc.size)) {
1194                                 r = -EBADMSG;
1195                                 goto fail;
1196                         }
1197
1198                         r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1199                         if (r < 0)
1200                                 goto fail;
1201
1202                         if (!loc_size_ok(rr->loc.horiz_pre)) {
1203                                 r = -EBADMSG;
1204                                 goto fail;
1205                         }
1206
1207                         r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1208                         if (r < 0)
1209                                 goto fail;
1210
1211                         if (!loc_size_ok(rr->loc.vert_pre)) {
1212                                 r = -EBADMSG;
1213                                 goto fail;
1214                         }
1215
1216                         r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1217                         if (r < 0)
1218                                 goto fail;
1219
1220                         r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1221                         if (r < 0)
1222                                 goto fail;
1223
1224                         r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1225                         if (r < 0)
1226                                 goto fail;
1227
1228                         break;
1229                 } else {
1230                         dns_packet_rewind(p, pos);
1231                         rr->unparseable = true;
1232                         goto unparseable;
1233                 }
1234         }
1235
1236         case DNS_TYPE_SSHFP:
1237                 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1238                 if (r < 0)
1239                         goto fail;
1240
1241                 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1242                 if (r < 0)
1243                         goto fail;
1244
1245                 r = dns_packet_read_public_key(p, rdlength - 2,
1246                                                &rr->sshfp.key, &rr->sshfp.key_size,
1247                                                NULL);
1248                 break;
1249
1250         case DNS_TYPE_DNSKEY: {
1251                 uint16_t flags;
1252                 uint8_t proto;
1253
1254                 r = dns_packet_read_uint16(p, &flags, NULL);
1255                 if (r < 0)
1256                         goto fail;
1257
1258                 r = dnskey_parse_flags(rr, flags);
1259                 if (r < 0)
1260                         goto fail;
1261
1262                 r = dns_packet_read_uint8(p, &proto, NULL);
1263                 if (r < 0)
1264                         goto fail;
1265
1266                 /* protocol is required to be always 3 */
1267                 if (proto != 3) {
1268                         r = -EBADMSG;
1269                         goto fail;
1270                 }
1271
1272                 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1273                 if (r < 0)
1274                         goto fail;
1275
1276                 r = dns_packet_read_public_key(p, rdlength - 4,
1277                                                &rr->dnskey.key, &rr->dnskey.key_size,
1278                                                NULL);
1279                 break;
1280         }
1281
1282         case DNS_TYPE_RRSIG:
1283                 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1284                 if (r < 0)
1285                         goto fail;
1286
1287                 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1288                 if (r < 0)
1289                         goto fail;
1290
1291                 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1292                 if (r < 0)
1293                         goto fail;
1294
1295                 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1296                 if (r < 0)
1297                         goto fail;
1298
1299                 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1300                 if (r < 0)
1301                         goto fail;
1302
1303                 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1304                 if (r < 0)
1305                         goto fail;
1306
1307                 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1308                 if (r < 0)
1309                         goto fail;
1310
1311                 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1312                 if (r < 0)
1313                         goto fail;
1314
1315                 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1316                                                &rr->rrsig.signature, &rr->rrsig.signature_size,
1317                                                NULL);
1318                 break;
1319
1320         default:
1321         unparseable:
1322                 r = dns_packet_read(p, rdlength, &d, NULL);
1323                 if (r < 0)
1324                         goto fail;
1325
1326                 rr->generic.data = memdup(d, rdlength);
1327                 if (!rr->generic.data) {
1328                         r = -ENOMEM;
1329                         goto fail;
1330                 }
1331
1332                 rr->generic.size = rdlength;
1333                 break;
1334         }
1335         if (r < 0)
1336                 goto fail;
1337         if (p->rindex != offset + rdlength) {
1338                 r = -EBADMSG;
1339                 goto fail;
1340         }
1341
1342         *ret = rr;
1343         rr = NULL;
1344
1345         if (start)
1346                 *start = saved_rindex;
1347
1348         return 0;
1349 fail:
1350         dns_packet_rewind(p, saved_rindex);
1351         return r;
1352 }
1353
1354 int dns_packet_extract(DnsPacket *p) {
1355         _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1356         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1357         size_t saved_rindex;
1358         unsigned n, i;
1359         int r;
1360
1361         if (p->extracted)
1362                 return 0;
1363
1364         saved_rindex = p->rindex;
1365         dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1366
1367         n = DNS_PACKET_QDCOUNT(p);
1368         if (n > 0) {
1369                 question = dns_question_new(n);
1370                 if (!question) {
1371                         r = -ENOMEM;
1372                         goto finish;
1373                 }
1374
1375                 for (i = 0; i < n; i++) {
1376                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1377
1378                         r = dns_packet_read_key(p, &key, NULL);
1379                         if (r < 0)
1380                                 goto finish;
1381
1382                         r = dns_question_add(question, key);
1383                         if (r < 0)
1384                                 goto finish;
1385                 }
1386         }
1387
1388         n = DNS_PACKET_RRCOUNT(p);
1389         if (n > 0) {
1390                 answer = dns_answer_new(n);
1391                 if (!answer) {
1392                         r = -ENOMEM;
1393                         goto finish;
1394                 }
1395
1396                 for (i = 0; i < n; i++) {
1397                         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1398
1399                         r = dns_packet_read_rr(p, &rr, NULL);
1400                         if (r < 0)
1401                                 goto finish;
1402
1403                         r = dns_answer_add(answer, rr);
1404                         if (r < 0)
1405                                 goto finish;
1406                 }
1407         }
1408
1409         p->question = question;
1410         question = NULL;
1411
1412         p->answer = answer;
1413         answer = NULL;
1414
1415         p->extracted = true;
1416
1417         r = 0;
1418
1419 finish:
1420         p->rindex = saved_rindex;
1421         return r;
1422 }
1423
1424 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1425         [DNS_RCODE_SUCCESS] = "SUCCESS",
1426         [DNS_RCODE_FORMERR] = "FORMERR",
1427         [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1428         [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1429         [DNS_RCODE_NOTIMP] = "NOTIMP",
1430         [DNS_RCODE_REFUSED] = "REFUSED",
1431         [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1432         [DNS_RCODE_YXRRSET] = "YRRSET",
1433         [DNS_RCODE_NXRRSET] = "NXRRSET",
1434         [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1435         [DNS_RCODE_NOTZONE] = "NOTZONE",
1436         [DNS_RCODE_BADVERS] = "BADVERS",
1437         [DNS_RCODE_BADKEY] = "BADKEY",
1438         [DNS_RCODE_BADTIME] = "BADTIME",
1439         [DNS_RCODE_BADMODE] = "BADMODE",
1440         [DNS_RCODE_BADNAME] = "BADNAME",
1441         [DNS_RCODE_BADALG] = "BADALG",
1442         [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1443 };
1444 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1445
1446 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1447         [DNS_PROTOCOL_DNS] = "dns",
1448         [DNS_PROTOCOL_MDNS] = "mdns",
1449         [DNS_PROTOCOL_LLMNR] = "llmnr",
1450 };
1451 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1452
1453 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1454         [DNSSEC_ALGORITHM_RSAMD5]     = "RSAMD5",
1455         [DNSSEC_ALGORITHM_DH]         = "DH",
1456         [DNSSEC_ALGORITHM_DSA]        = "DSA",
1457         [DNSSEC_ALGORITHM_ECC]        = "ECC",
1458         [DNSSEC_ALGORITHM_RSASHA1]    = "RSASHA1",
1459         [DNSSEC_ALGORITHM_INDIRECT]   = "INDIRECT",
1460         [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1461         [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1462 };
1463 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);