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