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