17b5038d7SDag-Erling Smørgrav /* 27b5038d7SDag-Erling Smørgrav * host2wire.c 37b5038d7SDag-Erling Smørgrav * 47b5038d7SDag-Erling Smørgrav * conversion routines from the host to the wire format. 57b5038d7SDag-Erling Smørgrav * This will usually just a re-ordering of the 67b5038d7SDag-Erling Smørgrav * data (as we store it in network format) 77b5038d7SDag-Erling Smørgrav * 87b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 97b5038d7SDag-Erling Smørgrav * 107b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 117b5038d7SDag-Erling Smørgrav * 127b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 137b5038d7SDag-Erling Smørgrav */ 147b5038d7SDag-Erling Smørgrav 157b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 167b5038d7SDag-Erling Smørgrav 177b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 187b5038d7SDag-Erling Smørgrav 197b5038d7SDag-Erling Smørgrav /* TODO Jelte 207b5038d7SDag-Erling Smørgrav add a pointer to a 'possiblecompression' structure 217b5038d7SDag-Erling Smørgrav to all the needed functions? 227b5038d7SDag-Erling Smørgrav something like an array of name, pointer values? 237b5038d7SDag-Erling Smørgrav every dname part could be added to it 247b5038d7SDag-Erling Smørgrav */ 257b5038d7SDag-Erling Smørgrav 267b5038d7SDag-Erling Smørgrav ldns_status 277b5038d7SDag-Erling Smørgrav ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name) 287b5038d7SDag-Erling Smørgrav { 297b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(name))) { 307b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name)); 317b5038d7SDag-Erling Smørgrav } 327b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 337b5038d7SDag-Erling Smørgrav } 347b5038d7SDag-Erling Smørgrav 357b5038d7SDag-Erling Smørgrav ldns_status 367b5038d7SDag-Erling Smørgrav ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf) 377b5038d7SDag-Erling Smørgrav { 387b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 397b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf)); 407b5038d7SDag-Erling Smørgrav } 417b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 427b5038d7SDag-Erling Smørgrav } 437b5038d7SDag-Erling Smørgrav 447b5038d7SDag-Erling Smørgrav ldns_status 457b5038d7SDag-Erling Smørgrav ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf) 467b5038d7SDag-Erling Smørgrav { 477b5038d7SDag-Erling Smørgrav size_t i; 487b5038d7SDag-Erling Smørgrav uint8_t *rdf_data; 497b5038d7SDag-Erling Smørgrav 507b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) { 517b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 527b5038d7SDag-Erling Smørgrav rdf_data = ldns_rdf_data(rdf); 537b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rdf_size(rdf); i++) { 547b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, 557b5038d7SDag-Erling Smørgrav (uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i])); 567b5038d7SDag-Erling Smørgrav } 577b5038d7SDag-Erling Smørgrav } 587b5038d7SDag-Erling Smørgrav } else { 597b5038d7SDag-Erling Smørgrav /* direct copy for all other types */ 607b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 617b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, 627b5038d7SDag-Erling Smørgrav ldns_rdf_data(rdf), 637b5038d7SDag-Erling Smørgrav ldns_rdf_size(rdf)); 647b5038d7SDag-Erling Smørgrav } 657b5038d7SDag-Erling Smørgrav } 667b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 677b5038d7SDag-Erling Smørgrav } 687b5038d7SDag-Erling Smørgrav 697b5038d7SDag-Erling Smørgrav /* convert a rr list to wireformat */ 707b5038d7SDag-Erling Smørgrav ldns_status 717b5038d7SDag-Erling Smørgrav ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list) 727b5038d7SDag-Erling Smørgrav { 737b5038d7SDag-Erling Smørgrav uint16_t rr_count; 747b5038d7SDag-Erling Smørgrav uint16_t i; 757b5038d7SDag-Erling Smørgrav 767b5038d7SDag-Erling Smørgrav rr_count = ldns_rr_list_rr_count(rr_list); 777b5038d7SDag-Erling Smørgrav for(i = 0; i < rr_count; i++) { 787b5038d7SDag-Erling Smørgrav (void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 797b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY); 807b5038d7SDag-Erling Smørgrav } 817b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 827b5038d7SDag-Erling Smørgrav } 837b5038d7SDag-Erling Smørgrav 847b5038d7SDag-Erling Smørgrav ldns_status 857b5038d7SDag-Erling Smørgrav ldns_rr2buffer_wire_canonical(ldns_buffer *buffer, 867b5038d7SDag-Erling Smørgrav const ldns_rr *rr, 877b5038d7SDag-Erling Smørgrav int section) 887b5038d7SDag-Erling Smørgrav { 897b5038d7SDag-Erling Smørgrav uint16_t i; 907b5038d7SDag-Erling Smørgrav uint16_t rdl_pos = 0; 917b5038d7SDag-Erling Smørgrav bool pre_rfc3597 = false; 927b5038d7SDag-Erling Smørgrav switch (ldns_rr_get_type(rr)) { 937b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NS: 947b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MD: 957b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MF: 967b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_CNAME: 977b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SOA: 987b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MB: 997b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MG: 1007b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MR: 1017b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_PTR: 1027b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_HINFO: 1037b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MINFO: 1047b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MX: 1057b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RP: 1067b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_AFSDB: 1077b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RT: 1087b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SIG: 1097b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_PX: 1107b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NXT: 1117b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NAPTR: 1127b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_KX: 1137b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SRV: 1147b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_DNAME: 1157b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_A6: 1167b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RRSIG: 1177b5038d7SDag-Erling Smørgrav pre_rfc3597 = true; 1187b5038d7SDag-Erling Smørgrav break; 1197b5038d7SDag-Erling Smørgrav default: 1207b5038d7SDag-Erling Smørgrav break; 1217b5038d7SDag-Erling Smørgrav } 1227b5038d7SDag-Erling Smørgrav 1237b5038d7SDag-Erling Smørgrav if (ldns_rr_owner(rr)) { 1247b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr)); 1257b5038d7SDag-Erling Smørgrav } 1267b5038d7SDag-Erling Smørgrav 1277b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 4)) { 1287b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr)); 1297b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr)); 1307b5038d7SDag-Erling Smørgrav } 1317b5038d7SDag-Erling Smørgrav 1327b5038d7SDag-Erling Smørgrav if (section != LDNS_SECTION_QUESTION) { 1337b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 6)) { 1347b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr)); 1357b5038d7SDag-Erling Smørgrav /* remember pos for later */ 1367b5038d7SDag-Erling Smørgrav rdl_pos = ldns_buffer_position(buffer); 1377b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, 0); 1387b5038d7SDag-Erling Smørgrav } 1397b5038d7SDag-Erling Smørgrav 1407b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 1417b5038d7SDag-Erling Smørgrav if (pre_rfc3597) { 1427b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical( 1437b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 1447b5038d7SDag-Erling Smørgrav } else { 1457b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire( 1467b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 1477b5038d7SDag-Erling Smørgrav } 1487b5038d7SDag-Erling Smørgrav } 1497b5038d7SDag-Erling Smørgrav 1507b5038d7SDag-Erling Smørgrav if (rdl_pos != 0) { 1517b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16_at(buffer, rdl_pos, 1527b5038d7SDag-Erling Smørgrav ldns_buffer_position(buffer) 1537b5038d7SDag-Erling Smørgrav - rdl_pos - 2); 1547b5038d7SDag-Erling Smørgrav } 1557b5038d7SDag-Erling Smørgrav } 1567b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 1577b5038d7SDag-Erling Smørgrav } 1587b5038d7SDag-Erling Smørgrav 1597b5038d7SDag-Erling Smørgrav ldns_status 1607b5038d7SDag-Erling Smørgrav ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section) 1617b5038d7SDag-Erling Smørgrav { 1627b5038d7SDag-Erling Smørgrav uint16_t i; 1637b5038d7SDag-Erling Smørgrav uint16_t rdl_pos = 0; 1647b5038d7SDag-Erling Smørgrav 1657b5038d7SDag-Erling Smørgrav if (ldns_rr_owner(rr)) { 1667b5038d7SDag-Erling Smørgrav (void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr)); 1677b5038d7SDag-Erling Smørgrav } 1687b5038d7SDag-Erling Smørgrav 1697b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 4)) { 1707b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr)); 1717b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr)); 1727b5038d7SDag-Erling Smørgrav } 1737b5038d7SDag-Erling Smørgrav 1747b5038d7SDag-Erling Smørgrav if (section != LDNS_SECTION_QUESTION) { 1757b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 6)) { 1767b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr)); 1777b5038d7SDag-Erling Smørgrav /* remember pos for later */ 1787b5038d7SDag-Erling Smørgrav rdl_pos = ldns_buffer_position(buffer); 1797b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, 0); 1807b5038d7SDag-Erling Smørgrav } 1817b5038d7SDag-Erling Smørgrav 1827b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 1837b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire( 1847b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 1857b5038d7SDag-Erling Smørgrav } 1867b5038d7SDag-Erling Smørgrav 1877b5038d7SDag-Erling Smørgrav if (rdl_pos != 0) { 1887b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16_at(buffer, rdl_pos, 1897b5038d7SDag-Erling Smørgrav ldns_buffer_position(buffer) 1907b5038d7SDag-Erling Smørgrav - rdl_pos - 2); 1917b5038d7SDag-Erling Smørgrav } 1927b5038d7SDag-Erling Smørgrav } 1937b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 1947b5038d7SDag-Erling Smørgrav } 1957b5038d7SDag-Erling Smørgrav 1967b5038d7SDag-Erling Smørgrav ldns_status 1977b5038d7SDag-Erling Smørgrav ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) 1987b5038d7SDag-Erling Smørgrav { 1997b5038d7SDag-Erling Smørgrav uint16_t i; 2007b5038d7SDag-Erling Smørgrav 2017b5038d7SDag-Erling Smørgrav /* it must be a sig RR */ 2027b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) { 2037b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 2047b5038d7SDag-Erling Smørgrav } 2057b5038d7SDag-Erling Smørgrav 2067b5038d7SDag-Erling Smørgrav /* Convert all the rdfs, except the actual signature data 2077b5038d7SDag-Erling Smørgrav * rdf number 8 - the last, hence: -1 */ 2087b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) { 2097b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i)); 2107b5038d7SDag-Erling Smørgrav } 2117b5038d7SDag-Erling Smørgrav 2127b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 2137b5038d7SDag-Erling Smørgrav } 2147b5038d7SDag-Erling Smørgrav 2157b5038d7SDag-Erling Smørgrav ldns_status 2167b5038d7SDag-Erling Smørgrav ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) 2177b5038d7SDag-Erling Smørgrav { 2187b5038d7SDag-Erling Smørgrav uint16_t i; 2197b5038d7SDag-Erling Smørgrav /* convert all the rdf's */ 2207b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 2217b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i)); 2227b5038d7SDag-Erling Smørgrav } 2237b5038d7SDag-Erling Smørgrav 2247b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 2257b5038d7SDag-Erling Smørgrav } 2267b5038d7SDag-Erling Smørgrav 2277b5038d7SDag-Erling Smørgrav /* 2287b5038d7SDag-Erling Smørgrav * Copies the packet header data to the buffer in wire format 2297b5038d7SDag-Erling Smørgrav */ 2307b5038d7SDag-Erling Smørgrav static ldns_status 2317b5038d7SDag-Erling Smørgrav ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) 2327b5038d7SDag-Erling Smørgrav { 2337b5038d7SDag-Erling Smørgrav uint8_t flags; 2347b5038d7SDag-Erling Smørgrav uint16_t arcount; 2357b5038d7SDag-Erling Smørgrav 2367b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 12)) { 2377b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_id(packet)); 2387b5038d7SDag-Erling Smørgrav 2397b5038d7SDag-Erling Smørgrav flags = ldns_pkt_qr(packet) << 7 2407b5038d7SDag-Erling Smørgrav | ldns_pkt_get_opcode(packet) << 3 2417b5038d7SDag-Erling Smørgrav | ldns_pkt_aa(packet) << 2 2427b5038d7SDag-Erling Smørgrav | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet); 2437b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, flags); 2447b5038d7SDag-Erling Smørgrav 2457b5038d7SDag-Erling Smørgrav flags = ldns_pkt_ra(packet) << 7 2467b5038d7SDag-Erling Smørgrav /*| ldns_pkt_z(packet) << 6*/ 2477b5038d7SDag-Erling Smørgrav | ldns_pkt_ad(packet) << 5 2487b5038d7SDag-Erling Smørgrav | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet); 2497b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, flags); 2507b5038d7SDag-Erling Smørgrav 2517b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet)); 2527b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet)); 2537b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet)); 2547b5038d7SDag-Erling Smørgrav /* add EDNS0 and TSIG to additional if they are there */ 2557b5038d7SDag-Erling Smørgrav arcount = ldns_pkt_arcount(packet); 2567b5038d7SDag-Erling Smørgrav if (ldns_pkt_tsig(packet)) { 2577b5038d7SDag-Erling Smørgrav arcount++; 2587b5038d7SDag-Erling Smørgrav } 2597b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns(packet)) { 2607b5038d7SDag-Erling Smørgrav arcount++; 2617b5038d7SDag-Erling Smørgrav } 2627b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, arcount); 2637b5038d7SDag-Erling Smørgrav } 2647b5038d7SDag-Erling Smørgrav 2657b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 2667b5038d7SDag-Erling Smørgrav } 2677b5038d7SDag-Erling Smørgrav 2687b5038d7SDag-Erling Smørgrav ldns_status 2697b5038d7SDag-Erling Smørgrav ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) 2707b5038d7SDag-Erling Smørgrav { 2717b5038d7SDag-Erling Smørgrav ldns_rr_list *rr_list; 2727b5038d7SDag-Erling Smørgrav uint16_t i; 2737b5038d7SDag-Erling Smørgrav 2747b5038d7SDag-Erling Smørgrav /* edns tmp vars */ 2757b5038d7SDag-Erling Smørgrav ldns_rr *edns_rr; 2767b5038d7SDag-Erling Smørgrav uint8_t edata[4]; 2777b5038d7SDag-Erling Smørgrav 2787b5038d7SDag-Erling Smørgrav (void) ldns_hdr2buffer_wire(buffer, packet); 2797b5038d7SDag-Erling Smørgrav 2807b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_question(packet); 2817b5038d7SDag-Erling Smørgrav if (rr_list) { 2827b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 2837b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 2847b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION); 2857b5038d7SDag-Erling Smørgrav } 2867b5038d7SDag-Erling Smørgrav } 2877b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_answer(packet); 2887b5038d7SDag-Erling Smørgrav if (rr_list) { 2897b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 2907b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 2917b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER); 2927b5038d7SDag-Erling Smørgrav } 2937b5038d7SDag-Erling Smørgrav } 2947b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_authority(packet); 2957b5038d7SDag-Erling Smørgrav if (rr_list) { 2967b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 2977b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 2987b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY); 2997b5038d7SDag-Erling Smørgrav } 3007b5038d7SDag-Erling Smørgrav } 3017b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_additional(packet); 3027b5038d7SDag-Erling Smørgrav if (rr_list) { 3037b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 3047b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 3057b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL); 3067b5038d7SDag-Erling Smørgrav } 3077b5038d7SDag-Erling Smørgrav } 3087b5038d7SDag-Erling Smørgrav 3097b5038d7SDag-Erling Smørgrav /* add EDNS to additional if it is needed */ 3107b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns(packet)) { 3117b5038d7SDag-Erling Smørgrav edns_rr = ldns_rr_new(); 3127b5038d7SDag-Erling Smørgrav if(!edns_rr) return LDNS_STATUS_MEM_ERR; 3137b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(edns_rr, 3147b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, ".")); 3157b5038d7SDag-Erling Smørgrav ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT); 3167b5038d7SDag-Erling Smørgrav ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet)); 3177b5038d7SDag-Erling Smørgrav edata[0] = ldns_pkt_edns_extended_rcode(packet); 3187b5038d7SDag-Erling Smørgrav edata[1] = ldns_pkt_edns_version(packet); 3197b5038d7SDag-Erling Smørgrav ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet)); 3207b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata)); 3217b5038d7SDag-Erling Smørgrav /* don't forget to add the edns rdata (if any) */ 3227b5038d7SDag-Erling Smørgrav if (packet->_edns_data) 3237b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf (edns_rr, packet->_edns_data); 3247b5038d7SDag-Erling Smørgrav (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL); 3257b5038d7SDag-Erling Smørgrav /* take the edns rdata back out of the rr before we free rr */ 3267b5038d7SDag-Erling Smørgrav if (packet->_edns_data) 3277b5038d7SDag-Erling Smørgrav (void)ldns_rr_pop_rdf (edns_rr); 3287b5038d7SDag-Erling Smørgrav ldns_rr_free(edns_rr); 3297b5038d7SDag-Erling Smørgrav } 3307b5038d7SDag-Erling Smørgrav 3317b5038d7SDag-Erling Smørgrav /* add TSIG to additional if it is there */ 3327b5038d7SDag-Erling Smørgrav if (ldns_pkt_tsig(packet)) { 3337b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 3347b5038d7SDag-Erling Smørgrav ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL); 3357b5038d7SDag-Erling Smørgrav } 3367b5038d7SDag-Erling Smørgrav 3377b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 3387b5038d7SDag-Erling Smørgrav } 3397b5038d7SDag-Erling Smørgrav 3407b5038d7SDag-Erling Smørgrav ldns_status 3417b5038d7SDag-Erling Smørgrav ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size) 3427b5038d7SDag-Erling Smørgrav { 3437b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 3447b5038d7SDag-Erling Smørgrav ldns_status status; 3457b5038d7SDag-Erling Smørgrav *result_size = 0; 3467b5038d7SDag-Erling Smørgrav *dest = NULL; 3477b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 3487b5038d7SDag-Erling Smørgrav 3497b5038d7SDag-Erling Smørgrav status = ldns_rdf2buffer_wire(buffer, rdf); 3507b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 3517b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 352*2787e39aSDag-Erling Smørgrav *dest = (uint8_t *) ldns_buffer_export(buffer); 3537b5038d7SDag-Erling Smørgrav } 3547b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 3557b5038d7SDag-Erling Smørgrav return status; 3567b5038d7SDag-Erling Smørgrav } 3577b5038d7SDag-Erling Smørgrav 3587b5038d7SDag-Erling Smørgrav ldns_status 3597b5038d7SDag-Erling Smørgrav ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size) 3607b5038d7SDag-Erling Smørgrav { 3617b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 3627b5038d7SDag-Erling Smørgrav ldns_status status; 3637b5038d7SDag-Erling Smørgrav *result_size = 0; 3647b5038d7SDag-Erling Smørgrav *dest = NULL; 3657b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 3667b5038d7SDag-Erling Smørgrav 3677b5038d7SDag-Erling Smørgrav status = ldns_rr2buffer_wire(buffer, rr, section); 3687b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 3697b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 370*2787e39aSDag-Erling Smørgrav *dest = (uint8_t *) ldns_buffer_export(buffer); 3717b5038d7SDag-Erling Smørgrav } 3727b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 3737b5038d7SDag-Erling Smørgrav return status; 3747b5038d7SDag-Erling Smørgrav } 3757b5038d7SDag-Erling Smørgrav 3767b5038d7SDag-Erling Smørgrav ldns_status 3777b5038d7SDag-Erling Smørgrav ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size) 3787b5038d7SDag-Erling Smørgrav { 3797b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 3807b5038d7SDag-Erling Smørgrav ldns_status status; 3817b5038d7SDag-Erling Smørgrav *result_size = 0; 3827b5038d7SDag-Erling Smørgrav *dest = NULL; 3837b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 3847b5038d7SDag-Erling Smørgrav 3857b5038d7SDag-Erling Smørgrav status = ldns_pkt2buffer_wire(buffer, packet); 3867b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 3877b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 388*2787e39aSDag-Erling Smørgrav *dest = (uint8_t *) ldns_buffer_export(buffer); 3897b5038d7SDag-Erling Smørgrav } 3907b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 3917b5038d7SDag-Erling Smørgrav return status; 3927b5038d7SDag-Erling Smørgrav } 393