]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ldns/packet.c
ifconfig(8): wordsmith -G and -g descriptions
[FreeBSD/FreeBSD.git] / contrib / ldns / packet.c
1 /*
2  * packet.c
3  *
4  * dns packet implementation
5  *
6  * a Net::DNS like library for C
7  *
8  * (c) NLnet Labs, 2004-2006
9  *
10  * See the file LICENSE for the license
11  */
12
13 #include <ldns/config.h>
14
15 #include <ldns/ldns.h>
16 #include <ldns/internal.h>
17
18 #include <strings.h>
19 #include <limits.h>
20
21 #ifdef HAVE_SSL
22 #include <openssl/rand.h>
23 #endif
24
25 /* Access functions 
26  * do this as functions to get type checking
27  */
28
29 #define LDNS_EDNS_MASK_DO_BIT 0x8000
30 #define LDNS_EDNS_MASK_UNASSIGNED (0xFFFF & ~LDNS_EDNS_MASK_DO_BIT)
31
32 /* TODO defines for 3600 */
33 /* convert to and from numerical flag values */
34 ldns_lookup_table ldns_edns_flags[] = {
35         { 3600, "do"},
36         { 0, NULL}
37 };
38
39 /* read */
40 uint16_t
41 ldns_pkt_id(const ldns_pkt *packet)
42 {
43         return packet->_header->_id;
44 }
45
46 bool
47 ldns_pkt_qr(const ldns_pkt *packet)
48 {
49         return packet->_header->_qr;
50 }
51
52 bool
53 ldns_pkt_aa(const ldns_pkt *packet)
54 {
55         return packet->_header->_aa;
56 }
57
58 bool
59 ldns_pkt_tc(const ldns_pkt *packet)
60 {
61         return packet->_header->_tc;
62 }
63
64 bool
65 ldns_pkt_rd(const ldns_pkt *packet)
66 {
67         return packet->_header->_rd;
68 }
69
70 bool
71 ldns_pkt_cd(const ldns_pkt *packet)
72 {
73         return packet->_header->_cd;
74 }
75
76 bool
77 ldns_pkt_ra(const ldns_pkt *packet)
78 {
79         return packet->_header->_ra;
80 }
81
82 bool
83 ldns_pkt_ad(const ldns_pkt *packet)
84 {
85         return packet->_header->_ad;
86 }
87
88 ldns_pkt_opcode
89 ldns_pkt_get_opcode(const ldns_pkt *packet)
90 {
91         return packet->_header->_opcode;
92 }
93
94 ldns_pkt_rcode
95 ldns_pkt_get_rcode(const ldns_pkt *packet)
96 {
97         return packet->_header->_rcode;
98 }
99
100 uint16_t
101 ldns_pkt_qdcount(const ldns_pkt *packet)
102 {
103         return packet->_header->_qdcount;
104 }
105
106 uint16_t
107 ldns_pkt_ancount(const ldns_pkt *packet)
108 {
109         return packet->_header->_ancount;
110 }
111
112 uint16_t
113 ldns_pkt_nscount(const ldns_pkt *packet)
114 {
115         return packet->_header->_nscount;
116 }
117
118 uint16_t
119 ldns_pkt_arcount(const ldns_pkt *packet)
120 {
121         return packet->_header->_arcount;
122 }
123
124 ldns_rr_list *
125 ldns_pkt_question(const ldns_pkt *packet)
126 {
127         return packet->_question;
128 }
129
130 ldns_rr_list *
131 ldns_pkt_answer(const ldns_pkt *packet)
132 {
133         return packet->_answer;
134 }
135
136 ldns_rr_list *
137 ldns_pkt_authority(const ldns_pkt *packet)
138 {
139         return packet->_authority;
140 }
141
142 ldns_rr_list *
143 ldns_pkt_additional(const ldns_pkt *packet)
144 {
145         return packet->_additional;
146 }
147
148 /* return ALL section concatenated */
149 ldns_rr_list *
150 ldns_pkt_all(const ldns_pkt *packet)
151 {
152         ldns_rr_list *all, *prev_all;
153
154         all = ldns_rr_list_cat_clone(
155                         ldns_pkt_question(packet),
156                         ldns_pkt_answer(packet));
157         prev_all = all;
158         all = ldns_rr_list_cat_clone(all,
159                         ldns_pkt_authority(packet));
160         ldns_rr_list_deep_free(prev_all);
161         prev_all = all;
162         all = ldns_rr_list_cat_clone(all,
163                         ldns_pkt_additional(packet));
164         ldns_rr_list_deep_free(prev_all);
165         return all;
166 }
167
168 ldns_rr_list *
169 ldns_pkt_all_noquestion(const ldns_pkt *packet)
170 {
171         ldns_rr_list *all, *all2;
172
173         all = ldns_rr_list_cat_clone(
174                         ldns_pkt_answer(packet),
175                         ldns_pkt_authority(packet));
176         all2 = ldns_rr_list_cat_clone(all,
177                         ldns_pkt_additional(packet));
178         
179         ldns_rr_list_deep_free(all);
180         return all2;
181 }
182
183 size_t
184 ldns_pkt_size(const ldns_pkt *packet)
185 {
186         return packet->_size;
187 }
188
189 uint32_t 
190 ldns_pkt_querytime(const ldns_pkt *packet)
191 {
192         return packet->_querytime;
193 }
194
195 ldns_rdf *
196 ldns_pkt_answerfrom(const ldns_pkt *packet)
197 {
198         return packet->_answerfrom;
199 }
200
201 struct timeval
202 ldns_pkt_timestamp(const ldns_pkt *packet)
203 {
204         return packet->timestamp;
205 }
206
207 uint16_t
208 ldns_pkt_edns_udp_size(const ldns_pkt *packet)
209 {
210         return packet->_edns_udp_size;
211 }
212
213 uint8_t
214 ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
215 {
216         return packet->_edns_extended_rcode;
217 }
218
219 uint8_t
220 ldns_pkt_edns_version(const ldns_pkt *packet)
221 {
222         return packet->_edns_version;
223 }
224
225 uint16_t
226 ldns_pkt_edns_z(const ldns_pkt *packet)
227 {
228         return packet->_edns_z;
229 }
230
231 bool
232 ldns_pkt_edns_do(const ldns_pkt *packet)
233 {
234         return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
235 }
236
237 void
238 ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
239 {
240         if (value) {
241                 packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
242         } else {
243                 packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT;
244         }
245 }
246
247 uint16_t
248 ldns_pkt_edns_unassigned(const ldns_pkt *packet)
249 {
250         return (packet->_edns_z & LDNS_EDNS_MASK_UNASSIGNED);
251 }
252
253 void
254 ldns_pkt_set_edns_unassigned(ldns_pkt *packet, uint16_t value)
255 {
256         packet->_edns_z = (packet->_edns_z & ~LDNS_EDNS_MASK_UNASSIGNED)
257                         | (value & LDNS_EDNS_MASK_UNASSIGNED);
258 }
259
260 ldns_rdf *
261 ldns_pkt_edns_data(const ldns_pkt *packet)
262 {
263         return packet->_edns_data;
264 }
265
266 /* return only those rr that share the ownername */
267 ldns_rr_list *
268 ldns_pkt_rr_list_by_name(const ldns_pkt *packet,
269                          const ldns_rdf *ownername,
270                          ldns_pkt_section sec)
271 {
272         ldns_rr_list *rrs;
273         ldns_rr_list *ret;
274         uint16_t i;
275
276         if (!packet) {
277                 return NULL;
278         }
279
280         rrs = ldns_pkt_get_section_clone(packet, sec);
281         ret = NULL;
282
283         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
284                 if (ldns_dname_compare(ldns_rr_owner(
285                                                 ldns_rr_list_rr(rrs, i)), 
286                                         ownername) == 0) {
287                         /* owner names match */
288                         if (ret == NULL) {
289                                 ret = ldns_rr_list_new();
290                         }
291                         ldns_rr_list_push_rr(ret,
292                                              ldns_rr_clone(
293                                                 ldns_rr_list_rr(rrs, i))
294                                             );
295                 }
296         }
297
298         ldns_rr_list_deep_free(rrs);
299
300         return ret;
301 }
302
303 /* return only those rr that share a type */
304 ldns_rr_list *
305 ldns_pkt_rr_list_by_type(const ldns_pkt *packet,
306                          ldns_rr_type type,
307                          ldns_pkt_section sec)
308 {
309         ldns_rr_list *rrs;
310         ldns_rr_list *new;
311         uint16_t i;
312
313         if(!packet) {
314                 return NULL;
315         }
316         
317         rrs = ldns_pkt_get_section_clone(packet, sec);
318         new = ldns_rr_list_new();
319         
320         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
321                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
322                         /* types match */
323                         ldns_rr_list_push_rr(new, 
324                                              ldns_rr_clone(
325                                                 ldns_rr_list_rr(rrs, i))
326                                              );
327                 }
328         }
329         ldns_rr_list_deep_free(rrs);
330
331         if (ldns_rr_list_rr_count(new) == 0) {
332                 ldns_rr_list_free(new);
333                 return NULL;
334         } else {
335                 return new;
336         }
337 }
338
339 /* return only those rrs that share name and type */
340 ldns_rr_list *
341 ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet,
342                                   const ldns_rdf *ownername,
343                                   ldns_rr_type type,
344                                   ldns_pkt_section sec)
345 {
346         ldns_rr_list *rrs;
347         ldns_rr_list *new;
348         ldns_rr_list *ret;
349         uint16_t i;
350
351         if(!packet) {
352                 return NULL;
353         }
354         
355         rrs = ldns_pkt_get_section_clone(packet, sec);
356         new = ldns_rr_list_new();
357         ret = NULL;
358
359         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
360                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
361                     ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
362                                      ownername
363                                     ) == 0
364                    ) {
365                         /* types match */
366                         ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
367                         ret = new;
368                 }
369         }
370         ldns_rr_list_deep_free(rrs);
371         if (!ret) {
372                 ldns_rr_list_free(new);
373         }
374         return ret;
375 }
376
377 bool
378 ldns_pkt_rr(const ldns_pkt *pkt, ldns_pkt_section sec, const ldns_rr *rr)
379 {
380         bool result = false;
381
382         switch (sec) {
383         case LDNS_SECTION_QUESTION:
384                 return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
385         case LDNS_SECTION_ANSWER:
386                 return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr);
387         case LDNS_SECTION_AUTHORITY:
388                 return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr);
389         case LDNS_SECTION_ADDITIONAL:
390                 return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
391         case LDNS_SECTION_ANY:
392                 result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
393                 /* fallthrough */
394         case LDNS_SECTION_ANY_NOQUESTION:
395                 result = result
396                     || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr)
397                     || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr)
398                     || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
399         }
400
401         return result;
402 }
403
404 uint16_t
405 ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
406 {
407         switch(s) {
408         case LDNS_SECTION_QUESTION:
409                 return ldns_pkt_qdcount(packet);
410         case LDNS_SECTION_ANSWER:
411                 return ldns_pkt_ancount(packet);
412         case LDNS_SECTION_AUTHORITY:
413                 return ldns_pkt_nscount(packet);
414         case LDNS_SECTION_ADDITIONAL:
415                 return ldns_pkt_arcount(packet);
416         case LDNS_SECTION_ANY:
417                 return ldns_pkt_qdcount(packet) +
418                         ldns_pkt_ancount(packet) +
419                         ldns_pkt_nscount(packet) +
420                         ldns_pkt_arcount(packet);
421         case LDNS_SECTION_ANY_NOQUESTION:
422                 return ldns_pkt_ancount(packet) +
423                         ldns_pkt_nscount(packet) +
424                         ldns_pkt_arcount(packet);
425         default:
426                 return 0;
427         }
428 }
429
430 bool
431 ldns_pkt_empty(ldns_pkt *p)
432 {
433         if (!p) {
434                 return true; /* NULL is empty? */
435         }
436         if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
437                 return false;
438         } else {
439                 return true;
440     }
441 }
442
443
444 ldns_rr_list *
445 ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s)
446 {
447         switch(s) {
448         case LDNS_SECTION_QUESTION:
449                 return ldns_rr_list_clone(ldns_pkt_question(packet));
450         case LDNS_SECTION_ANSWER:
451                 return ldns_rr_list_clone(ldns_pkt_answer(packet));
452         case LDNS_SECTION_AUTHORITY:
453                 return ldns_rr_list_clone(ldns_pkt_authority(packet));
454         case LDNS_SECTION_ADDITIONAL:
455                 return ldns_rr_list_clone(ldns_pkt_additional(packet));
456         case LDNS_SECTION_ANY:
457                 /* these are already clones */
458                 return ldns_pkt_all(packet);
459         case LDNS_SECTION_ANY_NOQUESTION:
460                 return ldns_pkt_all_noquestion(packet);
461         default:
462                 return NULL;
463         }
464 }
465
466 ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
467         return pkt->_tsig_rr;
468 }
469
470 /* write */
471 void
472 ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
473 {
474         packet->_header->_id = id;
475 }
476
477 void
478 ldns_pkt_set_random_id(ldns_pkt *packet)
479 {
480         uint16_t rid = ldns_get_random();
481         ldns_pkt_set_id(packet, rid);
482 }
483
484
485 void
486 ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
487 {
488         packet->_header->_qr = qr;
489 }
490
491 void
492 ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
493 {
494         packet->_header->_aa = aa;
495 }
496
497 void
498 ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
499 {
500         packet->_header->_tc = tc;
501 }
502
503 void
504 ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
505 {
506         packet->_header->_rd = rd;
507 }
508
509 void
510 ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
511 {
512         p->_additional = rr;
513 }
514
515 void
516 ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
517 {
518         p->_question = rr;
519 }
520
521 void
522 ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
523 {
524         p->_answer = rr;
525 }
526
527 void
528 ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
529 {
530         p->_authority = rr;
531 }
532
533 void
534 ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
535 {
536         packet->_header->_cd = cd;
537 }
538
539 void
540 ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
541 {
542         packet->_header->_ra = ra;
543 }
544
545 void
546 ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
547 {
548         packet->_header->_ad = ad;
549 }
550
551 void
552 ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
553 {
554         packet->_header->_opcode = opcode;
555 }
556
557 void
558 ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
559 {
560         packet->_header->_rcode = rcode;
561 }
562
563 void
564 ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
565 {
566         packet->_header->_qdcount = qdcount;
567 }
568
569 void
570 ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
571 {
572         packet->_header->_ancount = ancount;
573 }
574
575 void
576 ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
577 {
578         packet->_header->_nscount = nscount;
579 }
580
581 void
582 ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
583 {
584         packet->_header->_arcount = arcount;
585 }
586
587 void
588 ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 
589 {
590         packet->_querytime = time;
591 }
592
593 void
594 ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
595 {
596         packet->_answerfrom = answerfrom;
597 }
598
599 void
600 ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
601 {
602         packet->timestamp.tv_sec = timeval.tv_sec;
603         packet->timestamp.tv_usec = timeval.tv_usec;
604 }
605
606 void
607 ldns_pkt_set_size(ldns_pkt *packet, size_t s)
608 {
609         packet->_size = s;
610 }
611
612 void
613 ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
614 {
615         packet->_edns_udp_size = s;
616 }
617
618 void
619 ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
620 {
621         packet->_edns_extended_rcode = c;
622 }
623
624 void
625 ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
626 {
627         packet->_edns_version = v;
628 }
629
630 void
631 ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
632 {
633         packet->_edns_z = z;
634 }
635
636 void
637 ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
638 {
639         packet->_edns_data = data;
640 }
641
642 void
643 ldns_pkt_set_edns_option_list(ldns_pkt *packet, ldns_edns_option_list *list)
644 {
645         if (packet->_edns_list)
646                 ldns_edns_option_list_deep_free(packet->_edns_list);
647         packet->_edns_list = list;
648 }
649
650
651 void
652 ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
653 {
654         switch(s) {
655                 case LDNS_SECTION_QUESTION:
656                         ldns_pkt_set_qdcount(packet, count);
657                         break;
658                 case LDNS_SECTION_ANSWER:
659                         ldns_pkt_set_ancount(packet, count);
660                         break;
661                 case LDNS_SECTION_AUTHORITY:
662                         ldns_pkt_set_nscount(packet, count);
663                         break;
664                 case LDNS_SECTION_ADDITIONAL:
665                         ldns_pkt_set_arcount(packet, count);
666                         break;
667                 case LDNS_SECTION_ANY:
668                 case LDNS_SECTION_ANY_NOQUESTION:
669                         break;
670         }
671 }
672
673 void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
674 {
675         pkt->_tsig_rr = rr;
676 }
677
678 bool
679 ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
680 {
681         switch(section) {
682                 case LDNS_SECTION_QUESTION:
683                         if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
684                                 return false;
685                         }
686                         ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
687                         break;
688                 case LDNS_SECTION_ANSWER:
689                         if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
690                                 return false;
691                         }
692                         ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
693                         break;
694                 case LDNS_SECTION_AUTHORITY:
695                         if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
696                                 return false;
697                         }
698                         ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
699                         break;
700                 case LDNS_SECTION_ADDITIONAL:
701                         if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
702                                 return false;
703                         }
704                         ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
705                         break;
706                 case LDNS_SECTION_ANY:
707                 case LDNS_SECTION_ANY_NOQUESTION:
708                         /* shouldn't this error? */
709                         break;
710         }
711         return true;
712 }
713
714 bool
715 ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
716 {
717
718         /* check to see if its there */
719         if (ldns_pkt_rr(pkt, sec, rr)) {
720                 /* already there */
721                 return false;
722         }
723         return ldns_pkt_push_rr(pkt, sec, rr);
724 }
725
726 bool
727 ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
728 {
729         size_t i;
730         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
731                 if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
732                         return false;
733                 }
734         }
735         return true;
736 }
737
738 bool
739 ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
740 {
741         size_t i;
742         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
743                 if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
744                         return false;
745                 }
746         }
747         return true;
748 }
749
750 bool
751 ldns_pkt_edns(const ldns_pkt *pkt)
752 {
753         return (ldns_pkt_edns_udp_size(pkt) > 0 ||
754                 ldns_pkt_edns_extended_rcode(pkt) > 0 ||
755                 ldns_pkt_edns_data(pkt) ||
756                 ldns_pkt_edns_do(pkt) ||
757                 pkt->_edns_list ||
758                 pkt->_edns_present
759                );
760 }
761
762 ldns_edns_option_list*
763 pkt_edns_data2edns_option_list(const ldns_rdf *edns_data)
764 {
765         size_t pos = 0;
766         ldns_edns_option_list* edns_list;
767         size_t max;
768         const uint8_t* wire;
769
770         if (!edns_data)
771                 return NULL;
772
773         max = ldns_rdf_size(edns_data);
774         wire = ldns_rdf_data(edns_data);
775         if (!max)
776                 return NULL;
777
778         if (!(edns_list = ldns_edns_option_list_new()))
779                 return NULL;
780
781         while (pos < max) {
782                 ldns_edns_option* edns;
783                 uint8_t *data;
784
785                 if (pos + 4 > max) { /* make sure the header is  */
786                         ldns_edns_option_list_deep_free(edns_list);
787                         return NULL;
788                 }
789                 ldns_edns_option_code code = ldns_read_uint16(&wire[pos]);
790                 size_t size = ldns_read_uint16(&wire[pos+2]);
791                 pos += 4;
792
793                 if (pos + size > max) { /* make sure the size fits the data */
794                         ldns_edns_option_list_deep_free(edns_list);
795                         return NULL;
796                 }
797                 data = LDNS_XMALLOC(uint8_t, size);
798
799                 if (!data) {
800                         ldns_edns_option_list_deep_free(edns_list);
801                         return NULL;
802                 }
803                 memcpy(data, &wire[pos], size);
804                 pos += size;
805
806                 edns = ldns_edns_new(code, size, data);
807
808                 if (!edns) {
809                         ldns_edns_option_list_deep_free(edns_list);
810                         return NULL;
811                 }
812                 if (!ldns_edns_option_list_push(edns_list, edns)) {
813                         ldns_edns_option_list_deep_free(edns_list);
814                         return NULL;
815                 }
816         }
817         return edns_list;
818
819 }
820
821 ldns_edns_option_list*
822 ldns_pkt_edns_get_option_list(ldns_pkt *packet)
823 {
824         /* return the list if it already exists */
825         if (packet->_edns_list != NULL)
826                 return packet->_edns_list;
827
828         /* if the list doesn't exists, we create it by parsing the
829          * packet->_edns_data
830          */
831         if (!ldns_pkt_edns_data(packet))
832                 return NULL;
833
834         return ( packet->_edns_list
835                = pkt_edns_data2edns_option_list(ldns_pkt_edns_data(packet)));
836 }
837
838
839 /* Create/destroy/convert functions
840  */
841 ldns_pkt *
842 ldns_pkt_new(void)
843 {
844         ldns_pkt *packet;
845         packet = LDNS_MALLOC(ldns_pkt);
846         if (!packet) {
847                 return NULL;
848         }
849
850         packet->_header = LDNS_MALLOC(ldns_hdr);
851         if (!packet->_header) {
852                 LDNS_FREE(packet);
853                 return NULL;
854         }
855
856         packet->_question = ldns_rr_list_new();
857         packet->_answer = ldns_rr_list_new();
858         packet->_authority = ldns_rr_list_new();
859         packet->_additional = ldns_rr_list_new();
860
861         /* default everything to false */
862         ldns_pkt_set_qr(packet, false);
863         ldns_pkt_set_aa(packet, false);
864         ldns_pkt_set_tc(packet, false);
865         ldns_pkt_set_rd(packet, false);
866         ldns_pkt_set_ra(packet, false);
867         ldns_pkt_set_ad(packet, false);
868         ldns_pkt_set_cd(packet, false);
869
870         ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
871         ldns_pkt_set_rcode(packet, 0);
872         ldns_pkt_set_id(packet, 0); 
873         ldns_pkt_set_size(packet, 0);
874         ldns_pkt_set_querytime(packet, 0);
875         memset(&packet->timestamp, 0, sizeof(packet->timestamp));
876         ldns_pkt_set_answerfrom(packet, NULL);
877         ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
878         ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
879         ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
880         ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
881         
882         ldns_pkt_set_edns_udp_size(packet, 0);
883         ldns_pkt_set_edns_extended_rcode(packet, 0);
884         ldns_pkt_set_edns_version(packet, 0);
885         ldns_pkt_set_edns_z(packet, 0);
886         ldns_pkt_set_edns_data(packet, NULL);
887         packet->_edns_list = NULL;
888         packet->_edns_present = false;
889
890         ldns_pkt_set_tsig(packet, NULL);
891         
892         return packet;
893 }
894
895 void
896 ldns_pkt_free(ldns_pkt *packet)
897 {
898         if (packet) {
899                 LDNS_FREE(packet->_header);
900                 ldns_rr_list_deep_free(packet->_question);
901                 ldns_rr_list_deep_free(packet->_answer);
902                 ldns_rr_list_deep_free(packet->_authority);
903                 ldns_rr_list_deep_free(packet->_additional);
904                 ldns_rr_free(packet->_tsig_rr);
905                 ldns_rdf_deep_free(packet->_edns_data);
906                 ldns_edns_option_list_deep_free(packet->_edns_list);
907                 ldns_rdf_deep_free(packet->_answerfrom);
908                 LDNS_FREE(packet);
909         }
910 }
911
912 bool
913 ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
914 {
915         if (!packet) {
916                 return false;
917         }
918         if ((flags & LDNS_QR) == LDNS_QR) {
919                 ldns_pkt_set_qr(packet, true);
920         }
921         if ((flags & LDNS_AA) == LDNS_AA) {
922                 ldns_pkt_set_aa(packet, true);
923         }
924         if ((flags & LDNS_RD) == LDNS_RD) {
925                 ldns_pkt_set_rd(packet, true);
926         }
927         if ((flags & LDNS_TC) == LDNS_TC) {
928                 ldns_pkt_set_tc(packet, true);
929         }
930         if ((flags & LDNS_CD) == LDNS_CD) {
931                 ldns_pkt_set_cd(packet, true);
932         }
933         if ((flags & LDNS_RA) == LDNS_RA) {
934                 ldns_pkt_set_ra(packet, true);
935         }
936         if ((flags & LDNS_AD) == LDNS_AD) {
937                 ldns_pkt_set_ad(packet, true);
938         }
939         return true;
940 }
941
942
943 static ldns_rr*
944 ldns_pkt_authsoa(const ldns_rdf* rr_name, ldns_rr_class rr_class)
945 {
946         ldns_rr* soa_rr = ldns_rr_new();
947         ldns_rdf *owner_rdf;
948         ldns_rdf *mname_rdf;
949         ldns_rdf *rname_rdf;
950         ldns_rdf *serial_rdf;
951         ldns_rdf *refresh_rdf;
952         ldns_rdf *retry_rdf;
953         ldns_rdf *expire_rdf;
954         ldns_rdf *minimum_rdf;
955
956         if (!soa_rr) {
957                 return NULL;
958         }
959         owner_rdf = ldns_rdf_clone(rr_name);
960         if (!owner_rdf) {
961                 ldns_rr_free(soa_rr);
962                 return NULL;
963         }
964
965         ldns_rr_set_owner(soa_rr, owner_rdf);
966         ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
967         ldns_rr_set_class(soa_rr, rr_class);
968         ldns_rr_set_question(soa_rr, false);
969
970         if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
971                 ldns_rr_free(soa_rr);
972                 return NULL;
973         } else {
974                 ldns_rr_push_rdf(soa_rr, mname_rdf);
975         }
976         if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
977                 ldns_rr_free(soa_rr);
978                 return NULL;
979         } else {
980                 ldns_rr_push_rdf(soa_rr, rname_rdf);
981         }
982         serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
983         if (!serial_rdf) {
984                 ldns_rr_free(soa_rr);
985                 return NULL;
986         } else {
987                 ldns_rr_push_rdf(soa_rr, serial_rdf);
988         }
989         refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
990         if (!refresh_rdf) {
991                 ldns_rr_free(soa_rr);
992                 return NULL;
993         } else {
994                 ldns_rr_push_rdf(soa_rr, refresh_rdf);
995         }
996         retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
997         if (!retry_rdf) {
998                 ldns_rr_free(soa_rr);
999                 return NULL;
1000         } else {
1001                 ldns_rr_push_rdf(soa_rr, retry_rdf);
1002         }
1003         expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1004         if (!expire_rdf) {
1005                 ldns_rr_free(soa_rr);
1006                 return NULL;
1007         } else {
1008                 ldns_rr_push_rdf(soa_rr, expire_rdf);
1009         }
1010         minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1011         if (!minimum_rdf) {
1012                 ldns_rr_free(soa_rr);
1013                 return NULL;
1014         } else {
1015                 ldns_rr_push_rdf(soa_rr, minimum_rdf);
1016         }
1017         return soa_rr;
1018 }
1019
1020
1021 static ldns_status
1022 ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name,
1023         ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags,
1024         ldns_rr* authsoa_rr)
1025 {
1026         ldns_pkt *packet;
1027         ldns_rr *question_rr;
1028         ldns_rdf *name_rdf;
1029
1030         packet = ldns_pkt_new();
1031         if (!packet) {
1032                 return LDNS_STATUS_MEM_ERR;
1033         }
1034
1035         if (!ldns_pkt_set_flags(packet, flags)) {
1036                 ldns_pkt_free(packet);
1037                 return LDNS_STATUS_ERR;
1038         }
1039
1040         question_rr = ldns_rr_new();
1041         if (!question_rr) {
1042                 ldns_pkt_free(packet);
1043                 return LDNS_STATUS_MEM_ERR;
1044         }
1045
1046         if (rr_type == 0) {
1047                 rr_type = LDNS_RR_TYPE_A;
1048         }
1049         if (rr_class == 0) {
1050                 rr_class = LDNS_RR_CLASS_IN;
1051         }
1052
1053         if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
1054                 ldns_rr_set_owner(question_rr, name_rdf);
1055                 ldns_rr_set_type(question_rr, rr_type);
1056                 ldns_rr_set_class(question_rr, rr_class);
1057                 ldns_rr_set_question(question_rr, true);
1058
1059                 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
1060         } else {
1061                 ldns_rr_free(question_rr);
1062                 ldns_pkt_free(packet);
1063                 return LDNS_STATUS_ERR;
1064         }
1065
1066         if (authsoa_rr) {
1067                 ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
1068         }
1069
1070         packet->_tsig_rr = NULL;
1071         ldns_pkt_set_answerfrom(packet, NULL);
1072         if (p) {
1073                 *p = packet;
1074                 return LDNS_STATUS_OK;
1075         } else {
1076                 ldns_pkt_free(packet);
1077                 return LDNS_STATUS_NULL;
1078         }
1079 }
1080
1081 ldns_status
1082 ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name,
1083         ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
1084 {
1085         return ldns_pkt_query_new_frm_str_internal(p, name, rr_type,
1086                 rr_class, flags, NULL);
1087 }
1088
1089 ldns_status
1090 ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name,
1091         ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
1092 {
1093         ldns_rr* authsoa_rr = soa;
1094         if (!authsoa_rr) {
1095                 ldns_rdf *name_rdf;
1096                 if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
1097                         authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class);
1098                 }
1099                 ldns_rdf_free(name_rdf);
1100         }
1101         return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR,
1102                 rr_class, flags, authsoa_rr);
1103 }
1104
1105 static ldns_pkt *
1106 ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type,
1107         ldns_rr_class rr_class, uint16_t flags, ldns_rr* authsoa_rr)
1108 {
1109         ldns_pkt *packet;
1110         ldns_rr *question_rr;
1111
1112         packet = ldns_pkt_new();
1113         if (!packet) {
1114                 return NULL;
1115         }
1116
1117         if (!ldns_pkt_set_flags(packet, flags)) {
1118                 return NULL;
1119         }
1120
1121         question_rr = ldns_rr_new();
1122         if (!question_rr) {
1123                 ldns_pkt_free(packet);
1124                 return NULL;
1125         }
1126
1127         if (rr_type == 0) {
1128                 rr_type = LDNS_RR_TYPE_A;
1129         }
1130         if (rr_class == 0) {
1131                 rr_class = LDNS_RR_CLASS_IN;
1132         }
1133
1134         ldns_rr_set_owner(question_rr, rr_name);
1135         ldns_rr_set_type(question_rr, rr_type);
1136         ldns_rr_set_class(question_rr, rr_class);
1137         ldns_rr_set_question(question_rr, true);
1138         ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
1139
1140         if (authsoa_rr) {
1141                 ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
1142         }
1143
1144         packet->_tsig_rr = NULL;
1145         return packet;
1146 }
1147
1148 ldns_pkt *
1149 ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type,
1150         ldns_rr_class rr_class, uint16_t flags)
1151 {
1152         return ldns_pkt_query_new_internal(rr_name, rr_type,
1153                 rr_class, flags, NULL);
1154 }
1155
1156 ldns_pkt *
1157 ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class,
1158         uint16_t flags, ldns_rr* soa)
1159 {
1160         ldns_rr* authsoa_rr = soa;
1161         if (!authsoa_rr) {
1162                 authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class);
1163         }
1164         return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR,
1165                 rr_class, flags, authsoa_rr);
1166 }
1167
1168 ldns_pkt_type
1169 ldns_pkt_reply_type(const ldns_pkt *p)
1170 {
1171         ldns_rr_list *tmp;
1172
1173         if (!p) {
1174                 return LDNS_PACKET_UNKNOWN;
1175         }
1176
1177         if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
1178                 return LDNS_PACKET_NXDOMAIN;
1179         }
1180
1181         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
1182                         && ldns_pkt_nscount(p) == 1) {
1183
1184                 /* check for SOA */
1185                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 
1186                                         LDNS_SECTION_AUTHORITY);
1187                 if (tmp) {
1188                         ldns_rr_list_deep_free(tmp);
1189                         return LDNS_PACKET_NODATA;
1190                 } else {
1191                         /* I have no idea ... */
1192                 }
1193         }
1194
1195         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
1196                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
1197                                                LDNS_SECTION_AUTHORITY);
1198                 if (tmp) {
1199                         /* there are nameservers here */
1200                         ldns_rr_list_deep_free(tmp);
1201                         return LDNS_PACKET_REFERRAL;
1202                 } else {
1203                         /* I have no idea */
1204                 }
1205                 ldns_rr_list_deep_free(tmp);
1206         }
1207         
1208         /* if we cannot determine the packet type, we say it's an 
1209          * answer...
1210          */
1211         return LDNS_PACKET_ANSWER;
1212 }
1213
1214 ldns_pkt *
1215 ldns_pkt_clone(const ldns_pkt *pkt)
1216 {
1217         ldns_pkt *new_pkt;
1218         
1219         if (!pkt) {
1220                 return NULL;
1221         }
1222         new_pkt = ldns_pkt_new();
1223
1224         ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
1225         ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
1226         ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
1227         ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
1228         ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
1229         ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
1230         ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
1231         ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
1232         ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
1233         ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
1234         ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
1235         ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
1236         ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
1237         ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
1238         if (ldns_pkt_answerfrom(pkt))
1239                 ldns_pkt_set_answerfrom(new_pkt,
1240                         ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
1241         ldns_pkt_set_timestamp(new_pkt, ldns_pkt_timestamp(pkt));
1242         ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
1243         ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
1244         ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
1245         
1246         ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
1247         ldns_pkt_set_edns_extended_rcode(new_pkt, 
1248                 ldns_pkt_edns_extended_rcode(pkt));
1249         ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt));
1250         new_pkt->_edns_present = pkt->_edns_present;
1251         ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt));
1252         if(ldns_pkt_edns_data(pkt))
1253                 ldns_pkt_set_edns_data(new_pkt, 
1254                         ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
1255         ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
1256         if (pkt->_edns_list)
1257                 ldns_pkt_set_edns_option_list(new_pkt,
1258                         ldns_edns_option_list_clone(pkt->_edns_list));
1259
1260         ldns_rr_list_deep_free(new_pkt->_question);
1261         ldns_rr_list_deep_free(new_pkt->_answer);
1262         ldns_rr_list_deep_free(new_pkt->_authority);
1263         ldns_rr_list_deep_free(new_pkt->_additional);
1264         new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
1265         new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
1266         new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
1267         new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
1268         return new_pkt;
1269 }