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 */ 34ldns_lookup_table ldns_edns_flags[] = { 35 { 3600, "do"}, 36 { 0, NULL} 37}; 38 39/* read */ 40uint16_t 41ldns_pkt_id(const ldns_pkt *packet) 42{ 43 return packet->_header->_id; 44} 45 46bool 47ldns_pkt_qr(const ldns_pkt *packet) 48{ 49 return packet->_header->_qr; 50} 51 52bool 53ldns_pkt_aa(const ldns_pkt *packet) 54{ 55 return packet->_header->_aa; 56} 57 58bool 59ldns_pkt_tc(const ldns_pkt *packet) 60{ 61 return packet->_header->_tc; 62} 63 64bool 65ldns_pkt_rd(const ldns_pkt *packet) 66{ 67 return packet->_header->_rd; 68} 69 70bool 71ldns_pkt_cd(const ldns_pkt *packet) 72{ 73 return packet->_header->_cd; 74} 75 76bool 77ldns_pkt_ra(const ldns_pkt *packet) 78{ 79 return packet->_header->_ra; 80} 81 82bool 83ldns_pkt_ad(const ldns_pkt *packet) 84{ 85 return packet->_header->_ad; 86} 87 88ldns_pkt_opcode 89ldns_pkt_get_opcode(const ldns_pkt *packet) 90{ 91 return packet->_header->_opcode; 92} 93 94ldns_pkt_rcode 95ldns_pkt_get_rcode(const ldns_pkt *packet) 96{ 97 return packet->_header->_rcode; 98} 99 100uint16_t 101ldns_pkt_qdcount(const ldns_pkt *packet) 102{ 103 return packet->_header->_qdcount; 104} 105 106uint16_t 107ldns_pkt_ancount(const ldns_pkt *packet) 108{ 109 return packet->_header->_ancount; 110} 111 112uint16_t 113ldns_pkt_nscount(const ldns_pkt *packet) 114{ 115 return packet->_header->_nscount; 116} 117 118uint16_t 119ldns_pkt_arcount(const ldns_pkt *packet) 120{ 121 return packet->_header->_arcount; 122} 123 124ldns_rr_list * 125ldns_pkt_question(const ldns_pkt *packet) 126{ 127 return packet->_question; 128} 129 130ldns_rr_list * 131ldns_pkt_answer(const ldns_pkt *packet) 132{ 133 return packet->_answer; 134} 135 136ldns_rr_list * 137ldns_pkt_authority(const ldns_pkt *packet) 138{ 139 return packet->_authority; 140} 141 142ldns_rr_list * 143ldns_pkt_additional(const ldns_pkt *packet) 144{ 145 return packet->_additional; 146} 147 148/* return ALL section concatenated */ 149ldns_rr_list * 150ldns_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 168ldns_rr_list * 169ldns_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 183size_t 184ldns_pkt_size(const ldns_pkt *packet) 185{ 186 return packet->_size; 187} 188 189uint32_t 190ldns_pkt_querytime(const ldns_pkt *packet) 191{ 192 return packet->_querytime; 193} 194 195ldns_rdf * 196ldns_pkt_answerfrom(const ldns_pkt *packet) 197{ 198 return packet->_answerfrom; 199} 200 201struct timeval 202ldns_pkt_timestamp(const ldns_pkt *packet) 203{ 204 return packet->timestamp; 205} 206 207uint16_t 208ldns_pkt_edns_udp_size(const ldns_pkt *packet) 209{ 210 return packet->_edns_udp_size; 211} 212 213uint8_t 214ldns_pkt_edns_extended_rcode(const ldns_pkt *packet) 215{ 216 return packet->_edns_extended_rcode; 217} 218 219uint8_t 220ldns_pkt_edns_version(const ldns_pkt *packet) 221{ 222 return packet->_edns_version; 223} 224 225uint16_t 226ldns_pkt_edns_z(const ldns_pkt *packet) 227{ 228 return packet->_edns_z; 229} 230 231bool 232ldns_pkt_edns_do(const ldns_pkt *packet) 233{ 234 return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT); 235} 236 237void 238ldns_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 247uint16_t 248ldns_pkt_edns_unassigned(const ldns_pkt *packet) 249{ 250 return (packet->_edns_z & LDNS_EDNS_MASK_UNASSIGNED); 251} 252 253void 254ldns_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 260ldns_rdf * 261ldns_pkt_edns_data(const ldns_pkt *packet) 262{ 263 return packet->_edns_data; 264} 265 266/* return only those rr that share the ownername */ 267ldns_rr_list * 268ldns_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 */ 304ldns_rr_list * 305ldns_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 */ 340ldns_rr_list * 341ldns_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 377bool 378ldns_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 404uint16_t 405ldns_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 430bool 431ldns_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 444ldns_rr_list * 445ldns_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 466ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) { 467 return pkt->_tsig_rr; 468} 469 470/* write */ 471void 472ldns_pkt_set_id(ldns_pkt *packet, uint16_t id) 473{ 474 packet->_header->_id = id; 475} 476 477void 478ldns_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 485void 486ldns_pkt_set_qr(ldns_pkt *packet, bool qr) 487{ 488 packet->_header->_qr = qr; 489} 490 491void 492ldns_pkt_set_aa(ldns_pkt *packet, bool aa) 493{ 494 packet->_header->_aa = aa; 495} 496 497void 498ldns_pkt_set_tc(ldns_pkt *packet, bool tc) 499{ 500 packet->_header->_tc = tc; 501} 502 503void 504ldns_pkt_set_rd(ldns_pkt *packet, bool rd) 505{ 506 packet->_header->_rd = rd; 507} 508 509void 510ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr) 511{ 512 p->_additional = rr; 513} 514 515void 516ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr) 517{ 518 p->_question = rr; 519} 520 521void 522ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr) 523{ 524 p->_answer = rr; 525} 526 527void 528ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr) 529{ 530 p->_authority = rr; 531} 532 533void 534ldns_pkt_set_cd(ldns_pkt *packet, bool cd) 535{ 536 packet->_header->_cd = cd; 537} 538 539void 540ldns_pkt_set_ra(ldns_pkt *packet, bool ra) 541{ 542 packet->_header->_ra = ra; 543} 544 545void 546ldns_pkt_set_ad(ldns_pkt *packet, bool ad) 547{ 548 packet->_header->_ad = ad; 549} 550 551void 552ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode) 553{ 554 packet->_header->_opcode = opcode; 555} 556 557void 558ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode) 559{ 560 packet->_header->_rcode = rcode; 561} 562 563void 564ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount) 565{ 566 packet->_header->_qdcount = qdcount; 567} 568 569void 570ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount) 571{ 572 packet->_header->_ancount = ancount; 573} 574 575void 576ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount) 577{ 578 packet->_header->_nscount = nscount; 579} 580 581void 582ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount) 583{ 584 packet->_header->_arcount = arcount; 585} 586 587void 588ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 589{ 590 packet->_querytime = time; 591} 592 593void 594ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom) 595{ 596 packet->_answerfrom = answerfrom; 597} 598 599void 600ldns_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 606void 607ldns_pkt_set_size(ldns_pkt *packet, size_t s) 608{ 609 packet->_size = s; 610} 611 612void 613ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s) 614{ 615 packet->_edns_udp_size = s; 616} 617 618void 619ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c) 620{ 621 packet->_edns_extended_rcode = c; 622} 623 624void 625ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v) 626{ 627 packet->_edns_version = v; 628} 629 630void 631ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z) 632{ 633 packet->_edns_z = z; 634} 635 636void 637ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data) 638{ 639 packet->_edns_data = data; 640} 641 642void 643ldns_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 651void 652ldns_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 673void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr) 674{ 675 pkt->_tsig_rr = rr; 676} 677 678bool 679ldns_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 714bool 715ldns_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 726bool 727ldns_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 738bool 739ldns_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 750bool 751ldns_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 762ldns_edns_option_list* 763pkt_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 821ldns_edns_option_list* 822ldns_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 */ 841ldns_pkt * 842ldns_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 895void 896ldns_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 912bool 913ldns_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 943static ldns_rr* 944ldns_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 1021static ldns_status 1022ldns_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 1081ldns_status 1082ldns_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 1089ldns_status 1090ldns_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 1105static ldns_pkt * 1106ldns_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 1148ldns_pkt * 1149ldns_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 1156ldns_pkt * 1157ldns_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 1168ldns_pkt_type 1169ldns_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 1214ldns_pkt * 1215ldns_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