00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ldns/config.h>
00014
00015 #include <ldns/ldns.h>
00016
00017 #include <strings.h>
00018 #include <limits.h>
00019
00020 #ifdef HAVE_SSL
00021 #include <openssl/rand.h>
00022 #endif
00023
00024
00025
00026
00027
00028 #define LDNS_EDNS_MASK_DO_BIT 0x8000
00029
00030
00031
00032 ldns_lookup_table ldns_edns_flags[] = {
00033 { 3600, "do"},
00034 { 0, NULL}
00035 };
00036
00037
00038 uint16_t
00039 ldns_pkt_id(const ldns_pkt *packet)
00040 {
00041 return packet->_header->_id;
00042 }
00043
00044 bool
00045 ldns_pkt_qr(const ldns_pkt *packet)
00046 {
00047 return packet->_header->_qr;
00048 }
00049
00050 bool
00051 ldns_pkt_aa(const ldns_pkt *packet)
00052 {
00053 return packet->_header->_aa;
00054 }
00055
00056 bool
00057 ldns_pkt_tc(const ldns_pkt *packet)
00058 {
00059 return packet->_header->_tc;
00060 }
00061
00062 bool
00063 ldns_pkt_rd(const ldns_pkt *packet)
00064 {
00065 return packet->_header->_rd;
00066 }
00067
00068 bool
00069 ldns_pkt_cd(const ldns_pkt *packet)
00070 {
00071 return packet->_header->_cd;
00072 }
00073
00074 bool
00075 ldns_pkt_ra(const ldns_pkt *packet)
00076 {
00077 return packet->_header->_ra;
00078 }
00079
00080 bool
00081 ldns_pkt_ad(const ldns_pkt *packet)
00082 {
00083 return packet->_header->_ad;
00084 }
00085
00086 ldns_pkt_opcode
00087 ldns_pkt_get_opcode(const ldns_pkt *packet)
00088 {
00089 return packet->_header->_opcode;
00090 }
00091
00092 ldns_pkt_rcode
00093 ldns_pkt_get_rcode(const ldns_pkt *packet)
00094 {
00095 return packet->_header->_rcode;
00096 }
00097
00098 uint16_t
00099 ldns_pkt_qdcount(const ldns_pkt *packet)
00100 {
00101 return packet->_header->_qdcount;
00102 }
00103
00104 uint16_t
00105 ldns_pkt_ancount(const ldns_pkt *packet)
00106 {
00107 return packet->_header->_ancount;
00108 }
00109
00110 uint16_t
00111 ldns_pkt_nscount(const ldns_pkt *packet)
00112 {
00113 return packet->_header->_nscount;
00114 }
00115
00116 uint16_t
00117 ldns_pkt_arcount(const ldns_pkt *packet)
00118 {
00119 return packet->_header->_arcount;
00120 }
00121
00122 ldns_rr_list *
00123 ldns_pkt_question(const ldns_pkt *packet)
00124 {
00125 return packet->_question;
00126 }
00127
00128 ldns_rr_list *
00129 ldns_pkt_answer(const ldns_pkt *packet)
00130 {
00131 return packet->_answer;
00132 }
00133
00134 ldns_rr_list *
00135 ldns_pkt_authority(const ldns_pkt *packet)
00136 {
00137 return packet->_authority;
00138 }
00139
00140 ldns_rr_list *
00141 ldns_pkt_additional(const ldns_pkt *packet)
00142 {
00143 return packet->_additional;
00144 }
00145
00146
00147 ldns_rr_list *
00148 ldns_pkt_all(const ldns_pkt *packet)
00149 {
00150 ldns_rr_list *all, *prev_all;
00151
00152 all = ldns_rr_list_cat_clone(
00153 ldns_pkt_question(packet),
00154 ldns_pkt_answer(packet));
00155 prev_all = all;
00156 all = ldns_rr_list_cat_clone(all,
00157 ldns_pkt_authority(packet));
00158 ldns_rr_list_deep_free(prev_all);
00159 prev_all = all;
00160 all = ldns_rr_list_cat_clone(all,
00161 ldns_pkt_additional(packet));
00162 ldns_rr_list_deep_free(prev_all);
00163 return all;
00164 }
00165
00166 ldns_rr_list *
00167 ldns_pkt_all_noquestion(const ldns_pkt *packet)
00168 {
00169 ldns_rr_list *all, *all2;
00170
00171 all = ldns_rr_list_cat_clone(
00172 ldns_pkt_answer(packet),
00173 ldns_pkt_authority(packet));
00174 all2 = ldns_rr_list_cat_clone(all,
00175 ldns_pkt_additional(packet));
00176
00177 ldns_rr_list_deep_free(all);
00178 return all2;
00179 }
00180
00181 size_t
00182 ldns_pkt_size(const ldns_pkt *packet)
00183 {
00184 return packet->_size;
00185 }
00186
00187 uint32_t
00188 ldns_pkt_querytime(const ldns_pkt *packet)
00189 {
00190 return packet->_querytime;
00191 }
00192
00193 ldns_rdf *
00194 ldns_pkt_answerfrom(const ldns_pkt *packet)
00195 {
00196 return packet->_answerfrom;
00197 }
00198
00199 struct timeval
00200 ldns_pkt_timestamp(const ldns_pkt *packet)
00201 {
00202 return packet->timestamp;
00203 }
00204
00205 uint16_t
00206 ldns_pkt_edns_udp_size(const ldns_pkt *packet)
00207 {
00208 return packet->_edns_udp_size;
00209 }
00210
00211 uint8_t
00212 ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
00213 {
00214 return packet->_edns_extended_rcode;
00215 }
00216
00217 uint8_t
00218 ldns_pkt_edns_version(const ldns_pkt *packet)
00219 {
00220 return packet->_edns_version;
00221 }
00222
00223 uint16_t
00224 ldns_pkt_edns_z(const ldns_pkt *packet)
00225 {
00226 return packet->_edns_z;
00227 }
00228
00229 bool
00230 ldns_pkt_edns_do(const ldns_pkt *packet)
00231 {
00232 return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
00233 }
00234
00235 void
00236 ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
00237 {
00238 if (value) {
00239 packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
00240 } else {
00241 packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT;
00242 }
00243 }
00244
00245 ldns_rdf *
00246 ldns_pkt_edns_data(const ldns_pkt *packet)
00247 {
00248 return packet->_edns_data;
00249 }
00250
00251
00252 ldns_rr_list *
00253 ldns_pkt_rr_list_by_name(ldns_pkt *packet,
00254 ldns_rdf *ownername,
00255 ldns_pkt_section sec)
00256 {
00257 ldns_rr_list *rrs;
00258 ldns_rr_list *ret;
00259 uint16_t i;
00260
00261 if (!packet) {
00262 return NULL;
00263 }
00264
00265 rrs = ldns_pkt_get_section_clone(packet, sec);
00266 ret = NULL;
00267
00268 for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00269 if (ldns_dname_compare(ldns_rr_owner(
00270 ldns_rr_list_rr(rrs, i)),
00271 ownername) == 0) {
00272
00273 if (ret == NULL) {
00274 ret = ldns_rr_list_new();
00275 }
00276 ldns_rr_list_push_rr(ret, ldns_rr_list_rr(rrs, i));
00277 }
00278 }
00279 return ret;
00280 }
00281
00282
00283 ldns_rr_list *
00284 ldns_pkt_rr_list_by_type(const ldns_pkt *packet,
00285 ldns_rr_type type,
00286 ldns_pkt_section sec)
00287 {
00288 ldns_rr_list *rrs;
00289 ldns_rr_list *new;
00290 uint16_t i;
00291
00292 if(!packet) {
00293 return NULL;
00294 }
00295
00296 rrs = ldns_pkt_get_section_clone(packet, sec);
00297 new = ldns_rr_list_new();
00298
00299 for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00300 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
00301
00302 ldns_rr_list_push_rr(new,
00303 ldns_rr_clone(
00304 ldns_rr_list_rr(rrs, i))
00305 );
00306 }
00307 }
00308 ldns_rr_list_deep_free(rrs);
00309
00310 if (ldns_rr_list_rr_count(new) == 0) {
00311 ldns_rr_list_free(new);
00312 return NULL;
00313 } else {
00314 return new;
00315 }
00316 }
00317
00318
00319 ldns_rr_list *
00320 ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet,
00321 const ldns_rdf *ownername,
00322 ldns_rr_type type,
00323 ldns_pkt_section sec)
00324 {
00325 ldns_rr_list *rrs;
00326 ldns_rr_list *new;
00327 ldns_rr_list *ret;
00328 uint16_t i;
00329
00330 if(!packet) {
00331 return NULL;
00332 }
00333
00334 rrs = ldns_pkt_get_section_clone(packet, sec);
00335 new = ldns_rr_list_new();
00336 ret = NULL;
00337
00338 for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00339 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
00340 ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
00341 ownername
00342 ) == 0
00343 ) {
00344
00345 ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
00346 ret = new;
00347 }
00348 }
00349 ldns_rr_list_deep_free(rrs);
00350 if (!ret) {
00351 ldns_rr_list_free(new);
00352 }
00353 return ret;
00354 }
00355
00356 bool
00357 ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00358 {
00359 bool result = false;
00360
00361 switch (sec) {
00362 case LDNS_SECTION_QUESTION:
00363 return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
00364 case LDNS_SECTION_ANSWER:
00365 return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr);
00366 case LDNS_SECTION_AUTHORITY:
00367 return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr);
00368 case LDNS_SECTION_ADDITIONAL:
00369 return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
00370 case LDNS_SECTION_ANY:
00371 result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr);
00372 case LDNS_SECTION_ANY_NOQUESTION:
00373 result = result
00374 || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr)
00375 || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr)
00376 || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr);
00377 }
00378
00379 return result;
00380 }
00381
00382 uint16_t
00383 ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
00384 {
00385 switch(s) {
00386 case LDNS_SECTION_QUESTION:
00387 return ldns_pkt_qdcount(packet);
00388 case LDNS_SECTION_ANSWER:
00389 return ldns_pkt_ancount(packet);
00390 case LDNS_SECTION_AUTHORITY:
00391 return ldns_pkt_nscount(packet);
00392 case LDNS_SECTION_ADDITIONAL:
00393 return ldns_pkt_arcount(packet);
00394 case LDNS_SECTION_ANY:
00395 return ldns_pkt_qdcount(packet) +
00396 ldns_pkt_ancount(packet) +
00397 ldns_pkt_nscount(packet) +
00398 ldns_pkt_arcount(packet);
00399 case LDNS_SECTION_ANY_NOQUESTION:
00400 return ldns_pkt_ancount(packet) +
00401 ldns_pkt_nscount(packet) +
00402 ldns_pkt_arcount(packet);
00403 default:
00404 return 0;
00405 }
00406 }
00407
00408 bool
00409 ldns_pkt_empty(ldns_pkt *p)
00410 {
00411 if (!p) {
00412 return true;
00413 }
00414 if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
00415 return false;
00416 } else {
00417 return true;
00418 }
00419 }
00420
00421
00422 ldns_rr_list *
00423 ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s)
00424 {
00425 switch(s) {
00426 case LDNS_SECTION_QUESTION:
00427 return ldns_rr_list_clone(ldns_pkt_question(packet));
00428 case LDNS_SECTION_ANSWER:
00429 return ldns_rr_list_clone(ldns_pkt_answer(packet));
00430 case LDNS_SECTION_AUTHORITY:
00431 return ldns_rr_list_clone(ldns_pkt_authority(packet));
00432 case LDNS_SECTION_ADDITIONAL:
00433 return ldns_rr_list_clone(ldns_pkt_additional(packet));
00434 case LDNS_SECTION_ANY:
00435
00436 return ldns_pkt_all(packet);
00437 case LDNS_SECTION_ANY_NOQUESTION:
00438 return ldns_pkt_all_noquestion(packet);
00439 default:
00440 return NULL;
00441 }
00442 }
00443
00444 ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
00445 return pkt->_tsig_rr;
00446 }
00447
00448
00449 void
00450 ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
00451 {
00452 packet->_header->_id = id;
00453 }
00454
00455 void
00456 ldns_pkt_set_random_id(ldns_pkt *packet)
00457 {
00458 uint16_t rid = ldns_get_random();
00459 ldns_pkt_set_id(packet, rid);
00460 }
00461
00462
00463 void
00464 ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
00465 {
00466 packet->_header->_qr = qr;
00467 }
00468
00469 void
00470 ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
00471 {
00472 packet->_header->_aa = aa;
00473 }
00474
00475 void
00476 ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
00477 {
00478 packet->_header->_tc = tc;
00479 }
00480
00481 void
00482 ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
00483 {
00484 packet->_header->_rd = rd;
00485 }
00486
00487 void
00488 ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
00489 {
00490 p->_additional = rr;
00491 }
00492
00493 void
00494 ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
00495 {
00496 p->_question = rr;
00497 }
00498
00499 void
00500 ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
00501 {
00502 p->_answer = rr;
00503 }
00504
00505 void
00506 ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
00507 {
00508 p->_authority = rr;
00509 }
00510
00511 void
00512 ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
00513 {
00514 packet->_header->_cd = cd;
00515 }
00516
00517 void
00518 ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
00519 {
00520 packet->_header->_ra = ra;
00521 }
00522
00523 void
00524 ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
00525 {
00526 packet->_header->_ad = ad;
00527 }
00528
00529 void
00530 ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
00531 {
00532 packet->_header->_opcode = opcode;
00533 }
00534
00535 void
00536 ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
00537 {
00538 packet->_header->_rcode = rcode;
00539 }
00540
00541 void
00542 ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
00543 {
00544 packet->_header->_qdcount = qdcount;
00545 }
00546
00547 void
00548 ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
00549 {
00550 packet->_header->_ancount = ancount;
00551 }
00552
00553 void
00554 ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
00555 {
00556 packet->_header->_nscount = nscount;
00557 }
00558
00559 void
00560 ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
00561 {
00562 packet->_header->_arcount = arcount;
00563 }
00564
00565 void
00566 ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time)
00567 {
00568 packet->_querytime = time;
00569 }
00570
00571 void
00572 ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
00573 {
00574 packet->_answerfrom = answerfrom;
00575 }
00576
00577 void
00578 ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
00579 {
00580 packet->timestamp.tv_sec = timeval.tv_sec;
00581 packet->timestamp.tv_usec = timeval.tv_usec;
00582 }
00583
00584 void
00585 ldns_pkt_set_size(ldns_pkt *packet, size_t s)
00586 {
00587 packet->_size = s;
00588 }
00589
00590 void
00591 ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
00592 {
00593 packet->_edns_udp_size = s;
00594 }
00595
00596 void
00597 ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
00598 {
00599 packet->_edns_extended_rcode = c;
00600 }
00601
00602 void
00603 ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
00604 {
00605 packet->_edns_version = v;
00606 }
00607
00608 void
00609 ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
00610 {
00611 packet->_edns_z = z;
00612 }
00613
00614 void
00615 ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
00616 {
00617 packet->_edns_data = data;
00618 }
00619
00620 void
00621 ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
00622 {
00623 switch(s) {
00624 case LDNS_SECTION_QUESTION:
00625 ldns_pkt_set_qdcount(packet, count);
00626 break;
00627 case LDNS_SECTION_ANSWER:
00628 ldns_pkt_set_ancount(packet, count);
00629 break;
00630 case LDNS_SECTION_AUTHORITY:
00631 ldns_pkt_set_nscount(packet, count);
00632 break;
00633 case LDNS_SECTION_ADDITIONAL:
00634 ldns_pkt_set_arcount(packet, count);
00635 break;
00636 case LDNS_SECTION_ANY:
00637 case LDNS_SECTION_ANY_NOQUESTION:
00638 break;
00639 }
00640 }
00641
00642 void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
00643 {
00644 pkt->_tsig_rr = rr;
00645 }
00646
00647 bool
00648 ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
00649 {
00650 switch(section) {
00651 case LDNS_SECTION_QUESTION:
00652 if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
00653 return false;
00654 }
00655 ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
00656 break;
00657 case LDNS_SECTION_ANSWER:
00658 if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
00659 return false;
00660 }
00661 ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
00662 break;
00663 case LDNS_SECTION_AUTHORITY:
00664 if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
00665 return false;
00666 }
00667 ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
00668 break;
00669 case LDNS_SECTION_ADDITIONAL:
00670 if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
00671 return false;
00672 }
00673 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
00674 break;
00675 case LDNS_SECTION_ANY:
00676 case LDNS_SECTION_ANY_NOQUESTION:
00677
00678 break;
00679 }
00680 return true;
00681 }
00682
00683 bool
00684 ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00685 {
00686
00687
00688 if (ldns_pkt_rr(pkt, sec, rr)) {
00689
00690 return false;
00691 }
00692 return ldns_pkt_push_rr(pkt, sec, rr);
00693 }
00694
00695 bool
00696 ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00697 {
00698 size_t i;
00699 for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00700 if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00701 return false;
00702 }
00703 }
00704 return true;
00705 }
00706
00707 bool
00708 ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00709 {
00710 size_t i;
00711 for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00712 if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00713 return false;
00714 }
00715 }
00716 return true;
00717 }
00718
00719 bool
00720 ldns_pkt_edns(const ldns_pkt *pkt) {
00721 return (ldns_pkt_edns_udp_size(pkt) > 0 ||
00722 ldns_pkt_edns_extended_rcode(pkt) > 0 ||
00723 ldns_pkt_edns_data(pkt) ||
00724 ldns_pkt_edns_do(pkt)
00725 );
00726 }
00727
00728
00729
00730
00731 ldns_pkt *
00732 ldns_pkt_new(void)
00733 {
00734 ldns_pkt *packet;
00735 packet = LDNS_MALLOC(ldns_pkt);
00736 if (!packet) {
00737 return NULL;
00738 }
00739
00740 packet->_header = LDNS_MALLOC(ldns_hdr);
00741 if (!packet->_header) {
00742 LDNS_FREE(packet);
00743 return NULL;
00744 }
00745
00746 packet->_question = ldns_rr_list_new();
00747 packet->_answer = ldns_rr_list_new();
00748 packet->_authority = ldns_rr_list_new();
00749 packet->_additional = ldns_rr_list_new();
00750
00751
00752 ldns_pkt_set_qr(packet, false);
00753 ldns_pkt_set_aa(packet, false);
00754 ldns_pkt_set_tc(packet, false);
00755 ldns_pkt_set_rd(packet, false);
00756 ldns_pkt_set_ra(packet, false);
00757 ldns_pkt_set_ad(packet, false);
00758 ldns_pkt_set_cd(packet, false);
00759
00760 ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
00761 ldns_pkt_set_rcode(packet, 0);
00762 ldns_pkt_set_id(packet, 0);
00763 ldns_pkt_set_size(packet, 0);
00764 ldns_pkt_set_querytime(packet, 0);
00765 memset(&packet->timestamp, 0, sizeof(packet->timestamp));
00766 ldns_pkt_set_answerfrom(packet, NULL);
00767 ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
00768 ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
00769 ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
00770 ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
00771
00772 ldns_pkt_set_edns_udp_size(packet, 0);
00773 ldns_pkt_set_edns_extended_rcode(packet, 0);
00774 ldns_pkt_set_edns_version(packet, 0);
00775 ldns_pkt_set_edns_z(packet, 0);
00776 ldns_pkt_set_edns_data(packet, NULL);
00777
00778 ldns_pkt_set_tsig(packet, NULL);
00779
00780 return packet;
00781 }
00782
00783 void
00784 ldns_pkt_free(ldns_pkt *packet)
00785 {
00786 if (packet) {
00787 LDNS_FREE(packet->_header);
00788 ldns_rr_list_deep_free(packet->_question);
00789 ldns_rr_list_deep_free(packet->_answer);
00790 ldns_rr_list_deep_free(packet->_authority);
00791 ldns_rr_list_deep_free(packet->_additional);
00792 ldns_rr_free(packet->_tsig_rr);
00793 ldns_rdf_deep_free(packet->_edns_data);
00794 ldns_rdf_deep_free(packet->_answerfrom);
00795 LDNS_FREE(packet);
00796 }
00797 }
00798
00799 bool
00800 ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
00801 {
00802 if (!packet) {
00803 return false;
00804 }
00805 if ((flags & LDNS_QR) == LDNS_QR) {
00806 ldns_pkt_set_qr(packet, true);
00807 }
00808 if ((flags & LDNS_AA) == LDNS_AA) {
00809 ldns_pkt_set_aa(packet, true);
00810 }
00811 if ((flags & LDNS_RD) == LDNS_RD) {
00812 ldns_pkt_set_rd(packet, true);
00813 }
00814 if ((flags & LDNS_TC) == LDNS_TC) {
00815 ldns_pkt_set_tc(packet, true);
00816 }
00817 if ((flags & LDNS_CD) == LDNS_CD) {
00818 ldns_pkt_set_cd(packet, true);
00819 }
00820 if ((flags & LDNS_RA) == LDNS_RA) {
00821 ldns_pkt_set_ra(packet, true);
00822 }
00823 if ((flags & LDNS_AD) == LDNS_AD) {
00824 ldns_pkt_set_ad(packet, true);
00825 }
00826 return true;
00827 }
00828
00829
00830 static ldns_rr*
00831 ldns_pkt_authsoa(ldns_rdf* rr_name, ldns_rr_class rr_class)
00832 {
00833 ldns_rr* soa_rr = ldns_rr_new();
00834 ldns_rdf *owner_rdf;
00835 ldns_rdf *mname_rdf;
00836 ldns_rdf *rname_rdf;
00837 ldns_rdf *serial_rdf;
00838 ldns_rdf *refresh_rdf;
00839 ldns_rdf *retry_rdf;
00840 ldns_rdf *expire_rdf;
00841 ldns_rdf *minimum_rdf;
00842
00843 if (!soa_rr) {
00844 return NULL;
00845 }
00846 owner_rdf = ldns_rdf_clone(rr_name);
00847 if (!owner_rdf) {
00848 ldns_rr_free(soa_rr);
00849 return NULL;
00850 }
00851
00852 ldns_rr_set_owner(soa_rr, owner_rdf);
00853 ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA);
00854 ldns_rr_set_class(soa_rr, rr_class);
00855 ldns_rr_set_question(soa_rr, false);
00856
00857 if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
00858 ldns_rr_free(soa_rr);
00859 return NULL;
00860 } else {
00861 ldns_rr_push_rdf(soa_rr, mname_rdf);
00862 }
00863 if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
00864 ldns_rr_free(soa_rr);
00865 return NULL;
00866 } else {
00867 ldns_rr_push_rdf(soa_rr, rname_rdf);
00868 }
00869 serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
00870 if (!serial_rdf) {
00871 ldns_rr_free(soa_rr);
00872 return NULL;
00873 } else {
00874 ldns_rr_push_rdf(soa_rr, serial_rdf);
00875 }
00876 refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
00877 if (!refresh_rdf) {
00878 ldns_rr_free(soa_rr);
00879 return NULL;
00880 } else {
00881 ldns_rr_push_rdf(soa_rr, refresh_rdf);
00882 }
00883 retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
00884 if (!retry_rdf) {
00885 ldns_rr_free(soa_rr);
00886 return NULL;
00887 } else {
00888 ldns_rr_push_rdf(soa_rr, retry_rdf);
00889 }
00890 expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
00891 if (!expire_rdf) {
00892 ldns_rr_free(soa_rr);
00893 return NULL;
00894 } else {
00895 ldns_rr_push_rdf(soa_rr, expire_rdf);
00896 }
00897 minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
00898 if (!minimum_rdf) {
00899 ldns_rr_free(soa_rr);
00900 return NULL;
00901 } else {
00902 ldns_rr_push_rdf(soa_rr, minimum_rdf);
00903 }
00904 return soa_rr;
00905 }
00906
00907
00908 static ldns_status
00909 ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name,
00910 ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags,
00911 ldns_rr* authsoa_rr)
00912 {
00913 ldns_pkt *packet;
00914 ldns_rr *question_rr;
00915 ldns_rdf *name_rdf;
00916
00917 packet = ldns_pkt_new();
00918 if (!packet) {
00919 return LDNS_STATUS_MEM_ERR;
00920 }
00921
00922 if (!ldns_pkt_set_flags(packet, flags)) {
00923 return LDNS_STATUS_ERR;
00924 }
00925
00926 question_rr = ldns_rr_new();
00927 if (!question_rr) {
00928 return LDNS_STATUS_MEM_ERR;
00929 }
00930
00931 if (rr_type == 0) {
00932 rr_type = LDNS_RR_TYPE_A;
00933 }
00934 if (rr_class == 0) {
00935 rr_class = LDNS_RR_CLASS_IN;
00936 }
00937
00938 if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
00939 ldns_rr_set_owner(question_rr, name_rdf);
00940 ldns_rr_set_type(question_rr, rr_type);
00941 ldns_rr_set_class(question_rr, rr_class);
00942 ldns_rr_set_question(question_rr, true);
00943
00944 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
00945 } else {
00946 ldns_rr_free(question_rr);
00947 ldns_pkt_free(packet);
00948 return LDNS_STATUS_ERR;
00949 }
00950
00951 if (authsoa_rr) {
00952 ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
00953 }
00954
00955 packet->_tsig_rr = NULL;
00956 ldns_pkt_set_answerfrom(packet, NULL);
00957 if (p) {
00958 *p = packet;
00959 return LDNS_STATUS_OK;
00960 } else {
00961 ldns_pkt_free(packet);
00962 return LDNS_STATUS_NULL;
00963 }
00964 }
00965
00966 ldns_status
00967 ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name,
00968 ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
00969 {
00970 return ldns_pkt_query_new_frm_str_internal(p, name, rr_type,
00971 rr_class, flags, NULL);
00972 }
00973
00974 ldns_status
00975 ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name,
00976 ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
00977 {
00978 ldns_rr* authsoa_rr = soa;
00979 if (!authsoa_rr) {
00980 ldns_rdf *name_rdf;
00981 if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
00982 authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class);
00983 }
00984 ldns_rdf_free(name_rdf);
00985 }
00986 return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR,
00987 rr_class, flags, authsoa_rr);
00988 }
00989
00990 static ldns_pkt *
00991 ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type,
00992 ldns_rr_class rr_class, uint16_t flags, ldns_rr* authsoa_rr)
00993 {
00994 ldns_pkt *packet;
00995 ldns_rr *question_rr;
00996
00997 packet = ldns_pkt_new();
00998 if (!packet) {
00999 return NULL;
01000 }
01001
01002 if (!ldns_pkt_set_flags(packet, flags)) {
01003 return NULL;
01004 }
01005
01006 question_rr = ldns_rr_new();
01007 if (!question_rr) {
01008 ldns_pkt_free(packet);
01009 return NULL;
01010 }
01011
01012 if (rr_type == 0) {
01013 rr_type = LDNS_RR_TYPE_A;
01014 }
01015 if (rr_class == 0) {
01016 rr_class = LDNS_RR_CLASS_IN;
01017 }
01018
01019 ldns_rr_set_owner(question_rr, rr_name);
01020 ldns_rr_set_type(question_rr, rr_type);
01021 ldns_rr_set_class(question_rr, rr_class);
01022 ldns_rr_set_question(question_rr, true);
01023 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
01024
01025 if (authsoa_rr) {
01026 ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr);
01027 }
01028
01029 packet->_tsig_rr = NULL;
01030 return packet;
01031 }
01032
01033 ldns_pkt *
01034 ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type,
01035 ldns_rr_class rr_class, uint16_t flags)
01036 {
01037 return ldns_pkt_query_new_internal(rr_name, rr_type,
01038 rr_class, flags, NULL);
01039 }
01040
01041 ldns_pkt *
01042 ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class,
01043 uint16_t flags, ldns_rr* soa)
01044 {
01045 ldns_rr* authsoa_rr = soa;
01046 if (!authsoa_rr) {
01047 authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class);
01048 }
01049 return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR,
01050 rr_class, flags, authsoa_rr);
01051 }
01052
01053 ldns_pkt_type
01054 ldns_pkt_reply_type(ldns_pkt *p)
01055 {
01056 ldns_rr_list *tmp;
01057
01058 if (!p) {
01059 return LDNS_PACKET_UNKNOWN;
01060 }
01061
01062 if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
01063 return LDNS_PACKET_NXDOMAIN;
01064 }
01065
01066 if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
01067 && ldns_pkt_nscount(p) == 1) {
01068
01069
01070 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA,
01071 LDNS_SECTION_AUTHORITY);
01072 if (tmp) {
01073 ldns_rr_list_deep_free(tmp);
01074 return LDNS_PACKET_NODATA;
01075 } else {
01076
01077 }
01078 }
01079
01080 if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
01081 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
01082 LDNS_SECTION_AUTHORITY);
01083 if (tmp) {
01084
01085 ldns_rr_list_deep_free(tmp);
01086 return LDNS_PACKET_REFERRAL;
01087 } else {
01088
01089 }
01090 ldns_rr_list_deep_free(tmp);
01091 }
01092
01093
01094
01095
01096 return LDNS_PACKET_ANSWER;
01097 }
01098
01099 ldns_pkt *
01100 ldns_pkt_clone(ldns_pkt *pkt)
01101 {
01102 ldns_pkt *new_pkt;
01103
01104 if (!pkt) {
01105 return NULL;
01106 }
01107 new_pkt = ldns_pkt_new();
01108
01109 ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
01110 ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
01111 ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
01112 ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
01113 ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
01114 ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
01115 ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
01116 ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
01117 ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
01118 ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
01119 ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
01120 ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
01121 ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
01122 ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
01123 if (ldns_pkt_answerfrom(pkt))
01124 ldns_pkt_set_answerfrom(new_pkt,
01125 ldns_rdf_clone(ldns_pkt_answerfrom(pkt)));
01126 ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
01127 ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
01128 ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt)));
01129
01130 ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt));
01131 ldns_pkt_set_edns_extended_rcode(new_pkt,
01132 ldns_pkt_edns_extended_rcode(pkt));
01133 ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt));
01134 ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt));
01135 if(ldns_pkt_edns_data(pkt))
01136 ldns_pkt_set_edns_data(new_pkt,
01137 ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
01138 ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
01139
01140 ldns_rr_list_deep_free(new_pkt->_question);
01141 ldns_rr_list_deep_free(new_pkt->_answer);
01142 ldns_rr_list_deep_free(new_pkt->_authority);
01143 ldns_rr_list_deep_free(new_pkt->_additional);
01144 new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
01145 new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
01146 new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
01147 new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
01148 return new_pkt;
01149 }