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