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