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 * 253*986ba33cSDag-Erling Smørgrav ldns_pkt_rr_list_by_name(const ldns_pkt *packet, 254*986ba33cSDag-Erling Smørgrav const 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++) { 26917d15b25SDag-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 } 276*986ba33cSDag-Erling Smørgrav ldns_rr_list_push_rr(ret, 277*986ba33cSDag-Erling Smørgrav ldns_rr_clone( 278*986ba33cSDag-Erling Smørgrav ldns_rr_list_rr(rrs, i)) 279*986ba33cSDag-Erling Smørgrav ); 2807b5038d7SDag-Erling Smørgrav } 2817b5038d7SDag-Erling Smørgrav } 282*986ba33cSDag-Erling Smørgrav 283*986ba33cSDag-Erling Smørgrav ldns_rr_list_deep_free(rrs); 284*986ba33cSDag-Erling Smørgrav 2857b5038d7SDag-Erling Smørgrav return ret; 2867b5038d7SDag-Erling Smørgrav } 2877b5038d7SDag-Erling Smørgrav 2887b5038d7SDag-Erling Smørgrav /* return only those rr that share a type */ 2897b5038d7SDag-Erling Smørgrav ldns_rr_list * 2907b5038d7SDag-Erling Smørgrav ldns_pkt_rr_list_by_type(const ldns_pkt *packet, 2917b5038d7SDag-Erling Smørgrav ldns_rr_type type, 2927b5038d7SDag-Erling Smørgrav ldns_pkt_section sec) 2937b5038d7SDag-Erling Smørgrav { 2947b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs; 2957b5038d7SDag-Erling Smørgrav ldns_rr_list *new; 2967b5038d7SDag-Erling Smørgrav uint16_t i; 2977b5038d7SDag-Erling Smørgrav 2987b5038d7SDag-Erling Smørgrav if(!packet) { 2997b5038d7SDag-Erling Smørgrav return NULL; 3007b5038d7SDag-Erling Smørgrav } 3017b5038d7SDag-Erling Smørgrav 3027b5038d7SDag-Erling Smørgrav rrs = ldns_pkt_get_section_clone(packet, sec); 3037b5038d7SDag-Erling Smørgrav new = ldns_rr_list_new(); 3047b5038d7SDag-Erling Smørgrav 3057b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 3067b5038d7SDag-Erling Smørgrav if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i))) { 3077b5038d7SDag-Erling Smørgrav /* types match */ 3087b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new, 3097b5038d7SDag-Erling Smørgrav ldns_rr_clone( 3107b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rrs, i)) 3117b5038d7SDag-Erling Smørgrav ); 3127b5038d7SDag-Erling Smørgrav } 3137b5038d7SDag-Erling Smørgrav } 3147b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrs); 3157b5038d7SDag-Erling Smørgrav 3167b5038d7SDag-Erling Smørgrav if (ldns_rr_list_rr_count(new) == 0) { 3177b5038d7SDag-Erling Smørgrav ldns_rr_list_free(new); 3187b5038d7SDag-Erling Smørgrav return NULL; 3197b5038d7SDag-Erling Smørgrav } else { 3207b5038d7SDag-Erling Smørgrav return new; 3217b5038d7SDag-Erling Smørgrav } 3227b5038d7SDag-Erling Smørgrav } 3237b5038d7SDag-Erling Smørgrav 3247b5038d7SDag-Erling Smørgrav /* return only those rrs that share name and type */ 3257b5038d7SDag-Erling Smørgrav ldns_rr_list * 3267b5038d7SDag-Erling Smørgrav ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, 3277b5038d7SDag-Erling Smørgrav const ldns_rdf *ownername, 3287b5038d7SDag-Erling Smørgrav ldns_rr_type type, 3297b5038d7SDag-Erling Smørgrav ldns_pkt_section sec) 3307b5038d7SDag-Erling Smørgrav { 3317b5038d7SDag-Erling Smørgrav ldns_rr_list *rrs; 3327b5038d7SDag-Erling Smørgrav ldns_rr_list *new; 3337b5038d7SDag-Erling Smørgrav ldns_rr_list *ret; 3347b5038d7SDag-Erling Smørgrav uint16_t i; 3357b5038d7SDag-Erling Smørgrav 3367b5038d7SDag-Erling Smørgrav if(!packet) { 3377b5038d7SDag-Erling Smørgrav return NULL; 3387b5038d7SDag-Erling Smørgrav } 3397b5038d7SDag-Erling Smørgrav 3407b5038d7SDag-Erling Smørgrav rrs = ldns_pkt_get_section_clone(packet, sec); 3417b5038d7SDag-Erling Smørgrav new = ldns_rr_list_new(); 3427b5038d7SDag-Erling Smørgrav ret = NULL; 3437b5038d7SDag-Erling Smørgrav 3447b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrs); i++) { 3457b5038d7SDag-Erling Smørgrav if (type == ldns_rr_get_type(ldns_rr_list_rr(rrs, i)) && 34617d15b25SDag-Erling Smørgrav ldns_dname_compare(ldns_rr_owner(ldns_rr_list_rr(rrs, i)), 3477b5038d7SDag-Erling Smørgrav ownername 3487b5038d7SDag-Erling Smørgrav ) == 0 3497b5038d7SDag-Erling Smørgrav ) { 3507b5038d7SDag-Erling Smørgrav /* types match */ 3517b5038d7SDag-Erling Smørgrav ldns_rr_list_push_rr(new, ldns_rr_clone(ldns_rr_list_rr(rrs, i))); 3527b5038d7SDag-Erling Smørgrav ret = new; 3537b5038d7SDag-Erling Smørgrav } 3547b5038d7SDag-Erling Smørgrav } 3557b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(rrs); 3567b5038d7SDag-Erling Smørgrav if (!ret) { 3577b5038d7SDag-Erling Smørgrav ldns_rr_list_free(new); 3587b5038d7SDag-Erling Smørgrav } 3597b5038d7SDag-Erling Smørgrav return ret; 3607b5038d7SDag-Erling Smørgrav } 3617b5038d7SDag-Erling Smørgrav 3627b5038d7SDag-Erling Smørgrav bool 363*986ba33cSDag-Erling Smørgrav ldns_pkt_rr(const ldns_pkt *pkt, ldns_pkt_section sec, const ldns_rr *rr) 3647b5038d7SDag-Erling Smørgrav { 3657b5038d7SDag-Erling Smørgrav bool result = false; 3667b5038d7SDag-Erling Smørgrav 3677b5038d7SDag-Erling Smørgrav switch (sec) { 3687b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 3697b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr); 3707b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 3717b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr); 3727b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 3737b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr); 3747b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 3757b5038d7SDag-Erling Smørgrav return ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr); 3767b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 3777b5038d7SDag-Erling Smørgrav result = ldns_rr_list_contains_rr(ldns_pkt_question(pkt), rr); 3787b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 3797b5038d7SDag-Erling Smørgrav result = result 3807b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_answer(pkt), rr) 3817b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_authority(pkt), rr) 3827b5038d7SDag-Erling Smørgrav || ldns_rr_list_contains_rr(ldns_pkt_additional(pkt), rr); 3837b5038d7SDag-Erling Smørgrav } 3847b5038d7SDag-Erling Smørgrav 3857b5038d7SDag-Erling Smørgrav return result; 3867b5038d7SDag-Erling Smørgrav } 3877b5038d7SDag-Erling Smørgrav 38817d15b25SDag-Erling Smørgrav uint16_t 3897b5038d7SDag-Erling Smørgrav ldns_pkt_section_count(const ldns_pkt *packet, ldns_pkt_section s) 3907b5038d7SDag-Erling Smørgrav { 3917b5038d7SDag-Erling Smørgrav switch(s) { 3927b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 3937b5038d7SDag-Erling Smørgrav return ldns_pkt_qdcount(packet); 3947b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 3957b5038d7SDag-Erling Smørgrav return ldns_pkt_ancount(packet); 3967b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 3977b5038d7SDag-Erling Smørgrav return ldns_pkt_nscount(packet); 3987b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 3997b5038d7SDag-Erling Smørgrav return ldns_pkt_arcount(packet); 4007b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 4017b5038d7SDag-Erling Smørgrav return ldns_pkt_qdcount(packet) + 4027b5038d7SDag-Erling Smørgrav ldns_pkt_ancount(packet) + 4037b5038d7SDag-Erling Smørgrav ldns_pkt_nscount(packet) + 4047b5038d7SDag-Erling Smørgrav ldns_pkt_arcount(packet); 4057b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 4067b5038d7SDag-Erling Smørgrav return ldns_pkt_ancount(packet) + 4077b5038d7SDag-Erling Smørgrav ldns_pkt_nscount(packet) + 4087b5038d7SDag-Erling Smørgrav ldns_pkt_arcount(packet); 4097b5038d7SDag-Erling Smørgrav default: 4107b5038d7SDag-Erling Smørgrav return 0; 4117b5038d7SDag-Erling Smørgrav } 4127b5038d7SDag-Erling Smørgrav } 4137b5038d7SDag-Erling Smørgrav 4147b5038d7SDag-Erling Smørgrav bool 4157b5038d7SDag-Erling Smørgrav ldns_pkt_empty(ldns_pkt *p) 4167b5038d7SDag-Erling Smørgrav { 4177b5038d7SDag-Erling Smørgrav if (!p) { 4187b5038d7SDag-Erling Smørgrav return true; /* NULL is empty? */ 4197b5038d7SDag-Erling Smørgrav } 4207b5038d7SDag-Erling Smørgrav if (ldns_pkt_section_count(p, LDNS_SECTION_ANY) > 0) { 4217b5038d7SDag-Erling Smørgrav return false; 4227b5038d7SDag-Erling Smørgrav } else { 4237b5038d7SDag-Erling Smørgrav return true; 4247b5038d7SDag-Erling Smørgrav } 4257b5038d7SDag-Erling Smørgrav } 4267b5038d7SDag-Erling Smørgrav 4277b5038d7SDag-Erling Smørgrav 4287b5038d7SDag-Erling Smørgrav ldns_rr_list * 4297b5038d7SDag-Erling Smørgrav ldns_pkt_get_section_clone(const ldns_pkt *packet, ldns_pkt_section s) 4307b5038d7SDag-Erling Smørgrav { 4317b5038d7SDag-Erling Smørgrav switch(s) { 4327b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 4337b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_question(packet)); 4347b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 4357b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_answer(packet)); 4367b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 4377b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_authority(packet)); 4387b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 4397b5038d7SDag-Erling Smørgrav return ldns_rr_list_clone(ldns_pkt_additional(packet)); 4407b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 4417b5038d7SDag-Erling Smørgrav /* these are already clones */ 4427b5038d7SDag-Erling Smørgrav return ldns_pkt_all(packet); 4437b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 4447b5038d7SDag-Erling Smørgrav return ldns_pkt_all_noquestion(packet); 4457b5038d7SDag-Erling Smørgrav default: 4467b5038d7SDag-Erling Smørgrav return NULL; 4477b5038d7SDag-Erling Smørgrav } 4487b5038d7SDag-Erling Smørgrav } 4497b5038d7SDag-Erling Smørgrav 4507b5038d7SDag-Erling Smørgrav ldns_rr *ldns_pkt_tsig(const ldns_pkt *pkt) { 4517b5038d7SDag-Erling Smørgrav return pkt->_tsig_rr; 4527b5038d7SDag-Erling Smørgrav } 4537b5038d7SDag-Erling Smørgrav 4547b5038d7SDag-Erling Smørgrav /* write */ 4557b5038d7SDag-Erling Smørgrav void 4567b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(ldns_pkt *packet, uint16_t id) 4577b5038d7SDag-Erling Smørgrav { 4587b5038d7SDag-Erling Smørgrav packet->_header->_id = id; 4597b5038d7SDag-Erling Smørgrav } 4607b5038d7SDag-Erling Smørgrav 4617b5038d7SDag-Erling Smørgrav void 4627b5038d7SDag-Erling Smørgrav ldns_pkt_set_random_id(ldns_pkt *packet) 4637b5038d7SDag-Erling Smørgrav { 4647b5038d7SDag-Erling Smørgrav uint16_t rid = ldns_get_random(); 4657b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(packet, rid); 4667b5038d7SDag-Erling Smørgrav } 4677b5038d7SDag-Erling Smørgrav 4687b5038d7SDag-Erling Smørgrav 4697b5038d7SDag-Erling Smørgrav void 4707b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(ldns_pkt *packet, bool qr) 4717b5038d7SDag-Erling Smørgrav { 4727b5038d7SDag-Erling Smørgrav packet->_header->_qr = qr; 4737b5038d7SDag-Erling Smørgrav } 4747b5038d7SDag-Erling Smørgrav 4757b5038d7SDag-Erling Smørgrav void 4767b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(ldns_pkt *packet, bool aa) 4777b5038d7SDag-Erling Smørgrav { 4787b5038d7SDag-Erling Smørgrav packet->_header->_aa = aa; 4797b5038d7SDag-Erling Smørgrav } 4807b5038d7SDag-Erling Smørgrav 4817b5038d7SDag-Erling Smørgrav void 4827b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(ldns_pkt *packet, bool tc) 4837b5038d7SDag-Erling Smørgrav { 4847b5038d7SDag-Erling Smørgrav packet->_header->_tc = tc; 4857b5038d7SDag-Erling Smørgrav } 4867b5038d7SDag-Erling Smørgrav 4877b5038d7SDag-Erling Smørgrav void 4887b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(ldns_pkt *packet, bool rd) 4897b5038d7SDag-Erling Smørgrav { 4907b5038d7SDag-Erling Smørgrav packet->_header->_rd = rd; 4917b5038d7SDag-Erling Smørgrav } 4927b5038d7SDag-Erling Smørgrav 4937b5038d7SDag-Erling Smørgrav void 4947b5038d7SDag-Erling Smørgrav ldns_pkt_set_additional(ldns_pkt *p, ldns_rr_list *rr) 4957b5038d7SDag-Erling Smørgrav { 4967b5038d7SDag-Erling Smørgrav p->_additional = rr; 4977b5038d7SDag-Erling Smørgrav } 4987b5038d7SDag-Erling Smørgrav 4997b5038d7SDag-Erling Smørgrav void 5007b5038d7SDag-Erling Smørgrav ldns_pkt_set_question(ldns_pkt *p, ldns_rr_list *rr) 5017b5038d7SDag-Erling Smørgrav { 5027b5038d7SDag-Erling Smørgrav p->_question = rr; 5037b5038d7SDag-Erling Smørgrav } 5047b5038d7SDag-Erling Smørgrav 5057b5038d7SDag-Erling Smørgrav void 5067b5038d7SDag-Erling Smørgrav ldns_pkt_set_answer(ldns_pkt *p, ldns_rr_list *rr) 5077b5038d7SDag-Erling Smørgrav { 5087b5038d7SDag-Erling Smørgrav p->_answer = rr; 5097b5038d7SDag-Erling Smørgrav } 5107b5038d7SDag-Erling Smørgrav 5117b5038d7SDag-Erling Smørgrav void 5127b5038d7SDag-Erling Smørgrav ldns_pkt_set_authority(ldns_pkt *p, ldns_rr_list *rr) 5137b5038d7SDag-Erling Smørgrav { 5147b5038d7SDag-Erling Smørgrav p->_authority = rr; 5157b5038d7SDag-Erling Smørgrav } 5167b5038d7SDag-Erling Smørgrav 5177b5038d7SDag-Erling Smørgrav void 5187b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(ldns_pkt *packet, bool cd) 5197b5038d7SDag-Erling Smørgrav { 5207b5038d7SDag-Erling Smørgrav packet->_header->_cd = cd; 5217b5038d7SDag-Erling Smørgrav } 5227b5038d7SDag-Erling Smørgrav 5237b5038d7SDag-Erling Smørgrav void 5247b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(ldns_pkt *packet, bool ra) 5257b5038d7SDag-Erling Smørgrav { 5267b5038d7SDag-Erling Smørgrav packet->_header->_ra = ra; 5277b5038d7SDag-Erling Smørgrav } 5287b5038d7SDag-Erling Smørgrav 5297b5038d7SDag-Erling Smørgrav void 5307b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(ldns_pkt *packet, bool ad) 5317b5038d7SDag-Erling Smørgrav { 5327b5038d7SDag-Erling Smørgrav packet->_header->_ad = ad; 5337b5038d7SDag-Erling Smørgrav } 5347b5038d7SDag-Erling Smørgrav 5357b5038d7SDag-Erling Smørgrav void 5367b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(ldns_pkt *packet, ldns_pkt_opcode opcode) 5377b5038d7SDag-Erling Smørgrav { 5387b5038d7SDag-Erling Smørgrav packet->_header->_opcode = opcode; 5397b5038d7SDag-Erling Smørgrav } 5407b5038d7SDag-Erling Smørgrav 5417b5038d7SDag-Erling Smørgrav void 5427b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(ldns_pkt *packet, uint8_t rcode) 5437b5038d7SDag-Erling Smørgrav { 5447b5038d7SDag-Erling Smørgrav packet->_header->_rcode = rcode; 5457b5038d7SDag-Erling Smørgrav } 5467b5038d7SDag-Erling Smørgrav 5477b5038d7SDag-Erling Smørgrav void 5487b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(ldns_pkt *packet, uint16_t qdcount) 5497b5038d7SDag-Erling Smørgrav { 5507b5038d7SDag-Erling Smørgrav packet->_header->_qdcount = qdcount; 5517b5038d7SDag-Erling Smørgrav } 5527b5038d7SDag-Erling Smørgrav 5537b5038d7SDag-Erling Smørgrav void 5547b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(ldns_pkt *packet, uint16_t ancount) 5557b5038d7SDag-Erling Smørgrav { 5567b5038d7SDag-Erling Smørgrav packet->_header->_ancount = ancount; 5577b5038d7SDag-Erling Smørgrav } 5587b5038d7SDag-Erling Smørgrav 5597b5038d7SDag-Erling Smørgrav void 5607b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(ldns_pkt *packet, uint16_t nscount) 5617b5038d7SDag-Erling Smørgrav { 5627b5038d7SDag-Erling Smørgrav packet->_header->_nscount = nscount; 5637b5038d7SDag-Erling Smørgrav } 5647b5038d7SDag-Erling Smørgrav 5657b5038d7SDag-Erling Smørgrav void 5667b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(ldns_pkt *packet, uint16_t arcount) 5677b5038d7SDag-Erling Smørgrav { 5687b5038d7SDag-Erling Smørgrav packet->_header->_arcount = arcount; 5697b5038d7SDag-Erling Smørgrav } 5707b5038d7SDag-Erling Smørgrav 5717b5038d7SDag-Erling Smørgrav void 5727b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(ldns_pkt *packet, uint32_t time) 5737b5038d7SDag-Erling Smørgrav { 5747b5038d7SDag-Erling Smørgrav packet->_querytime = time; 5757b5038d7SDag-Erling Smørgrav } 5767b5038d7SDag-Erling Smørgrav 5777b5038d7SDag-Erling Smørgrav void 5787b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(ldns_pkt *packet, ldns_rdf *answerfrom) 5797b5038d7SDag-Erling Smørgrav { 5807b5038d7SDag-Erling Smørgrav packet->_answerfrom = answerfrom; 5817b5038d7SDag-Erling Smørgrav } 5827b5038d7SDag-Erling Smørgrav 5837b5038d7SDag-Erling Smørgrav void 5847b5038d7SDag-Erling Smørgrav ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval) 5857b5038d7SDag-Erling Smørgrav { 5867b5038d7SDag-Erling Smørgrav packet->timestamp.tv_sec = timeval.tv_sec; 5877b5038d7SDag-Erling Smørgrav packet->timestamp.tv_usec = timeval.tv_usec; 5887b5038d7SDag-Erling Smørgrav } 5897b5038d7SDag-Erling Smørgrav 5907b5038d7SDag-Erling Smørgrav void 5917b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(ldns_pkt *packet, size_t s) 5927b5038d7SDag-Erling Smørgrav { 5937b5038d7SDag-Erling Smørgrav packet->_size = s; 5947b5038d7SDag-Erling Smørgrav } 5957b5038d7SDag-Erling Smørgrav 5967b5038d7SDag-Erling Smørgrav void 5977b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s) 5987b5038d7SDag-Erling Smørgrav { 5997b5038d7SDag-Erling Smørgrav packet->_edns_udp_size = s; 6007b5038d7SDag-Erling Smørgrav } 6017b5038d7SDag-Erling Smørgrav 6027b5038d7SDag-Erling Smørgrav void 6037b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(ldns_pkt *packet, uint8_t c) 6047b5038d7SDag-Erling Smørgrav { 6057b5038d7SDag-Erling Smørgrav packet->_edns_extended_rcode = c; 6067b5038d7SDag-Erling Smørgrav } 6077b5038d7SDag-Erling Smørgrav 6087b5038d7SDag-Erling Smørgrav void 6097b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v) 6107b5038d7SDag-Erling Smørgrav { 6117b5038d7SDag-Erling Smørgrav packet->_edns_version = v; 6127b5038d7SDag-Erling Smørgrav } 6137b5038d7SDag-Erling Smørgrav 6147b5038d7SDag-Erling Smørgrav void 6157b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z) 6167b5038d7SDag-Erling Smørgrav { 6177b5038d7SDag-Erling Smørgrav packet->_edns_z = z; 6187b5038d7SDag-Erling Smørgrav } 6197b5038d7SDag-Erling Smørgrav 6207b5038d7SDag-Erling Smørgrav void 6217b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data) 6227b5038d7SDag-Erling Smørgrav { 6237b5038d7SDag-Erling Smørgrav packet->_edns_data = data; 6247b5038d7SDag-Erling Smørgrav } 6257b5038d7SDag-Erling Smørgrav 6267b5038d7SDag-Erling Smørgrav void 6277b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count) 6287b5038d7SDag-Erling Smørgrav { 6297b5038d7SDag-Erling Smørgrav switch(s) { 6307b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 6317b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(packet, count); 6327b5038d7SDag-Erling Smørgrav break; 6337b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 6347b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(packet, count); 6357b5038d7SDag-Erling Smørgrav break; 6367b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 6377b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(packet, count); 6387b5038d7SDag-Erling Smørgrav break; 6397b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 6407b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(packet, count); 6417b5038d7SDag-Erling Smørgrav break; 6427b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 6437b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 6447b5038d7SDag-Erling Smørgrav break; 6457b5038d7SDag-Erling Smørgrav } 6467b5038d7SDag-Erling Smørgrav } 6477b5038d7SDag-Erling Smørgrav 6487b5038d7SDag-Erling Smørgrav void ldns_pkt_set_tsig(ldns_pkt *pkt, ldns_rr *rr) 6497b5038d7SDag-Erling Smørgrav { 6507b5038d7SDag-Erling Smørgrav pkt->_tsig_rr = rr; 6517b5038d7SDag-Erling Smørgrav } 6527b5038d7SDag-Erling Smørgrav 6537b5038d7SDag-Erling Smørgrav bool 6547b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(ldns_pkt *packet, ldns_pkt_section section, ldns_rr *rr) 6557b5038d7SDag-Erling Smørgrav { 6567b5038d7SDag-Erling Smørgrav switch(section) { 6577b5038d7SDag-Erling Smørgrav case LDNS_SECTION_QUESTION: 6582787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) { 6592787e39aSDag-Erling Smørgrav return false; 6602787e39aSDag-Erling Smørgrav } 6617b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(packet, ldns_pkt_qdcount(packet) + 1); 6627b5038d7SDag-Erling Smørgrav break; 6637b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANSWER: 6642787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) { 6652787e39aSDag-Erling Smørgrav return false; 6662787e39aSDag-Erling Smørgrav } 6677b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(packet, ldns_pkt_ancount(packet) + 1); 6687b5038d7SDag-Erling Smørgrav break; 6697b5038d7SDag-Erling Smørgrav case LDNS_SECTION_AUTHORITY: 6702787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) { 6712787e39aSDag-Erling Smørgrav return false; 6722787e39aSDag-Erling Smørgrav } 6737b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(packet, ldns_pkt_nscount(packet) + 1); 6747b5038d7SDag-Erling Smørgrav break; 6757b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ADDITIONAL: 6762787e39aSDag-Erling Smørgrav if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) { 6772787e39aSDag-Erling Smørgrav return false; 6782787e39aSDag-Erling Smørgrav } 6797b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) + 1); 6807b5038d7SDag-Erling Smørgrav break; 6817b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY: 6827b5038d7SDag-Erling Smørgrav case LDNS_SECTION_ANY_NOQUESTION: 6837b5038d7SDag-Erling Smørgrav /* shouldn't this error? */ 6847b5038d7SDag-Erling Smørgrav break; 6857b5038d7SDag-Erling Smørgrav } 6867b5038d7SDag-Erling Smørgrav return true; 6877b5038d7SDag-Erling Smørgrav } 6887b5038d7SDag-Erling Smørgrav 6897b5038d7SDag-Erling Smørgrav bool 6907b5038d7SDag-Erling Smørgrav ldns_pkt_safe_push_rr(ldns_pkt *pkt, ldns_pkt_section sec, ldns_rr *rr) 6917b5038d7SDag-Erling Smørgrav { 6927b5038d7SDag-Erling Smørgrav 6937b5038d7SDag-Erling Smørgrav /* check to see if its there */ 6947b5038d7SDag-Erling Smørgrav if (ldns_pkt_rr(pkt, sec, rr)) { 6957b5038d7SDag-Erling Smørgrav /* already there */ 6967b5038d7SDag-Erling Smørgrav return false; 6977b5038d7SDag-Erling Smørgrav } 6987b5038d7SDag-Erling Smørgrav return ldns_pkt_push_rr(pkt, sec, rr); 6997b5038d7SDag-Erling Smørgrav } 7007b5038d7SDag-Erling Smørgrav 7017b5038d7SDag-Erling Smørgrav bool 7027b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 7037b5038d7SDag-Erling Smørgrav { 7047b5038d7SDag-Erling Smørgrav size_t i; 7057b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 7067b5038d7SDag-Erling Smørgrav if (!ldns_pkt_push_rr(p, s, ldns_rr_list_rr(list, i))) { 7077b5038d7SDag-Erling Smørgrav return false; 7087b5038d7SDag-Erling Smørgrav } 7097b5038d7SDag-Erling Smørgrav } 7107b5038d7SDag-Erling Smørgrav return true; 7117b5038d7SDag-Erling Smørgrav } 7127b5038d7SDag-Erling Smørgrav 7137b5038d7SDag-Erling Smørgrav bool 7147b5038d7SDag-Erling Smørgrav ldns_pkt_safe_push_rr_list(ldns_pkt *p, ldns_pkt_section s, ldns_rr_list *list) 7157b5038d7SDag-Erling Smørgrav { 7167b5038d7SDag-Erling Smørgrav size_t i; 7177b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(list); i++) { 7187b5038d7SDag-Erling Smørgrav if (!ldns_pkt_safe_push_rr(p, s, ldns_rr_list_rr(list, i))) { 7197b5038d7SDag-Erling Smørgrav return false; 7207b5038d7SDag-Erling Smørgrav } 7217b5038d7SDag-Erling Smørgrav } 7227b5038d7SDag-Erling Smørgrav return true; 7237b5038d7SDag-Erling Smørgrav } 7247b5038d7SDag-Erling Smørgrav 7257b5038d7SDag-Erling Smørgrav bool 7267b5038d7SDag-Erling Smørgrav ldns_pkt_edns(const ldns_pkt *pkt) { 7277b5038d7SDag-Erling Smørgrav return (ldns_pkt_edns_udp_size(pkt) > 0 || 7287b5038d7SDag-Erling Smørgrav ldns_pkt_edns_extended_rcode(pkt) > 0 || 7297b5038d7SDag-Erling Smørgrav ldns_pkt_edns_data(pkt) || 730*986ba33cSDag-Erling Smørgrav ldns_pkt_edns_do(pkt) || 731*986ba33cSDag-Erling Smørgrav pkt->_edns_present 7327b5038d7SDag-Erling Smørgrav ); 7337b5038d7SDag-Erling Smørgrav } 7347b5038d7SDag-Erling Smørgrav 7357b5038d7SDag-Erling Smørgrav 7367b5038d7SDag-Erling Smørgrav /* Create/destroy/convert functions 7377b5038d7SDag-Erling Smørgrav */ 7387b5038d7SDag-Erling Smørgrav ldns_pkt * 7397b5038d7SDag-Erling Smørgrav ldns_pkt_new(void) 7407b5038d7SDag-Erling Smørgrav { 7417b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 7427b5038d7SDag-Erling Smørgrav packet = LDNS_MALLOC(ldns_pkt); 7437b5038d7SDag-Erling Smørgrav if (!packet) { 7447b5038d7SDag-Erling Smørgrav return NULL; 7457b5038d7SDag-Erling Smørgrav } 7467b5038d7SDag-Erling Smørgrav 7477b5038d7SDag-Erling Smørgrav packet->_header = LDNS_MALLOC(ldns_hdr); 7487b5038d7SDag-Erling Smørgrav if (!packet->_header) { 7497b5038d7SDag-Erling Smørgrav LDNS_FREE(packet); 7507b5038d7SDag-Erling Smørgrav return NULL; 7517b5038d7SDag-Erling Smørgrav } 7527b5038d7SDag-Erling Smørgrav 7537b5038d7SDag-Erling Smørgrav packet->_question = ldns_rr_list_new(); 7547b5038d7SDag-Erling Smørgrav packet->_answer = ldns_rr_list_new(); 7557b5038d7SDag-Erling Smørgrav packet->_authority = ldns_rr_list_new(); 7567b5038d7SDag-Erling Smørgrav packet->_additional = ldns_rr_list_new(); 7577b5038d7SDag-Erling Smørgrav 7587b5038d7SDag-Erling Smørgrav /* default everything to false */ 7597b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(packet, false); 7607b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(packet, false); 7617b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(packet, false); 7627b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(packet, false); 7637b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(packet, false); 7647b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(packet, false); 7657b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(packet, false); 7667b5038d7SDag-Erling Smørgrav 7677b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(packet, LDNS_PACKET_QUERY); 7687b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(packet, 0); 7697b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(packet, 0); 7707b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(packet, 0); 7717b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(packet, 0); 7727b5038d7SDag-Erling Smørgrav memset(&packet->timestamp, 0, sizeof(packet->timestamp)); 7737b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(packet, NULL); 7747b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_QUESTION, 0); 7757b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_ANSWER, 0); 7767b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_AUTHORITY, 0); 7777b5038d7SDag-Erling Smørgrav ldns_pkt_set_section_count(packet, LDNS_SECTION_ADDITIONAL, 0); 7787b5038d7SDag-Erling Smørgrav 7797b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(packet, 0); 7807b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(packet, 0); 7817b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(packet, 0); 7827b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(packet, 0); 7837b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(packet, NULL); 784*986ba33cSDag-Erling Smørgrav packet->_edns_present = false; 7857b5038d7SDag-Erling Smørgrav 7867b5038d7SDag-Erling Smørgrav ldns_pkt_set_tsig(packet, NULL); 7877b5038d7SDag-Erling Smørgrav 7887b5038d7SDag-Erling Smørgrav return packet; 7897b5038d7SDag-Erling Smørgrav } 7907b5038d7SDag-Erling Smørgrav 7917b5038d7SDag-Erling Smørgrav void 7927b5038d7SDag-Erling Smørgrav ldns_pkt_free(ldns_pkt *packet) 7937b5038d7SDag-Erling Smørgrav { 7947b5038d7SDag-Erling Smørgrav if (packet) { 7957b5038d7SDag-Erling Smørgrav LDNS_FREE(packet->_header); 7967b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_question); 7977b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_answer); 7987b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_authority); 7997b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(packet->_additional); 8007b5038d7SDag-Erling Smørgrav ldns_rr_free(packet->_tsig_rr); 8017b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(packet->_edns_data); 8022787e39aSDag-Erling Smørgrav ldns_rdf_deep_free(packet->_answerfrom); 8037b5038d7SDag-Erling Smørgrav LDNS_FREE(packet); 8047b5038d7SDag-Erling Smørgrav } 8057b5038d7SDag-Erling Smørgrav } 8067b5038d7SDag-Erling Smørgrav 8077b5038d7SDag-Erling Smørgrav bool 8087b5038d7SDag-Erling Smørgrav ldns_pkt_set_flags(ldns_pkt *packet, uint16_t flags) 8097b5038d7SDag-Erling Smørgrav { 8107b5038d7SDag-Erling Smørgrav if (!packet) { 8117b5038d7SDag-Erling Smørgrav return false; 8127b5038d7SDag-Erling Smørgrav } 8137b5038d7SDag-Erling Smørgrav if ((flags & LDNS_QR) == LDNS_QR) { 8147b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(packet, true); 8157b5038d7SDag-Erling Smørgrav } 8167b5038d7SDag-Erling Smørgrav if ((flags & LDNS_AA) == LDNS_AA) { 8177b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(packet, true); 8187b5038d7SDag-Erling Smørgrav } 8197b5038d7SDag-Erling Smørgrav if ((flags & LDNS_RD) == LDNS_RD) { 8207b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(packet, true); 8217b5038d7SDag-Erling Smørgrav } 8227b5038d7SDag-Erling Smørgrav if ((flags & LDNS_TC) == LDNS_TC) { 8237b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(packet, true); 8247b5038d7SDag-Erling Smørgrav } 8257b5038d7SDag-Erling Smørgrav if ((flags & LDNS_CD) == LDNS_CD) { 8267b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(packet, true); 8277b5038d7SDag-Erling Smørgrav } 8287b5038d7SDag-Erling Smørgrav if ((flags & LDNS_RA) == LDNS_RA) { 8297b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(packet, true); 8307b5038d7SDag-Erling Smørgrav } 8317b5038d7SDag-Erling Smørgrav if ((flags & LDNS_AD) == LDNS_AD) { 8327b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(packet, true); 8337b5038d7SDag-Erling Smørgrav } 8347b5038d7SDag-Erling Smørgrav return true; 8357b5038d7SDag-Erling Smørgrav } 8367b5038d7SDag-Erling Smørgrav 8372787e39aSDag-Erling Smørgrav 83817d15b25SDag-Erling Smørgrav static ldns_rr* 839*986ba33cSDag-Erling Smørgrav ldns_pkt_authsoa(const ldns_rdf* rr_name, ldns_rr_class rr_class) 8402787e39aSDag-Erling Smørgrav { 8412787e39aSDag-Erling Smørgrav ldns_rr* soa_rr = ldns_rr_new(); 8422787e39aSDag-Erling Smørgrav ldns_rdf *owner_rdf; 8432787e39aSDag-Erling Smørgrav ldns_rdf *mname_rdf; 8442787e39aSDag-Erling Smørgrav ldns_rdf *rname_rdf; 8452787e39aSDag-Erling Smørgrav ldns_rdf *serial_rdf; 8462787e39aSDag-Erling Smørgrav ldns_rdf *refresh_rdf; 8472787e39aSDag-Erling Smørgrav ldns_rdf *retry_rdf; 8482787e39aSDag-Erling Smørgrav ldns_rdf *expire_rdf; 8492787e39aSDag-Erling Smørgrav ldns_rdf *minimum_rdf; 8502787e39aSDag-Erling Smørgrav 8512787e39aSDag-Erling Smørgrav if (!soa_rr) { 85217d15b25SDag-Erling Smørgrav return NULL; 8532787e39aSDag-Erling Smørgrav } 8542787e39aSDag-Erling Smørgrav owner_rdf = ldns_rdf_clone(rr_name); 8552787e39aSDag-Erling Smørgrav if (!owner_rdf) { 8562787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 85717d15b25SDag-Erling Smørgrav return NULL; 8582787e39aSDag-Erling Smørgrav } 8592787e39aSDag-Erling Smørgrav 8602787e39aSDag-Erling Smørgrav ldns_rr_set_owner(soa_rr, owner_rdf); 8612787e39aSDag-Erling Smørgrav ldns_rr_set_type(soa_rr, LDNS_RR_TYPE_SOA); 8622787e39aSDag-Erling Smørgrav ldns_rr_set_class(soa_rr, rr_class); 8632787e39aSDag-Erling Smørgrav ldns_rr_set_question(soa_rr, false); 8642787e39aSDag-Erling Smørgrav 8652787e39aSDag-Erling Smørgrav if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) { 8662787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 86717d15b25SDag-Erling Smørgrav return NULL; 8682787e39aSDag-Erling Smørgrav } else { 8692787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, mname_rdf); 8702787e39aSDag-Erling Smørgrav } 8712787e39aSDag-Erling Smørgrav if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) { 8722787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 87317d15b25SDag-Erling Smørgrav return NULL; 8742787e39aSDag-Erling Smørgrav } else { 8752787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, rname_rdf); 8762787e39aSDag-Erling Smørgrav } 8772787e39aSDag-Erling Smørgrav serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8782787e39aSDag-Erling Smørgrav if (!serial_rdf) { 8792787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 88017d15b25SDag-Erling Smørgrav return NULL; 8812787e39aSDag-Erling Smørgrav } else { 8822787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, serial_rdf); 8832787e39aSDag-Erling Smørgrav } 8842787e39aSDag-Erling Smørgrav refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8852787e39aSDag-Erling Smørgrav if (!refresh_rdf) { 8862787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 88717d15b25SDag-Erling Smørgrav return NULL; 8882787e39aSDag-Erling Smørgrav } else { 8892787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, refresh_rdf); 8902787e39aSDag-Erling Smørgrav } 8912787e39aSDag-Erling Smørgrav retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8922787e39aSDag-Erling Smørgrav if (!retry_rdf) { 8932787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 89417d15b25SDag-Erling Smørgrav return NULL; 8952787e39aSDag-Erling Smørgrav } else { 8962787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, retry_rdf); 8972787e39aSDag-Erling Smørgrav } 8982787e39aSDag-Erling Smørgrav expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 8992787e39aSDag-Erling Smørgrav if (!expire_rdf) { 9002787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 90117d15b25SDag-Erling Smørgrav return NULL; 9022787e39aSDag-Erling Smørgrav } else { 9032787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, expire_rdf); 9042787e39aSDag-Erling Smørgrav } 9052787e39aSDag-Erling Smørgrav minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); 9062787e39aSDag-Erling Smørgrav if (!minimum_rdf) { 9072787e39aSDag-Erling Smørgrav ldns_rr_free(soa_rr); 90817d15b25SDag-Erling Smørgrav return NULL; 9092787e39aSDag-Erling Smørgrav } else { 9102787e39aSDag-Erling Smørgrav ldns_rr_push_rdf(soa_rr, minimum_rdf); 9112787e39aSDag-Erling Smørgrav } 91217d15b25SDag-Erling Smørgrav return soa_rr; 9132787e39aSDag-Erling Smørgrav } 9142787e39aSDag-Erling Smørgrav 9152787e39aSDag-Erling Smørgrav 91617d15b25SDag-Erling Smørgrav static ldns_status 91717d15b25SDag-Erling Smørgrav ldns_pkt_query_new_frm_str_internal(ldns_pkt **p, const char *name, 91817d15b25SDag-Erling Smørgrav ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags, 91917d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr) 9207b5038d7SDag-Erling Smørgrav { 9217b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 9227b5038d7SDag-Erling Smørgrav ldns_rr *question_rr; 9237b5038d7SDag-Erling Smørgrav ldns_rdf *name_rdf; 9247b5038d7SDag-Erling Smørgrav 9257b5038d7SDag-Erling Smørgrav packet = ldns_pkt_new(); 9267b5038d7SDag-Erling Smørgrav if (!packet) { 9277b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 9287b5038d7SDag-Erling Smørgrav } 9297b5038d7SDag-Erling Smørgrav 9307b5038d7SDag-Erling Smørgrav if (!ldns_pkt_set_flags(packet, flags)) { 9317b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 9327b5038d7SDag-Erling Smørgrav } 9337b5038d7SDag-Erling Smørgrav 9347b5038d7SDag-Erling Smørgrav question_rr = ldns_rr_new(); 9357b5038d7SDag-Erling Smørgrav if (!question_rr) { 9367b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 9377b5038d7SDag-Erling Smørgrav } 9387b5038d7SDag-Erling Smørgrav 9397b5038d7SDag-Erling Smørgrav if (rr_type == 0) { 9407b5038d7SDag-Erling Smørgrav rr_type = LDNS_RR_TYPE_A; 9417b5038d7SDag-Erling Smørgrav } 9427b5038d7SDag-Erling Smørgrav if (rr_class == 0) { 9437b5038d7SDag-Erling Smørgrav rr_class = LDNS_RR_CLASS_IN; 9447b5038d7SDag-Erling Smørgrav } 9457b5038d7SDag-Erling Smørgrav 9467b5038d7SDag-Erling Smørgrav if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) { 9477b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(question_rr, name_rdf); 9487b5038d7SDag-Erling Smørgrav ldns_rr_set_type(question_rr, rr_type); 9497b5038d7SDag-Erling Smørgrav ldns_rr_set_class(question_rr, rr_class); 9507b5038d7SDag-Erling Smørgrav ldns_rr_set_question(question_rr, true); 9517b5038d7SDag-Erling Smørgrav 9527b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 9537b5038d7SDag-Erling Smørgrav } else { 9547b5038d7SDag-Erling Smørgrav ldns_rr_free(question_rr); 9557b5038d7SDag-Erling Smørgrav ldns_pkt_free(packet); 9567b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 9577b5038d7SDag-Erling Smørgrav } 9587b5038d7SDag-Erling Smørgrav 95917d15b25SDag-Erling Smørgrav if (authsoa_rr) { 96017d15b25SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr); 9612787e39aSDag-Erling Smørgrav } 9627b5038d7SDag-Erling Smørgrav 9632787e39aSDag-Erling Smørgrav packet->_tsig_rr = NULL; 9647b5038d7SDag-Erling Smørgrav ldns_pkt_set_answerfrom(packet, NULL); 9657b5038d7SDag-Erling Smørgrav if (p) { 9667b5038d7SDag-Erling Smørgrav *p = packet; 9677b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 9687b5038d7SDag-Erling Smørgrav } else { 9692787e39aSDag-Erling Smørgrav ldns_pkt_free(packet); 9707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 9717b5038d7SDag-Erling Smørgrav } 9727b5038d7SDag-Erling Smørgrav } 9737b5038d7SDag-Erling Smørgrav 97417d15b25SDag-Erling Smørgrav ldns_status 97517d15b25SDag-Erling Smørgrav ldns_pkt_query_new_frm_str(ldns_pkt **p, const char *name, 97617d15b25SDag-Erling Smørgrav ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags) 97717d15b25SDag-Erling Smørgrav { 97817d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_frm_str_internal(p, name, rr_type, 97917d15b25SDag-Erling Smørgrav rr_class, flags, NULL); 98017d15b25SDag-Erling Smørgrav } 98117d15b25SDag-Erling Smørgrav 98217d15b25SDag-Erling Smørgrav ldns_status 98317d15b25SDag-Erling Smørgrav ldns_pkt_ixfr_request_new_frm_str(ldns_pkt **p, const char *name, 98417d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa) 98517d15b25SDag-Erling Smørgrav { 98617d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr = soa; 98717d15b25SDag-Erling Smørgrav if (!authsoa_rr) { 98817d15b25SDag-Erling Smørgrav ldns_rdf *name_rdf; 98917d15b25SDag-Erling Smørgrav if (ldns_str2rdf_dname(&name_rdf, name) == LDNS_STATUS_OK) { 99017d15b25SDag-Erling Smørgrav authsoa_rr = ldns_pkt_authsoa(name_rdf, rr_class); 99117d15b25SDag-Erling Smørgrav } 99217d15b25SDag-Erling Smørgrav ldns_rdf_free(name_rdf); 99317d15b25SDag-Erling Smørgrav } 99417d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_frm_str_internal(p, name, LDNS_RR_TYPE_IXFR, 99517d15b25SDag-Erling Smørgrav rr_class, flags, authsoa_rr); 99617d15b25SDag-Erling Smørgrav } 99717d15b25SDag-Erling Smørgrav 99817d15b25SDag-Erling Smørgrav static ldns_pkt * 99917d15b25SDag-Erling Smørgrav ldns_pkt_query_new_internal(ldns_rdf *rr_name, ldns_rr_type rr_type, 100017d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags, ldns_rr* authsoa_rr) 10017b5038d7SDag-Erling Smørgrav { 10027b5038d7SDag-Erling Smørgrav ldns_pkt *packet; 10037b5038d7SDag-Erling Smørgrav ldns_rr *question_rr; 10047b5038d7SDag-Erling Smørgrav 10057b5038d7SDag-Erling Smørgrav packet = ldns_pkt_new(); 10067b5038d7SDag-Erling Smørgrav if (!packet) { 10077b5038d7SDag-Erling Smørgrav return NULL; 10087b5038d7SDag-Erling Smørgrav } 10097b5038d7SDag-Erling Smørgrav 10107b5038d7SDag-Erling Smørgrav if (!ldns_pkt_set_flags(packet, flags)) { 10117b5038d7SDag-Erling Smørgrav return NULL; 10127b5038d7SDag-Erling Smørgrav } 10137b5038d7SDag-Erling Smørgrav 10147b5038d7SDag-Erling Smørgrav question_rr = ldns_rr_new(); 10157b5038d7SDag-Erling Smørgrav if (!question_rr) { 10162787e39aSDag-Erling Smørgrav ldns_pkt_free(packet); 10177b5038d7SDag-Erling Smørgrav return NULL; 10187b5038d7SDag-Erling Smørgrav } 10197b5038d7SDag-Erling Smørgrav 10207b5038d7SDag-Erling Smørgrav if (rr_type == 0) { 10217b5038d7SDag-Erling Smørgrav rr_type = LDNS_RR_TYPE_A; 10227b5038d7SDag-Erling Smørgrav } 10237b5038d7SDag-Erling Smørgrav if (rr_class == 0) { 10247b5038d7SDag-Erling Smørgrav rr_class = LDNS_RR_CLASS_IN; 10257b5038d7SDag-Erling Smørgrav } 10267b5038d7SDag-Erling Smørgrav 10277b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(question_rr, rr_name); 10287b5038d7SDag-Erling Smørgrav ldns_rr_set_type(question_rr, rr_type); 10297b5038d7SDag-Erling Smørgrav ldns_rr_set_class(question_rr, rr_class); 10307b5038d7SDag-Erling Smørgrav ldns_rr_set_question(question_rr, true); 10317b5038d7SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_QUESTION, question_rr); 10327b5038d7SDag-Erling Smørgrav 103317d15b25SDag-Erling Smørgrav if (authsoa_rr) { 103417d15b25SDag-Erling Smørgrav ldns_pkt_push_rr(packet, LDNS_SECTION_AUTHORITY, authsoa_rr); 10352787e39aSDag-Erling Smørgrav } 10362787e39aSDag-Erling Smørgrav 10372787e39aSDag-Erling Smørgrav packet->_tsig_rr = NULL; 10387b5038d7SDag-Erling Smørgrav return packet; 10397b5038d7SDag-Erling Smørgrav } 10407b5038d7SDag-Erling Smørgrav 104117d15b25SDag-Erling Smørgrav ldns_pkt * 104217d15b25SDag-Erling Smørgrav ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, 104317d15b25SDag-Erling Smørgrav ldns_rr_class rr_class, uint16_t flags) 104417d15b25SDag-Erling Smørgrav { 104517d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_internal(rr_name, rr_type, 104617d15b25SDag-Erling Smørgrav rr_class, flags, NULL); 104717d15b25SDag-Erling Smørgrav } 104817d15b25SDag-Erling Smørgrav 104917d15b25SDag-Erling Smørgrav ldns_pkt * 105017d15b25SDag-Erling Smørgrav ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class, 105117d15b25SDag-Erling Smørgrav uint16_t flags, ldns_rr* soa) 105217d15b25SDag-Erling Smørgrav { 105317d15b25SDag-Erling Smørgrav ldns_rr* authsoa_rr = soa; 105417d15b25SDag-Erling Smørgrav if (!authsoa_rr) { 105517d15b25SDag-Erling Smørgrav authsoa_rr = ldns_pkt_authsoa(rr_name, rr_class); 105617d15b25SDag-Erling Smørgrav } 105717d15b25SDag-Erling Smørgrav return ldns_pkt_query_new_internal(rr_name, LDNS_RR_TYPE_IXFR, 105817d15b25SDag-Erling Smørgrav rr_class, flags, authsoa_rr); 105917d15b25SDag-Erling Smørgrav } 106017d15b25SDag-Erling Smørgrav 10617b5038d7SDag-Erling Smørgrav ldns_pkt_type 1062*986ba33cSDag-Erling Smørgrav ldns_pkt_reply_type(const ldns_pkt *p) 10637b5038d7SDag-Erling Smørgrav { 10647b5038d7SDag-Erling Smørgrav ldns_rr_list *tmp; 10657b5038d7SDag-Erling Smørgrav 10667b5038d7SDag-Erling Smørgrav if (!p) { 10677b5038d7SDag-Erling Smørgrav return LDNS_PACKET_UNKNOWN; 10687b5038d7SDag-Erling Smørgrav } 10697b5038d7SDag-Erling Smørgrav 10707b5038d7SDag-Erling Smørgrav if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NXDOMAIN) { 10717b5038d7SDag-Erling Smørgrav return LDNS_PACKET_NXDOMAIN; 10727b5038d7SDag-Erling Smørgrav } 10737b5038d7SDag-Erling Smørgrav 10747b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(p) == 0 && ldns_pkt_arcount(p) == 0 10757b5038d7SDag-Erling Smørgrav && ldns_pkt_nscount(p) == 1) { 10767b5038d7SDag-Erling Smørgrav 10777b5038d7SDag-Erling Smørgrav /* check for SOA */ 10787b5038d7SDag-Erling Smørgrav tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_SOA, 10797b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY); 10807b5038d7SDag-Erling Smørgrav if (tmp) { 10817b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10827b5038d7SDag-Erling Smørgrav return LDNS_PACKET_NODATA; 10837b5038d7SDag-Erling Smørgrav } else { 10847b5038d7SDag-Erling Smørgrav /* I have no idea ... */ 10857b5038d7SDag-Erling Smørgrav } 10867b5038d7SDag-Erling Smørgrav } 10877b5038d7SDag-Erling Smørgrav 10887b5038d7SDag-Erling Smørgrav if (ldns_pkt_ancount(p) == 0 && ldns_pkt_nscount(p) > 0) { 10897b5038d7SDag-Erling Smørgrav tmp = ldns_pkt_rr_list_by_type(p, LDNS_RR_TYPE_NS, 10907b5038d7SDag-Erling Smørgrav LDNS_SECTION_AUTHORITY); 10917b5038d7SDag-Erling Smørgrav if (tmp) { 10927b5038d7SDag-Erling Smørgrav /* there are nameservers here */ 10937b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10947b5038d7SDag-Erling Smørgrav return LDNS_PACKET_REFERRAL; 10957b5038d7SDag-Erling Smørgrav } else { 10967b5038d7SDag-Erling Smørgrav /* I have no idea */ 10977b5038d7SDag-Erling Smørgrav } 10987b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(tmp); 10997b5038d7SDag-Erling Smørgrav } 11007b5038d7SDag-Erling Smørgrav 11017b5038d7SDag-Erling Smørgrav /* if we cannot determine the packet type, we say it's an 11027b5038d7SDag-Erling Smørgrav * answer... 11037b5038d7SDag-Erling Smørgrav */ 11047b5038d7SDag-Erling Smørgrav return LDNS_PACKET_ANSWER; 11057b5038d7SDag-Erling Smørgrav } 11067b5038d7SDag-Erling Smørgrav 11077b5038d7SDag-Erling Smørgrav ldns_pkt * 1108*986ba33cSDag-Erling Smørgrav ldns_pkt_clone(const ldns_pkt *pkt) 11097b5038d7SDag-Erling Smørgrav { 11107b5038d7SDag-Erling Smørgrav ldns_pkt *new_pkt; 11117b5038d7SDag-Erling Smørgrav 11127b5038d7SDag-Erling Smørgrav if (!pkt) { 11137b5038d7SDag-Erling Smørgrav return NULL; 11147b5038d7SDag-Erling Smørgrav } 11157b5038d7SDag-Erling Smørgrav new_pkt = ldns_pkt_new(); 11167b5038d7SDag-Erling Smørgrav 11177b5038d7SDag-Erling Smørgrav ldns_pkt_set_id(new_pkt, ldns_pkt_id(pkt)); 11187b5038d7SDag-Erling Smørgrav ldns_pkt_set_qr(new_pkt, ldns_pkt_qr(pkt)); 11197b5038d7SDag-Erling Smørgrav ldns_pkt_set_aa(new_pkt, ldns_pkt_aa(pkt)); 11207b5038d7SDag-Erling Smørgrav ldns_pkt_set_tc(new_pkt, ldns_pkt_tc(pkt)); 11217b5038d7SDag-Erling Smørgrav ldns_pkt_set_rd(new_pkt, ldns_pkt_rd(pkt)); 11227b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(new_pkt, ldns_pkt_cd(pkt)); 11237b5038d7SDag-Erling Smørgrav ldns_pkt_set_ra(new_pkt, ldns_pkt_ra(pkt)); 11247b5038d7SDag-Erling Smørgrav ldns_pkt_set_ad(new_pkt, ldns_pkt_ad(pkt)); 11257b5038d7SDag-Erling Smørgrav ldns_pkt_set_opcode(new_pkt, ldns_pkt_get_opcode(pkt)); 11267b5038d7SDag-Erling Smørgrav ldns_pkt_set_rcode(new_pkt, ldns_pkt_get_rcode(pkt)); 11277b5038d7SDag-Erling Smørgrav ldns_pkt_set_qdcount(new_pkt, ldns_pkt_qdcount(pkt)); 11287b5038d7SDag-Erling Smørgrav ldns_pkt_set_ancount(new_pkt, ldns_pkt_ancount(pkt)); 11297b5038d7SDag-Erling Smørgrav ldns_pkt_set_nscount(new_pkt, ldns_pkt_nscount(pkt)); 11307b5038d7SDag-Erling Smørgrav ldns_pkt_set_arcount(new_pkt, ldns_pkt_arcount(pkt)); 11312787e39aSDag-Erling Smørgrav if (ldns_pkt_answerfrom(pkt)) 11322787e39aSDag-Erling Smørgrav ldns_pkt_set_answerfrom(new_pkt, 11332787e39aSDag-Erling Smørgrav ldns_rdf_clone(ldns_pkt_answerfrom(pkt))); 1134*986ba33cSDag-Erling Smørgrav ldns_pkt_set_timestamp(new_pkt, ldns_pkt_timestamp(pkt)); 11357b5038d7SDag-Erling Smørgrav ldns_pkt_set_querytime(new_pkt, ldns_pkt_querytime(pkt)); 11367b5038d7SDag-Erling Smørgrav ldns_pkt_set_size(new_pkt, ldns_pkt_size(pkt)); 11377b5038d7SDag-Erling Smørgrav ldns_pkt_set_tsig(new_pkt, ldns_rr_clone(ldns_pkt_tsig(pkt))); 11387b5038d7SDag-Erling Smørgrav 11397b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(new_pkt, ldns_pkt_edns_udp_size(pkt)); 11407b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_extended_rcode(new_pkt, 11417b5038d7SDag-Erling Smørgrav ldns_pkt_edns_extended_rcode(pkt)); 11427b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_version(new_pkt, ldns_pkt_edns_version(pkt)); 1143*986ba33cSDag-Erling Smørgrav new_pkt->_edns_present = pkt->_edns_present; 11447b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_z(new_pkt, ldns_pkt_edns_z(pkt)); 11457b5038d7SDag-Erling Smørgrav if(ldns_pkt_edns_data(pkt)) 11467b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_data(new_pkt, 11477b5038d7SDag-Erling Smørgrav ldns_rdf_clone(ldns_pkt_edns_data(pkt))); 11487b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt)); 11497b5038d7SDag-Erling Smørgrav 11507b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_question); 11517b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_answer); 11527b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_authority); 11537b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(new_pkt->_additional); 11547b5038d7SDag-Erling Smørgrav new_pkt->_question = ldns_rr_list_clone(ldns_pkt_question(pkt)); 11557b5038d7SDag-Erling Smørgrav new_pkt->_answer = ldns_rr_list_clone(ldns_pkt_answer(pkt)); 11567b5038d7SDag-Erling Smørgrav new_pkt->_authority = ldns_rr_list_clone(ldns_pkt_authority(pkt)); 11577b5038d7SDag-Erling Smørgrav new_pkt->_additional = ldns_rr_list_clone(ldns_pkt_additional(pkt)); 11587b5038d7SDag-Erling Smørgrav return new_pkt; 11597b5038d7SDag-Erling Smørgrav } 1160