File Coverage

src/ldns/packet.c
Criterion Covered Total %
statement 318 551 57.7
branch 45 162 27.7
condition n/a
subroutine n/a
pod n/a
total 363 713 50.9


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