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