17b5038d7SDag-Erling Smørgrav /* 27b5038d7SDag-Erling Smørgrav * packet.c 37b5038d7SDag-Erling Smørgrav * 47b5038d7SDag-Erling Smørgrav * dns packet implementation 57b5038d7SDag-Erling Smørgrav * 67b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 77b5038d7SDag-Erling Smørgrav * 87b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 97b5038d7SDag-Erling Smørgrav * 107b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 117b5038d7SDag-Erling Smørgrav */ 127b5038d7SDag-Erling Smørgrav 137b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 147b5038d7SDag-Erling Smørgrav 157b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 167b5038d7SDag-Erling Smørgrav 177b5038d7SDag-Erling Smørgrav #include <strings.h> 187b5038d7SDag-Erling Smørgrav #include <limits.h> 197b5038d7SDag-Erling Smørgrav 207b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 217b5038d7SDag-Erling Smørgrav #include <openssl/rand.h> 227b5038d7SDag-Erling Smørgrav #endif 237b5038d7SDag-Erling Smørgrav 247b5038d7SDag-Erling Smørgrav /* Access functions 257b5038d7SDag-Erling Smørgrav * do this as functions to get type checking 267b5038d7SDag-Erling Smørgrav */ 277b5038d7SDag-Erling Smørgrav 287b5038d7SDag-Erling Smørgrav #define LDNS_EDNS_MASK_DO_BIT 0x8000 297b5038d7SDag-Erling Smørgrav 307b5038d7SDag-Erling Smørgrav /* TODO defines for 3600 */ 317b5038d7SDag-Erling Smørgrav /* convert to and from numerical flag values */ 327b5038d7SDag-Erling Smørgrav ldns_lookup_table ldns_edns_flags[] = { 337b5038d7SDag-Erling Smørgrav { 3600, "do"}, 347b5038d7SDag-Erling Smørgrav { 0, NULL} 357b5038d7SDag-Erling Smørgrav }; 367b5038d7SDag-Erling Smørgrav 377b5038d7SDag-Erling Smørgrav /* read */ 387b5038d7SDag-Erling Smørgrav uint16_t 397b5038d7SDag-Erling Smørgrav ldns_pkt_id(const ldns_pkt *packet) 407b5038d7SDag-Erling Smørgrav { 417b5038d7SDag-Erling Smørgrav return packet->_header->_id; 427b5038d7SDag-Erling Smørgrav } 437b5038d7SDag-Erling Smørgrav 447b5038d7SDag-Erling Smørgrav bool 457b5038d7SDag-Erling Smørgrav ldns_pkt_qr(const ldns_pkt *packet) 467b5038d7SDag-Erling Smørgrav { 477b5038d7SDag-Erling Smørgrav return packet->_header->_qr; 487b5038d7SDag-Erling Smørgrav } 497b5038d7SDag-Erling Smørgrav 507b5038d7SDag-Erling Smørgrav bool 517b5038d7SDag-Erling Smørgrav ldns_pkt_aa(const ldns_pkt *packet) 527b5038d7SDag-Erling Smørgrav { 537b5038d7SDag-Erling Smørgrav return packet->_header->_aa; 547b5038d7SDag-Erling Smørgrav } 557b5038d7SDag-Erling Smørgrav 567b5038d7SDag-Erling Smørgrav bool 577b5038d7SDag-Erling Smørgrav ldns_pkt_tc(const ldns_pkt *packet) 587b5038d7SDag-Erling Smørgrav { 597b5038d7SDag-Erling Smørgrav return packet->_header->_tc; 607b5038d7SDag-Erling Smørgrav } 617b5038d7SDag-Erling Smørgrav 627b5038d7SDag-Erling Smørgrav bool 637b5038d7SDag-Erling Smørgrav ldns_pkt_rd(const ldns_pkt *packet) 647b5038d7SDag-Erling Smørgrav { 657b5038d7SDag-Erling Smørgrav return packet->_header->_rd; 667b5038d7SDag-Erling Smørgrav } 677b5038d7SDag-Erling Smørgrav 687b5038d7SDag-Erling Smørgrav bool 697b5038d7SDag-Erling Smørgrav ldns_pkt_cd(const ldns_pkt *packet) 707b5038d7SDag-Erling Smørgrav { 717b5038d7SDag-Erling Smørgrav return packet->_header->_cd; 727b5038d7SDag-Erling Smørgrav } 737b5038d7SDag-Erling Smørgrav 747b5038d7SDag-Erling Smørgrav bool 757b5038d7SDag-Erling Smørgrav ldns_pkt_ra(const ldns_pkt *packet) 767b5038d7SDag-Erling Smørgrav { 777b5038d7SDag-Erling Smørgrav return packet->_header->_ra; 787b5038d7SDag-Erling Smørgrav } 797b5038d7SDag-Erling Smørgrav 807b5038d7SDag-Erling Smørgrav bool 817b5038d7SDag-Erling Smørgrav ldns_pkt_ad(const ldns_pkt *packet) 827b5038d7SDag-Erling Smørgrav { 837b5038d7SDag-Erling Smørgrav return packet->_header->_ad; 847b5038d7SDag-Erling Smørgrav } 857b5038d7SDag-Erling Smørgrav 867b5038d7SDag-Erling Smørgrav ldns_pkt_opcode 877b5038d7SDag-Erling Smørgrav ldns_pkt_get_opcode(const ldns_pkt *packet) 887b5038d7SDag-Erling Smørgrav { 897b5038d7SDag-Erling Smørgrav return packet->_header->_opcode; 907b5038d7SDag-Erling Smørgrav } 917b5038d7SDag-Erling Smørgrav 927b5038d7SDag-Erling Smørgrav ldns_pkt_rcode 937b5038d7SDag-Erling Smørgrav ldns_pkt_get_rcode(const ldns_pkt *packet) 947b5038d7SDag-Erling Smørgrav { 957b5038d7SDag-Erling Smørgrav return packet->_header->_rcode; 967b5038d7SDag-Erling Smørgrav } 977b5038d7SDag-Erling Smørgrav 987b5038d7SDag-Erling Smørgrav uint16_t 997b5038d7SDag-Erling Smørgrav ldns_pkt_qdcount(const ldns_pkt *packet) 1007b5038d7SDag-Erling Smørgrav { 1017b5038d7SDag-Erling Smørgrav return packet->_header->_qdcount; 1027b5038d7SDag-Erling Smørgrav } 1037b5038d7SDag-Erling Smørgrav 1047b5038d7SDag-Erling Smørgrav uint16_t 1057b5038d7SDag-Erling Smørgrav ldns_pkt_ancount(const ldns_pkt *packet) 1067b5038d7SDag-Erling Smørgrav { 1077b5038d7SDag-Erling Smørgrav return packet->_header->_ancount; 1087b5038d7SDag-Erling Smørgrav } 1097b5038d7SDag-Erling Smørgrav 1107b5038d7SDag-Erling Smørgrav uint16_t 1117b5038d7SDag-Erling Smørgrav ldns_pkt_nscount(const ldns_pkt *packet) 1127b5038d7SDag-Erling Smørgrav { 1137b5038d7SDag-Erling Smørgrav return packet->_header->_nscount; 1147b5038d7SDag-Erling Smørgrav } 1157b5038d7SDag-Erling Smørgrav 1167b5038d7SDag-Erling Smørgrav uint16_t 1177b5038d7SDag-Erling Smørgrav ldns_pkt_arcount(const ldns_pkt *packet) 1187b5038d7SDag-Erling Smørgrav { 1197b5038d7SDag-Erling Smørgrav return packet->_header->_arcount; 1207b5038d7SDag-Erling Smørgrav } 1217b5038d7SDag-Erling Smørgrav 1227b5038d7SDag-Erling Smørgrav ldns_rr_list * 1237b5038d7SDag-Erling Smørgrav ldns_pkt_question(const ldns_pkt *packet) 1247b5038d7SDag-Erling Smørgrav { 1257b5038d7SDag-Erling Smørgrav return packet->_question; 1267b5038d7SDag-Erling Smørgrav } 1277b5038d7SDag-Erling Smørgrav 1287b5038d7SDag-Erling Smørgrav ldns_rr_list * 1297b5038d7SDag-Erling Smørgrav ldns_pkt_answer(const ldns_pkt *packet) 1307b5038d7SDag-Erling Smørgrav { 1317b5038d7SDag-Erling Smørgrav return packet->_answer; 1327b5038d7SDag-Erling Smørgrav } 1337b5038d7SDag-Erling Smørgrav 1347b5038d7SDag-Erling Smørgrav ldns_rr_list * 1357b5038d7SDag-Erling Smørgrav ldns_pkt_authority(const ldns_pkt *packet) 1367b5038d7SDag-Erling Smørgrav { 1377b5038d7SDag-Erling Smørgrav return packet->_authority; 1387b5038d7SDag-Erling Smørgrav } 1397b5038d7SDag-Erling Smørgrav 1407b5038d7SDag-Erling Smørgrav ldns_rr_list * 1417b5038d7SDag-Erling Smørgrav ldns_pkt_additional(const ldns_pkt *packet) 1427b5038d7SDag-Erling Smørgrav { 1437b5038d7SDag-Erling Smørgrav return packet->_additional; 1447b5038d7SDag-Erling Smørgrav } 1457b5038d7SDag-Erling Smørgrav 1467b5038d7SDag-Erling Smørgrav /* return ALL section concatenated */ 1477b5038d7SDag-Erling Smørgrav ldns_rr_list * 1487b5038d7SDag-Erling Smørgrav ldns_pkt_all(const ldns_pkt *packet) 1497b5038d7SDag-Erling Smørgrav { 1507b5038d7SDag-Erling Smørgrav ldns_rr_list *all, *prev_all; 1517b5038d7SDag-Erling Smørgrav 1527b5038d7SDag-Erling Smørgrav all = ldns_rr_list_cat_clone( 1537b5038d7SDag-Erling Smørgrav ldns_pkt_question(packet), 1547b5038d7SDag-Erling Smørgrav ldns_pkt_answer(packet)); 1557b5038d7SDag-Erling Smørgrav prev_all = all; 1567b5038d7SDag-Erling Smørgrav all = ldns_rr_list_cat_clone(all, 1577b5038d7SDag-Erling Smørgrav ldns_pkt_authority(packet)); 1587b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(prev_all); 1597b5038d7SDag-Erling Smørgrav prev_all = all; 1607b5038d7SDag-Erling Smørgrav all = ldns_rr_list_cat_clone(all, 1617b5038d7SDag-Erling Smørgrav ldns_pkt_additional(packet)); 1627b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(prev_all); 1637b5038d7SDag-Erling Smørgrav return all; 1647b5038d7SDag-Erling Smørgrav } 1657b5038d7SDag-Erling Smørgrav 1667b5038d7SDag-Erling Smørgrav ldns_rr_list * 1677b5038d7SDag-Erling Smørgrav ldns_pkt_all_noquestion(const ldns_pkt *packet) 1687b5038d7SDag-Erling Smørgrav { 1697b5038d7SDag-Erling Smørgrav ldns_rr_list *all, *all2; 1707b5038d7SDag-Erling Smørgrav 1717b5038d7SDag-Erling Smørgrav all = ldns_rr_list_cat_clone( 1727b5038d7SDag-Erling Smørgrav ldns_pkt_answer(packet), 1737b5038d7SDag-Erling Smørgrav ldns_pkt_authority(packet)); 1747b5038d7SDag-Erling Smørgrav all2 = ldns_rr_list_cat_clone(all, 1757b5038d7SDag-Erling Smørgrav ldns_pkt_additional(packet)); 1767b5038d7SDag-Erling Smørgrav 1777b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(all); 1787b5038d7SDag-Erling Smørgrav return all2; 1797b5038d7SDag-Erling Smørgrav } 1807b5038d7SDag-Erling Smørgrav 1817b5038d7SDag-Erling Smørgrav size_t 1827b5038d7SDag-Erling Smørgrav ldns_pkt_size(const ldns_pkt *packet) 1837b5038d7SDag-Erling Smørgrav { 1847b5038d7SDag-Erling Smørgrav return packet->_size; 1857b5038d7SDag-Erling Smørgrav } 1867b5038d7SDag-Erling Smørgrav 1877b5038d7SDag-Erling Smørgrav uint32_t 1887b5038d7SDag-Erling Smørgrav ldns_pkt_querytime(const ldns_pkt *packet) 1897b5038d7SDag-Erling Smørgrav { 1907b5038d7SDag-Erling Smørgrav return packet->_querytime; 1917b5038d7SDag-Erling Smørgrav } 1927b5038d7SDag-Erling Smørgrav 1937b5038d7SDag-Erling Smørgrav ldns_rdf * 1947b5038d7SDag-Erling Smørgrav ldns_pkt_answerfrom(const ldns_pkt *packet) 1957b5038d7SDag-Erling Smørgrav { 1967b5038d7SDag-Erling Smørgrav return packet->_answerfrom; 1977b5038d7SDag-Erling Smørgrav } 1987b5038d7SDag-Erling Smørgrav 1997b5038d7SDag-Erling Smørgrav struct timeval 2007b5038d7SDag-Erling Smørgrav ldns_pkt_timestamp(const ldns_pkt *packet) 2017b5038d7SDag-Erling Smørgrav { 2027b5038d7SDag-Erling Smørgrav return packet->timestamp; 2037b5038d7SDag-Erling Smørgrav } 2047b5038d7SDag-Erling Smørgrav 2057b5038d7SDag-Erling Smørgrav uint16_t 2067b5038d7SDag-Erling Smørgrav ldns_pkt_edns_udp_size(const ldns_pkt *packet) 2077b5038d7SDag-Erling Smørgrav { 2087b5038d7SDag-Erling Smørgrav return packet->_edns_udp_size; 2097b5038d7SDag-Erling Smørgrav } 2107b5038d7SDag-Erling Smørgrav 2117b5038d7SDag-Erling Smørgrav uint8_t 2127b5038d7SDag-Erling Smørgrav ldns_pkt_edns_extended_rcode(const ldns_pkt *packet) 2137b5038d7SDag-Erling Smørgrav { 2147b5038d7SDag-Erling Smørgrav return packet->_edns_extended_rcode; 2157b5038d7SDag-Erling Smørgrav } 2167b5038d7SDag-Erling Smørgrav 2177b5038d7SDag-Erling Smørgrav uint8_t 2187b5038d7SDag-Erling Smørgrav ldns_pkt_edns_version(const ldns_pkt *packet) 2197b5038d7SDag-Erling Smørgrav { 2207b5038d7SDag-Erling Smørgrav return packet->_edns_version; 2217b5038d7SDag-Erling Smørgrav } 2227b5038d7SDag-Erling Smørgrav 2237b5038d7SDag-Erling Smørgrav uint16_t 2247b5038d7SDag-Erling Smørgrav ldns_pkt_edns_z(const ldns_pkt *packet) 2257b5038d7SDag-Erling Smørgrav { 2267b5038d7SDag-Erling Smørgrav return packet->_edns_z; 2277b5038d7SDag-Erling Smørgrav } 2287b5038d7SDag-Erling Smørgrav 2297b5038d7SDag-Erling Smørgrav bool 2307b5038d7SDag-Erling Smørgrav ldns_pkt_edns_do(const ldns_pkt *packet) 2317b5038d7SDag-Erling Smørgrav { 2327b5038d7SDag-Erling Smørgrav return (packet->_edns_z & LDNS_EDNS_MASK_DO_BIT); 2337b5038d7SDag-Erling Smørgrav } 2347b5038d7SDag-Erling Smørgrav 2357b5038d7SDag-Erling Smørgrav void 2367b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_do(ldns_pkt *packet, bool value) 2377b5038d7SDag-Erling Smørgrav { 2387b5038d7SDag-Erling Smørgrav if (value) { 2397b5038d7SDag-Erling Smørgrav packet->_edns_z = packet->_edns_z | LDNS_EDNS_MASK_DO_BIT; 2407b5038d7SDag-Erling Smørgrav } else { 2417b5038d7SDag-Erling Smørgrav packet->_edns_z = packet->_edns_z & ~LDNS_EDNS_MASK_DO_BIT; 2427b5038d7SDag-Erling Smørgrav } 2437b5038d7SDag-Erling Smørgrav } 2447b5038d7SDag-Erling Smørgrav 2457b5038d7SDag-Erling Smørgrav ldns_rdf * 2467b5038d7SDag-Erling Smørgrav ldns_pkt_edns_data(const ldns_pkt *packet) 2477b5038d7SDag-Erling Smørgrav { 2487b5038d7SDag-Erling Smørgrav return packet->_edns_data; 2497b5038d7SDag-Erling Smørgrav } 2507b5038d7SDag-Erling Smørgrav 2517b5038d7SDag-Erling Smørgrav /* return only those rr that share the ownername */ 2527b5038d7SDag-Erling Smørgrav ldns_rr_list * 2537b5038d7SDag-Erling Smørgrav ldns_pkt_rr_list_by_name(ldns_pkt *packet, 2547b5038d7SDag-Erling Smørgrav ldns_rdf *ownername, 2557b5038d7SDag-Erling Smørgrav ldns_pkt_section sec) 2567b5038d7SDag-Erling Smørgrav { 2577b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs; 2587b5038d7SDag-Erling Smørgrav ldns_rr_list *ret; 2597b5038d7SDag-Erling Smørgrav uint16_t i; 2607b5038d7SDag-Erling Smørgrav 2617b5038d7SDag-Erling Smørgrav if (!packet) { 2627b5038d7SDag-Erling Smørgrav return NULL; 2637b5038d7SDag-Erling Smørgrav } 2647b5038d7SDag-Erling Smørgrav 2657b5038d7SDag-Erling Smørgrav rrs = ldns_pkt_get_section_clone(packet, sec); 2667b5038d7SDag-Erling Smørgrav ret = NULL; 2677b5038d7SDag-Erling Smørgrav 2687b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 269*17d15b25SDag-Erling Smørgrav if (ldns_dname_compare(ldns_rr_owner( 2707b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrs, i)), 2717b5038d7SDag-Erling Smørgrav ownername) == 0) { 2727b5038d7SDag-Erling Smørgrav /* owner names match */ 2732787e39aSDag-Erling Smørgrav if (ret == NULL) { 2742787e39aSDag-Erling Smørgrav ret = ldns_rr_list_new(); 2752787e39aSDag-Erling Smørgrav } 2762787e39aSDag-Erling Smørgrav ldns_rr_list_push_rr(ret, ldns_rr_list_rr(rrs, i)); 2777b5038d7SDag-Erling Smørgrav } 2787b5038d7SDag-Erling Smørgrav } 2797b5038d7SDag-Erling Smørgrav return ret; 2807b5038d7SDag-Erling Smørgrav } 2817b5038d7SDag-Erling Smørgrav 2827b5038d7SDag-Erling Smørgrav /* return only those rr that share a type */ 2837b5038d7SDag-Erling Smørgrav ldns_rr_list * 2847b5038d7SDag-Erling Smørgrav ldns_pkt_rr_list_by_type(const ldns_pkt *packet, 2857b5038d7SDag-Erling Smørgrav ldns_rr_type type, 2867b5038d7SDag-Erling Smørgrav ldns_pkt_section sec) 2877b5038d7SDag-Erling Smørgrav { 2887b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs; 2897b5038d7SDag-Erling Smørgrav ldns_rr_list *new; 2907b5038d7SDag-Erling Smørgrav uint16_t i; 2917b5038d7SDag-Erling Smørgrav 2927b5038d7SDag-Erling Smørgrav if(!packet) { 2937b5038d7SDag-Erling Smørgrav return NULL; 2947b5038d7SDag-Erling Smørgrav } 2957b5038d7SDag-Erling Smørgrav 2967b5038d7SDag-Erling Smørgrav rrs = ldns_pkt_get_section_clone(packet, sec); 2977b5038d7SDag-Erling Smørgrav new = ldns_rr_list_new(); 2987b5038d7SDag-Erling Smørgrav 2997b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 3007b5038d7SDag-Erling Smørgrav if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) { 3017b5038d7SDag-Erling Smørgrav /* types match */ 3027b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new, 3037b5038d7SDag-Erling Smørgrav ldns_rr_clone( 3047b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrs, i)) 3057b5038d7SDag-Erling Smørgrav ); 3067b5038d7SDag-Erling Smørgrav } 3077b5038d7SDag-Erling Smørgrav } 3087b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrs); 3097b5038d7SDag-Erling Smørgrav 3107b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(new) == 0) { 3117b5038d7SDag-Erling Smørgrav ldns_rr_list_free(new); 3127b5038d7SDag-Erling Smørgrav return NULL; 3137b5038d7SDag-Erling Smørgrav } else { 3147b5038d7SDag-Erling Smørgrav return new; 3157b5038d7SDag-Erling Smørgrav } 3167b5038d7SDag-Erling Smørgrav } 3177b5038d7SDag-Erling Smørgrav 3187b5038d7SDag-Erling Smørgrav /* return only those rrs that share name and type */ 3197b5038d7SDag-Erling Smørgrav ldns_rr_list * 3207b5038d7SDag-Erling Smørgrav ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, 3217b5038d7SDag-Erling Smørgrav const ldns_rdf *ownername, 3227b5038d7SDag-Erling Smørgrav ldns_rr_type type, 3237b5038d7SDag-Erling Smørgrav ldns_pkt_section sec) 3247b5038d7SDag-Erling Smørgrav { 3257b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs; 3267b5038d7SDag-Erling Smørgrav ldns_rr_list *new; 3277b5038d7SDag-Erling Smørgrav ldns_rr_list *ret; 3287b5038d7SDag-Erling Smørgrav uint16_t i; 3297b5038d7SDag-Erling Smørgrav 3307b5038d7SDag-Erling Smørgrav if(!packet) { 3317b5038d7SDag-Erling Smørgrav return NULL; 3327b5038d7SDag-Erling Smørgrav } 3337b5038d7SDag-Erling Smørgrav 3347b5038d7SDag-Erling Smørgrav rrs = ldns_pkt_get_section_clone(packet, sec); 3357b5038d7SDag-Erling Smørgrav new = ldns_rr_list_new(); 3367b5038d7SDag-Erling Smørgrav ret = NULL; 3377b5038d7SDag-Erling Smørgrav 3387b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 3397b5038d7SDag-Erling Smørgrav if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) && 340*17d15b25SDag-Erling Smørgrav ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)), 3417b5038d7SDag-Erling Smørgrav ownername 3427b5038d7SDag-Erling Smørgrav ) == 0 3437b5038d7SDag-Erling Smørgrav ) { 3447b5038d7SDag-Erling Smørgrav /* types match */ 3457b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i))); 3467b5038d7SDag-Erling Smørgrav ret = new; 3477b5038d7SDag-Erling Smørgrav } 3487b5038d7SDag-Erling Smørgrav } 3497b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrs); 3507b5038d7SDag-Erling Smørgrav if (!ret) { 3517b5038d7SDag-Erling Smørgrav ldns_rr_list_free(new); 3527b5038d7SDag-Erling Smørgrav } 3537b5038d7SDag-Erling Smørgrav return ret; 3547b5038d7SDag-Erling Smørgrav } 3557b5038d7SDag-Erling Smørgrav 3567b5038d7SDag-Erling Smørgrav bool 3577b5038d7SDag-Erling Smørgrav ldns_pkt_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr) 3587b5038d7SDag-Erling Smørgrav { 3597b5038d7SDag-Erling Smørgrav bool result = false; 3607b5038d7SDag-Erling Smørgrav 3617b5038d7SDag-Erling Smørgrav switch (sec) { 3627b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 3637b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr); 3647b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 3657b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr); 3667b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 3677b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr); 3687b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 3697b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr); 3707b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 3717b5038d7SDag-Erling Smørgrav result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr); 3727b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 3737b5038d7SDag-Erling Smørgrav result = result 3747b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr) 3757b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr) 3767b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr); 3777b5038d7SDag-Erling Smørgrav } 3787b5038d7SDag-Erling Smørgrav 3797b5038d7SDag-Erling Smørgrav return result; 3807b5038d7SDag-Erling Smørgrav } 3817b5038d7SDag-Erling Smørgrav 382*17d15b25SDag-Erling Smørgrav uint16_t 3837b5038d7SDag-Erling Smørgrav ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s) 3847b5038d7SDag-Erling Smørgrav { 3857b5038d7SDag-Erling Smørgrav switch(s) { 3867b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 3877b5038d7SDag-Erling Smørgrav return ldns_pkt_qdcount(packet); 3887b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 3897b5038d7SDag-Erling Smørgrav return ldns_pkt_ancount(packet); 3907b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 3917b5038d7SDag-Erling Smørgrav return ldns_pkt_nscount(packet); 3927b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 3937b5038d7SDag-Erling Smørgrav return ldns_pkt_arcount(packet); 3947b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 3957b5038d7SDag-Erling Smørgrav return ldns_pkt_qdcount(packet) + 3967b5038d7SDag-Erling Smørgrav ldns_pkt_ancount(packet) + 3977b5038d7SDag-Erling Smørgrav ldns_pkt_nscount(packet) + 3987b5038d7SDag-Erling Smørgrav ldns_pkt_arcount(packet); 3997b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 4007b5038d7SDag-Erling Smørgrav return ldns_pkt_ancount(packet) + 4017b5038d7SDag-Erling Smørgrav ldns_pkt_nscount(packet) + 4027b5038d7SDag-Erling Smørgrav ldns_pkt_arcount(packet); 4037b5038d7SDag-Erling Smørgrav default: 4047b5038d7SDag-Erling Smørgrav return 0; 4057b5038d7SDag-Erling Smørgrav } 4067b5038d7SDag-Erling Smørgrav } 4077b5038d7SDag-Erling Smørgrav 4087b5038d7SDag-Erling Smørgrav bool 4097b5038d7SDag-Erling Smørgrav ldns_pkt_empty(ldns_pkt *p) 4107b5038d7SDag-Erling Smørgrav { 4117b5038d7SDag-Erling Smørgrav if (!p) { 4127b5038d7SDag-Erling Smørgrav return true; /* NULL is empty? */ 4137b5038d7SDag-Erling Smørgrav } 4147b5038d7SDag-Erling Smørgrav if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) { 4157b5038d7SDag-Erling Smørgrav return false; 4167b5038d7SDag-Erling Smørgrav } else { 4177b5038d7SDag-Erling Smørgrav return true; 4187b5038d7SDag-Erling Smørgrav } 4197b5038d7SDag-Erling Smørgrav } 4207b5038d7SDag-Erling Smørgrav 4217b5038d7SDag-Erling Smørgrav 4227b5038d7SDag-Erling Smørgrav ldns_rr_list * 4237b5038d7SDag-Erling Smørgrav ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s) 4247b5038d7SDag-Erling Smørgrav { 4257b5038d7SDag-Erling Smørgrav switch(s) { 4267b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 4277b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_question(packet)); 4287b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 4297b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_answer(packet)); 4307b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 4317b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_authority(packet)); 4327b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 4337b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_additional(packet)); 4347b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 4357b5038d7SDag-Erling Smørgrav /* these are already clones */ 4367b5038d7SDag-Erling Smørgrav return ldns_pkt_all(packet); 4377b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 4387b5038d7SDag-Erling Smørgrav return ldns_pkt_all_noquestion(packet); 4397b5038d7SDag-Erling Smørgrav default: 4407b5038d7SDag-Erling Smørgrav return NULL; 4417b5038d7SDag-Erling Smørgrav } 4427b5038d7SDag-Erling Smørgrav } 4437b5038d7SDag-Erling Smørgrav 4447b5038d7SDag-Erling Smørgrav ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) { 4457b5038d7SDag-Erling Smørgrav return pkt->_tsig_rr; 4467b5038d7SDag-Erling Smørgrav } 4477b5038d7SDag-Erling Smørgrav 4487b5038d7SDag-Erling Smørgrav /* write */ 4497b5038d7SDag-Erling Smørgrav void 4507b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(ldns_pkt *packet, uint16_t id) 4517b5038d7SDag-Erling Smørgrav { 4527b5038d7SDag-Erling Smørgrav packet->_header->_id = id; 4537b5038d7SDag-Erling Smørgrav } 4547b5038d7SDag-Erling Smørgrav 4557b5038d7SDag-Erling Smørgrav void 4567b5038d7SDag-Erling Smørgrav ldns_pkt_set_random_id(ldns_pkt *packet) 4577b5038d7SDag-Erling Smørgrav { 4587b5038d7SDag-Erling Smørgrav uint16_t rid = ldns_get_random(); 4597b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(packet, rid); 4607b5038d7SDag-Erling Smørgrav } 4617b5038d7SDag-Erling Smørgrav 4627b5038d7SDag-Erling Smørgrav 4637b5038d7SDag-Erling Smørgrav void 4647b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(ldns_pkt *packet, bool qr) 4657b5038d7SDag-Erling Smørgrav { 4667b5038d7SDag-Erling Smørgrav packet->_header->_qr = qr; 4677b5038d7SDag-Erling Smørgrav } 4687b5038d7SDag-Erling Smørgrav 4697b5038d7SDag-Erling Smørgrav void 4707b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(ldns_pkt *packet, bool aa) 4717b5038d7SDag-Erling Smørgrav { 4727b5038d7SDag-Erling Smørgrav packet->_header->_aa = aa; 4737b5038d7SDag-Erling Smørgrav } 4747b5038d7SDag-Erling Smørgrav 4757b5038d7SDag-Erling Smørgrav void 4767b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(ldns_pkt *packet, bool tc) 4777b5038d7SDag-Erling Smørgrav { 4787b5038d7SDag-Erling Smørgrav packet->_header->_tc = tc; 4797b5038d7SDag-Erling Smørgrav } 4807b5038d7SDag-Erling Smørgrav 4817b5038d7SDag-Erling Smørgrav void 4827b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(ldns_pkt *packet, bool rd) 4837b5038d7SDag-Erling Smørgrav { 4847b5038d7SDag-Erling Smørgrav packet->_header->_rd = rd; 4857b5038d7SDag-Erling Smørgrav } 4867b5038d7SDag-Erling Smørgrav 4877b5038d7SDag-Erling Smørgrav void 4887b5038d7SDag-Erling Smørgrav ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr) 4897b5038d7SDag-Erling Smørgrav { 4907b5038d7SDag-Erling Smørgrav p->_additional = rr; 4917b5038d7SDag-Erling Smørgrav } 4927b5038d7SDag-Erling Smørgrav 4937b5038d7SDag-Erling Smørgrav void 4947b5038d7SDag-Erling Smørgrav ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr) 4957b5038d7SDag-Erling Smørgrav { 4967b5038d7SDag-Erling Smørgrav p->_question = rr; 4977b5038d7SDag-Erling Smørgrav } 4987b5038d7SDag-Erling Smørgrav 4997b5038d7SDag-Erling Smørgrav void 5007b5038d7SDag-Erling Smørgrav ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr) 5017b5038d7SDag-Erling Smørgrav { 5027b5038d7SDag-Erling Smørgrav p->_answer = rr; 5037b5038d7SDag-Erling Smørgrav } 5047b5038d7SDag-Erling Smørgrav 5057b5038d7SDag-Erling Smørgrav void 5067b5038d7SDag-Erling Smørgrav ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr) 5077b5038d7SDag-Erling Smørgrav { 5087b5038d7SDag-Erling Smørgrav p->_authority = rr; 5097b5038d7SDag-Erling Smørgrav } 5107b5038d7SDag-Erling Smørgrav 5117b5038d7SDag-Erling Smørgrav void 5127b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(ldns_pkt *packet, bool cd) 5137b5038d7SDag-Erling Smørgrav { 5147b5038d7SDag-Erling Smørgrav packet->_header->_cd = cd; 5157b5038d7SDag-Erling Smørgrav } 5167b5038d7SDag-Erling Smørgrav 5177b5038d7SDag-Erling Smørgrav void 5187b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(ldns_pkt *packet, bool ra) 5197b5038d7SDag-Erling Smørgrav { 5207b5038d7SDag-Erling Smørgrav packet->_header->_ra = ra; 5217b5038d7SDag-Erling Smørgrav } 5227b5038d7SDag-Erling Smørgrav 5237b5038d7SDag-Erling Smørgrav void 5247b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(ldns_pkt *packet, bool ad) 5257b5038d7SDag-Erling Smørgrav { 5267b5038d7SDag-Erling Smørgrav packet->_header->_ad = ad; 5277b5038d7SDag-Erling Smørgrav } 5287b5038d7SDag-Erling Smørgrav 5297b5038d7SDag-Erling Smørgrav void 5307b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode) 5317b5038d7SDag-Erling Smørgrav { 5327b5038d7SDag-Erling Smørgrav packet->_header->_opcode = opcode; 5337b5038d7SDag-Erling Smørgrav } 5347b5038d7SDag-Erling Smørgrav 5357b5038d7SDag-Erling Smørgrav void 5367b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode) 5377b5038d7SDag-Erling Smørgrav { 5387b5038d7SDag-Erling Smørgrav packet->_header->_rcode = rcode; 5397b5038d7SDag-Erling Smørgrav } 5407b5038d7SDag-Erling Smørgrav 5417b5038d7SDag-Erling Smørgrav void 5427b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount) 5437b5038d7SDag-Erling Smørgrav { 5447b5038d7SDag-Erling Smørgrav packet->_header->_qdcount = qdcount; 5457b5038d7SDag-Erling Smørgrav } 5467b5038d7SDag-Erling Smørgrav 5477b5038d7SDag-Erling Smørgrav void 5487b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount) 5497b5038d7SDag-Erling Smørgrav { 5507b5038d7SDag-Erling Smørgrav packet->_header->_ancount = ancount; 5517b5038d7SDag-Erling Smørgrav } 5527b5038d7SDag-Erling Smørgrav 5537b5038d7SDag-Erling Smørgrav void 5547b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount) 5557b5038d7SDag-Erling Smørgrav { 5567b5038d7SDag-Erling Smørgrav packet->_header->_nscount = nscount; 5577b5038d7SDag-Erling Smørgrav } 5587b5038d7SDag-Erling Smørgrav 5597b5038d7SDag-Erling Smørgrav void 5607b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount) 5617b5038d7SDag-Erling Smørgrav { 5627b5038d7SDag-Erling Smørgrav packet->_header->_arcount = arcount; 5637b5038d7SDag-Erling Smørgrav } 5647b5038d7SDag-Erling Smørgrav 5657b5038d7SDag-Erling Smørgrav void 5667b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 5677b5038d7SDag-Erling Smørgrav { 5687b5038d7SDag-Erling Smørgrav packet->_querytime = time; 5697b5038d7SDag-Erling Smørgrav } 5707b5038d7SDag-Erling Smørgrav 5717b5038d7SDag-Erling Smørgrav void 5727b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom) 5737b5038d7SDag-Erling Smørgrav { 5747b5038d7SDag-Erling Smørgrav packet->_answerfrom = answerfrom; 5757b5038d7SDag-Erling Smørgrav } 5767b5038d7SDag-Erling Smørgrav 5777b5038d7SDag-Erling Smørgrav void 5787b5038d7SDag-Erling Smørgrav ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval) 5797b5038d7SDag-Erling Smørgrav { 5807b5038d7SDag-Erling Smørgrav packet->timestamp.tv_sec = timeval.tv_sec; 5817b5038d7SDag-Erling Smørgrav packet->timestamp.tv_usec = timeval.tv_usec; 5827b5038d7SDag-Erling Smørgrav } 5837b5038d7SDag-Erling Smørgrav 5847b5038d7SDag-Erling Smørgrav void 5857b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(ldns_pkt *packet, size_t s) 5867b5038d7SDag-Erling Smørgrav { 5877b5038d7SDag-Erling Smørgrav packet->_size = s; 5887b5038d7SDag-Erling Smørgrav } 5897b5038d7SDag-Erling Smørgrav 5907b5038d7SDag-Erling Smørgrav void 5917b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s) 5927b5038d7SDag-Erling Smørgrav { 5937b5038d7SDag-Erling Smørgrav packet->_edns_udp_size = s; 5947b5038d7SDag-Erling Smørgrav } 5957b5038d7SDag-Erling Smørgrav 5967b5038d7SDag-Erling Smørgrav void 5977b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c) 5987b5038d7SDag-Erling Smørgrav { 5997b5038d7SDag-Erling Smørgrav packet->_edns_extended_rcode = c; 6007b5038d7SDag-Erling Smørgrav } 6017b5038d7SDag-Erling Smørgrav 6027b5038d7SDag-Erling Smørgrav void 6037b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v) 6047b5038d7SDag-Erling Smørgrav { 6057b5038d7SDag-Erling Smørgrav packet->_edns_version = v; 6067b5038d7SDag-Erling Smørgrav } 6077b5038d7SDag-Erling Smørgrav 6087b5038d7SDag-Erling Smørgrav void 6097b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z) 6107b5038d7SDag-Erling Smørgrav { 6117b5038d7SDag-Erling Smørgrav packet->_edns_z = z; 6127b5038d7SDag-Erling Smørgrav } 6137b5038d7SDag-Erling Smørgrav 6147b5038d7SDag-Erling Smørgrav void 6157b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data) 6167b5038d7SDag-Erling Smørgrav { 6177b5038d7SDag-Erling Smørgrav packet->_edns_data = data; 6187b5038d7SDag-Erling Smørgrav } 6197b5038d7SDag-Erling Smørgrav 6207b5038d7SDag-Erling Smørgrav void 6217b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count) 6227b5038d7SDag-Erling Smørgrav { 6237b5038d7SDag-Erling Smørgrav switch(s) { 6247b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 6257b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(packet, count); 6267b5038d7SDag-Erling Smørgrav break; 6277b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 6287b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(packet, count); 6297b5038d7SDag-Erling Smørgrav break; 6307b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 6317b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(packet, count); 6327b5038d7SDag-Erling Smørgrav break; 6337b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 6347b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(packet, count); 6357b5038d7SDag-Erling Smørgrav break; 6367b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 6377b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 6387b5038d7SDag-Erling Smørgrav break; 6397b5038d7SDag-Erling Smørgrav } 6407b5038d7SDag-Erling Smørgrav } 6417b5038d7SDag-Erling Smørgrav 6427b5038d7SDag-Erling Smørgrav void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr) 6437b5038d7SDag-Erling Smørgrav { 6447b5038d7SDag-Erling Smørgrav pkt->_tsig_rr = rr; 6457b5038d7SDag-Erling Smørgrav } 6467b5038d7SDag-Erling Smørgrav 6477b5038d7SDag-Erling Smørgrav bool 6487b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr) 6497b5038d7SDag-Erling Smørgrav { 6507b5038d7SDag-Erling Smørgrav switch(section) { 6517b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 6522787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) { 6532787e39aSDag-Erling Smørgrav return false; 6542787e39aSDag-Erling Smørgrav } 6557b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1); 6567b5038d7SDag-Erling Smørgrav break; 6577b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 6582787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) { 6592787e39aSDag-Erling Smørgrav return false; 6602787e39aSDag-Erling Smørgrav } 6617b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1); 6627b5038d7SDag-Erling Smørgrav break; 6637b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 6642787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) { 6652787e39aSDag-Erling Smørgrav return false; 6662787e39aSDag-Erling Smørgrav } 6677b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1); 6687b5038d7SDag-Erling Smørgrav break; 6697b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 6702787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) { 6712787e39aSDag-Erling Smørgrav return false; 6722787e39aSDag-Erling Smørgrav } 6737b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1); 6747b5038d7SDag-Erling Smørgrav break; 6757b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 6767b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 6777b5038d7SDag-Erling Smørgrav /* shouldn't this error? */ 6787b5038d7SDag-Erling Smørgrav break; 6797b5038d7SDag-Erling Smørgrav } 6807b5038d7SDag-Erling Smørgrav return true; 6817b5038d7SDag-Erling Smørgrav } 6827b5038d7SDag-Erling Smørgrav 6837b5038d7SDag-Erling Smørgrav bool 6847b5038d7SDag-Erling Smørgrav ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr) 6857b5038d7SDag-Erling Smørgrav { 6867b5038d7SDag-Erling Smørgrav 6877b5038d7SDag-Erling Smørgrav /* check to see if its there */ 6887b5038d7SDag-Erling Smørgrav if (ldns_pkt_rr(pkt, sec, rr)) { 6897b5038d7SDag-Erling Smørgrav /* already there */ 6907b5038d7SDag-Erling Smørgrav return false; 6917b5038d7SDag-Erling Smørgrav } 6927b5038d7SDag-Erling Smørgrav return ldns_pkt_push_rr(pkt, sec, rr); 6937b5038d7SDag-Erling Smørgrav } 6947b5038d7SDag-Erling Smørgrav 6957b5038d7SDag-Erling Smørgrav bool 6967b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 6977b5038d7SDag-Erling Smørgrav { 6987b5038d7SDag-Erling Smørgrav size_t i; 6997b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 7007b5038d7SDag-Erling Smørgrav if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) { 7017b5038d7SDag-Erling Smørgrav return false; 7027b5038d7SDag-Erling Smørgrav } 7037b5038d7SDag-Erling Smørgrav } 7047b5038d7SDag-Erling Smørgrav return true; 7057b5038d7SDag-Erling Smørgrav } 7067b5038d7SDag-Erling Smørgrav 7077b5038d7SDag-Erling Smørgrav bool 7087b5038d7SDag-Erling Smørgrav ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 7097b5038d7SDag-Erling Smørgrav { 7107b5038d7SDag-Erling Smørgrav size_t i; 7117b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 7127b5038d7SDag-Erling Smørgrav if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) { 7137b5038d7SDag-Erling Smørgrav return false; 7147b5038d7SDag-Erling Smørgrav } 7157b5038d7SDag-Erling Smørgrav } 7167b5038d7SDag-Erling Smørgrav return true; 7177b5038d7SDag-Erling Smørgrav } 7187b5038d7SDag-Erling Smørgrav 7197b5038d7SDag-Erling Smørgrav bool 7207b5038d7SDag-Erling Smørgrav ldns_pkt_edns(const ldns_pkt *pkt) { 7217b5038d7SDag-Erling Smørgrav return (ldns_pkt_edns_udp_size(pkt) > 0 || 7227b5038d7SDag-Erling Smørgrav ldns_pkt_edns_extended_rcode(pkt) > 0 || 7237b5038d7SDag-Erling Smørgrav ldns_pkt_edns_data(pkt) || 7247b5038d7SDag-Erling Smørgrav ldns_pkt_edns_do(pkt) 7257b5038d7SDag-Erling Smørgrav ); 7267b5038d7SDag-Erling Smørgrav } 7277b5038d7SDag-Erling Smørgrav 7287b5038d7SDag-Erling Smørgrav 7297b5038d7SDag-Erling Smørgrav /* Create/destroy/convert functions 7307b5038d7SDag-Erling Smørgrav */ 7317b5038d7SDag-Erling Smørgrav ldns_pkt * 7327b5038d7SDag-Erling Smørgrav ldns_pkt_new(void) 7337b5038d7SDag-Erling Smørgrav { 7347b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 7357b5038d7SDag-Erling Smørgrav packet = LDNS_MALLOC(ldns_pkt); 7367b5038d7SDag-Erling Smørgrav if (!packet) { 7377b5038d7SDag-Erling Smørgrav return NULL; 7387b5038d7SDag-Erling Smørgrav } 7397b5038d7SDag-Erling Smørgrav 7407b5038d7SDag-Erling Smørgrav packet->_header = LDNS_MALLOC(ldns_hdr); 7417b5038d7SDag-Erling Smørgrav if (!packet->_header) { 7427b5038d7SDag-Erling Smørgrav LDNS_FREE(packet); 7437b5038d7SDag-Erling Smørgrav return NULL; 7447b5038d7SDag-Erling Smørgrav } 7457b5038d7SDag-Erling Smørgrav 7467b5038d7SDag-Erling Smørgrav packet->_question = ldns_rr_list_new(); 7477b5038d7SDag-Erling Smørgrav packet->_answer = ldns_rr_list_new(); 7487b5038d7SDag-Erling Smørgrav packet->_authority = ldns_rr_list_new(); 7497b5038d7SDag-Erling Smørgrav packet->_additional = ldns_rr_list_new(); 7507b5038d7SDag-Erling Smørgrav 7517b5038d7SDag-Erling Smørgrav /* default everything to false */ 7527b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(packet, false); 7537b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(packet, false); 7547b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(packet, false); 7557b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(packet, false); 7567b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(packet, false); 7577b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(packet, false); 7587b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(packet, false); 7597b5038d7SDag-Erling Smørgrav 7607b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY); 7617b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(packet, 0); 7627b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(packet, 0); 7637b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(packet, 0); 7647b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(packet, 0); 7657b5038d7SDag-Erling Smørgrav memset(&packet->timestamp, 0, sizeof(packet->timestamp)); 7667b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(packet, NULL); 7677b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0); 7687b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0); 7697b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0); 7707b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0); 7717b5038d7SDag-Erling Smørgrav 7727b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(packet, 0); 7737b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(packet, 0); 7747b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(packet, 0); 7757b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(packet, 0); 7767b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(packet, NULL); 7777b5038d7SDag-Erling Smørgrav 7787b5038d7SDag-Erling Smørgrav ldns_pkt_set_tsig(packet, NULL); 7797b5038d7SDag-Erling Smørgrav 7807b5038d7SDag-Erling Smørgrav return packet; 7817b5038d7SDag-Erling Smørgrav } 7827b5038d7SDag-Erling Smørgrav 7837b5038d7SDag-Erling Smørgrav void 7847b5038d7SDag-Erling Smørgrav ldns_pkt_free(ldns_pkt *packet) 7857b5038d7SDag-Erling Smørgrav { 7867b5038d7SDag-Erling Smørgrav if (packet) { 7877b5038d7SDag-Erling Smørgrav LDNS_FREE(packet->_header); 7887b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_question); 7897b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_answer); 7907b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_authority); 7917b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_additional); 7927b5038d7SDag-Erling Smørgrav ldns_rr_free(packet->_tsig_rr); 7937b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(packet->_edns_data); 7942787e39aSDag-Erling Smørgrav ldns_rdf_deep_free(packet->_answerfrom); 7957b5038d7SDag-Erling Smørgrav LDNS_FREE(packet); 7967b5038d7SDag-Erling Smørgrav } 7977b5038d7SDag-Erling Smørgrav } 7987b5038d7SDag-Erling Smørgrav 7997b5038d7SDag-Erling Smørgrav bool 8007b5038d7SDag-Erling Smørgrav ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags) 8017b5038d7SDag-Erling Smørgrav { 8027b5038d7SDag-Erling Smørgrav if (!packet) { 8037b5038d7SDag-Erling Smørgrav return false; 8047b5038d7SDag-Erling Smørgrav } 8057b5038d7SDag-Erling Smørgrav if ((flags & LDNS_QR) == LDNS_QR) { 8067b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(packet, true); 8077b5038d7SDag-Erling Smørgrav } 8087b5038d7SDag-Erling Smørgrav if ((flags & LDNS_AA) == LDNS_AA) { 8097b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(packet, true); 8107b5038d7SDag-Erling Smørgrav } 8117b5038d7SDag-Erling Smørgrav if ((flags & LDNS_RD) == LDNS_RD) { 8127b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(packet, true); 8137b5038d7SDag-Erling Smørgrav } 8147b5038d7SDag-Erling Smørgrav if ((flags & LDNS_TC) == LDNS_TC) { 8157b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(packet, true); 8167b5038d7SDag-Erling Smørgrav } 8177b5038d7SDag-Erling Smørgrav if ((flags & LDNS_CD) == LDNS_CD) { 8187b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(packet, true); 8197b5038d7SDag-Erling Smørgrav } 8207b5038d7SDag-Erling Smørgrav if ((flags & LDNS_RA) == LDNS_RA) { 8217b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(packet, true); 8227b5038d7SDag-Erling Smørgrav } 8237b5038d7SDag-Erling Smørgrav if ((flags & LDNS_AD) == LDNS_AD) { 8247b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(packet, true); 8257b5038d7SDag-Erling Smørgrav } 8267b5038d7SDag-Erling Smørgrav return true; 8277b5038d7SDag-Erling Smørgrav } 8287b5038d7SDag-Erling Smørgrav 8292787e39aSDag-Erling Smørgrav 830*17d15b25SDag-Erling Smørgrav static ldns_rr* 831*17d15b25SDag-Erling Smørgrav ldns_pkt_authsoa(ldns_rdf* rr_name, ldns_rr_class rr_class) 8322787e39aSDag-Erling Smørgrav { 8332787e39aSDag-Erling Smørgrav ldns_rr* soa_rr = ldns_rr_new(); 8342787e39aSDag-Erling Smørgrav ldns_rdf *owner_rdf; 8352787e39aSDag-Erling Smørgrav ldns_rdf *mname_rdf; 8362787e39aSDag-Erling Smørgrav ldns_rdf *rname_rdf; 8372787e39aSDag-Erling Smørgrav ldns_rdf *serial_rdf; 8382787e39aSDag-Erling Smørgrav ldns_rdf *refresh_rdf; 8392787e39aSDag-Erling Smørgrav ldns_rdf *retry_rdf; 8402787e39aSDag-Erling Smørgrav ldns_rdf *expire_rdf; 8412787e39aSDag-Erling Smørgrav ldns_rdf *minimum_rdf; 8422787e39aSDag-Erling Smørgrav 8432787e39aSDag-Erling Smørgrav if (!soa_rr) { 844*17d15b25SDag-Erling Smørgrav return NULL; 8452787e39aSDag-Erling Smørgrav } 8462787e39aSDag-Erling Smørgrav owner_rdf = ldns_rdf_clone(rr_name); 8472787e39aSDag-Erling Smørgrav if (!owner_rdf) { 8482787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 849*17d15b25SDag-Erling Smørgrav return NULL; 8502787e39aSDag-Erling Smørgrav } 8512787e39aSDag-Erling Smørgrav 8522787e39aSDag-Erling Smørgrav ldns_rr_set_owner(soa_rr, owner_rdf); 8532787e39aSDag-Erling Smørgrav ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA); 8542787e39aSDag-Erling Smørgrav ldns_rr_set_class(soa_rr, rr_class); 8552787e39aSDag-Erling Smørgrav ldns_rr_set_question(soa_rr, false); 8562787e39aSDag-Erling Smørgrav 8572787e39aSDag-Erling Smørgrav if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) { 8582787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 859*17d15b25SDag-Erling Smørgrav return NULL; 8602787e39aSDag-Erling Smørgrav } else { 8612787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, mname_rdf); 8622787e39aSDag-Erling Smørgrav } 8632787e39aSDag-Erling Smørgrav if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) { 8642787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 865*17d15b25SDag-Erling Smørgrav return NULL; 8662787e39aSDag-Erling Smørgrav } else { 8672787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, rname_rdf); 8682787e39aSDag-Erling Smørgrav } 8692787e39aSDag-Erling Smørgrav serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8702787e39aSDag-Erling Smørgrav if (!serial_rdf) { 8712787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 872*17d15b25SDag-Erling Smørgrav return NULL; 8732787e39aSDag-Erling Smørgrav } else { 8742787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, serial_rdf); 8752787e39aSDag-Erling Smørgrav } 8762787e39aSDag-Erling Smørgrav refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8772787e39aSDag-Erling Smørgrav if (!refresh_rdf) { 8782787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 879*17d15b25SDag-Erling Smørgrav return NULL; 8802787e39aSDag-Erling Smørgrav } else { 8812787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, refresh_rdf); 8822787e39aSDag-Erling Smørgrav } 8832787e39aSDag-Erling Smørgrav retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8842787e39aSDag-Erling Smørgrav if (!retry_rdf) { 8852787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 886*17d15b25SDag-Erling Smørgrav return NULL; 8872787e39aSDag-Erling Smørgrav } else { 8882787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, retry_rdf); 8892787e39aSDag-Erling Smørgrav } 8902787e39aSDag-Erling Smørgrav expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8912787e39aSDag-Erling Smørgrav if (!expire_rdf) { 8922787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 893*17d15b25SDag-Erling Smørgrav return NULL; 8942787e39aSDag-Erling Smørgrav } else { 8952787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, expire_rdf); 8962787e39aSDag-Erling Smørgrav } 8972787e39aSDag-Erling Smørgrav minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8982787e39aSDag-Erling Smørgrav if (!minimum_rdf) { 8992787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 900*17d15b25SDag-Erling Smørgrav return NULL; 9012787e39aSDag-Erling Smørgrav } else { 9022787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, minimum_rdf); 9032787e39aSDag-Erling Smørgrav } 904*17d15b25SDag-Erling Smørgrav return soa_rr; 9052787e39aSDag-Erling Smørgrav } 9062787e39aSDag-Erling Smørgrav 9072787e39aSDag-Erling Smørgrav 908*17d15b25SDag-Erling Smørgrav static ldns_status 909*17d15b25SDag-Erling Smørgrav ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name, 910*17d15b25SDag-Erling Smørgrav ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags, 911*17d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr) 9127b5038d7SDag-Erling Smørgrav { 9137b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 9147b5038d7SDag-Erling Smørgrav ldns_rr *question_rr; 9157b5038d7SDag-Erling Smørgrav ldns_rdf *name_rdf; 9167b5038d7SDag-Erling Smørgrav 9177b5038d7SDag-Erling Smørgrav packet = ldns_pkt_new(); 9187b5038d7SDag-Erling Smørgrav if (!packet) { 9197b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 9207b5038d7SDag-Erling Smørgrav } 9217b5038d7SDag-Erling Smørgrav 9227b5038d7SDag-Erling Smørgrav if (!ldns_pkt_set_flags(packet, flags)) { 9237b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 9247b5038d7SDag-Erling Smørgrav } 9257b5038d7SDag-Erling Smørgrav 9267b5038d7SDag-Erling Smørgrav question_rr = ldns_rr_new(); 9277b5038d7SDag-Erling Smørgrav if (!question_rr) { 9287b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 9297b5038d7SDag-Erling Smørgrav } 9307b5038d7SDag-Erling Smørgrav 9317b5038d7SDag-Erling Smørgrav if (rr_type == 0) { 9327b5038d7SDag-Erling Smørgrav rr_type = LDNS_RR_TYPE_A; 9337b5038d7SDag-Erling Smørgrav } 9347b5038d7SDag-Erling Smørgrav if (rr_class == 0) { 9357b5038d7SDag-Erling Smørgrav rr_class = LDNS_RR_CLASS_IN; 9367b5038d7SDag-Erling Smørgrav } 9377b5038d7SDag-Erling Smørgrav 9387b5038d7SDag-Erling Smørgrav if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) { 9397b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(question_rr, name_rdf); 9407b5038d7SDag-Erling Smørgrav ldns_rr_set_type(question_rr, rr_type); 9417b5038d7SDag-Erling Smørgrav ldns_rr_set_class(question_rr, rr_class); 9427b5038d7SDag-Erling Smørgrav ldns_rr_set_question(question_rr, true); 9437b5038d7SDag-Erling Smørgrav 9447b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 9457b5038d7SDag-Erling Smørgrav } else { 9467b5038d7SDag-Erling Smørgrav ldns_rr_free(question_rr); 9477b5038d7SDag-Erling Smørgrav ldns_pkt_free(packet); 9487b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 9497b5038d7SDag-Erling Smørgrav } 9507b5038d7SDag-Erling Smørgrav 951*17d15b25SDag-Erling Smørgrav if (authsoa_rr) { 952*17d15b25SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr); 9532787e39aSDag-Erling Smørgrav } 9547b5038d7SDag-Erling Smørgrav 9552787e39aSDag-Erling Smørgrav packet->_tsig_rr = NULL; 9567b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(packet, NULL); 9577b5038d7SDag-Erling Smørgrav if (p) { 9587b5038d7SDag-Erling Smørgrav *p = packet; 9597b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 9607b5038d7SDag-Erling Smørgrav } else { 9612787e39aSDag-Erling Smørgrav ldns_pkt_free(packet); 9627b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 9637b5038d7SDag-Erling Smørgrav } 9647b5038d7SDag-Erling Smørgrav } 9657b5038d7SDag-Erling Smørgrav 966*17d15b25SDag-Erling Smørgrav ldns_status 967*17d15b25SDag-Erling Smørgrav ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, 968*17d15b25SDag-Erling Smørgrav ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags) 969*17d15b25SDag-Erling Smørgrav { 970*17d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_frm_str_internal(p, name, rr_type, 971*17d15b25SDag-Erling Smørgrav rr_class, flags, NULL); 972*17d15b25SDag-Erling Smørgrav } 973*17d15b25SDag-Erling Smørgrav 974*17d15b25SDag-Erling Smørgrav ldns_status 975*17d15b25SDag-Erling Smørgrav ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name, 976*17d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa) 977*17d15b25SDag-Erling Smørgrav { 978*17d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr = soa; 979*17d15b25SDag-Erling Smørgrav if (!authsoa_rr) { 980*17d15b25SDag-Erling Smørgrav ldns_rdf *name_rdf; 981*17d15b25SDag-Erling Smørgrav if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) { 982*17d15b25SDag-Erling Smørgrav authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class); 983*17d15b25SDag-Erling Smørgrav } 984*17d15b25SDag-Erling Smørgrav ldns_rdf_free(name_rdf); 985*17d15b25SDag-Erling Smørgrav } 986*17d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR, 987*17d15b25SDag-Erling Smørgrav rr_class, flags, authsoa_rr); 988*17d15b25SDag-Erling Smørgrav } 989*17d15b25SDag-Erling Smørgrav 990*17d15b25SDag-Erling Smørgrav static ldns_pkt * 991*17d15b25SDag-Erling Smørgrav ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type, 992*17d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags, ldns_rr* authsoa_rr) 9937b5038d7SDag-Erling Smørgrav { 9947b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 9957b5038d7SDag-Erling Smørgrav ldns_rr *question_rr; 9967b5038d7SDag-Erling Smørgrav 9977b5038d7SDag-Erling Smørgrav packet = ldns_pkt_new(); 9987b5038d7SDag-Erling Smørgrav if (!packet) { 9997b5038d7SDag-Erling Smørgrav return NULL; 10007b5038d7SDag-Erling Smørgrav } 10017b5038d7SDag-Erling Smørgrav 10027b5038d7SDag-Erling Smørgrav if (!ldns_pkt_set_flags(packet, flags)) { 10037b5038d7SDag-Erling Smørgrav return NULL; 10047b5038d7SDag-Erling Smørgrav } 10057b5038d7SDag-Erling Smørgrav 10067b5038d7SDag-Erling Smørgrav question_rr = ldns_rr_new(); 10077b5038d7SDag-Erling Smørgrav if (!question_rr) { 10082787e39aSDag-Erling Smørgrav ldns_pkt_free(packet); 10097b5038d7SDag-Erling Smørgrav return NULL; 10107b5038d7SDag-Erling Smørgrav } 10117b5038d7SDag-Erling Smørgrav 10127b5038d7SDag-Erling Smørgrav if (rr_type == 0) { 10137b5038d7SDag-Erling Smørgrav rr_type = LDNS_RR_TYPE_A; 10147b5038d7SDag-Erling Smørgrav } 10157b5038d7SDag-Erling Smørgrav if (rr_class == 0) { 10167b5038d7SDag-Erling Smørgrav rr_class = LDNS_RR_CLASS_IN; 10177b5038d7SDag-Erling Smørgrav } 10187b5038d7SDag-Erling Smørgrav 10197b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(question_rr, rr_name); 10207b5038d7SDag-Erling Smørgrav ldns_rr_set_type(question_rr, rr_type); 10217b5038d7SDag-Erling Smørgrav ldns_rr_set_class(question_rr, rr_class); 10227b5038d7SDag-Erling Smørgrav ldns_rr_set_question(question_rr, true); 10237b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 10247b5038d7SDag-Erling Smørgrav 1025*17d15b25SDag-Erling Smørgrav if (authsoa_rr) { 1026*17d15b25SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr); 10272787e39aSDag-Erling Smørgrav } 10282787e39aSDag-Erling Smørgrav 10292787e39aSDag-Erling Smørgrav packet->_tsig_rr = NULL; 10307b5038d7SDag-Erling Smørgrav return packet; 10317b5038d7SDag-Erling Smørgrav } 10327b5038d7SDag-Erling Smørgrav 1033*17d15b25SDag-Erling Smørgrav ldns_pkt * 1034*17d15b25SDag-Erling Smørgrav ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, 1035*17d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags) 1036*17d15b25SDag-Erling Smørgrav { 1037*17d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_internal(rr_name, rr_type, 1038*17d15b25SDag-Erling Smørgrav rr_class, flags, NULL); 1039*17d15b25SDag-Erling Smørgrav } 1040*17d15b25SDag-Erling Smørgrav 1041*17d15b25SDag-Erling Smørgrav ldns_pkt * 1042*17d15b25SDag-Erling Smørgrav ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class, 1043*17d15b25SDag-Erling Smørgrav uint16_t flags, ldns_rr* soa) 1044*17d15b25SDag-Erling Smørgrav { 1045*17d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr = soa; 1046*17d15b25SDag-Erling Smørgrav if (!authsoa_rr) { 1047*17d15b25SDag-Erling Smørgrav authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class); 1048*17d15b25SDag-Erling Smørgrav } 1049*17d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR, 1050*17d15b25SDag-Erling Smørgrav rr_class, flags, authsoa_rr); 1051*17d15b25SDag-Erling Smørgrav } 1052*17d15b25SDag-Erling Smørgrav 10537b5038d7SDag-Erling Smørgrav ldns_pkt_type 10547b5038d7SDag-Erling Smørgrav ldns_pkt_reply_type(ldns_pkt *p) 10557b5038d7SDag-Erling Smørgrav { 10567b5038d7SDag-Erling Smørgrav ldns_rr_list *tmp; 10577b5038d7SDag-Erling Smørgrav 10587b5038d7SDag-Erling Smørgrav if (!p) { 10597b5038d7SDag-Erling Smørgrav return LDNS_PACKET_UNKNOWN; 10607b5038d7SDag-Erling Smørgrav } 10617b5038d7SDag-Erling Smørgrav 10627b5038d7SDag-Erling Smørgrav if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) { 10637b5038d7SDag-Erling Smørgrav return LDNS_PACKET_NXDOMAIN; 10647b5038d7SDag-Erling Smørgrav } 10657b5038d7SDag-Erling Smørgrav 10667b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0 10677b5038d7SDag-Erling Smørgrav && ldns_pkt_nscount(p) == 1) { 10687b5038d7SDag-Erling Smørgrav 10697b5038d7SDag-Erling Smørgrav /* check for SOA */ 10707b5038d7SDag-Erling Smørgrav tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 10717b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY); 10727b5038d7SDag-Erling Smørgrav if (tmp) { 10737b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10747b5038d7SDag-Erling Smørgrav return LDNS_PACKET_NODATA; 10757b5038d7SDag-Erling Smørgrav } else { 10767b5038d7SDag-Erling Smørgrav /* I have no idea ... */ 10777b5038d7SDag-Erling Smørgrav } 10787b5038d7SDag-Erling Smørgrav } 10797b5038d7SDag-Erling Smørgrav 10807b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) { 10817b5038d7SDag-Erling Smørgrav tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS, 10827b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY); 10837b5038d7SDag-Erling Smørgrav if (tmp) { 10847b5038d7SDag-Erling Smørgrav /* there are nameservers here */ 10857b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10867b5038d7SDag-Erling Smørgrav return LDNS_PACKET_REFERRAL; 10877b5038d7SDag-Erling Smørgrav } else { 10887b5038d7SDag-Erling Smørgrav /* I have no idea */ 10897b5038d7SDag-Erling Smørgrav } 10907b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10917b5038d7SDag-Erling Smørgrav } 10927b5038d7SDag-Erling Smørgrav 10937b5038d7SDag-Erling Smørgrav /* if we cannot determine the packet type, we say it's an 10947b5038d7SDag-Erling Smørgrav * answer... 10957b5038d7SDag-Erling Smørgrav */ 10967b5038d7SDag-Erling Smørgrav return LDNS_PACKET_ANSWER; 10977b5038d7SDag-Erling Smørgrav } 10987b5038d7SDag-Erling Smørgrav 10997b5038d7SDag-Erling Smørgrav ldns_pkt * 11007b5038d7SDag-Erling Smørgrav ldns_pkt_clone(ldns_pkt *pkt) 11017b5038d7SDag-Erling Smørgrav { 11027b5038d7SDag-Erling Smørgrav ldns_pkt *new_pkt; 11037b5038d7SDag-Erling Smørgrav 11047b5038d7SDag-Erling Smørgrav if (!pkt) { 11057b5038d7SDag-Erling Smørgrav return NULL; 11067b5038d7SDag-Erling Smørgrav } 11077b5038d7SDag-Erling Smørgrav new_pkt = ldns_pkt_new(); 11087b5038d7SDag-Erling Smørgrav 11097b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt)); 11107b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt)); 11117b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt)); 11127b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt)); 11137b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt)); 11147b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt)); 11157b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt)); 11167b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt)); 11177b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt)); 11187b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt)); 11197b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt)); 11207b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt)); 11217b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt)); 11227b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt)); 11232787e39aSDag-Erling Smørgrav if (ldns_pkt_answerfrom(pkt)) 11242787e39aSDag-Erling Smørgrav ldns_pkt_set_answerfrom(new_pkt, 11252787e39aSDag-Erling Smørgrav ldns_rdf_clone(ldns_pkt_answerfrom(pkt))); 11267b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt)); 11277b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt)); 11287b5038d7SDag-Erling Smørgrav ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt))); 11297b5038d7SDag-Erling Smørgrav 11307b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt)); 11317b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(new_pkt, 11327b5038d7SDag-Erling Smørgrav ldns_pkt_edns_extended_rcode(pkt)); 11337b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt)); 11347b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt)); 11357b5038d7SDag-Erling Smørgrav if(ldns_pkt_edns_data(pkt)) 11367b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(new_pkt, 11377b5038d7SDag-Erling Smørgrav ldns_rdf_clone(ldns_pkt_edns_data(pkt))); 11387b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt)); 11397b5038d7SDag-Erling Smørgrav 11407b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_question); 11417b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_answer); 11427b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_authority); 11437b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_additional); 11447b5038d7SDag-Erling Smørgrav new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt)); 11457b5038d7SDag-Erling Smørgrav new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt)); 11467b5038d7SDag-Erling Smørgrav new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt)); 11477b5038d7SDag-Erling Smørgrav new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt)); 11487b5038d7SDag-Erling Smørgrav return new_pkt; 11497b5038d7SDag-Erling Smørgrav } 1150