4 * dns packet implementation
6 * a Net::DNS like library for C
8 * (c) NLnet Labs, 2004-2006
10 * See the file LICENSE for the license
13 #include <ldns/config.h>
15 #include <ldns/ldns.h>
21 #include <openssl/rand.h>
25 * do this as functions to get type checking
28 #define LDNS_EDNS_MASK_DO_BIT 0x8000
29 #define LDNS_EDNS_MASK_UNASSIGNED (0xFFFF & ~LDNS_EDNS_MASK_DO_BIT)
31 /* TODO defines for 3600 */
32 /* convert to and from numerical flag values */
33 ldns_lookup_table ldns_edns_flags
[] = {
40 ldns_pkt_id(const ldns_pkt
*packet
)
42 return packet
->_header
->_id
;
46 ldns_pkt_qr(const ldns_pkt
*packet
)
48 return packet
->_header
->_qr
;
52 ldns_pkt_aa(const ldns_pkt
*packet
)
54 return packet
->_header
->_aa
;
58 ldns_pkt_tc(const ldns_pkt
*packet
)
60 return packet
->_header
->_tc
;
64 ldns_pkt_rd(const ldns_pkt
*packet
)
66 return packet
->_header
->_rd
;
70 ldns_pkt_cd(const ldns_pkt
*packet
)
72 return packet
->_header
->_cd
;
76 ldns_pkt_ra(const ldns_pkt
*packet
)
78 return packet
->_header
->_ra
;
82 ldns_pkt_ad(const ldns_pkt
*packet
)
84 return packet
->_header
->_ad
;
88 ldns_pkt_get_opcode(const ldns_pkt
*packet
)
90 return packet
->_header
->_opcode
;
94 ldns_pkt_get_rcode(const ldns_pkt
*packet
)
96 return packet
->_header
->_rcode
;
100 ldns_pkt_qdcount(const ldns_pkt
*packet
)
102 return packet
->_header
->_qdcount
;
106 ldns_pkt_ancount(const ldns_pkt
*packet
)
108 return packet
->_header
->_ancount
;
112 ldns_pkt_nscount(const ldns_pkt
*packet
)
114 return packet
->_header
->_nscount
;
118 ldns_pkt_arcount(const ldns_pkt
*packet
)
120 return packet
->_header
->_arcount
;
124 ldns_pkt_question(const ldns_pkt
*packet
)
126 return packet
->_question
;
130 ldns_pkt_answer(const ldns_pkt
*packet
)
132 return packet
->_answer
;
136 ldns_pkt_authority(const ldns_pkt
*packet
)
138 return packet
->_authority
;
142 ldns_pkt_additional(const ldns_pkt
*packet
)
144 return packet
->_additional
;
147 /* return ALL section concatenated */
149 ldns_pkt_all(const ldns_pkt
*packet
)
151 ldns_rr_list
*all
, *prev_all
;
153 all
= ldns_rr_list_cat_clone(
154 ldns_pkt_question(packet
),
155 ldns_pkt_answer(packet
));
157 all
= ldns_rr_list_cat_clone(all
,
158 ldns_pkt_authority(packet
));
159 ldns_rr_list_deep_free(prev_all
);
161 all
= ldns_rr_list_cat_clone(all
,
162 ldns_pkt_additional(packet
));
163 ldns_rr_list_deep_free(prev_all
);
168 ldns_pkt_all_noquestion(const ldns_pkt
*packet
)
170 ldns_rr_list
*all
, *all2
;
172 all
= ldns_rr_list_cat_clone(
173 ldns_pkt_answer(packet
),
174 ldns_pkt_authority(packet
));
175 all2
= ldns_rr_list_cat_clone(all
,
176 ldns_pkt_additional(packet
));
178 ldns_rr_list_deep_free(all
);
183 ldns_pkt_size(const ldns_pkt
*packet
)
185 return packet
->_size
;
189 ldns_pkt_querytime(const ldns_pkt
*packet
)
191 return packet
->_querytime
;
195 ldns_pkt_answerfrom(const ldns_pkt
*packet
)
197 return packet
->_answerfrom
;
201 ldns_pkt_timestamp(const ldns_pkt
*packet
)
203 return packet
->timestamp
;
207 ldns_pkt_edns_udp_size(const ldns_pkt
*packet
)
209 return packet
->_edns_udp_size
;
213 ldns_pkt_edns_extended_rcode(const ldns_pkt
*packet
)
215 return packet
->_edns_extended_rcode
;
219 ldns_pkt_edns_version(const ldns_pkt
*packet
)
221 return packet
->_edns_version
;
225 ldns_pkt_edns_z(const ldns_pkt
*packet
)
227 return packet
->_edns_z
;
231 ldns_pkt_edns_do(const ldns_pkt
*packet
)
233 return (packet
->_edns_z
& LDNS_EDNS_MASK_DO_BIT
);
237 ldns_pkt_set_edns_do(ldns_pkt
*packet
, bool value
)
240 packet
->_edns_z
= packet
->_edns_z
| LDNS_EDNS_MASK_DO_BIT
;
242 packet
->_edns_z
= packet
->_edns_z
& ~LDNS_EDNS_MASK_DO_BIT
;
247 ldns_pkt_edns_unassigned(const ldns_pkt
*packet
)
249 return (packet
->_edns_z
& LDNS_EDNS_MASK_UNASSIGNED
);
253 ldns_pkt_set_edns_unassigned(ldns_pkt
*packet
, uint16_t value
)
255 packet
->_edns_z
= (packet
->_edns_z
& ~LDNS_EDNS_MASK_UNASSIGNED
)
256 | (value
& LDNS_EDNS_MASK_UNASSIGNED
);
260 ldns_pkt_edns_data(const ldns_pkt
*packet
)
262 return packet
->_edns_data
;
265 /* return only those rr that share the ownername */
267 ldns_pkt_rr_list_by_name(const ldns_pkt
*packet
,
268 const ldns_rdf
*ownername
,
269 ldns_pkt_section sec
)
279 rrs
= ldns_pkt_get_section_clone(packet
, sec
);
282 for(i
= 0; i
< ldns_rr_list_rr_count(rrs
); i
++) {
283 if (ldns_dname_compare(ldns_rr_owner(
284 ldns_rr_list_rr(rrs
, i
)),
286 /* owner names match */
288 ret
= ldns_rr_list_new();
290 ldns_rr_list_push_rr(ret
,
292 ldns_rr_list_rr(rrs
, i
))
297 ldns_rr_list_deep_free(rrs
);
302 /* return only those rr that share a type */
304 ldns_pkt_rr_list_by_type(const ldns_pkt
*packet
,
306 ldns_pkt_section sec
)
316 rrs
= ldns_pkt_get_section_clone(packet
, sec
);
317 new = ldns_rr_list_new();
319 for(i
= 0; i
< ldns_rr_list_rr_count(rrs
); i
++) {
320 if (type
== ldns_rr_get_type(ldns_rr_list_rr(rrs
, i
))) {
322 ldns_rr_list_push_rr(new,
324 ldns_rr_list_rr(rrs
, i
))
328 ldns_rr_list_deep_free(rrs
);
330 if (ldns_rr_list_rr_count(new) == 0) {
331 ldns_rr_list_free(new);
338 /* return only those rrs that share name and type */
340 ldns_pkt_rr_list_by_name_and_type(const ldns_pkt
*packet
,
341 const ldns_rdf
*ownername
,
343 ldns_pkt_section sec
)
354 rrs
= ldns_pkt_get_section_clone(packet
, sec
);
355 new = ldns_rr_list_new();
358 for(i
= 0; i
< ldns_rr_list_rr_count(rrs
); i
++) {
359 if (type
== ldns_rr_get_type(ldns_rr_list_rr(rrs
, i
)) &&
360 ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs
, i
)),
365 ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs
, i
)));
369 ldns_rr_list_deep_free(rrs
);
371 ldns_rr_list_free(new);
377 ldns_pkt_rr(const ldns_pkt
*pkt
, ldns_pkt_section sec
, const ldns_rr
*rr
)
382 case LDNS_SECTION_QUESTION
:
383 return ldns_rr_list_contains_rr(ldns_pkt_question(pkt
), rr
);
384 case LDNS_SECTION_ANSWER
:
385 return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt
), rr
);
386 case LDNS_SECTION_AUTHORITY
:
387 return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt
), rr
);
388 case LDNS_SECTION_ADDITIONAL
:
389 return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt
), rr
);
390 case LDNS_SECTION_ANY
:
391 result
= ldns_rr_list_contains_rr(ldns_pkt_question(pkt
), rr
);
393 case LDNS_SECTION_ANY_NOQUESTION
:
395 || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt
), rr
)
396 || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt
), rr
)
397 || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt
), rr
);
404 ldns_pkt_section_count(const ldns_pkt
*packet
, ldns_pkt_section s
)
407 case LDNS_SECTION_QUESTION
:
408 return ldns_pkt_qdcount(packet
);
409 case LDNS_SECTION_ANSWER
:
410 return ldns_pkt_ancount(packet
);
411 case LDNS_SECTION_AUTHORITY
:
412 return ldns_pkt_nscount(packet
);
413 case LDNS_SECTION_ADDITIONAL
:
414 return ldns_pkt_arcount(packet
);
415 case LDNS_SECTION_ANY
:
416 return ldns_pkt_qdcount(packet
) +
417 ldns_pkt_ancount(packet
) +
418 ldns_pkt_nscount(packet
) +
419 ldns_pkt_arcount(packet
);
420 case LDNS_SECTION_ANY_NOQUESTION
:
421 return ldns_pkt_ancount(packet
) +
422 ldns_pkt_nscount(packet
) +
423 ldns_pkt_arcount(packet
);
430 ldns_pkt_empty(ldns_pkt
*p
)
433 return true; /* NULL is empty? */
435 if (ldns_pkt_section_count(p
, LDNS_SECTION_ANY
) > 0) {
444 ldns_pkt_get_section_clone(const ldns_pkt
*packet
, ldns_pkt_section s
)
447 case LDNS_SECTION_QUESTION
:
448 return ldns_rr_list_clone(ldns_pkt_question(packet
));
449 case LDNS_SECTION_ANSWER
:
450 return ldns_rr_list_clone(ldns_pkt_answer(packet
));
451 case LDNS_SECTION_AUTHORITY
:
452 return ldns_rr_list_clone(ldns_pkt_authority(packet
));
453 case LDNS_SECTION_ADDITIONAL
:
454 return ldns_rr_list_clone(ldns_pkt_additional(packet
));
455 case LDNS_SECTION_ANY
:
456 /* these are already clones */
457 return ldns_pkt_all(packet
);
458 case LDNS_SECTION_ANY_NOQUESTION
:
459 return ldns_pkt_all_noquestion(packet
);
465 ldns_rr
*ldns_pkt_tsig(const ldns_pkt
*pkt
) {
466 return pkt
->_tsig_rr
;
471 ldns_pkt_set_id(ldns_pkt
*packet
, uint16_t id
)
473 packet
->_header
->_id
= id
;
477 ldns_pkt_set_random_id(ldns_pkt
*packet
)
479 uint16_t rid
= ldns_get_random();
480 ldns_pkt_set_id(packet
, rid
);
485 ldns_pkt_set_qr(ldns_pkt
*packet
, bool qr
)
487 packet
->_header
->_qr
= qr
;
491 ldns_pkt_set_aa(ldns_pkt
*packet
, bool aa
)
493 packet
->_header
->_aa
= aa
;
497 ldns_pkt_set_tc(ldns_pkt
*packet
, bool tc
)
499 packet
->_header
->_tc
= tc
;
503 ldns_pkt_set_rd(ldns_pkt
*packet
, bool rd
)
505 packet
->_header
->_rd
= rd
;
509 ldns_pkt_set_additional(ldns_pkt
*p
, ldns_rr_list
*rr
)
515 ldns_pkt_set_question(ldns_pkt
*p
, ldns_rr_list
*rr
)
521 ldns_pkt_set_answer(ldns_pkt
*p
, ldns_rr_list
*rr
)
527 ldns_pkt_set_authority(ldns_pkt
*p
, ldns_rr_list
*rr
)
533 ldns_pkt_set_cd(ldns_pkt
*packet
, bool cd
)
535 packet
->_header
->_cd
= cd
;
539 ldns_pkt_set_ra(ldns_pkt
*packet
, bool ra
)
541 packet
->_header
->_ra
= ra
;
545 ldns_pkt_set_ad(ldns_pkt
*packet
, bool ad
)
547 packet
->_header
->_ad
= ad
;
551 ldns_pkt_set_opcode(ldns_pkt
*packet
, ldns_pkt_opcode opcode
)
553 packet
->_header
->_opcode
= opcode
;
557 ldns_pkt_set_rcode(ldns_pkt
*packet
, uint8_t rcode
)
559 packet
->_header
->_rcode
= rcode
;
563 ldns_pkt_set_qdcount(ldns_pkt
*packet
, uint16_t qdcount
)
565 packet
->_header
->_qdcount
= qdcount
;
569 ldns_pkt_set_ancount(ldns_pkt
*packet
, uint16_t ancount
)
571 packet
->_header
->_ancount
= ancount
;
575 ldns_pkt_set_nscount(ldns_pkt
*packet
, uint16_t nscount
)
577 packet
->_header
->_nscount
= nscount
;
581 ldns_pkt_set_arcount(ldns_pkt
*packet
, uint16_t arcount
)
583 packet
->_header
->_arcount
= arcount
;
587 ldns_pkt_set_querytime(ldns_pkt
*packet
, uint32_t time
)
589 packet
->_querytime
= time
;
593 ldns_pkt_set_answerfrom(ldns_pkt
*packet
, ldns_rdf
*answerfrom
)
595 packet
->_answerfrom
= answerfrom
;
599 ldns_pkt_set_timestamp(ldns_pkt
*packet
, struct timeval timeval
)
601 packet
->timestamp
.tv_sec
= timeval
.tv_sec
;
602 packet
->timestamp
.tv_usec
= timeval
.tv_usec
;
606 ldns_pkt_set_size(ldns_pkt
*packet
, size_t s
)
612 ldns_pkt_set_edns_udp_size(ldns_pkt
*packet
, uint16_t s
)
614 packet
->_edns_udp_size
= s
;
618 ldns_pkt_set_edns_extended_rcode(ldns_pkt
*packet
, uint8_t c
)
620 packet
->_edns_extended_rcode
= c
;
624 ldns_pkt_set_edns_version(ldns_pkt
*packet
, uint8_t v
)
626 packet
->_edns_version
= v
;
630 ldns_pkt_set_edns_z(ldns_pkt
*packet
, uint16_t z
)
636 ldns_pkt_set_edns_data(ldns_pkt
*packet
, ldns_rdf
*data
)
638 packet
->_edns_data
= data
;
642 ldns_pkt_set_edns_option_list(ldns_pkt
*packet
, ldns_edns_option_list
*list
)
644 if (packet
->_edns_list
)
645 ldns_edns_option_list_deep_free(packet
->_edns_list
);
646 packet
->_edns_list
= list
;
651 ldns_pkt_set_section_count(ldns_pkt
*packet
, ldns_pkt_section s
, uint16_t count
)
654 case LDNS_SECTION_QUESTION
:
655 ldns_pkt_set_qdcount(packet
, count
);
657 case LDNS_SECTION_ANSWER
:
658 ldns_pkt_set_ancount(packet
, count
);
660 case LDNS_SECTION_AUTHORITY
:
661 ldns_pkt_set_nscount(packet
, count
);
663 case LDNS_SECTION_ADDITIONAL
:
664 ldns_pkt_set_arcount(packet
, count
);
666 case LDNS_SECTION_ANY
:
667 case LDNS_SECTION_ANY_NOQUESTION
:
672 void ldns_pkt_set_tsig(ldns_pkt
*pkt
, ldns_rr
*rr
)
678 ldns_pkt_push_rr(ldns_pkt
*packet
, ldns_pkt_section section
, ldns_rr
*rr
)
681 case LDNS_SECTION_QUESTION
:
682 if (!ldns_rr_list_push_rr(ldns_pkt_question(packet
), rr
)) {
685 ldns_pkt_set_qdcount(packet
, ldns_pkt_qdcount(packet
) + 1);
687 case LDNS_SECTION_ANSWER
:
688 if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet
), rr
)) {
691 ldns_pkt_set_ancount(packet
, ldns_pkt_ancount(packet
) + 1);
693 case LDNS_SECTION_AUTHORITY
:
694 if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet
), rr
)) {
697 ldns_pkt_set_nscount(packet
, ldns_pkt_nscount(packet
) + 1);
699 case LDNS_SECTION_ADDITIONAL
:
700 if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet
), rr
)) {
703 ldns_pkt_set_arcount(packet
, ldns_pkt_arcount(packet
) + 1);
705 case LDNS_SECTION_ANY
:
706 case LDNS_SECTION_ANY_NOQUESTION
:
707 /* shouldn't this error? */
714 ldns_pkt_safe_push_rr(ldns_pkt
*pkt
, ldns_pkt_section sec
, ldns_rr
*rr
)
717 /* check to see if its there */
718 if (ldns_pkt_rr(pkt
, sec
, rr
)) {
722 return ldns_pkt_push_rr(pkt
, sec
, rr
);
726 ldns_pkt_push_rr_list(ldns_pkt
*p
, ldns_pkt_section s
, ldns_rr_list
*list
)
729 for(i
= 0; i
< ldns_rr_list_rr_count(list
); i
++) {
730 if (!ldns_pkt_push_rr(p
, s
, ldns_rr_list_rr(list
, i
))) {
738 ldns_pkt_safe_push_rr_list(ldns_pkt
*p
, ldns_pkt_section s
, ldns_rr_list
*list
)
741 for(i
= 0; i
< ldns_rr_list_rr_count(list
); i
++) {
742 if (!ldns_pkt_safe_push_rr(p
, s
, ldns_rr_list_rr(list
, i
))) {
750 ldns_pkt_edns(const ldns_pkt
*pkt
)
752 return (ldns_pkt_edns_udp_size(pkt
) > 0 ||
753 ldns_pkt_edns_extended_rcode(pkt
) > 0 ||
754 ldns_pkt_edns_data(pkt
) ||
755 ldns_pkt_edns_do(pkt
) ||
761 ldns_edns_option_list
*
762 pkt_edns_data2edns_option_list(const ldns_rdf
*edns_data
)
765 ldns_edns_option_list
* edns_list
;
772 max
= ldns_rdf_size(edns_data
);
773 wire
= ldns_rdf_data(edns_data
);
777 if (!(edns_list
= ldns_edns_option_list_new()))
781 ldns_edns_option
* edns
;
784 if (pos
+ 4 > max
) { /* make sure the header is */
785 ldns_edns_option_list_deep_free(edns_list
);
788 ldns_edns_option_code code
= ldns_read_uint16(&wire
[pos
]);
789 size_t size
= ldns_read_uint16(&wire
[pos
+2]);
792 if (pos
+ size
> max
) { /* make sure the size fits the data */
793 ldns_edns_option_list_deep_free(edns_list
);
796 data
= LDNS_XMALLOC(uint8_t, size
);
799 ldns_edns_option_list_deep_free(edns_list
);
802 memcpy(data
, &wire
[pos
], size
);
805 edns
= ldns_edns_new(code
, size
, data
);
808 ldns_edns_option_list_deep_free(edns_list
);
811 if (!ldns_edns_option_list_push(edns_list
, edns
)) {
812 ldns_edns_option_list_deep_free(edns_list
);
820 ldns_edns_option_list
*
821 ldns_pkt_edns_get_option_list(ldns_pkt
*packet
)
823 /* return the list if it already exists */
824 if (packet
->_edns_list
!= NULL
)
825 return packet
->_edns_list
;
827 /* if the list doesn't exists, we create it by parsing the
830 if (!ldns_pkt_edns_data(packet
))
833 return ( packet
->_edns_list
834 = pkt_edns_data2edns_option_list(ldns_pkt_edns_data(packet
)));
838 /* Create/destroy/convert functions
844 packet
= LDNS_MALLOC(ldns_pkt
);
849 packet
->_header
= LDNS_MALLOC(ldns_hdr
);
850 if (!packet
->_header
) {
855 packet
->_question
= ldns_rr_list_new();
856 packet
->_answer
= ldns_rr_list_new();
857 packet
->_authority
= ldns_rr_list_new();
858 packet
->_additional
= ldns_rr_list_new();
860 /* default everything to false */
861 ldns_pkt_set_qr(packet
, false);
862 ldns_pkt_set_aa(packet
, false);
863 ldns_pkt_set_tc(packet
, false);
864 ldns_pkt_set_rd(packet
, false);
865 ldns_pkt_set_ra(packet
, false);
866 ldns_pkt_set_ad(packet
, false);
867 ldns_pkt_set_cd(packet
, false);
869 ldns_pkt_set_opcode(packet
, LDNS_PACKET_QUERY
);
870 ldns_pkt_set_rcode(packet
, 0);
871 ldns_pkt_set_id(packet
, 0);
872 ldns_pkt_set_size(packet
, 0);
873 ldns_pkt_set_querytime(packet
, 0);
874 memset(&packet
->timestamp
, 0, sizeof(packet
->timestamp
));
875 ldns_pkt_set_answerfrom(packet
, NULL
);
876 ldns_pkt_set_section_count(packet
, LDNS_SECTION_QUESTION
, 0);
877 ldns_pkt_set_section_count(packet
, LDNS_SECTION_ANSWER
, 0);
878 ldns_pkt_set_section_count(packet
, LDNS_SECTION_AUTHORITY
, 0);
879 ldns_pkt_set_section_count(packet
, LDNS_SECTION_ADDITIONAL
, 0);
881 ldns_pkt_set_edns_udp_size(packet
, 0);
882 ldns_pkt_set_edns_extended_rcode(packet
, 0);
883 ldns_pkt_set_edns_version(packet
, 0);
884 ldns_pkt_set_edns_z(packet
, 0);
885 ldns_pkt_set_edns_data(packet
, NULL
);
886 packet
->_edns_list
= NULL
;
887 packet
->_edns_present
= false;
889 ldns_pkt_set_tsig(packet
, NULL
);
895 ldns_pkt_free(ldns_pkt
*packet
)
898 LDNS_FREE(packet
->_header
);
899 ldns_rr_list_deep_free(packet
->_question
);
900 ldns_rr_list_deep_free(packet
->_answer
);
901 ldns_rr_list_deep_free(packet
->_authority
);
902 ldns_rr_list_deep_free(packet
->_additional
);
903 ldns_rr_free(packet
->_tsig_rr
);
904 ldns_rdf_deep_free(packet
->_edns_data
);
905 ldns_edns_option_list_deep_free(packet
->_edns_list
);
906 ldns_rdf_deep_free(packet
->_answerfrom
);
912 ldns_pkt_set_flags(ldns_pkt
*packet
, uint16_t flags
)
917 if ((flags
& LDNS_QR
) == LDNS_QR
) {
918 ldns_pkt_set_qr(packet
, true);
920 if ((flags
& LDNS_AA
) == LDNS_AA
) {
921 ldns_pkt_set_aa(packet
, true);
923 if ((flags
& LDNS_RD
) == LDNS_RD
) {
924 ldns_pkt_set_rd(packet
, true);
926 if ((flags
& LDNS_TC
) == LDNS_TC
) {
927 ldns_pkt_set_tc(packet
, true);
929 if ((flags
& LDNS_CD
) == LDNS_CD
) {
930 ldns_pkt_set_cd(packet
, true);
932 if ((flags
& LDNS_RA
) == LDNS_RA
) {
933 ldns_pkt_set_ra(packet
, true);
935 if ((flags
& LDNS_AD
) == LDNS_AD
) {
936 ldns_pkt_set_ad(packet
, true);
943 ldns_pkt_authsoa(const ldns_rdf
* rr_name
, ldns_rr_class rr_class
)
945 ldns_rr
* soa_rr
= ldns_rr_new();
949 ldns_rdf
*serial_rdf
;
950 ldns_rdf
*refresh_rdf
;
952 ldns_rdf
*expire_rdf
;
953 ldns_rdf
*minimum_rdf
;
958 owner_rdf
= ldns_rdf_clone(rr_name
);
960 ldns_rr_free(soa_rr
);
964 ldns_rr_set_owner(soa_rr
, owner_rdf
);
965 ldns_rr_set_type(soa_rr
, LDNS_RR_TYPE_SOA
);
966 ldns_rr_set_class(soa_rr
, rr_class
);
967 ldns_rr_set_question(soa_rr
, false);
969 if (ldns_str2rdf_dname(&mname_rdf
, ".") != LDNS_STATUS_OK
) {
970 ldns_rr_free(soa_rr
);
973 ldns_rr_push_rdf(soa_rr
, mname_rdf
);
975 if (ldns_str2rdf_dname(&rname_rdf
, ".") != LDNS_STATUS_OK
) {
976 ldns_rr_free(soa_rr
);
979 ldns_rr_push_rdf(soa_rr
, rname_rdf
);
981 serial_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
983 ldns_rr_free(soa_rr
);
986 ldns_rr_push_rdf(soa_rr
, serial_rdf
);
988 refresh_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
990 ldns_rr_free(soa_rr
);
993 ldns_rr_push_rdf(soa_rr
, refresh_rdf
);
995 retry_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
997 ldns_rr_free(soa_rr
);
1000 ldns_rr_push_rdf(soa_rr
, retry_rdf
);
1002 expire_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1004 ldns_rr_free(soa_rr
);
1007 ldns_rr_push_rdf(soa_rr
, expire_rdf
);
1009 minimum_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1011 ldns_rr_free(soa_rr
);
1014 ldns_rr_push_rdf(soa_rr
, minimum_rdf
);
1021 ldns_pkt_query_new_frm_str_internal(ldns_pkt
**p
, const char *name
,
1022 ldns_rr_type rr_type
, ldns_rr_class rr_class
, uint16_t flags
,
1023 ldns_rr
* authsoa_rr
)
1026 ldns_rr
*question_rr
;
1029 packet
= ldns_pkt_new();
1031 return LDNS_STATUS_MEM_ERR
;
1034 if (!ldns_pkt_set_flags(packet
, flags
)) {
1035 ldns_pkt_free(packet
);
1036 return LDNS_STATUS_ERR
;
1039 question_rr
= ldns_rr_new();
1041 ldns_pkt_free(packet
);
1042 return LDNS_STATUS_MEM_ERR
;
1046 rr_type
= LDNS_RR_TYPE_A
;
1048 if (rr_class
== 0) {
1049 rr_class
= LDNS_RR_CLASS_IN
;
1052 if (ldns_str2rdf_dname(&name_rdf
, name
) == LDNS_STATUS_OK
) {
1053 ldns_rr_set_owner(question_rr
, name_rdf
);
1054 ldns_rr_set_type(question_rr
, rr_type
);
1055 ldns_rr_set_class(question_rr
, rr_class
);
1056 ldns_rr_set_question(question_rr
, true);
1058 ldns_pkt_push_rr(packet
, LDNS_SECTION_QUESTION
, question_rr
);
1060 ldns_rr_free(question_rr
);
1061 ldns_pkt_free(packet
);
1062 return LDNS_STATUS_ERR
;
1066 ldns_pkt_push_rr(packet
, LDNS_SECTION_AUTHORITY
, authsoa_rr
);
1069 packet
->_tsig_rr
= NULL
;
1070 ldns_pkt_set_answerfrom(packet
, NULL
);
1073 return LDNS_STATUS_OK
;
1075 ldns_pkt_free(packet
);
1076 return LDNS_STATUS_NULL
;
1081 ldns_pkt_query_new_frm_str(ldns_pkt
**p
, const char *name
,
1082 ldns_rr_type rr_type
, ldns_rr_class rr_class
, uint16_t flags
)
1084 return ldns_pkt_query_new_frm_str_internal(p
, name
, rr_type
,
1085 rr_class
, flags
, NULL
);
1089 ldns_pkt_ixfr_request_new_frm_str(ldns_pkt
**p
, const char *name
,
1090 ldns_rr_class rr_class
, uint16_t flags
, ldns_rr
*soa
)
1092 ldns_rr
* authsoa_rr
= soa
;
1095 if (ldns_str2rdf_dname(&name_rdf
, name
) == LDNS_STATUS_OK
) {
1096 authsoa_rr
= ldns_pkt_authsoa(name_rdf
, rr_class
);
1098 ldns_rdf_free(name_rdf
);
1100 return ldns_pkt_query_new_frm_str_internal(p
, name
, LDNS_RR_TYPE_IXFR
,
1101 rr_class
, flags
, authsoa_rr
);
1105 ldns_pkt_query_new_internal(ldns_rdf
*rr_name
, ldns_rr_type rr_type
,
1106 ldns_rr_class rr_class
, uint16_t flags
, ldns_rr
* authsoa_rr
)
1109 ldns_rr
*question_rr
;
1111 packet
= ldns_pkt_new();
1116 if (!ldns_pkt_set_flags(packet
, flags
)) {
1120 question_rr
= ldns_rr_new();
1122 ldns_pkt_free(packet
);
1127 rr_type
= LDNS_RR_TYPE_A
;
1129 if (rr_class
== 0) {
1130 rr_class
= LDNS_RR_CLASS_IN
;
1133 ldns_rr_set_owner(question_rr
, rr_name
);
1134 ldns_rr_set_type(question_rr
, rr_type
);
1135 ldns_rr_set_class(question_rr
, rr_class
);
1136 ldns_rr_set_question(question_rr
, true);
1137 ldns_pkt_push_rr(packet
, LDNS_SECTION_QUESTION
, question_rr
);
1140 ldns_pkt_push_rr(packet
, LDNS_SECTION_AUTHORITY
, authsoa_rr
);
1143 packet
->_tsig_rr
= NULL
;
1148 ldns_pkt_query_new(ldns_rdf
*rr_name
, ldns_rr_type rr_type
,
1149 ldns_rr_class rr_class
, uint16_t flags
)
1151 return ldns_pkt_query_new_internal(rr_name
, rr_type
,
1152 rr_class
, flags
, NULL
);
1156 ldns_pkt_ixfr_request_new(ldns_rdf
*rr_name
, ldns_rr_class rr_class
,
1157 uint16_t flags
, ldns_rr
* soa
)
1159 ldns_rr
* authsoa_rr
= soa
;
1161 authsoa_rr
= ldns_pkt_authsoa(rr_name
, rr_class
);
1163 return ldns_pkt_query_new_internal(rr_name
, LDNS_RR_TYPE_IXFR
,
1164 rr_class
, flags
, authsoa_rr
);
1168 ldns_pkt_reply_type(const ldns_pkt
*p
)
1173 return LDNS_PACKET_UNKNOWN
;
1176 if (ldns_pkt_get_rcode(p
) == LDNS_RCODE_NXDOMAIN
) {
1177 return LDNS_PACKET_NXDOMAIN
;
1180 if (ldns_pkt_ancount(p
) == 0 && ldns_pkt_arcount(p
) == 0
1181 && ldns_pkt_nscount(p
) == 1) {
1184 tmp
= ldns_pkt_rr_list_by_type(p
, LDNS_RR_TYPE_SOA
,
1185 LDNS_SECTION_AUTHORITY
);
1187 ldns_rr_list_deep_free(tmp
);
1188 return LDNS_PACKET_NODATA
;
1190 /* I have no idea ... */
1194 if (ldns_pkt_ancount(p
) == 0 && ldns_pkt_nscount(p
) > 0) {
1195 tmp
= ldns_pkt_rr_list_by_type(p
, LDNS_RR_TYPE_NS
,
1196 LDNS_SECTION_AUTHORITY
);
1198 /* there are nameservers here */
1199 ldns_rr_list_deep_free(tmp
);
1200 return LDNS_PACKET_REFERRAL
;
1202 /* I have no idea */
1204 ldns_rr_list_deep_free(tmp
);
1207 /* if we cannot determine the packet type, we say it's an
1210 return LDNS_PACKET_ANSWER
;
1214 ldns_pkt_clone(const ldns_pkt
*pkt
)
1221 new_pkt
= ldns_pkt_new();
1223 ldns_pkt_set_id(new_pkt
, ldns_pkt_id(pkt
));
1224 ldns_pkt_set_qr(new_pkt
, ldns_pkt_qr(pkt
));
1225 ldns_pkt_set_aa(new_pkt
, ldns_pkt_aa(pkt
));
1226 ldns_pkt_set_tc(new_pkt
, ldns_pkt_tc(pkt
));
1227 ldns_pkt_set_rd(new_pkt
, ldns_pkt_rd(pkt
));
1228 ldns_pkt_set_cd(new_pkt
, ldns_pkt_cd(pkt
));
1229 ldns_pkt_set_ra(new_pkt
, ldns_pkt_ra(pkt
));
1230 ldns_pkt_set_ad(new_pkt
, ldns_pkt_ad(pkt
));
1231 ldns_pkt_set_opcode(new_pkt
, ldns_pkt_get_opcode(pkt
));
1232 ldns_pkt_set_rcode(new_pkt
, ldns_pkt_get_rcode(pkt
));
1233 ldns_pkt_set_qdcount(new_pkt
, ldns_pkt_qdcount(pkt
));
1234 ldns_pkt_set_ancount(new_pkt
, ldns_pkt_ancount(pkt
));
1235 ldns_pkt_set_nscount(new_pkt
, ldns_pkt_nscount(pkt
));
1236 ldns_pkt_set_arcount(new_pkt
, ldns_pkt_arcount(pkt
));
1237 if (ldns_pkt_answerfrom(pkt
))
1238 ldns_pkt_set_answerfrom(new_pkt
,
1239 ldns_rdf_clone(ldns_pkt_answerfrom(pkt
)));
1240 ldns_pkt_set_timestamp(new_pkt
, ldns_pkt_timestamp(pkt
));
1241 ldns_pkt_set_querytime(new_pkt
, ldns_pkt_querytime(pkt
));
1242 ldns_pkt_set_size(new_pkt
, ldns_pkt_size(pkt
));
1243 ldns_pkt_set_tsig(new_pkt
, ldns_rr_clone(ldns_pkt_tsig(pkt
)));
1245 ldns_pkt_set_edns_udp_size(new_pkt
, ldns_pkt_edns_udp_size(pkt
));
1246 ldns_pkt_set_edns_extended_rcode(new_pkt
,
1247 ldns_pkt_edns_extended_rcode(pkt
));
1248 ldns_pkt_set_edns_version(new_pkt
, ldns_pkt_edns_version(pkt
));
1249 new_pkt
->_edns_present
= pkt
->_edns_present
;
1250 ldns_pkt_set_edns_z(new_pkt
, ldns_pkt_edns_z(pkt
));
1251 if(ldns_pkt_edns_data(pkt
))
1252 ldns_pkt_set_edns_data(new_pkt
,
1253 ldns_rdf_clone(ldns_pkt_edns_data(pkt
)));
1254 ldns_pkt_set_edns_do(new_pkt
, ldns_pkt_edns_do(pkt
));
1255 if (pkt
->_edns_list
)
1256 ldns_pkt_set_edns_option_list(new_pkt
,
1257 ldns_edns_option_list_clone(pkt
->_edns_list
));
1259 ldns_rr_list_deep_free(new_pkt
->_question
);
1260 ldns_rr_list_deep_free(new_pkt
->_answer
);
1261 ldns_rr_list_deep_free(new_pkt
->_authority
);
1262 ldns_rr_list_deep_free(new_pkt
->_additional
);
1263 new_pkt
->_question
= ldns_rr_list_clone(ldns_pkt_question(pkt
));
1264 new_pkt
->_answer
= ldns_rr_list_clone(ldns_pkt_answer(pkt
));
1265 new_pkt
->_authority
= ldns_rr_list_clone(ldns_pkt_authority(pkt
));
1266 new_pkt
->_additional
= ldns_rr_list_clone(ldns_pkt_additional(pkt
));