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