chiark / gitweb /
mount: add remote-fs dependencies if needed after change
[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                 STRV_FOREACH(s, rr->txt.strings) {
551                         r = dns_packet_append_string(p, *s, NULL);
552                         if (r < 0)
553                                 goto fail;
554                 }
555
556                 r = 0;
557                 break;
558         }
559
560         case DNS_TYPE_A:
561                 r = dns_packet_append_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
562                 break;
563
564         case DNS_TYPE_AAAA:
565                 r = dns_packet_append_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
566                 break;
567
568         case DNS_TYPE_SOA:
569                 r = dns_packet_append_name(p, rr->soa.mname, true, NULL);
570                 if (r < 0)
571                         goto fail;
572
573                 r = dns_packet_append_name(p, rr->soa.rname, true, NULL);
574                 if (r < 0)
575                         goto fail;
576
577                 r = dns_packet_append_uint32(p, rr->soa.serial, NULL);
578                 if (r < 0)
579                         goto fail;
580
581                 r = dns_packet_append_uint32(p, rr->soa.refresh, NULL);
582                 if (r < 0)
583                         goto fail;
584
585                 r = dns_packet_append_uint32(p, rr->soa.retry, NULL);
586                 if (r < 0)
587                         goto fail;
588
589                 r = dns_packet_append_uint32(p, rr->soa.expire, NULL);
590                 if (r < 0)
591                         goto fail;
592
593                 r = dns_packet_append_uint32(p, rr->soa.minimum, NULL);
594                 break;
595
596         case DNS_TYPE_MX:
597                 r = dns_packet_append_uint16(p, rr->mx.priority, NULL);
598                 if (r < 0)
599                         goto fail;
600
601                 r = dns_packet_append_name(p, rr->mx.exchange, true, NULL);
602                 break;
603
604         case DNS_TYPE_LOC:
605                 r = dns_packet_append_uint8(p, rr->loc.version, NULL);
606                 if (r < 0)
607                         goto fail;
608
609                 r = dns_packet_append_uint8(p, rr->loc.size, NULL);
610                 if (r < 0)
611                         goto fail;
612
613                 r = dns_packet_append_uint8(p, rr->loc.horiz_pre, NULL);
614                 if (r < 0)
615                         goto fail;
616
617                 r = dns_packet_append_uint8(p, rr->loc.vert_pre, NULL);
618                 if (r < 0)
619                         goto fail;
620
621                 r = dns_packet_append_uint32(p, rr->loc.latitude, NULL);
622                 if (r < 0)
623                         goto fail;
624
625                 r = dns_packet_append_uint32(p, rr->loc.longitude, NULL);
626                 if (r < 0)
627                         goto fail;
628
629                 r = dns_packet_append_uint32(p, rr->loc.altitude, NULL);
630                 break;
631
632         case DNS_TYPE_SSHFP:
633                 r = dns_packet_append_uint8(p, rr->sshfp.algorithm, NULL);
634                 if (r < 0)
635                         goto fail;
636
637                 r = dns_packet_append_uint8(p, rr->sshfp.fptype, NULL);
638                 if (r < 0)
639                         goto fail;
640
641                 r = dns_packet_append_blob(p, rr->sshfp.key, rr->sshfp.key_size, NULL);
642                 break;
643
644         case DNS_TYPE_DNSKEY:
645                 r = dns_packet_append_uint16(p, dnskey_to_flags(rr), NULL);
646                 if (r < 0)
647                         goto fail;
648
649                 r = dns_packet_append_uint8(p, 3u, NULL);
650                 if (r < 0)
651                         goto fail;
652
653                 r = dns_packet_append_uint8(p, rr->dnskey.algorithm, NULL);
654                 if (r < 0)
655                         goto fail;
656
657                 r = dns_packet_append_blob(p, rr->dnskey.key, rr->dnskey.key_size, NULL);
658                 break;
659
660         case DNS_TYPE_RRSIG:
661                 r = dns_packet_append_uint16(p, rr->rrsig.type_covered, NULL);
662                 if (r < 0)
663                         goto fail;
664
665                 r = dns_packet_append_uint8(p, rr->rrsig.algorithm, NULL);
666                 if (r < 0)
667                         goto fail;
668
669                 r = dns_packet_append_uint8(p, rr->rrsig.labels, NULL);
670                 if (r < 0)
671                         goto fail;
672
673                 r = dns_packet_append_uint32(p, rr->rrsig.original_ttl, NULL);
674                 if (r < 0)
675                         goto fail;
676
677                 r = dns_packet_append_uint32(p, rr->rrsig.expiration, NULL);
678                 if (r < 0)
679                         goto fail;
680
681                 r = dns_packet_append_uint32(p, rr->rrsig.inception, NULL);
682                 if (r < 0)
683                         goto fail;
684
685                 r = dns_packet_append_uint8(p, rr->rrsig.key_tag, NULL);
686                 if (r < 0)
687                         goto fail;
688
689                 r = dns_packet_append_name(p, rr->rrsig.signer, false, NULL);
690                 if (r < 0)
691                         goto fail;
692
693                 r = dns_packet_append_blob(p, rr->rrsig.signature, rr->rrsig.signature_size, NULL);
694                 break;
695
696         case _DNS_TYPE_INVALID: /* unparseable */
697         default:
698
699                 r = dns_packet_append_blob(p, rr->generic.data, rr->generic.size, NULL);
700                 break;
701         }
702         if (r < 0)
703                 goto fail;
704
705         /* Let's calculate the actual data size and update the field */
706         rdlength = p->size - rdlength_offset - sizeof(uint16_t);
707         if (rdlength > 0xFFFF) {
708                 r = ENOSPC;
709                 goto fail;
710         }
711
712         end = p->size;
713         p->size = rdlength_offset;
714         r = dns_packet_append_uint16(p, rdlength, NULL);
715         if (r < 0)
716                 goto fail;
717         p->size = end;
718
719         if (start)
720                 *start = saved_size;
721
722         return 0;
723
724 fail:
725         dns_packet_truncate(p, saved_size);
726         return r;
727 }
728
729
730 int dns_packet_read(DnsPacket *p, size_t sz, const void **ret, size_t *start) {
731         assert(p);
732
733         if (p->rindex + sz > p->size)
734                 return -EMSGSIZE;
735
736         if (ret)
737                 *ret = (uint8_t*) DNS_PACKET_DATA(p) + p->rindex;
738
739         if (start)
740                 *start = p->rindex;
741
742         p->rindex += sz;
743         return 0;
744 }
745
746 void dns_packet_rewind(DnsPacket *p, size_t idx) {
747         assert(p);
748         assert(idx <= p->size);
749         assert(idx >= DNS_PACKET_HEADER_SIZE);
750
751         p->rindex = idx;
752 }
753
754 int dns_packet_read_blob(DnsPacket *p, void *d, size_t sz, size_t *start) {
755         const void *q;
756         int r;
757
758         assert(p);
759         assert(d);
760
761         r = dns_packet_read(p, sz, &q, start);
762         if (r < 0)
763                 return r;
764
765         memcpy(d, q, sz);
766         return 0;
767 }
768
769 int dns_packet_read_uint8(DnsPacket *p, uint8_t *ret, size_t *start) {
770         const void *d;
771         int r;
772
773         assert(p);
774
775         r = dns_packet_read(p, sizeof(uint8_t), &d, start);
776         if (r < 0)
777                 return r;
778
779         *ret = ((uint8_t*) d)[0];
780         return 0;
781 }
782
783 int dns_packet_read_uint16(DnsPacket *p, uint16_t *ret, size_t *start) {
784         const void *d;
785         int r;
786
787         assert(p);
788
789         r = dns_packet_read(p, sizeof(uint16_t), &d, start);
790         if (r < 0)
791                 return r;
792
793         *ret = unaligned_read_be16(d);
794
795         return 0;
796 }
797
798 int dns_packet_read_uint32(DnsPacket *p, uint32_t *ret, size_t *start) {
799         const void *d;
800         int r;
801
802         assert(p);
803
804         r = dns_packet_read(p, sizeof(uint32_t), &d, start);
805         if (r < 0)
806                 return r;
807
808         *ret = unaligned_read_be32(d);
809
810         return 0;
811 }
812
813 int dns_packet_read_string(DnsPacket *p, char **ret, size_t *start) {
814         size_t saved_rindex;
815         const void *d;
816         char *t;
817         uint8_t c;
818         int r;
819
820         assert(p);
821
822         saved_rindex = p->rindex;
823
824         r = dns_packet_read_uint8(p, &c, NULL);
825         if (r < 0)
826                 goto fail;
827
828         r = dns_packet_read(p, c, &d, NULL);
829         if (r < 0)
830                 goto fail;
831
832         if (memchr(d, 0, c)) {
833                 r = -EBADMSG;
834                 goto fail;
835         }
836
837         t = strndup(d, c);
838         if (!t) {
839                 r = -ENOMEM;
840                 goto fail;
841         }
842
843         if (!utf8_is_valid(t)) {
844                 free(t);
845                 r = -EBADMSG;
846                 goto fail;
847         }
848
849         *ret = t;
850
851         if (start)
852                 *start = saved_rindex;
853
854         return 0;
855
856 fail:
857         dns_packet_rewind(p, saved_rindex);
858         return r;
859 }
860
861 int dns_packet_read_name(DnsPacket *p, char **_ret,
862                          bool allow_compression, size_t *start) {
863         size_t saved_rindex, after_rindex = 0, jump_barrier;
864         _cleanup_free_ char *ret = NULL;
865         size_t n = 0, allocated = 0;
866         bool first = true;
867         int r;
868
869         assert(p);
870         assert(_ret);
871
872         saved_rindex = p->rindex;
873         jump_barrier = p->rindex;
874
875         for (;;) {
876                 uint8_t c, d;
877
878                 r = dns_packet_read_uint8(p, &c, NULL);
879                 if (r < 0)
880                         goto fail;
881
882                 if (c == 0)
883                         /* End of name */
884                         break;
885                 else if (c <= 63) {
886                         _cleanup_free_ char *t = NULL;
887                         const char *label;
888
889                         /* Literal label */
890                         r = dns_packet_read(p, c, (const void**) &label, NULL);
891                         if (r < 0)
892                                 goto fail;
893
894                         r = dns_label_escape(label, c, &t);
895                         if (r < 0)
896                                 goto fail;
897
898                         if (!GREEDY_REALLOC(ret, allocated, n + !first + strlen(t) + 1)) {
899                                 r = -ENOMEM;
900                                 goto fail;
901                         }
902
903                         if (!first)
904                                 ret[n++] = '.';
905                         else
906                                 first = false;
907
908                         memcpy(ret + n, t, r);
909                         n += r;
910                         continue;
911                 } else if (allow_compression && (c & 0xc0) == 0xc0) {
912                         uint16_t ptr;
913
914                         /* Pointer */
915                         r = dns_packet_read_uint8(p, &d, NULL);
916                         if (r < 0)
917                                 goto fail;
918
919                         ptr = (uint16_t) (c & ~0xc0) << 8 | (uint16_t) d;
920                         if (ptr < DNS_PACKET_HEADER_SIZE || ptr >= jump_barrier) {
921                                 r = -EBADMSG;
922                                 goto fail;
923                         }
924
925                         if (after_rindex == 0)
926                                 after_rindex = p->rindex;
927
928                         /* Jumps are limited to a "prior occurence" (RFC-1035 4.1.4) */
929                         jump_barrier = ptr;
930                         p->rindex = ptr;
931                 } else {
932                         r = -EBADMSG;
933                         goto fail;
934                 }
935         }
936
937         if (!GREEDY_REALLOC(ret, allocated, n + 1)) {
938                 r = -ENOMEM;
939                 goto fail;
940         }
941
942         ret[n] = 0;
943
944         if (after_rindex != 0)
945                 p->rindex= after_rindex;
946
947         *_ret = ret;
948         ret = NULL;
949
950         if (start)
951                 *start = saved_rindex;
952
953         return 0;
954
955 fail:
956         dns_packet_rewind(p, saved_rindex);
957         return r;
958 }
959
960 int dns_packet_read_key(DnsPacket *p, DnsResourceKey **ret, size_t *start) {
961         _cleanup_free_ char *name = NULL;
962         uint16_t class, type;
963         DnsResourceKey *key;
964         size_t saved_rindex;
965         int r;
966
967         assert(p);
968         assert(ret);
969
970         saved_rindex = p->rindex;
971
972         r = dns_packet_read_name(p, &name, true, NULL);
973         if (r < 0)
974                 goto fail;
975
976         r = dns_packet_read_uint16(p, &type, NULL);
977         if (r < 0)
978                 goto fail;
979
980         r = dns_packet_read_uint16(p, &class, NULL);
981         if (r < 0)
982                 goto fail;
983
984         key = dns_resource_key_new_consume(class, type, name);
985         if (!key) {
986                 r = -ENOMEM;
987                 goto fail;
988         }
989
990         name = NULL;
991         *ret = key;
992
993         if (start)
994                 *start = saved_rindex;
995
996         return 0;
997 fail:
998         dns_packet_rewind(p, saved_rindex);
999         return r;
1000 }
1001
1002 static int dns_packet_read_public_key(DnsPacket *p, size_t length,
1003                                       void **dp, size_t *lengthp,
1004                                       size_t *start) {
1005         int r;
1006         const void *d;
1007         void *d2;
1008
1009         r = dns_packet_read(p, length, &d, NULL);
1010         if (r < 0)
1011                 return r;
1012
1013         d2 = memdup(d, length);
1014         if (!d2)
1015                 return -ENOMEM;
1016
1017         *dp = d2;
1018         *lengthp = length;
1019         return 0;
1020 }
1021
1022 static bool loc_size_ok(uint8_t size) {
1023         uint8_t m = size >> 4, e = size & 0xF;
1024
1025         return m <= 9 && e <= 9 && (m > 0 || e == 0);
1026 }
1027
1028 static int dnskey_parse_flags(DnsResourceRecord *rr, uint16_t flags) {
1029         assert(rr);
1030
1031         if (flags & ~(DNSKEY_FLAG_SEP | DNSKEY_FLAG_ZONE_KEY))
1032                 return -EBADMSG;
1033
1034         rr->dnskey.zone_key_flag = flags & DNSKEY_FLAG_ZONE_KEY;
1035         rr->dnskey.sep_flag = flags & DNSKEY_FLAG_SEP;
1036         return 0;
1037 }
1038
1039 int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, size_t *start) {
1040         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1041         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1042         size_t saved_rindex, offset;
1043         uint16_t rdlength;
1044         const void *d;
1045         int r;
1046
1047         assert(p);
1048         assert(ret);
1049
1050         saved_rindex = p->rindex;
1051
1052         r = dns_packet_read_key(p, &key, NULL);
1053         if (r < 0)
1054                 goto fail;
1055
1056         if (key->class == DNS_CLASS_ANY ||
1057             key->type == DNS_TYPE_ANY) {
1058                 r = -EBADMSG;
1059                 goto fail;
1060         }
1061
1062         rr = dns_resource_record_new(key);
1063         if (!rr) {
1064                 r = -ENOMEM;
1065                 goto fail;
1066         }
1067
1068         r = dns_packet_read_uint32(p, &rr->ttl, NULL);
1069         if (r < 0)
1070                 goto fail;
1071
1072         r = dns_packet_read_uint16(p, &rdlength, NULL);
1073         if (r < 0)
1074                 goto fail;
1075
1076         if (p->rindex + rdlength > p->size) {
1077                 r = -EBADMSG;
1078                 goto fail;
1079         }
1080
1081         offset = p->rindex;
1082
1083         switch (rr->key->type) {
1084
1085         case DNS_TYPE_SRV:
1086                 r = dns_packet_read_uint16(p, &rr->srv.priority, NULL);
1087                 if (r < 0)
1088                         goto fail;
1089                 r = dns_packet_read_uint16(p, &rr->srv.weight, NULL);
1090                 if (r < 0)
1091                         goto fail;
1092                 r = dns_packet_read_uint16(p, &rr->srv.port, NULL);
1093                 if (r < 0)
1094                         goto fail;
1095                 r = dns_packet_read_name(p, &rr->srv.name, true, NULL);
1096                 break;
1097
1098         case DNS_TYPE_PTR:
1099         case DNS_TYPE_NS:
1100         case DNS_TYPE_CNAME:
1101         case DNS_TYPE_DNAME:
1102                 r = dns_packet_read_name(p, &rr->ptr.name, true, NULL);
1103                 break;
1104
1105         case DNS_TYPE_HINFO:
1106                 r = dns_packet_read_string(p, &rr->hinfo.cpu, NULL);
1107                 if (r < 0)
1108                         goto fail;
1109
1110                 r = dns_packet_read_string(p, &rr->hinfo.os, NULL);
1111                 break;
1112
1113         case DNS_TYPE_SPF: /* exactly the same as TXT */
1114         case DNS_TYPE_TXT: {
1115                 char *s;
1116
1117                 /* RFC 1035 says that TXT must be at least one
1118                    string. Reject empty records. */
1119                 if (!rdlength) {
1120                         r = -EBADMSG;
1121                         goto fail;
1122                 }
1123
1124                 while (p->rindex < offset + rdlength) {
1125                         r = dns_packet_read_string(p, &s, NULL);
1126                         if (r < 0)
1127                                 goto fail;
1128
1129                         r = strv_consume(&rr->txt.strings, s);
1130                         if (r < 0)
1131                                 goto fail;
1132                 }
1133
1134                 r = 0;
1135                 break;
1136         }
1137
1138         case DNS_TYPE_A:
1139                 r = dns_packet_read_blob(p, &rr->a.in_addr, sizeof(struct in_addr), NULL);
1140                 break;
1141
1142         case DNS_TYPE_AAAA:
1143                 r = dns_packet_read_blob(p, &rr->aaaa.in6_addr, sizeof(struct in6_addr), NULL);
1144                 break;
1145
1146         case DNS_TYPE_SOA:
1147                 r = dns_packet_read_name(p, &rr->soa.mname, true, NULL);
1148                 if (r < 0)
1149                         goto fail;
1150
1151                 r = dns_packet_read_name(p, &rr->soa.rname, true, NULL);
1152                 if (r < 0)
1153                         goto fail;
1154
1155                 r = dns_packet_read_uint32(p, &rr->soa.serial, NULL);
1156                 if (r < 0)
1157                         goto fail;
1158
1159                 r = dns_packet_read_uint32(p, &rr->soa.refresh, NULL);
1160                 if (r < 0)
1161                         goto fail;
1162
1163                 r = dns_packet_read_uint32(p, &rr->soa.retry, NULL);
1164                 if (r < 0)
1165                         goto fail;
1166
1167                 r = dns_packet_read_uint32(p, &rr->soa.expire, NULL);
1168                 if (r < 0)
1169                         goto fail;
1170
1171                 r = dns_packet_read_uint32(p, &rr->soa.minimum, NULL);
1172                 break;
1173
1174         case DNS_TYPE_MX:
1175                 r = dns_packet_read_uint16(p, &rr->mx.priority, NULL);
1176                 if (r < 0)
1177                         goto fail;
1178
1179                 r = dns_packet_read_name(p, &rr->mx.exchange, true, NULL);
1180                 break;
1181
1182         case DNS_TYPE_LOC: {
1183                 uint8_t t;
1184                 size_t pos;
1185
1186                 r = dns_packet_read_uint8(p, &t, &pos);
1187                 if (r < 0)
1188                         goto fail;
1189
1190                 if (t == 0) {
1191                         rr->loc.version = t;
1192
1193                         r = dns_packet_read_uint8(p, &rr->loc.size, NULL);
1194                         if (r < 0)
1195                                 goto fail;
1196
1197                         if (!loc_size_ok(rr->loc.size)) {
1198                                 r = -EBADMSG;
1199                                 goto fail;
1200                         }
1201
1202                         r = dns_packet_read_uint8(p, &rr->loc.horiz_pre, NULL);
1203                         if (r < 0)
1204                                 goto fail;
1205
1206                         if (!loc_size_ok(rr->loc.horiz_pre)) {
1207                                 r = -EBADMSG;
1208                                 goto fail;
1209                         }
1210
1211                         r = dns_packet_read_uint8(p, &rr->loc.vert_pre, NULL);
1212                         if (r < 0)
1213                                 goto fail;
1214
1215                         if (!loc_size_ok(rr->loc.vert_pre)) {
1216                                 r = -EBADMSG;
1217                                 goto fail;
1218                         }
1219
1220                         r = dns_packet_read_uint32(p, &rr->loc.latitude, NULL);
1221                         if (r < 0)
1222                                 goto fail;
1223
1224                         r = dns_packet_read_uint32(p, &rr->loc.longitude, NULL);
1225                         if (r < 0)
1226                                 goto fail;
1227
1228                         r = dns_packet_read_uint32(p, &rr->loc.altitude, NULL);
1229                         if (r < 0)
1230                                 goto fail;
1231
1232                         break;
1233                 } else {
1234                         dns_packet_rewind(p, pos);
1235                         rr->unparseable = true;
1236                         goto unparseable;
1237                 }
1238         }
1239
1240         case DNS_TYPE_SSHFP:
1241                 r = dns_packet_read_uint8(p, &rr->sshfp.algorithm, NULL);
1242                 if (r < 0)
1243                         goto fail;
1244
1245                 r = dns_packet_read_uint8(p, &rr->sshfp.fptype, NULL);
1246                 if (r < 0)
1247                         goto fail;
1248
1249                 r = dns_packet_read_public_key(p, rdlength - 2,
1250                                                &rr->sshfp.key, &rr->sshfp.key_size,
1251                                                NULL);
1252                 break;
1253
1254         case DNS_TYPE_DNSKEY: {
1255                 uint16_t flags;
1256                 uint8_t proto;
1257
1258                 r = dns_packet_read_uint16(p, &flags, NULL);
1259                 if (r < 0)
1260                         goto fail;
1261
1262                 r = dnskey_parse_flags(rr, flags);
1263                 if (r < 0)
1264                         goto fail;
1265
1266                 r = dns_packet_read_uint8(p, &proto, NULL);
1267                 if (r < 0)
1268                         goto fail;
1269
1270                 /* protocol is required to be always 3 */
1271                 if (proto != 3) {
1272                         r = -EBADMSG;
1273                         goto fail;
1274                 }
1275
1276                 r = dns_packet_read_uint8(p, &rr->dnskey.algorithm, NULL);
1277                 if (r < 0)
1278                         goto fail;
1279
1280                 r = dns_packet_read_public_key(p, rdlength - 4,
1281                                                &rr->dnskey.key, &rr->dnskey.key_size,
1282                                                NULL);
1283                 break;
1284         }
1285
1286         case DNS_TYPE_RRSIG:
1287                 r = dns_packet_read_uint16(p, &rr->rrsig.type_covered, NULL);
1288                 if (r < 0)
1289                         goto fail;
1290
1291                 r = dns_packet_read_uint8(p, &rr->rrsig.algorithm, NULL);
1292                 if (r < 0)
1293                         goto fail;
1294
1295                 r = dns_packet_read_uint8(p, &rr->rrsig.labels, NULL);
1296                 if (r < 0)
1297                         goto fail;
1298
1299                 r = dns_packet_read_uint32(p, &rr->rrsig.original_ttl, NULL);
1300                 if (r < 0)
1301                         goto fail;
1302
1303                 r = dns_packet_read_uint32(p, &rr->rrsig.expiration, NULL);
1304                 if (r < 0)
1305                         goto fail;
1306
1307                 r = dns_packet_read_uint32(p, &rr->rrsig.inception, NULL);
1308                 if (r < 0)
1309                         goto fail;
1310
1311                 r = dns_packet_read_uint16(p, &rr->rrsig.key_tag, NULL);
1312                 if (r < 0)
1313                         goto fail;
1314
1315                 r = dns_packet_read_name(p, &rr->rrsig.signer, false, NULL);
1316                 if (r < 0)
1317                         goto fail;
1318
1319                 r = dns_packet_read_public_key(p, offset + rdlength - p->rindex,
1320                                                &rr->rrsig.signature, &rr->rrsig.signature_size,
1321                                                NULL);
1322                 break;
1323
1324         default:
1325         unparseable:
1326                 r = dns_packet_read(p, rdlength, &d, NULL);
1327                 if (r < 0)
1328                         goto fail;
1329
1330                 rr->generic.data = memdup(d, rdlength);
1331                 if (!rr->generic.data) {
1332                         r = -ENOMEM;
1333                         goto fail;
1334                 }
1335
1336                 rr->generic.size = rdlength;
1337                 break;
1338         }
1339         if (r < 0)
1340                 goto fail;
1341         if (p->rindex != offset + rdlength) {
1342                 r = -EBADMSG;
1343                 goto fail;
1344         }
1345
1346         *ret = rr;
1347         rr = NULL;
1348
1349         if (start)
1350                 *start = saved_rindex;
1351
1352         return 0;
1353 fail:
1354         dns_packet_rewind(p, saved_rindex);
1355         return r;
1356 }
1357
1358 int dns_packet_extract(DnsPacket *p) {
1359         _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
1360         _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
1361         size_t saved_rindex;
1362         unsigned n, i;
1363         int r;
1364
1365         if (p->extracted)
1366                 return 0;
1367
1368         saved_rindex = p->rindex;
1369         dns_packet_rewind(p, DNS_PACKET_HEADER_SIZE);
1370
1371         n = DNS_PACKET_QDCOUNT(p);
1372         if (n > 0) {
1373                 question = dns_question_new(n);
1374                 if (!question) {
1375                         r = -ENOMEM;
1376                         goto finish;
1377                 }
1378
1379                 for (i = 0; i < n; i++) {
1380                         _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
1381
1382                         r = dns_packet_read_key(p, &key, NULL);
1383                         if (r < 0)
1384                                 goto finish;
1385
1386                         r = dns_question_add(question, key);
1387                         if (r < 0)
1388                                 goto finish;
1389                 }
1390         }
1391
1392         n = DNS_PACKET_RRCOUNT(p);
1393         if (n > 0) {
1394                 answer = dns_answer_new(n);
1395                 if (!answer) {
1396                         r = -ENOMEM;
1397                         goto finish;
1398                 }
1399
1400                 for (i = 0; i < n; i++) {
1401                         _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
1402
1403                         r = dns_packet_read_rr(p, &rr, NULL);
1404                         if (r < 0)
1405                                 goto finish;
1406
1407                         r = dns_answer_add(answer, rr);
1408                         if (r < 0)
1409                                 goto finish;
1410                 }
1411         }
1412
1413         p->question = question;
1414         question = NULL;
1415
1416         p->answer = answer;
1417         answer = NULL;
1418
1419         p->extracted = true;
1420
1421         r = 0;
1422
1423 finish:
1424         p->rindex = saved_rindex;
1425         return r;
1426 }
1427
1428 static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
1429         [DNS_RCODE_SUCCESS] = "SUCCESS",
1430         [DNS_RCODE_FORMERR] = "FORMERR",
1431         [DNS_RCODE_SERVFAIL] = "SERVFAIL",
1432         [DNS_RCODE_NXDOMAIN] = "NXDOMAIN",
1433         [DNS_RCODE_NOTIMP] = "NOTIMP",
1434         [DNS_RCODE_REFUSED] = "REFUSED",
1435         [DNS_RCODE_YXDOMAIN] = "YXDOMAIN",
1436         [DNS_RCODE_YXRRSET] = "YRRSET",
1437         [DNS_RCODE_NXRRSET] = "NXRRSET",
1438         [DNS_RCODE_NOTAUTH] = "NOTAUTH",
1439         [DNS_RCODE_NOTZONE] = "NOTZONE",
1440         [DNS_RCODE_BADVERS] = "BADVERS",
1441         [DNS_RCODE_BADKEY] = "BADKEY",
1442         [DNS_RCODE_BADTIME] = "BADTIME",
1443         [DNS_RCODE_BADMODE] = "BADMODE",
1444         [DNS_RCODE_BADNAME] = "BADNAME",
1445         [DNS_RCODE_BADALG] = "BADALG",
1446         [DNS_RCODE_BADTRUNC] = "BADTRUNC",
1447 };
1448 DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
1449
1450 static const char* const dns_protocol_table[_DNS_PROTOCOL_MAX] = {
1451         [DNS_PROTOCOL_DNS] = "dns",
1452         [DNS_PROTOCOL_MDNS] = "mdns",
1453         [DNS_PROTOCOL_LLMNR] = "llmnr",
1454 };
1455 DEFINE_STRING_TABLE_LOOKUP(dns_protocol, DnsProtocol);
1456
1457 static const char* const dnssec_algorithm_table[_DNSSEC_ALGORITHM_MAX_DEFINED] = {
1458         [DNSSEC_ALGORITHM_RSAMD5]     = "RSAMD5",
1459         [DNSSEC_ALGORITHM_DH]         = "DH",
1460         [DNSSEC_ALGORITHM_DSA]        = "DSA",
1461         [DNSSEC_ALGORITHM_ECC]        = "ECC",
1462         [DNSSEC_ALGORITHM_RSASHA1]    = "RSASHA1",
1463         [DNSSEC_ALGORITHM_INDIRECT]   = "INDIRECT",
1464         [DNSSEC_ALGORITHM_PRIVATEDNS] = "PRIVATEDNS",
1465         [DNSSEC_ALGORITHM_PRIVATEOID] = "PRIVATEOID",
1466 };
1467 DEFINE_STRING_TABLE_LOOKUP(dnssec_algorithm, int);