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 /* Access functions 
00021  * do this as functions to get type checking
00022  */
00023 
00024 #define LDNS_EDNS_MASK_DO_BIT 0x8000
00025 
00026 /* TODO defines for 3600 */
00027 /* convert to and from numerical flag values */
00028 ldns_lookup_table ldns_edns_flags[] = {
00029         { 3600, "do"},
00030         { 0, NULL}
00031 };
00032 
00033 /* read */
00034 uint16_t
00035 ldns_pkt_id(const ldns_pkt *packet)
00036 {
00037         return packet->_header->_id;
00038 }
00039 
00040 bool
00041 ldns_pkt_qr(const ldns_pkt *packet)
00042 {
00043         return packet->_header->_qr;
00044 }
00045 
00046 bool
00047 ldns_pkt_aa(const ldns_pkt *packet)
00048 {
00049         return packet->_header->_aa;
00050 }
00051 
00052 bool
00053 ldns_pkt_tc(const ldns_pkt *packet)
00054 {
00055         return packet->_header->_tc;
00056 }
00057 
00058 bool
00059 ldns_pkt_rd(const ldns_pkt *packet)
00060 {
00061         return packet->_header->_rd;
00062 }
00063 
00064 bool
00065 ldns_pkt_cd(const ldns_pkt *packet)
00066 {
00067         return packet->_header->_cd;
00068 }
00069 
00070 bool
00071 ldns_pkt_ra(const ldns_pkt *packet)
00072 {
00073         return packet->_header->_ra;
00074 }
00075 
00076 bool
00077 ldns_pkt_ad(const ldns_pkt *packet)
00078 {
00079         return packet->_header->_ad;
00080 }
00081 
00082 ldns_pkt_opcode
00083 ldns_pkt_get_opcode(const ldns_pkt *packet)
00084 {
00085         return packet->_header->_opcode;
00086 }
00087 
00088 ldns_pkt_rcode
00089 ldns_pkt_get_rcode(const ldns_pkt *packet)
00090 {
00091         return packet->_header->_rcode;
00092 }
00093 
00094 uint16_t
00095 ldns_pkt_qdcount(const ldns_pkt *packet)
00096 {
00097         return packet->_header->_qdcount;
00098 }
00099 
00100 uint16_t
00101 ldns_pkt_ancount(const ldns_pkt *packet)
00102 {
00103         return packet->_header->_ancount;
00104 }
00105 
00106 uint16_t
00107 ldns_pkt_nscount(const ldns_pkt *packet)
00108 {
00109         return packet->_header->_nscount;
00110 }
00111 
00112 uint16_t
00113 ldns_pkt_arcount(const ldns_pkt *packet)
00114 {
00115         return packet->_header->_arcount;
00116 }
00117 
00118 ldns_rr_list *
00119 ldns_pkt_question(const ldns_pkt *packet)
00120 {
00121         return packet->_question;
00122 }
00123 
00124 ldns_rr_list *
00125 ldns_pkt_answer(const ldns_pkt *packet)
00126 {
00127         return packet->_answer;
00128 }
00129 
00130 ldns_rr_list *
00131 ldns_pkt_authority(const ldns_pkt *packet)
00132 {
00133         return packet->_authority;
00134 }
00135 
00136 ldns_rr_list *
00137 ldns_pkt_additional(const ldns_pkt *packet)
00138 {
00139         return packet->_additional;
00140 }
00141 
00142 /* return ALL section concatenated */
00143 ldns_rr_list *
00144 ldns_pkt_all(ldns_pkt *packet)
00145 {
00146         ldns_rr_list *all, *prev_all;
00147 
00148         all = ldns_rr_list_cat_clone(
00149                         ldns_pkt_question(packet),
00150                         ldns_pkt_answer(packet));
00151         prev_all = all;
00152         all = ldns_rr_list_cat_clone(all,
00153                         ldns_pkt_authority(packet));
00154         ldns_rr_list_deep_free(prev_all);
00155         prev_all = all;
00156         all = ldns_rr_list_cat_clone(all,
00157                         ldns_pkt_additional(packet));
00158         ldns_rr_list_deep_free(prev_all);
00159         return all;
00160 }
00161 
00162 ldns_rr_list *
00163 ldns_pkt_all_noquestion(ldns_pkt *packet)
00164 {
00165         ldns_rr_list *all, *all2;
00166 
00167         all = ldns_rr_list_cat_clone(
00168                         ldns_pkt_answer(packet),
00169                         ldns_pkt_authority(packet));
00170         all2 = ldns_rr_list_cat_clone(all,
00171                         ldns_pkt_additional(packet));
00172         
00173         ldns_rr_list_deep_free(all);
00174         return all2;
00175 }
00176 
00177 size_t
00178 ldns_pkt_size(const ldns_pkt *packet)
00179 {
00180         return packet->_size;
00181 }
00182 
00183 uint32_t 
00184 ldns_pkt_querytime(const ldns_pkt *packet)
00185 {
00186         return packet->_querytime;
00187 }
00188 
00189 ldns_rdf *
00190 ldns_pkt_answerfrom(const ldns_pkt *packet)
00191 {
00192         return packet->_answerfrom;
00193 }
00194 
00195 struct timeval
00196 ldns_pkt_timestamp(const ldns_pkt *packet)
00197 {
00198         return packet->timestamp;
00199 }
00200 
00201 uint16_t
00202 ldns_pkt_edns_udp_size(const ldns_pkt *packet)
00203 {
00204         return packet->_edns_udp_size;
00205 }
00206 
00207 uint8_t
00208 ldns_pkt_edns_extended_rcode(const ldns_pkt *packet)
00209 {
00210         return packet->_edns_extended_rcode;
00211 }
00212 
00213 uint8_t
00214 ldns_pkt_edns_version(const ldns_pkt *packet)
00215 {
00216         return packet->_edns_version;
00217 }
00218 
00219 uint16_t
00220 ldns_pkt_edns_z(const ldns_pkt *packet)
00221 {
00222         return packet->_edns_z;
00223 }
00224 
00225 bool
00226 ldns_pkt_edns_do(const ldns_pkt *packet)
00227 {
00228         return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT);
00229 }
00230 
00231 void
00232 ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
00233 {
00234         if (value) {
00235                 packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT;
00236         } else {
00237                 packet->_edns_z = packet->_edns_z & !LDNS_EDNS_MASK_DO_BIT;
00238         }
00239 }
00240 
00241 ldns_rdf *
00242 ldns_pkt_edns_data(const ldns_pkt *packet)
00243 {
00244         return packet->_edns_data;
00245 }
00246 
00247 /* return only those rr that share the ownername */
00248 ldns_rr_list *
00249 ldns_pkt_rr_list_by_name(ldns_pkt *packet, ldns_rdf *ownername, ldns_pkt_section sec)
00250 {
00251         ldns_rr_list *rrs;
00252         ldns_rr_list *new;
00253         ldns_rr_list *ret;
00254         uint16_t i;
00255 
00256         if (!packet) {
00257                 return NULL;
00258         }
00259 
00260         rrs = ldns_pkt_get_section_clone(packet, sec);
00261         new = ldns_rr_list_new();
00262         ret = NULL;
00263 
00264         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00265                 if (ldns_rdf_compare(ldns_rr_owner(
00266                                                 ldns_rr_list_rr(rrs, i)), 
00267                                         ownername) == 0) {
00268                         /* owner names match */
00269                         ldns_rr_list_push_rr(new, ldns_rr_list_rr(rrs, i));
00270                         ret = new;
00271                 }
00272         }
00273         return ret;
00274 }
00275 
00276 /* return only those rr that share a type */
00277 ldns_rr_list *
00278 ldns_pkt_rr_list_by_type(ldns_pkt *packet, ldns_rr_type type, ldns_pkt_section sec)
00279 {
00280         ldns_rr_list *rrs;
00281         ldns_rr_list *new;
00282         uint16_t i;
00283 
00284         if(!packet) {
00285                 return NULL;
00286         }
00287         
00288         rrs = ldns_pkt_get_section_clone(packet, sec);
00289         new = ldns_rr_list_new();
00290         
00291         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00292                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) {
00293                         /* types match */
00294                         ldns_rr_list_push_rr(new, 
00295                                              ldns_rr_clone(
00296                                                 ldns_rr_list_rr(rrs, i))
00297                                              );
00298                 }
00299         }
00300         ldns_rr_list_deep_free(rrs);
00301 
00302         if (ldns_rr_list_rr_count(new) == 0) {
00303                 ldns_rr_list_free(new);
00304                 return NULL;
00305         } else {
00306                 return new;
00307         }
00308 }
00309 
00310 /* return only those rrs that share name and type */
00311 ldns_rr_list *
00312 ldns_pkt_rr_list_by_name_and_type(ldns_pkt *packet, ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec)
00313 {
00314         ldns_rr_list *rrs;
00315         ldns_rr_list *new;
00316         ldns_rr_list *ret;
00317         uint16_t i;
00318 
00319         if(!packet) {
00320                 return NULL;
00321         }
00322         
00323         rrs = ldns_pkt_get_section_clone(packet, sec);
00324         new = ldns_rr_list_new();
00325         ret = NULL;
00326 
00327         for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) {
00328                 if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) &&
00329                     ldns_rdf_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)),
00330                                      ownername
00331                                     ) == 0
00332                    ) {
00333                         /* types match */
00334                         ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i)));
00335                         ret = new;
00336                 }
00337         }
00338         ldns_rr_list_deep_free(rrs);
00339         if (!ret) {
00340                 ldns_rr_list_free(new);
00341         }
00342         return ret;
00343 }
00344 
00345 bool
00346 ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00347 {
00348         ldns_rr_list *rrs;
00349         uint16_t rr_count;
00350         uint16_t i;
00351 
00352         rrs = ldns_pkt_get_section_clone(pkt, sec);
00353         if (!rrs) {
00354                 return false;
00355         }
00356         rr_count = ldns_rr_list_rr_count(rrs);
00357         
00358         /* walk the rrs and compare them with rr */     
00359         for(i = 0; i < rr_count; i++) {
00360                 if (ldns_rr_compare(ldns_rr_list_rr(rrs, i), rr) == 0) {
00361                         /* a match */
00362                         return true;
00363                 }
00364         }
00365         return false;
00366 }
00367 
00368 uint16_t
00369 ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s)
00370 {
00371         switch(s) {
00372         case LDNS_SECTION_QUESTION:
00373                 return ldns_pkt_qdcount(packet);
00374         case LDNS_SECTION_ANSWER:
00375                 return ldns_pkt_ancount(packet);
00376         case LDNS_SECTION_AUTHORITY:
00377                 return ldns_pkt_nscount(packet);
00378         case LDNS_SECTION_ADDITIONAL:
00379                 return ldns_pkt_arcount(packet);
00380         case LDNS_SECTION_ANY:
00381                 return ldns_pkt_qdcount(packet) +
00382                         ldns_pkt_ancount(packet) +
00383                         ldns_pkt_nscount(packet) +
00384                         ldns_pkt_arcount(packet);
00385         case LDNS_SECTION_ANY_NOQUESTION:
00386                 return ldns_pkt_ancount(packet) +
00387                         ldns_pkt_nscount(packet) +
00388                         ldns_pkt_arcount(packet);
00389         default:
00390                 return 0;
00391         }
00392 }
00393 
00394 bool
00395 ldns_pkt_empty(ldns_pkt *p)
00396 {
00397         if (!p) {
00398                 return true; /* NULL is empty? */
00399         }
00400         if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) {
00401                 return true;
00402         } else
00403                 return false;
00404 }
00405 
00406 
00407 ldns_rr_list *
00408 ldns_pkt_get_section_clone(ldns_pkt *packet, ldns_pkt_section s)
00409 {
00410         switch(s) {
00411         case LDNS_SECTION_QUESTION:
00412                 return ldns_rr_list_clone(ldns_pkt_question(packet));
00413         case LDNS_SECTION_ANSWER:
00414                 return ldns_rr_list_clone(ldns_pkt_answer(packet));
00415         case LDNS_SECTION_AUTHORITY:
00416                 return ldns_rr_list_clone(ldns_pkt_authority(packet));
00417         case LDNS_SECTION_ADDITIONAL:
00418                 return ldns_rr_list_clone(ldns_pkt_additional(packet));
00419         case LDNS_SECTION_ANY:
00420                 /* these are already clones */
00421                 return ldns_pkt_all(packet);
00422         case LDNS_SECTION_ANY_NOQUESTION:
00423                 return ldns_pkt_all_noquestion(packet);
00424         default:
00425                 return NULL;
00426         }
00427 }
00428 
00429 ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) {
00430         return pkt->_tsig_rr;
00431 }
00432 
00433 /* write */
00434 void
00435 ldns_pkt_set_id(ldns_pkt *packet, uint16_t id)
00436 {
00437         packet->_header->_id = id;
00438 }
00439 
00440 void
00441 ldns_pkt_set_random_id(ldns_pkt *packet)
00442 {
00443         /* TODO: time is a terrible seed */
00444         srandom((unsigned) time(NULL) ^ getpid());
00445         ldns_pkt_set_id(packet, (uint16_t)random());
00446 }
00447 
00448 
00449 void
00450 ldns_pkt_set_qr(ldns_pkt *packet, bool qr)
00451 {
00452         packet->_header->_qr = qr;
00453 }
00454 
00455 void
00456 ldns_pkt_set_aa(ldns_pkt *packet, bool aa)
00457 {
00458         packet->_header->_aa = aa;
00459 }
00460 
00461 void
00462 ldns_pkt_set_tc(ldns_pkt *packet, bool tc)
00463 {
00464         packet->_header->_tc = tc;
00465 }
00466 
00467 void
00468 ldns_pkt_set_rd(ldns_pkt *packet, bool rd)
00469 {
00470         packet->_header->_rd = rd;
00471 }
00472 
00473 void
00474 ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr)
00475 {
00476         p->_additional = rr;
00477 }
00478 
00479 void
00480 ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr)
00481 {
00482         p->_question = rr;
00483 }
00484 
00485 void
00486 ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr)
00487 {
00488         p->_answer = rr;
00489 }
00490 
00491 void
00492 ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr)
00493 {
00494         p->_authority = rr;
00495 }
00496 
00497 void
00498 ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
00499 {
00500         packet->_header->_cd = cd;
00501 }
00502 
00503 void
00504 ldns_pkt_set_ra(ldns_pkt *packet, bool ra)
00505 {
00506         packet->_header->_ra = ra;
00507 }
00508 
00509 void
00510 ldns_pkt_set_ad(ldns_pkt *packet, bool ad)
00511 {
00512         packet->_header->_ad = ad;
00513 }
00514 
00515 void
00516 ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode)
00517 {
00518         packet->_header->_opcode = opcode;
00519 }
00520 
00521 void
00522 ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode)
00523 {
00524         packet->_header->_rcode = rcode;
00525 }
00526 
00527 void
00528 ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount)
00529 {
00530         packet->_header->_qdcount = qdcount;
00531 }
00532 
00533 void
00534 ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount)
00535 {
00536         packet->_header->_ancount = ancount;
00537 }
00538 
00539 void
00540 ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount)
00541 {
00542         packet->_header->_nscount = nscount;
00543 }
00544 
00545 void
00546 ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount)
00547 {
00548         packet->_header->_arcount = arcount;
00549 }
00550 
00551 void
00552 ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 
00553 {
00554         packet->_querytime = time;
00555 }
00556 
00557 void
00558 ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom)
00559 {
00560         packet->_answerfrom = answerfrom;
00561 }
00562 
00563 void
00564 ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
00565 {
00566         packet->timestamp.tv_sec = timeval.tv_sec;
00567         packet->timestamp.tv_usec = timeval.tv_usec;
00568 }
00569 
00570 void
00571 ldns_pkt_set_size(ldns_pkt *packet, size_t s)
00572 {
00573         packet->_size = s;
00574 }
00575 
00576 void
00577 ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
00578 {
00579         packet->_edns_udp_size = s;
00580 }
00581 
00582 void
00583 ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c)
00584 {
00585         packet->_edns_extended_rcode = c;
00586 }
00587 
00588 void
00589 ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v)
00590 {
00591         packet->_edns_version = v;
00592 }
00593 
00594 void
00595 ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z)
00596 {
00597         packet->_edns_z = z;
00598 }
00599 
00600 void
00601 ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
00602 {
00603         packet->_edns_data = data;
00604 }
00605 
00606 void
00607 ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count)
00608 {
00609         switch(s) {
00610                 case LDNS_SECTION_QUESTION:
00611                         ldns_pkt_set_qdcount(packet, count);
00612                         break;
00613                 case LDNS_SECTION_ANSWER:
00614                         ldns_pkt_set_ancount(packet, count);
00615                         break;
00616                 case LDNS_SECTION_AUTHORITY:
00617                         ldns_pkt_set_nscount(packet, count);
00618                         break;
00619                 case LDNS_SECTION_ADDITIONAL:
00620                         ldns_pkt_set_arcount(packet, count);
00621                         break;
00622                 case LDNS_SECTION_ANY:
00623                 case LDNS_SECTION_ANY_NOQUESTION:
00624                         break;
00625         }
00626 }
00627 
00628 void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr)
00629 {
00630         pkt->_tsig_rr = rr;
00631 }
00632 
00633 bool
00634 ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr)
00635 {
00636         switch(section) {
00637                 case LDNS_SECTION_QUESTION:
00638                         ldns_rr_list_push_rr(ldns_pkt_question(packet), rr);
00639                         ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1);
00640                         break;
00641                 case LDNS_SECTION_ANSWER:
00642                         ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr);
00643                         ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1);
00644                         break;
00645                 case LDNS_SECTION_AUTHORITY:
00646                         ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr);
00647                         ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1);
00648                         break;
00649                 case LDNS_SECTION_ADDITIONAL:
00650                         ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr);
00651                         ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1);
00652                         break;
00653                 case LDNS_SECTION_ANY:
00654                 case LDNS_SECTION_ANY_NOQUESTION:
00655                         /* shouldn't this error? */
00656                         break;
00657         }
00658         return true;
00659 }
00660 
00661 bool
00662 ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr)
00663 {
00664 
00665         /* check to see if its there */
00666         if (ldns_pkt_rr(pkt, sec, rr)) {
00667                 /* already there */
00668                 return false;
00669         }
00670         return ldns_pkt_push_rr(pkt, sec, rr);
00671 }
00672 
00673 bool
00674 ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00675 {
00676         size_t i;
00677         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00678                 if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00679                         return false;
00680                 }
00681         }
00682         return true;
00683 }
00684 
00685 bool
00686 ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list)
00687 {
00688         size_t i;
00689         for(i = 0; i < ldns_rr_list_rr_count(list); i++) {
00690                 if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) {
00691                         return false;
00692                 }
00693         }
00694         return true;
00695 }
00696 
00697 bool
00698 ldns_pkt_edns(const ldns_pkt *pkt) {
00699         return (ldns_pkt_edns_udp_size(pkt) > 0 ||
00700                 ldns_pkt_edns_extended_rcode(pkt) > 0 ||
00701                 ldns_pkt_edns_data(pkt)
00702                );
00703 }
00704 
00705 
00706 /* Create/destroy/convert functions
00707  */
00708 ldns_pkt *
00709 ldns_pkt_new()
00710 {
00711         ldns_pkt *packet;
00712         packet = LDNS_MALLOC(ldns_pkt);
00713         if (!packet) {
00714                 return NULL;
00715         }
00716 
00717         packet->_header = LDNS_MALLOC(ldns_hdr);
00718         if (!packet->_header) {
00719                 LDNS_FREE(packet);
00720                 return NULL;
00721         }
00722 
00723         packet->_question = ldns_rr_list_new();
00724         packet->_answer = ldns_rr_list_new();
00725         packet->_authority = ldns_rr_list_new();
00726         packet->_additional = ldns_rr_list_new();
00727 
00728         /* default everything to false */
00729         ldns_pkt_set_qr(packet, false);
00730         ldns_pkt_set_aa(packet, false);
00731         ldns_pkt_set_tc(packet, false);
00732         ldns_pkt_set_rd(packet, false);
00733         ldns_pkt_set_ra(packet, false);
00734         ldns_pkt_set_ad(packet, false);
00735         ldns_pkt_set_cd(packet, false);
00736 
00737         ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY);
00738         ldns_pkt_set_rcode(packet, 0);
00739         ldns_pkt_set_id(packet, 0); 
00740         ldns_pkt_set_size(packet, 0);
00741         ldns_pkt_set_querytime(packet, 0);
00742         memset(&packet->timestamp, 0, sizeof(packet->timestamp));
00743         ldns_pkt_set_answerfrom(packet, NULL);
00744         ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0);
00745         ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0);
00746         ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0);
00747         ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0);
00748         
00749         ldns_pkt_set_edns_udp_size(packet, 0);
00750         ldns_pkt_set_edns_extended_rcode(packet, 0);
00751         ldns_pkt_set_edns_version(packet, 0);
00752         ldns_pkt_set_edns_z(packet, 0);
00753         ldns_pkt_set_edns_data(packet, NULL);
00754         
00755         ldns_pkt_set_tsig(packet, NULL);
00756         
00757         return packet;
00758 }
00759 
00760 void
00761 ldns_pkt_free(ldns_pkt *packet)
00762 {
00763         if (packet) {
00764                 LDNS_FREE(packet->_header);
00765                 ldns_rr_list_deep_free(packet->_question);
00766                 ldns_rr_list_deep_free(packet->_answer);
00767                 ldns_rr_list_deep_free(packet->_authority);
00768                 ldns_rr_list_deep_free(packet->_additional);
00769                 ldns_rr_free(packet->_tsig_rr);
00770                 LDNS_FREE(packet);
00771         }
00772 }
00773 
00774 bool
00775 ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags)
00776 {
00777         if (!packet) {
00778                 return false;
00779         }
00780         if ((flags & LDNS_QR) == LDNS_QR) {
00781                 ldns_pkt_set_qr(packet, true);
00782         }
00783         if ((flags & LDNS_AA) == LDNS_AA) {
00784                 ldns_pkt_set_aa(packet, true);
00785         }
00786         if ((flags & LDNS_RD) == LDNS_RD) {
00787                 ldns_pkt_set_rd(packet, true);
00788         }
00789         if ((flags & LDNS_TC) == LDNS_TC) {
00790                 ldns_pkt_set_tc(packet, true);
00791         }
00792         if ((flags & LDNS_CD) == LDNS_CD) {
00793                 ldns_pkt_set_cd(packet, true);
00794         }
00795         if ((flags & LDNS_RA) == LDNS_RA) {
00796                 ldns_pkt_set_ra(packet, true);
00797         }
00798         if ((flags & LDNS_AD) == LDNS_AD) {
00799                 ldns_pkt_set_ad(packet, true);
00800         }
00801         return true;
00802 }
00803 
00804 ldns_status
00805 ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, ldns_rr_type rr_type, 
00806                 ldns_rr_class rr_class, uint16_t flags)
00807 {
00808         ldns_pkt *packet;
00809         ldns_rr *question_rr;
00810         ldns_rdf *name_rdf;
00811 
00812         packet = ldns_pkt_new();
00813         if (!packet) {
00814                 return LDNS_STATUS_MEM_ERR;
00815         }
00816         
00817         if (!ldns_pkt_set_flags(packet, flags)) {
00818                 return LDNS_STATUS_ERR;
00819         }
00820         
00821         question_rr = ldns_rr_new();
00822         if (!question_rr) {
00823                 return LDNS_STATUS_MEM_ERR;
00824         }
00825 
00826         if (rr_type == 0) {
00827                 rr_type = LDNS_RR_TYPE_A;
00828         }
00829         if (rr_class == 0) {
00830                 rr_class = LDNS_RR_CLASS_IN;
00831         }
00832 
00833         if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) {
00834                 ldns_rr_set_owner(question_rr, name_rdf);
00835                 ldns_rr_set_type(question_rr, rr_type);
00836                 ldns_rr_set_class(question_rr, rr_class);
00837                 
00838                 ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
00839         } else {
00840                 ldns_rr_free(question_rr);
00841                 ldns_pkt_free(packet);
00842                 return LDNS_STATUS_ERR;
00843         }
00844         
00845         packet->_tsig_rr = NULL;
00846         
00847         ldns_pkt_set_answerfrom(packet, NULL);
00848         if (p) {
00849                 *p = packet;
00850                 return LDNS_STATUS_OK;
00851         } else {
00852                 return LDNS_STATUS_NULL;
00853         }
00854 }
00855 
00856 ldns_pkt *
00857 ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class,
00858                 uint16_t flags)
00859 {
00860         ldns_pkt *packet;
00861         ldns_rr *question_rr;
00862 
00863         packet = ldns_pkt_new();
00864         if (!packet) {
00865                 return NULL;
00866         }
00867 
00868         if (!ldns_pkt_set_flags(packet, flags)) {
00869                 return NULL;
00870         }
00871         
00872         question_rr = ldns_rr_new();
00873         if (!question_rr) {
00874                 return NULL;
00875         }
00876 
00877         if (rr_type == 0) {
00878                 rr_type = LDNS_RR_TYPE_A;
00879         }
00880         if (rr_class == 0) {
00881                 rr_class = LDNS_RR_CLASS_IN;
00882         }
00883 
00884         ldns_rr_set_owner(question_rr, rr_name);
00885         ldns_rr_set_type(question_rr, rr_type);
00886         ldns_rr_set_class(question_rr, rr_class);
00887         
00888         packet->_tsig_rr = NULL;
00889         
00890         ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr);
00891 
00892         return packet;
00893 }
00894 
00895 ldns_pkt_type
00896 ldns_pkt_reply_type(ldns_pkt *p)
00897 {
00898         ldns_rr_list *tmp;
00899 
00900         if (!p) {
00901                 return LDNS_PACKET_UNKNOWN;
00902         }
00903 
00904         if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) {
00905                 return LDNS_PACKET_NXDOMAIN;
00906         }
00907 
00908         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0
00909                         && ldns_pkt_nscount(p) == 1) {
00910 
00911                 /* check for SOA */
00912                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 
00913                                         LDNS_SECTION_AUTHORITY);
00914                 if (tmp) {
00915                         ldns_rr_list_deep_free(tmp);
00916                         return LDNS_PACKET_NODATA;
00917                 } else {
00918                         /* I have no idea ... */
00919                 }
00920         }
00921 
00922         if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) {
00923                 tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS,
00924                                                LDNS_SECTION_AUTHORITY);
00925                 if (tmp) {
00926                         /* there are nameservers here */
00927                         ldns_rr_list_deep_free(tmp);
00928                         return LDNS_PACKET_REFERRAL;
00929                 } else {
00930                         /* I have no idea */
00931                 }
00932                 ldns_rr_list_deep_free(tmp);
00933         }
00934         
00935         /* if we cannot determine the packet type, we say it's an 
00936          * answer...
00937          */
00938         return LDNS_PACKET_ANSWER;
00939 }
00940 
00941 ldns_pkt *
00942 ldns_pkt_clone(ldns_pkt *pkt)
00943 {
00944         ldns_pkt *new_pkt;
00945         
00946         if (!pkt) {
00947                 return NULL;
00948         }
00949         new_pkt = ldns_pkt_new();
00950 
00951         ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt));
00952         ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt));
00953         ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt));
00954         ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt));
00955         ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt));
00956         ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt));
00957         ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt));
00958         ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt));
00959         ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt));
00960         ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt));
00961         ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt));
00962         ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt));
00963         ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt));
00964         ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt));
00965         ldns_pkt_set_answerfrom(new_pkt, ldns_pkt_answerfrom(pkt));
00966         ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt));
00967         ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt));
00968         ldns_pkt_set_tsig(new_pkt, ldns_pkt_tsig(pkt));
00969         
00970         /* todo: edns? jelte?? */
00971         ldns_rr_list_deep_free(new_pkt->_question);
00972         ldns_rr_list_deep_free(new_pkt->_answer);
00973         ldns_rr_list_deep_free(new_pkt->_authority);
00974         ldns_rr_list_deep_free(new_pkt->_additional);
00975         new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt));
00976         new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt));
00977         new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt));
00978         new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt));
00979         return new_pkt;
00980 }

Generated on Wed Oct 10 16:24:39 2007 for ldns by  doxygen 1.5.2