packet.c

Go to the documentation of this file.
00001 /*
00002  * packet.c
00003  *
00004  * dns packet implementation
00005  *
00006  * a Net::DNS like library for C
00007  *
00008  * (c) NLnet Labs, 2004-2006
00009  *
00010  * See the file LICENSE for the license
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 /* Access functions 
00025  * do this as functions to get type checking
00026  */
00027 
00028 #define LDNS_EDNS_MASK_DO_BIT 0x8000
00029 
00030 /* TODO defines for 3600 */
00031 /* convert to and from numerical flag values */
00032 ldns_lookup_table ldns_edns_flags[] = {
00033         { 3600, "do"},
00034         { 0, NULL}
00035 };
00036 
00037 /* read */
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 /* return ALL section concatenated */
00147 ldns_rr_list *
00148 ldns_pkt_all(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(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 /* return only those rr that share the ownername */
00252 ldns_rr_list *
00253 ldns_pkt_rr_list_by_name(ldns_pkt *packet, ldns_rdf *ownername, ldns_pkt_section sec)
00254 {
00255         ldns_rr_list *rrs;
00256         ldns_rr_list *new;
00257         ldns_rr_list *ret;
00258         uint16_t i;
00259 
00260         if (!packet) {
00261                 return NULL;
00262         }
00263 
00264         rrs = ldns_pkt_get_section_clone(packet, sec);
00265         new = ldns_rr_list_new();
00266         ret = NULL;
00267 
00268         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00269                 if (ldns_rdf_compare(ldns_rr_owner(
00270                                                 ldns_rr_list_rr(rrs, i)), 
00271                                         ownername) == 0) {
00272                         /* owner names match */
00273                         ldns_rr_list_push_rr(new, ldns_rr_list_rr(rrs, i));
00274                         ret = new;
00275                 }
00276         }
00277         return ret;
00278 }
00279 
00280 /* return only those rr that share a type */
00281 ldns_rr_list *
00282 ldns_pkt_rr_list_by_type(ldns_pkt *packet, ldns_rr_type type, ldns_pkt_section sec)
00283 {
00284         ldns_rr_list *rrs;
00285         ldns_rr_list *new;
00286         uint16_t i;
00287 
00288         if(!packet) {
00289                 return NULL;
00290         }
00291         
00292         rrs = ldns_pkt_get_section_clone(packet, sec);
00293         new = ldns_rr_list_new();
00294         
00295         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00296                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
00297                         /* types match */
00298                         ldns_rr_list_push_rr(new, 
00299                                              ldns_rr_clone(
00300                                                 ldns_rr_list_rr(rrs, i))
00301                                              );
00302                 }
00303         }
00304         ldns_rr_list_deep_free(rrs);
00305 
00306         if (ldns_rr_list_rr_count(new) == 0) {
00307                 ldns_rr_list_free(new);
00308                 return NULL;
00309         } else {
00310                 return new;
00311         }
00312 }
00313 
00314 /* return only those rrs that share name and type */
00315 ldns_rr_list *
00316 ldns_pkt_rr_list_by_name_and_type(ldns_pkt *packet, ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec)
00317 {
00318         ldns_rr_list *rrs;
00319         ldns_rr_list *new;
00320         ldns_rr_list *ret;
00321         uint16_t i;
00322 
00323         if(!packet) {
00324                 return NULL;
00325         }
00326         
00327         rrs = ldns_pkt_get_section_clone(packet, sec);
00328         new = ldns_rr_list_new();
00329         ret = NULL;
00330 
00331         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00332                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
00333                     ldns_rdf_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
00334                                      ownername
00335                                     ) == 0
00336                    ) {
00337                         /* types match */
00338                         ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
00339                         ret = new;
00340                 }
00341         }
00342         ldns_rr_list_deep_free(rrs);
00343         if (!ret) {
00344                 ldns_rr_list_free(new);
00345         }
00346         return ret;
00347 }
00348 
00349 bool
00350 ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00351 {
00352         ldns_rr_list *rrs;
00353         uint16_t rr_count;
00354         uint16_t i;
00355 
00356         rrs = ldns_pkt_get_section_clone(pkt, sec);
00357         if (!rrs) {
00358                 return false;
00359         }
00360         rr_count = ldns_rr_list_rr_count(rrs);
00361         
00362         /* walk the rrs and compare them with rr */     
00363         for(i = 0; i < rr_count; i++) {
00364                 if (ldns_rr_compare(ldns_rr_list_rr(rrs, i), rr) == 0) {
00365                         /* a match */
00366                         return true;
00367                 }
00368         }
00369         return false;
00370 }
00371 
00372 uint16_t
00373 ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
00374 {
00375         switch(s) {
00376         case LDNS_SECTION_QUESTION:
00377                 return ldns_pkt_qdcount(packet);
00378         case LDNS_SECTION_ANSWER:
00379                 return ldns_pkt_ancount(packet);
00380         case LDNS_SECTION_AUTHORITY:
00381                 return ldns_pkt_nscount(packet);
00382         case LDNS_SECTION_ADDITIONAL:
00383                 return ldns_pkt_arcount(packet);
00384         case LDNS_SECTION_ANY:
00385                 return ldns_pkt_qdcount(packet) +
00386                         ldns_pkt_ancount(packet) +
00387                         ldns_pkt_nscount(packet) +
00388                         ldns_pkt_arcount(packet);
00389         case LDNS_SECTION_ANY_NOQUESTION:
00390                 return ldns_pkt_ancount(packet) +
00391                         ldns_pkt_nscount(packet) +
00392                         ldns_pkt_arcount(packet);
00393         default:
00394                 return 0;
00395         }
00396 }
00397 
00398 bool
00399 ldns_pkt_empty(ldns_pkt *p)
00400 {
00401         if (!p) {
00402                 return true; /* NULL is empty? */
00403         }
00404         if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
00405                 return true;
00406         } else
00407                 return false;
00408 }
00409 
00410 
00411 ldns_rr_list *
00412 ldns_pkt_get_section_clone(ldns_pkt *packet, ldns_pkt_section s)
00413 {
00414         switch(s) {
00415         case LDNS_SECTION_QUESTION:
00416                 return ldns_rr_list_clone(ldns_pkt_question(packet));
00417         case LDNS_SECTION_ANSWER:
00418                 return ldns_rr_list_clone(ldns_pkt_answer(packet));
00419         case LDNS_SECTION_AUTHORITY:
00420                 return ldns_rr_list_clone(ldns_pkt_authority(packet));
00421         case LDNS_SECTION_ADDITIONAL:
00422                 return ldns_rr_list_clone(ldns_pkt_additional(packet));
00423         case LDNS_SECTION_ANY:
00424                 /* these are already clones */
00425                 return ldns_pkt_all(packet);
00426         case LDNS_SECTION_ANY_NOQUESTION:
00427                 return ldns_pkt_all_noquestion(packet);
00428         default:
00429                 return NULL;
00430         }
00431 }
00432 
00433 ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
00434         return pkt->_tsig_rr;
00435 }
00436 
00437 /* write */
00438 void
00439 ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
00440 {
00441         packet->_header->_id = id;
00442 }
00443 
00444 void
00445 ldns_pkt_set_random_id(ldns_pkt *packet)
00446 {
00447         uint16_t rid = 0;
00448 #ifdef HAVE_SSL
00449         unsigned char *rb;
00450         rb = LDNS_XMALLOC(unsigned char, 2);
00451         if (RAND_bytes(rb, 2) == 1) {
00452                 rid = ldns_read_uint16(rb);
00453         }
00454         LDNS_FREE(rb);
00455 #endif
00456         if (rid == 0) {
00457                 rid = (uint16_t) random();
00458         }
00459 
00460         ldns_pkt_set_id(packet, rid);
00461 }
00462 
00463 
00464 void
00465 ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
00466 {
00467         packet->_header->_qr = qr;
00468 }
00469 
00470 void
00471 ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
00472 {
00473         packet->_header->_aa = aa;
00474 }
00475 
00476 void
00477 ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
00478 {
00479         packet->_header->_tc = tc;
00480 }
00481 
00482 void
00483 ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
00484 {
00485         packet->_header->_rd = rd;
00486 }
00487 
00488 void
00489 ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
00490 {
00491         p->_additional = rr;
00492 }
00493 
00494 void
00495 ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
00496 {
00497         p->_question = rr;
00498 }
00499 
00500 void
00501 ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
00502 {
00503         p->_answer = rr;
00504 }
00505 
00506 void
00507 ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
00508 {
00509         p->_authority = rr;
00510 }
00511 
00512 void
00513 ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
00514 {
00515         packet->_header->_cd = cd;
00516 }
00517 
00518 void
00519 ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
00520 {
00521         packet->_header->_ra = ra;
00522 }
00523 
00524 void
00525 ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
00526 {
00527         packet->_header->_ad = ad;
00528 }
00529 
00530 void
00531 ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
00532 {
00533         packet->_header->_opcode = opcode;
00534 }
00535 
00536 void
00537 ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
00538 {
00539         packet->_header->_rcode = rcode;
00540 }
00541 
00542 void
00543 ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
00544 {
00545         packet->_header->_qdcount = qdcount;
00546 }
00547 
00548 void
00549 ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
00550 {
00551         packet->_header->_ancount = ancount;
00552 }
00553 
00554 void
00555 ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
00556 {
00557         packet->_header->_nscount = nscount;
00558 }
00559 
00560 void
00561 ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
00562 {
00563         packet->_header->_arcount = arcount;
00564 }
00565 
00566 void
00567 ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 
00568 {
00569         packet->_querytime = time;
00570 }
00571 
00572 void
00573 ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
00574 {
00575         packet->_answerfrom = answerfrom;
00576 }
00577 
00578 void
00579 ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
00580 {
00581         packet->timestamp.tv_sec = timeval.tv_sec;
00582         packet->timestamp.tv_usec = timeval.tv_usec;
00583 }
00584 
00585 void
00586 ldns_pkt_set_size(ldns_pkt *packet, size_t s)
00587 {
00588         packet->_size = s;
00589 }
00590 
00591 void
00592 ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
00593 {
00594         packet->_edns_udp_size = s;
00595 }
00596 
00597 void
00598 ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
00599 {
00600         packet->_edns_extended_rcode = c;
00601 }
00602 
00603 void
00604 ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
00605 {
00606         packet->_edns_version = v;
00607 }
00608 
00609 void
00610 ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
00611 {
00612         packet->_edns_z = z;
00613 }
00614 
00615 void
00616 ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
00617 {
00618         packet->_edns_data = data;
00619 }
00620 
00621 void
00622 ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
00623 {
00624         switch(s) {
00625                 case LDNS_SECTION_QUESTION:
00626                         ldns_pkt_set_qdcount(packet, count);
00627                         break;
00628                 case LDNS_SECTION_ANSWER:
00629                         ldns_pkt_set_ancount(packet, count);
00630                         break;
00631                 case LDNS_SECTION_AUTHORITY:
00632                         ldns_pkt_set_nscount(packet, count);
00633                         break;
00634                 case LDNS_SECTION_ADDITIONAL:
00635                         ldns_pkt_set_arcount(packet, count);
00636                         break;
00637                 case LDNS_SECTION_ANY:
00638                 case LDNS_SECTION_ANY_NOQUESTION:
00639                         break;
00640         }
00641 }
00642 
00643 void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
00644 {
00645         pkt->_tsig_rr = rr;
00646 }
00647 
00648 bool
00649 ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
00650 {
00651         switch(section) {
00652                 case LDNS_SECTION_QUESTION:
00653                         ldns_rr_list_push_rr(ldns_pkt_question(packet), rr);
00654                         ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
00655                         break;
00656                 case LDNS_SECTION_ANSWER:
00657                         ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr);
00658                         ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
00659                         break;
00660                 case LDNS_SECTION_AUTHORITY:
00661                         ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr);
00662                         ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
00663                         break;
00664                 case LDNS_SECTION_ADDITIONAL:
00665                         ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr);
00666                         ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
00667                         break;
00668                 case LDNS_SECTION_ANY:
00669                 case LDNS_SECTION_ANY_NOQUESTION:
00670                         /* shouldn't this error? */
00671                         break;
00672         }
00673         return true;
00674 }
00675 
00676 bool
00677 ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00678 {
00679 
00680         /* check to see if its there */
00681         if (ldns_pkt_rr(pkt, sec, rr)) {
00682                 /* already there */
00683                 return false;
00684         }
00685         return ldns_pkt_push_rr(pkt, sec, rr);
00686 }
00687 
00688 bool
00689 ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00690 {
00691         size_t i;
00692         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00693                 if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00694                         return false;
00695                 }
00696         }
00697         return true;
00698 }
00699 
00700 bool
00701 ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00702 {
00703         size_t i;
00704         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00705                 if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00706                         return false;
00707                 }
00708         }
00709         return true;
00710 }
00711 
00712 bool
00713 ldns_pkt_edns(const ldns_pkt *pkt) {
00714         return (ldns_pkt_edns_udp_size(pkt) > 0 ||
00715                 ldns_pkt_edns_extended_rcode(pkt) > 0 ||
00716                 ldns_pkt_edns_data(pkt)
00717                );
00718 }
00719 
00720 
00721 /* Create/destroy/convert functions
00722  */
00723 ldns_pkt *
00724 ldns_pkt_new()
00725 {
00726         ldns_pkt *packet;
00727         packet = LDNS_MALLOC(ldns_pkt);
00728         if (!packet) {
00729                 return NULL;
00730         }
00731 
00732         packet->_header = LDNS_MALLOC(ldns_hdr);
00733         if (!packet->_header) {
00734                 LDNS_FREE(packet);
00735                 return NULL;
00736         }
00737 
00738         packet->_question = ldns_rr_list_new();
00739         packet->_answer = ldns_rr_list_new();
00740         packet->_authority = ldns_rr_list_new();
00741         packet->_additional = ldns_rr_list_new();
00742 
00743         /* default everything to false */
00744         ldns_pkt_set_qr(packet, false);
00745         ldns_pkt_set_aa(packet, false);
00746         ldns_pkt_set_tc(packet, false);
00747         ldns_pkt_set_rd(packet, false);
00748         ldns_pkt_set_ra(packet, false);
00749         ldns_pkt_set_ad(packet, false);
00750         ldns_pkt_set_cd(packet, false);
00751 
00752         ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
00753         ldns_pkt_set_rcode(packet, 0);
00754         ldns_pkt_set_id(packet, 0); 
00755         ldns_pkt_set_size(packet, 0);
00756         ldns_pkt_set_querytime(packet, 0);
00757         memset(&packet->timestamp, 0, sizeof(packet->timestamp));
00758         ldns_pkt_set_answerfrom(packet, NULL);
00759         ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
00760         ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
00761         ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
00762         ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
00763         
00764         ldns_pkt_set_edns_udp_size(packet, 0);
00765         ldns_pkt_set_edns_extended_rcode(packet, 0);
00766         ldns_pkt_set_edns_version(packet, 0);
00767         ldns_pkt_set_edns_z(packet, 0);
00768         ldns_pkt_set_edns_data(packet, NULL);
00769         
00770         ldns_pkt_set_tsig(packet, NULL);
00771         
00772         return packet;
00773 }
00774 
00775 void
00776 ldns_pkt_free(ldns_pkt *packet)
00777 {
00778         if (packet) {
00779                 LDNS_FREE(packet->_header);
00780                 ldns_rr_list_deep_free(packet->_question);
00781                 ldns_rr_list_deep_free(packet->_answer);
00782                 ldns_rr_list_deep_free(packet->_authority);
00783                 ldns_rr_list_deep_free(packet->_additional);
00784                 ldns_rr_free(packet->_tsig_rr);
00785                 LDNS_FREE(packet);
00786         }
00787 }
00788 
00789 bool
00790 ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
00791 {
00792         if (!packet) {
00793                 return false;
00794         }
00795         if ((flags & LDNS_QR) == LDNS_QR) {
00796                 ldns_pkt_set_qr(packet, true);
00797         }
00798         if ((flags & LDNS_AA) == LDNS_AA) {
00799                 ldns_pkt_set_aa(packet, true);
00800         }
00801         if ((flags & LDNS_RD) == LDNS_RD) {
00802                 ldns_pkt_set_rd(packet, true);
00803         }
00804         if ((flags & LDNS_TC) == LDNS_TC) {
00805                 ldns_pkt_set_tc(packet, true);
00806         }
00807         if ((flags & LDNS_CD) == LDNS_CD) {
00808                 ldns_pkt_set_cd(packet, true);
00809         }
00810         if ((flags & LDNS_RA) == LDNS_RA) {
00811                 ldns_pkt_set_ra(packet, true);
00812         }
00813         if ((flags & LDNS_AD) == LDNS_AD) {
00814                 ldns_pkt_set_ad(packet, true);
00815         }
00816         return true;
00817 }
00818 
00819 ldns_status
00820 ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, ldns_rr_type rr_type, 
00821                 ldns_rr_class rr_class, uint16_t flags)
00822 {
00823         ldns_pkt *packet;
00824         ldns_rr *question_rr;
00825         ldns_rdf *name_rdf;
00826 
00827         packet = ldns_pkt_new();
00828         if (!packet) {
00829                 return LDNS_STATUS_MEM_ERR;
00830         }
00831         
00832         if (!ldns_pkt_set_flags(packet, flags)) {
00833                 return LDNS_STATUS_ERR;
00834         }
00835         
00836         question_rr = ldns_rr_new();
00837         if (!question_rr) {
00838                 return LDNS_STATUS_MEM_ERR;
00839         }
00840 
00841         if (rr_type == 0) {
00842                 rr_type = LDNS_RR_TYPE_A;
00843         }
00844         if (rr_class == 0) {
00845                 rr_class = LDNS_RR_CLASS_IN;
00846         }
00847 
00848         if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
00849                 ldns_rr_set_owner(question_rr, name_rdf);
00850                 ldns_rr_set_type(question_rr, rr_type);
00851                 ldns_rr_set_class(question_rr, rr_class);
00852                 
00853                 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
00854         } else {
00855                 ldns_rr_free(question_rr);
00856                 ldns_pkt_free(packet);
00857                 return LDNS_STATUS_ERR;
00858         }
00859         
00860         packet->_tsig_rr = NULL;
00861         
00862         ldns_pkt_set_answerfrom(packet, NULL);
00863         if (p) {
00864                 *p = packet;
00865                 return LDNS_STATUS_OK;
00866         } else {
00867                 return LDNS_STATUS_NULL;
00868         }
00869 }
00870 
00871 ldns_pkt *
00872 ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class,
00873                 uint16_t flags)
00874 {
00875         ldns_pkt *packet;
00876         ldns_rr *question_rr;
00877 
00878         packet = ldns_pkt_new();
00879         if (!packet) {
00880                 return NULL;
00881         }
00882 
00883         if (!ldns_pkt_set_flags(packet, flags)) {
00884                 return NULL;
00885         }
00886         
00887         question_rr = ldns_rr_new();
00888         if (!question_rr) {
00889                 return NULL;
00890         }
00891 
00892         if (rr_type == 0) {
00893                 rr_type = LDNS_RR_TYPE_A;
00894         }
00895         if (rr_class == 0) {
00896                 rr_class = LDNS_RR_CLASS_IN;
00897         }
00898 
00899         ldns_rr_set_owner(question_rr, rr_name);
00900         ldns_rr_set_type(question_rr, rr_type);
00901         ldns_rr_set_class(question_rr, rr_class);
00902         
00903         packet->_tsig_rr = NULL;
00904         
00905         ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
00906 
00907         return packet;
00908 }
00909 
00910 ldns_pkt_type
00911 ldns_pkt_reply_type(ldns_pkt *p)
00912 {
00913         ldns_rr_list *tmp;
00914 
00915         if (!p) {
00916                 return LDNS_PACKET_UNKNOWN;
00917         }
00918 
00919         if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
00920                 return LDNS_PACKET_NXDOMAIN;
00921         }
00922 
00923         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
00924                         && ldns_pkt_nscount(p) == 1) {
00925 
00926                 /* check for SOA */
00927                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 
00928                                         LDNS_SECTION_AUTHORITY);
00929                 if (tmp) {
00930                         ldns_rr_list_deep_free(tmp);
00931                         return LDNS_PACKET_NODATA;
00932                 } else {
00933                         /* I have no idea ... */
00934                 }
00935         }
00936 
00937         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
00938                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
00939                                                LDNS_SECTION_AUTHORITY);
00940                 if (tmp) {
00941                         /* there are nameservers here */
00942                         ldns_rr_list_deep_free(tmp);
00943                         return LDNS_PACKET_REFERRAL;
00944                 } else {
00945                         /* I have no idea */
00946                 }
00947                 ldns_rr_list_deep_free(tmp);
00948         }
00949         
00950         /* if we cannot determine the packet type, we say it's an 
00951          * answer...
00952          */
00953         return LDNS_PACKET_ANSWER;
00954 }
00955 
00956 ldns_pkt *
00957 ldns_pkt_clone(ldns_pkt *pkt)
00958 {
00959         ldns_pkt *new_pkt;
00960         
00961         if (!pkt) {
00962                 return NULL;
00963         }
00964         new_pkt = ldns_pkt_new();
00965 
00966         ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
00967         ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
00968         ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
00969         ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
00970         ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
00971         ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
00972         ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
00973         ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
00974         ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
00975         ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
00976         ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
00977         ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
00978         ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
00979         ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
00980         ldns_pkt_set_answerfrom(new_pkt, ldns_pkt_answerfrom(pkt));
00981         ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
00982         ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
00983         ldns_pkt_set_tsig(new_pkt, ldns_pkt_tsig(pkt));
00984         
00985         /* todo: edns? jelte?? */
00986         ldns_rr_list_deep_free(new_pkt->_question);
00987         ldns_rr_list_deep_free(new_pkt->_answer);
00988         ldns_rr_list_deep_free(new_pkt->_authority);
00989         ldns_rr_list_deep_free(new_pkt->_additional);
00990         new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
00991         new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
00992         new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
00993         new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
00994         return new_pkt;
00995 }

Generated on Thu Nov 29 13:38:26 2007 for ldns by  doxygen 1.5.2