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