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