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