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 */ 32 ldns_lookup_table ldns_edns_flags[] = { 33 { 3600, "do"}, 34 { 0, NULL} 35 }; 36 37 /* read */ 38 uint16_t 39 ldns_pkt_id(const ldns_pkt *packet) 40 { 41 return packet->_header->_id; 42 } 43 44 bool 45 ldns_pkt_qr(const ldns_pkt *packet) 46 { 47 return packet->_header->_qr; 48 } 49 50 bool 51 ldns_pkt_aa(const ldns_pkt *packet) 52 { 53 return packet->_header->_aa; 54 } 55 56 bool 57 ldns_pkt_tc(const ldns_pkt *packet) 58 { 59 return packet->_header->_tc; 60 } 61 62 bool 63 ldns_pkt_rd(const ldns_pkt *packet) 64 { 65 return packet->_header->_rd; 66 } 67 68 bool 69 ldns_pkt_cd(const ldns_pkt *packet) 70 { 71 return packet->_header->_cd; 72 } 73 74 bool 75 ldns_pkt_ra(const ldns_pkt *packet) 76 { 77 return packet->_header->_ra; 78 } 79 80 bool 81 ldns_pkt_ad(const ldns_pkt *packet) 82 { 83 return packet->_header->_ad; 84 } 85 86 ldns_pkt_opcode 87 ldns_pkt_get_opcode(const ldns_pkt *packet) 88 { 89 return packet->_header->_opcode; 90 } 91 92 ldns_pkt_rcode 93 ldns_pkt_get_rcode(const ldns_pkt *packet) 94 { 95 return packet->_header->_rcode; 96 } 97 98 uint16_t 99 ldns_pkt_qdcount(const ldns_pkt *packet) 100 { 101 return packet->_header->_qdcount; 102 } 103 104 uint16_t 105 ldns_pkt_ancount(const ldns_pkt *packet) 106 { 107 return packet->_header->_ancount; 108 } 109 110 uint16_t 111 ldns_pkt_nscount(const ldns_pkt *packet) 112 { 113 return packet->_header->_nscount; 114 } 115 116 uint16_t 117 ldns_pkt_arcount(const ldns_pkt *packet) 118 { 119 return packet->_header->_arcount; 120 } 121 122 ldns_rr_list * 123 ldns_pkt_question(const ldns_pkt *packet) 124 { 125 return packet->_question; 126 } 127 128 ldns_rr_list * 129 ldns_pkt_answer(const ldns_pkt *packet) 130 { 131 return packet->_answer; 132 } 133 134 ldns_rr_list * 135 ldns_pkt_authority(const ldns_pkt *packet) 136 { 137 return packet->_authority; 138 } 139 140 ldns_rr_list * 141 ldns_pkt_additional(const ldns_pkt *packet) 142 { 143 return packet->_additional; 144 } 145 146 /* return ALL section concatenated */ 147 ldns_rr_list * 148 ldns_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 166 ldns_rr_list * 167 ldns_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 181 size_t 182 ldns_pkt_size(const ldns_pkt *packet) 183 { 184 return packet->_size; 185 } 186 187 uint32_t 188 ldns_pkt_querytime(const ldns_pkt *packet) 189 { 190 return packet->_querytime; 191 } 192 193 ldns_rdf * 194 ldns_pkt_answerfrom(const ldns_pkt *packet) 195 { 196 return packet->_answerfrom; 197 } 198 199 struct timeval 200 ldns_pkt_timestamp(const ldns_pkt *packet) 201 { 202 return packet->timestamp; 203 } 204 205 uint16_t 206 ldns_pkt_edns_udp_size(const ldns_pkt *packet) 207 { 208 return packet->_edns_udp_size; 209 } 210 211 uint8_t 212 ldns_pkt_edns_extended_rcode(const ldns_pkt *packet) 213 { 214 return packet->_edns_extended_rcode; 215 } 216 217 uint8_t 218 ldns_pkt_edns_version(const ldns_pkt *packet) 219 { 220 return packet->_edns_version; 221 } 222 223 uint16_t 224 ldns_pkt_edns_z(const ldns_pkt *packet) 225 { 226 return packet->_edns_z; 227 } 228 229 bool 230 ldns_pkt_edns_do(const ldns_pkt *packet) 231 { 232 return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT); 233 } 234 235 void 236 ldns_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 245 ldns_rdf * 246 ldns_pkt_edns_data(const ldns_pkt *packet) 247 { 248 return packet->_edns_data; 249 } 250 251 /* return only those rr that share the ownername */ 252 ldns_rr_list * 253 ldns_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 *new; 259 ldns_rr_list *ret; 260 uint16_t i; 261 262 if (!packet) { 263 return NULL; 264 } 265 266 rrs = ldns_pkt_get_section_clone(packet, sec); 267 new = ldns_rr_list_new(); 268 ret = NULL; 269 270 for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 271 if (ldns_rdf_compare(ldns_rr_owner( 272 ldns_rr_list_rr(rrs, i)), 273 ownername) == 0) { 274 /* owner names match */ 275 ldns_rr_list_push_rr(new, ldns_rr_list_rr(rrs, i)); 276 ret = new; 277 } 278 } 279 return ret; 280 } 281 282 /* return only those rr that share a type */ 283 ldns_rr_list * 284 ldns_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 */ 319 ldns_rr_list * 320 ldns_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 356 bool 357 ldns_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 382 uint16_t 383 ldns_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 408 bool 409 ldns_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 true; 416 } else 417 return false; 418 } 419 420 421 ldns_rr_list * 422 ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s) 423 { 424 switch(s) { 425 case LDNS_SECTION_QUESTION: 426 return ldns_rr_list_clone(ldns_pkt_question(packet)); 427 case LDNS_SECTION_ANSWER: 428 return ldns_rr_list_clone(ldns_pkt_answer(packet)); 429 case LDNS_SECTION_AUTHORITY: 430 return ldns_rr_list_clone(ldns_pkt_authority(packet)); 431 case LDNS_SECTION_ADDITIONAL: 432 return ldns_rr_list_clone(ldns_pkt_additional(packet)); 433 case LDNS_SECTION_ANY: 434 /* these are already clones */ 435 return ldns_pkt_all(packet); 436 case LDNS_SECTION_ANY_NOQUESTION: 437 return ldns_pkt_all_noquestion(packet); 438 default: 439 return NULL; 440 } 441 } 442 443 ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) { 444 return pkt->_tsig_rr; 445 } 446 447 /* write */ 448 void 449 ldns_pkt_set_id(ldns_pkt *packet, uint16_t id) 450 { 451 packet->_header->_id = id; 452 } 453 454 void 455 ldns_pkt_set_random_id(ldns_pkt *packet) 456 { 457 uint16_t rid = 0; 458 #ifdef HAVE_SSL 459 if (RAND_bytes((unsigned char*)&rid, 2) != 1) { 460 rid = (uint16_t) random(); 461 } 462 #else 463 rid = (uint16_t) random(); 464 #endif 465 ldns_pkt_set_id(packet, rid); 466 } 467 468 469 void 470 ldns_pkt_set_qr(ldns_pkt *packet, bool qr) 471 { 472 packet->_header->_qr = qr; 473 } 474 475 void 476 ldns_pkt_set_aa(ldns_pkt *packet, bool aa) 477 { 478 packet->_header->_aa = aa; 479 } 480 481 void 482 ldns_pkt_set_tc(ldns_pkt *packet, bool tc) 483 { 484 packet->_header->_tc = tc; 485 } 486 487 void 488 ldns_pkt_set_rd(ldns_pkt *packet, bool rd) 489 { 490 packet->_header->_rd = rd; 491 } 492 493 void 494 ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr) 495 { 496 p->_additional = rr; 497 } 498 499 void 500 ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr) 501 { 502 p->_question = rr; 503 } 504 505 void 506 ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr) 507 { 508 p->_answer = rr; 509 } 510 511 void 512 ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr) 513 { 514 p->_authority = rr; 515 } 516 517 void 518 ldns_pkt_set_cd(ldns_pkt *packet, bool cd) 519 { 520 packet->_header->_cd = cd; 521 } 522 523 void 524 ldns_pkt_set_ra(ldns_pkt *packet, bool ra) 525 { 526 packet->_header->_ra = ra; 527 } 528 529 void 530 ldns_pkt_set_ad(ldns_pkt *packet, bool ad) 531 { 532 packet->_header->_ad = ad; 533 } 534 535 void 536 ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode) 537 { 538 packet->_header->_opcode = opcode; 539 } 540 541 void 542 ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode) 543 { 544 packet->_header->_rcode = rcode; 545 } 546 547 void 548 ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount) 549 { 550 packet->_header->_qdcount = qdcount; 551 } 552 553 void 554 ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount) 555 { 556 packet->_header->_ancount = ancount; 557 } 558 559 void 560 ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount) 561 { 562 packet->_header->_nscount = nscount; 563 } 564 565 void 566 ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount) 567 { 568 packet->_header->_arcount = arcount; 569 } 570 571 void 572 ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 573 { 574 packet->_querytime = time; 575 } 576 577 void 578 ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom) 579 { 580 packet->_answerfrom = answerfrom; 581 } 582 583 void 584 ldns_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 590 void 591 ldns_pkt_set_size(ldns_pkt *packet, size_t s) 592 { 593 packet->_size = s; 594 } 595 596 void 597 ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s) 598 { 599 packet->_edns_udp_size = s; 600 } 601 602 void 603 ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c) 604 { 605 packet->_edns_extended_rcode = c; 606 } 607 608 void 609 ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v) 610 { 611 packet->_edns_version = v; 612 } 613 614 void 615 ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z) 616 { 617 packet->_edns_z = z; 618 } 619 620 void 621 ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data) 622 { 623 packet->_edns_data = data; 624 } 625 626 void 627 ldns_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 648 void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr) 649 { 650 pkt->_tsig_rr = rr; 651 } 652 653 bool 654 ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr) 655 { 656 switch(section) { 657 case LDNS_SECTION_QUESTION: 658 ldns_rr_list_push_rr(ldns_pkt_question(packet), rr); 659 ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1); 660 break; 661 case LDNS_SECTION_ANSWER: 662 ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr); 663 ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1); 664 break; 665 case LDNS_SECTION_AUTHORITY: 666 ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr); 667 ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1); 668 break; 669 case LDNS_SECTION_ADDITIONAL: 670 ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr); 671 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1); 672 break; 673 case LDNS_SECTION_ANY: 674 case LDNS_SECTION_ANY_NOQUESTION: 675 /* shouldn't this error? */ 676 break; 677 } 678 return true; 679 } 680 681 bool 682 ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr) 683 { 684 685 /* check to see if its there */ 686 if (ldns_pkt_rr(pkt, sec, rr)) { 687 /* already there */ 688 return false; 689 } 690 return ldns_pkt_push_rr(pkt, sec, rr); 691 } 692 693 bool 694 ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 695 { 696 size_t i; 697 for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 698 if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) { 699 return false; 700 } 701 } 702 return true; 703 } 704 705 bool 706 ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 707 { 708 size_t i; 709 for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 710 if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) { 711 return false; 712 } 713 } 714 return true; 715 } 716 717 bool 718 ldns_pkt_edns(const ldns_pkt *pkt) { 719 return (ldns_pkt_edns_udp_size(pkt) > 0 || 720 ldns_pkt_edns_extended_rcode(pkt) > 0 || 721 ldns_pkt_edns_data(pkt) || 722 ldns_pkt_edns_do(pkt) 723 ); 724 } 725 726 727 /* Create/destroy/convert functions 728 */ 729 ldns_pkt * 730 ldns_pkt_new() 731 { 732 ldns_pkt *packet; 733 packet = LDNS_MALLOC(ldns_pkt); 734 if (!packet) { 735 return NULL; 736 } 737 738 packet->_header = LDNS_MALLOC(ldns_hdr); 739 if (!packet->_header) { 740 LDNS_FREE(packet); 741 return NULL; 742 } 743 744 packet->_question = ldns_rr_list_new(); 745 packet->_answer = ldns_rr_list_new(); 746 packet->_authority = ldns_rr_list_new(); 747 packet->_additional = ldns_rr_list_new(); 748 749 /* default everything to false */ 750 ldns_pkt_set_qr(packet, false); 751 ldns_pkt_set_aa(packet, false); 752 ldns_pkt_set_tc(packet, false); 753 ldns_pkt_set_rd(packet, false); 754 ldns_pkt_set_ra(packet, false); 755 ldns_pkt_set_ad(packet, false); 756 ldns_pkt_set_cd(packet, false); 757 758 ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY); 759 ldns_pkt_set_rcode(packet, 0); 760 ldns_pkt_set_id(packet, 0); 761 ldns_pkt_set_size(packet, 0); 762 ldns_pkt_set_querytime(packet, 0); 763 memset(&packet->timestamp, 0, sizeof(packet->timestamp)); 764 ldns_pkt_set_answerfrom(packet, NULL); 765 ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0); 766 ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0); 767 ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0); 768 ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0); 769 770 ldns_pkt_set_edns_udp_size(packet, 0); 771 ldns_pkt_set_edns_extended_rcode(packet, 0); 772 ldns_pkt_set_edns_version(packet, 0); 773 ldns_pkt_set_edns_z(packet, 0); 774 ldns_pkt_set_edns_data(packet, NULL); 775 776 ldns_pkt_set_tsig(packet, NULL); 777 778 return packet; 779 } 780 781 void 782 ldns_pkt_free(ldns_pkt *packet) 783 { 784 if (packet) { 785 LDNS_FREE(packet->_header); 786 ldns_rr_list_deep_free(packet->_question); 787 ldns_rr_list_deep_free(packet->_answer); 788 ldns_rr_list_deep_free(packet->_authority); 789 ldns_rr_list_deep_free(packet->_additional); 790 ldns_rr_free(packet->_tsig_rr); 791 ldns_rdf_deep_free(packet->_edns_data); 792 LDNS_FREE(packet); 793 } 794 } 795 796 bool 797 ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags) 798 { 799 if (!packet) { 800 return false; 801 } 802 if ((flags & LDNS_QR) == LDNS_QR) { 803 ldns_pkt_set_qr(packet, true); 804 } 805 if ((flags & LDNS_AA) == LDNS_AA) { 806 ldns_pkt_set_aa(packet, true); 807 } 808 if ((flags & LDNS_RD) == LDNS_RD) { 809 ldns_pkt_set_rd(packet, true); 810 } 811 if ((flags & LDNS_TC) == LDNS_TC) { 812 ldns_pkt_set_tc(packet, true); 813 } 814 if ((flags & LDNS_CD) == LDNS_CD) { 815 ldns_pkt_set_cd(packet, true); 816 } 817 if ((flags & LDNS_RA) == LDNS_RA) { 818 ldns_pkt_set_ra(packet, true); 819 } 820 if ((flags & LDNS_AD) == LDNS_AD) { 821 ldns_pkt_set_ad(packet, true); 822 } 823 return true; 824 } 825 826 ldns_status 827 ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, ldns_rr_type rr_type, 828 ldns_rr_class rr_class, uint16_t flags) 829 { 830 ldns_pkt *packet; 831 ldns_rr *question_rr; 832 ldns_rdf *name_rdf; 833 834 packet = ldns_pkt_new(); 835 if (!packet) { 836 return LDNS_STATUS_MEM_ERR; 837 } 838 839 if (!ldns_pkt_set_flags(packet, flags)) { 840 return LDNS_STATUS_ERR; 841 } 842 843 question_rr = ldns_rr_new(); 844 if (!question_rr) { 845 return LDNS_STATUS_MEM_ERR; 846 } 847 848 if (rr_type == 0) { 849 rr_type = LDNS_RR_TYPE_A; 850 } 851 if (rr_class == 0) { 852 rr_class = LDNS_RR_CLASS_IN; 853 } 854 855 if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) { 856 ldns_rr_set_owner(question_rr, name_rdf); 857 ldns_rr_set_type(question_rr, rr_type); 858 ldns_rr_set_class(question_rr, rr_class); 859 ldns_rr_set_question(question_rr, true); 860 861 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 862 } else { 863 ldns_rr_free(question_rr); 864 ldns_pkt_free(packet); 865 return LDNS_STATUS_ERR; 866 } 867 868 packet->_tsig_rr = NULL; 869 870 ldns_pkt_set_answerfrom(packet, NULL); 871 if (p) { 872 *p = packet; 873 return LDNS_STATUS_OK; 874 } else { 875 return LDNS_STATUS_NULL; 876 } 877 } 878 879 ldns_pkt * 880 ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, 881 uint16_t flags) 882 { 883 ldns_pkt *packet; 884 ldns_rr *question_rr; 885 886 packet = ldns_pkt_new(); 887 if (!packet) { 888 return NULL; 889 } 890 891 if (!ldns_pkt_set_flags(packet, flags)) { 892 return NULL; 893 } 894 895 question_rr = ldns_rr_new(); 896 if (!question_rr) { 897 return NULL; 898 } 899 900 if (rr_type == 0) { 901 rr_type = LDNS_RR_TYPE_A; 902 } 903 if (rr_class == 0) { 904 rr_class = LDNS_RR_CLASS_IN; 905 } 906 907 ldns_rr_set_owner(question_rr, rr_name); 908 ldns_rr_set_type(question_rr, rr_type); 909 ldns_rr_set_class(question_rr, rr_class); 910 ldns_rr_set_question(question_rr, true); 911 912 packet->_tsig_rr = NULL; 913 914 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 915 916 return packet; 917 } 918 919 ldns_pkt_type 920 ldns_pkt_reply_type(ldns_pkt *p) 921 { 922 ldns_rr_list *tmp; 923 924 if (!p) { 925 return LDNS_PACKET_UNKNOWN; 926 } 927 928 if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) { 929 return LDNS_PACKET_NXDOMAIN; 930 } 931 932 if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0 933 && ldns_pkt_nscount(p) == 1) { 934 935 /* check for SOA */ 936 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 937 LDNS_SECTION_AUTHORITY); 938 if (tmp) { 939 ldns_rr_list_deep_free(tmp); 940 return LDNS_PACKET_NODATA; 941 } else { 942 /* I have no idea ... */ 943 } 944 } 945 946 if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) { 947 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS, 948 LDNS_SECTION_AUTHORITY); 949 if (tmp) { 950 /* there are nameservers here */ 951 ldns_rr_list_deep_free(tmp); 952 return LDNS_PACKET_REFERRAL; 953 } else { 954 /* I have no idea */ 955 } 956 ldns_rr_list_deep_free(tmp); 957 } 958 959 /* if we cannot determine the packet type, we say it's an 960 * answer... 961 */ 962 return LDNS_PACKET_ANSWER; 963 } 964 965 ldns_pkt * 966 ldns_pkt_clone(ldns_pkt *pkt) 967 { 968 ldns_pkt *new_pkt; 969 970 if (!pkt) { 971 return NULL; 972 } 973 new_pkt = ldns_pkt_new(); 974 975 ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt)); 976 ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt)); 977 ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt)); 978 ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt)); 979 ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt)); 980 ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt)); 981 ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt)); 982 ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt)); 983 ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt)); 984 ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt)); 985 ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt)); 986 ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt)); 987 ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt)); 988 ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt)); 989 ldns_pkt_set_answerfrom(new_pkt, ldns_pkt_answerfrom(pkt)); 990 ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt)); 991 ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt)); 992 ldns_pkt_set_tsig(new_pkt, ldns_pkt_tsig(pkt)); 993 994 ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt)); 995 ldns_pkt_set_edns_extended_rcode(new_pkt, 996 ldns_pkt_edns_extended_rcode(pkt)); 997 ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt)); 998 ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt)); 999 if(ldns_pkt_edns_data(pkt)) 1000 ldns_pkt_set_edns_data(new_pkt, 1001 ldns_rdf_clone(ldns_pkt_edns_data(pkt))); 1002 ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt)); 1003 1004 ldns_rr_list_deep_free(new_pkt->_question); 1005 ldns_rr_list_deep_free(new_pkt->_answer); 1006 ldns_rr_list_deep_free(new_pkt->_authority); 1007 ldns_rr_list_deep_free(new_pkt->_additional); 1008 new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt)); 1009 new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt)); 1010 new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt)); 1011 new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt)); 1012 return new_pkt; 1013 } 1014