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