1*7b5038d7SDag-Erling Smørgrav /* 2*7b5038d7SDag-Erling Smørgrav * host2wire.c 3*7b5038d7SDag-Erling Smørgrav * 4*7b5038d7SDag-Erling Smørgrav * conversion routines from the host to the wire format. 5*7b5038d7SDag-Erling Smørgrav * This will usually just a re-ordering of the 6*7b5038d7SDag-Erling Smørgrav * data (as we store it in network format) 7*7b5038d7SDag-Erling Smørgrav * 8*7b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 9*7b5038d7SDag-Erling Smørgrav * 10*7b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 11*7b5038d7SDag-Erling Smørgrav * 12*7b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 13*7b5038d7SDag-Erling Smørgrav */ 14*7b5038d7SDag-Erling Smørgrav 15*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 16*7b5038d7SDag-Erling Smørgrav 17*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 18*7b5038d7SDag-Erling Smørgrav 19*7b5038d7SDag-Erling Smørgrav /* TODO Jelte 20*7b5038d7SDag-Erling Smørgrav add a pointer to a 'possiblecompression' structure 21*7b5038d7SDag-Erling Smørgrav to all the needed functions? 22*7b5038d7SDag-Erling Smørgrav something like an array of name, pointer values? 23*7b5038d7SDag-Erling Smørgrav every dname part could be added to it 24*7b5038d7SDag-Erling Smørgrav */ 25*7b5038d7SDag-Erling Smørgrav 26*7b5038d7SDag-Erling Smørgrav ldns_status 27*7b5038d7SDag-Erling Smørgrav ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name) 28*7b5038d7SDag-Erling Smørgrav { 29*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(name))) { 30*7b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name)); 31*7b5038d7SDag-Erling Smørgrav } 32*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 33*7b5038d7SDag-Erling Smørgrav } 34*7b5038d7SDag-Erling Smørgrav 35*7b5038d7SDag-Erling Smørgrav ldns_status 36*7b5038d7SDag-Erling Smørgrav ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf) 37*7b5038d7SDag-Erling Smørgrav { 38*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 39*7b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf)); 40*7b5038d7SDag-Erling Smørgrav } 41*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 42*7b5038d7SDag-Erling Smørgrav } 43*7b5038d7SDag-Erling Smørgrav 44*7b5038d7SDag-Erling Smørgrav ldns_status 45*7b5038d7SDag-Erling Smørgrav ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf) 46*7b5038d7SDag-Erling Smørgrav { 47*7b5038d7SDag-Erling Smørgrav size_t i; 48*7b5038d7SDag-Erling Smørgrav uint8_t *rdf_data; 49*7b5038d7SDag-Erling Smørgrav 50*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) { 51*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 52*7b5038d7SDag-Erling Smørgrav rdf_data = ldns_rdf_data(rdf); 53*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rdf_size(rdf); i++) { 54*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, 55*7b5038d7SDag-Erling Smørgrav (uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i])); 56*7b5038d7SDag-Erling Smørgrav } 57*7b5038d7SDag-Erling Smørgrav } 58*7b5038d7SDag-Erling Smørgrav } else { 59*7b5038d7SDag-Erling Smørgrav /* direct copy for all other types */ 60*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) { 61*7b5038d7SDag-Erling Smørgrav ldns_buffer_write(buffer, 62*7b5038d7SDag-Erling Smørgrav ldns_rdf_data(rdf), 63*7b5038d7SDag-Erling Smørgrav ldns_rdf_size(rdf)); 64*7b5038d7SDag-Erling Smørgrav } 65*7b5038d7SDag-Erling Smørgrav } 66*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 67*7b5038d7SDag-Erling Smørgrav } 68*7b5038d7SDag-Erling Smørgrav 69*7b5038d7SDag-Erling Smørgrav /* convert a rr list to wireformat */ 70*7b5038d7SDag-Erling Smørgrav ldns_status 71*7b5038d7SDag-Erling Smørgrav ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list) 72*7b5038d7SDag-Erling Smørgrav { 73*7b5038d7SDag-Erling Smørgrav uint16_t rr_count; 74*7b5038d7SDag-Erling Smørgrav uint16_t i; 75*7b5038d7SDag-Erling Smørgrav 76*7b5038d7SDag-Erling Smørgrav rr_count = ldns_rr_list_rr_count(rr_list); 77*7b5038d7SDag-Erling Smørgrav for(i = 0; i < rr_count; i++) { 78*7b5038d7SDag-Erling Smørgrav (void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i), 79*7b5038d7SDag-Erling Smørgrav LDNS_SECTION_ANY); 80*7b5038d7SDag-Erling Smørgrav } 81*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 82*7b5038d7SDag-Erling Smørgrav } 83*7b5038d7SDag-Erling Smørgrav 84*7b5038d7SDag-Erling Smørgrav ldns_status 85*7b5038d7SDag-Erling Smørgrav ldns_rr2buffer_wire_canonical(ldns_buffer *buffer, 86*7b5038d7SDag-Erling Smørgrav const ldns_rr *rr, 87*7b5038d7SDag-Erling Smørgrav int section) 88*7b5038d7SDag-Erling Smørgrav { 89*7b5038d7SDag-Erling Smørgrav uint16_t i; 90*7b5038d7SDag-Erling Smørgrav uint16_t rdl_pos = 0; 91*7b5038d7SDag-Erling Smørgrav bool pre_rfc3597 = false; 92*7b5038d7SDag-Erling Smørgrav switch (ldns_rr_get_type(rr)) { 93*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NS: 94*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MD: 95*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MF: 96*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_CNAME: 97*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SOA: 98*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MB: 99*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MG: 100*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MR: 101*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_PTR: 102*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_HINFO: 103*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MINFO: 104*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_MX: 105*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RP: 106*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_AFSDB: 107*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RT: 108*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SIG: 109*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_PX: 110*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NXT: 111*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_NAPTR: 112*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_KX: 113*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_SRV: 114*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_DNAME: 115*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_A6: 116*7b5038d7SDag-Erling Smørgrav case LDNS_RR_TYPE_RRSIG: 117*7b5038d7SDag-Erling Smørgrav pre_rfc3597 = true; 118*7b5038d7SDag-Erling Smørgrav break; 119*7b5038d7SDag-Erling Smørgrav default: 120*7b5038d7SDag-Erling Smørgrav break; 121*7b5038d7SDag-Erling Smørgrav } 122*7b5038d7SDag-Erling Smørgrav 123*7b5038d7SDag-Erling Smørgrav if (ldns_rr_owner(rr)) { 124*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr)); 125*7b5038d7SDag-Erling Smørgrav } 126*7b5038d7SDag-Erling Smørgrav 127*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 4)) { 128*7b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr)); 129*7b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr)); 130*7b5038d7SDag-Erling Smørgrav } 131*7b5038d7SDag-Erling Smørgrav 132*7b5038d7SDag-Erling Smørgrav if (section != LDNS_SECTION_QUESTION) { 133*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 6)) { 134*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr)); 135*7b5038d7SDag-Erling Smørgrav /* remember pos for later */ 136*7b5038d7SDag-Erling Smørgrav rdl_pos = ldns_buffer_position(buffer); 137*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, 0); 138*7b5038d7SDag-Erling Smørgrav } 139*7b5038d7SDag-Erling Smørgrav 140*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 141*7b5038d7SDag-Erling Smørgrav if (pre_rfc3597) { 142*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical( 143*7b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 144*7b5038d7SDag-Erling Smørgrav } else { 145*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire( 146*7b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 147*7b5038d7SDag-Erling Smørgrav } 148*7b5038d7SDag-Erling Smørgrav } 149*7b5038d7SDag-Erling Smørgrav 150*7b5038d7SDag-Erling Smørgrav if (rdl_pos != 0) { 151*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16_at(buffer, rdl_pos, 152*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(buffer) 153*7b5038d7SDag-Erling Smørgrav - rdl_pos - 2); 154*7b5038d7SDag-Erling Smørgrav } 155*7b5038d7SDag-Erling Smørgrav } 156*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 157*7b5038d7SDag-Erling Smørgrav } 158*7b5038d7SDag-Erling Smørgrav 159*7b5038d7SDag-Erling Smørgrav ldns_status 160*7b5038d7SDag-Erling Smørgrav ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section) 161*7b5038d7SDag-Erling Smørgrav { 162*7b5038d7SDag-Erling Smørgrav uint16_t i; 163*7b5038d7SDag-Erling Smørgrav uint16_t rdl_pos = 0; 164*7b5038d7SDag-Erling Smørgrav 165*7b5038d7SDag-Erling Smørgrav if (ldns_rr_owner(rr)) { 166*7b5038d7SDag-Erling Smørgrav (void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr)); 167*7b5038d7SDag-Erling Smørgrav } 168*7b5038d7SDag-Erling Smørgrav 169*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 4)) { 170*7b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr)); 171*7b5038d7SDag-Erling Smørgrav (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr)); 172*7b5038d7SDag-Erling Smørgrav } 173*7b5038d7SDag-Erling Smørgrav 174*7b5038d7SDag-Erling Smørgrav if (section != LDNS_SECTION_QUESTION) { 175*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 6)) { 176*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr)); 177*7b5038d7SDag-Erling Smørgrav /* remember pos for later */ 178*7b5038d7SDag-Erling Smørgrav rdl_pos = ldns_buffer_position(buffer); 179*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, 0); 180*7b5038d7SDag-Erling Smørgrav } 181*7b5038d7SDag-Erling Smørgrav 182*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 183*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire( 184*7b5038d7SDag-Erling Smørgrav buffer, ldns_rr_rdf(rr, i)); 185*7b5038d7SDag-Erling Smørgrav } 186*7b5038d7SDag-Erling Smørgrav 187*7b5038d7SDag-Erling Smørgrav if (rdl_pos != 0) { 188*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16_at(buffer, rdl_pos, 189*7b5038d7SDag-Erling Smørgrav ldns_buffer_position(buffer) 190*7b5038d7SDag-Erling Smørgrav - rdl_pos - 2); 191*7b5038d7SDag-Erling Smørgrav } 192*7b5038d7SDag-Erling Smørgrav } 193*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 194*7b5038d7SDag-Erling Smørgrav } 195*7b5038d7SDag-Erling Smørgrav 196*7b5038d7SDag-Erling Smørgrav ldns_status 197*7b5038d7SDag-Erling Smørgrav ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) 198*7b5038d7SDag-Erling Smørgrav { 199*7b5038d7SDag-Erling Smørgrav uint16_t i; 200*7b5038d7SDag-Erling Smørgrav 201*7b5038d7SDag-Erling Smørgrav /* it must be a sig RR */ 202*7b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) { 203*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 204*7b5038d7SDag-Erling Smørgrav } 205*7b5038d7SDag-Erling Smørgrav 206*7b5038d7SDag-Erling Smørgrav /* Convert all the rdfs, except the actual signature data 207*7b5038d7SDag-Erling Smørgrav * rdf number 8 - the last, hence: -1 */ 208*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) { 209*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i)); 210*7b5038d7SDag-Erling Smørgrav } 211*7b5038d7SDag-Erling Smørgrav 212*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 213*7b5038d7SDag-Erling Smørgrav } 214*7b5038d7SDag-Erling Smørgrav 215*7b5038d7SDag-Erling Smørgrav ldns_status 216*7b5038d7SDag-Erling Smørgrav ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr) 217*7b5038d7SDag-Erling Smørgrav { 218*7b5038d7SDag-Erling Smørgrav uint16_t i; 219*7b5038d7SDag-Erling Smørgrav /* convert all the rdf's */ 220*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_rd_count(rr); i++) { 221*7b5038d7SDag-Erling Smørgrav (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i)); 222*7b5038d7SDag-Erling Smørgrav } 223*7b5038d7SDag-Erling Smørgrav 224*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 225*7b5038d7SDag-Erling Smørgrav } 226*7b5038d7SDag-Erling Smørgrav 227*7b5038d7SDag-Erling Smørgrav /* 228*7b5038d7SDag-Erling Smørgrav * Copies the packet header data to the buffer in wire format 229*7b5038d7SDag-Erling Smørgrav */ 230*7b5038d7SDag-Erling Smørgrav static ldns_status 231*7b5038d7SDag-Erling Smørgrav ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) 232*7b5038d7SDag-Erling Smørgrav { 233*7b5038d7SDag-Erling Smørgrav uint8_t flags; 234*7b5038d7SDag-Erling Smørgrav uint16_t arcount; 235*7b5038d7SDag-Erling Smørgrav 236*7b5038d7SDag-Erling Smørgrav if (ldns_buffer_reserve(buffer, 12)) { 237*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_id(packet)); 238*7b5038d7SDag-Erling Smørgrav 239*7b5038d7SDag-Erling Smørgrav flags = ldns_pkt_qr(packet) << 7 240*7b5038d7SDag-Erling Smørgrav | ldns_pkt_get_opcode(packet) << 3 241*7b5038d7SDag-Erling Smørgrav | ldns_pkt_aa(packet) << 2 242*7b5038d7SDag-Erling Smørgrav | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet); 243*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, flags); 244*7b5038d7SDag-Erling Smørgrav 245*7b5038d7SDag-Erling Smørgrav flags = ldns_pkt_ra(packet) << 7 246*7b5038d7SDag-Erling Smørgrav /*| ldns_pkt_z(packet) << 6*/ 247*7b5038d7SDag-Erling Smørgrav | ldns_pkt_ad(packet) << 5 248*7b5038d7SDag-Erling Smørgrav | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet); 249*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u8(buffer, flags); 250*7b5038d7SDag-Erling Smørgrav 251*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet)); 252*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet)); 253*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet)); 254*7b5038d7SDag-Erling Smørgrav /* add EDNS0 and TSIG to additional if they are there */ 255*7b5038d7SDag-Erling Smørgrav arcount = ldns_pkt_arcount(packet); 256*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_tsig(packet)) { 257*7b5038d7SDag-Erling Smørgrav arcount++; 258*7b5038d7SDag-Erling Smørgrav } 259*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns(packet)) { 260*7b5038d7SDag-Erling Smørgrav arcount++; 261*7b5038d7SDag-Erling Smørgrav } 262*7b5038d7SDag-Erling Smørgrav ldns_buffer_write_u16(buffer, arcount); 263*7b5038d7SDag-Erling Smørgrav } 264*7b5038d7SDag-Erling Smørgrav 265*7b5038d7SDag-Erling Smørgrav return ldns_buffer_status(buffer); 266*7b5038d7SDag-Erling Smørgrav } 267*7b5038d7SDag-Erling Smørgrav 268*7b5038d7SDag-Erling Smørgrav ldns_status 269*7b5038d7SDag-Erling Smørgrav ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet) 270*7b5038d7SDag-Erling Smørgrav { 271*7b5038d7SDag-Erling Smørgrav ldns_rr_list *rr_list; 272*7b5038d7SDag-Erling Smørgrav uint16_t i; 273*7b5038d7SDag-Erling Smørgrav 274*7b5038d7SDag-Erling Smørgrav /* edns tmp vars */ 275*7b5038d7SDag-Erling Smørgrav ldns_rr *edns_rr; 276*7b5038d7SDag-Erling Smørgrav uint8_t edata[4]; 277*7b5038d7SDag-Erling Smørgrav 278*7b5038d7SDag-Erling Smørgrav (void) ldns_hdr2buffer_wire(buffer, packet); 279*7b5038d7SDag-Erling Smørgrav 280*7b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_question(packet); 281*7b5038d7SDag-Erling Smørgrav if (rr_list) { 282*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 283*7b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 284*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION); 285*7b5038d7SDag-Erling Smørgrav } 286*7b5038d7SDag-Erling Smørgrav } 287*7b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_answer(packet); 288*7b5038d7SDag-Erling Smørgrav if (rr_list) { 289*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 290*7b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 291*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER); 292*7b5038d7SDag-Erling Smørgrav } 293*7b5038d7SDag-Erling Smørgrav } 294*7b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_authority(packet); 295*7b5038d7SDag-Erling Smørgrav if (rr_list) { 296*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 297*7b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 298*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY); 299*7b5038d7SDag-Erling Smørgrav } 300*7b5038d7SDag-Erling Smørgrav } 301*7b5038d7SDag-Erling Smørgrav rr_list = ldns_pkt_additional(packet); 302*7b5038d7SDag-Erling Smørgrav if (rr_list) { 303*7b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) { 304*7b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 305*7b5038d7SDag-Erling Smørgrav ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL); 306*7b5038d7SDag-Erling Smørgrav } 307*7b5038d7SDag-Erling Smørgrav } 308*7b5038d7SDag-Erling Smørgrav 309*7b5038d7SDag-Erling Smørgrav /* add EDNS to additional if it is needed */ 310*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns(packet)) { 311*7b5038d7SDag-Erling Smørgrav edns_rr = ldns_rr_new(); 312*7b5038d7SDag-Erling Smørgrav if(!edns_rr) return LDNS_STATUS_MEM_ERR; 313*7b5038d7SDag-Erling Smørgrav ldns_rr_set_owner(edns_rr, 314*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, ".")); 315*7b5038d7SDag-Erling Smørgrav ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT); 316*7b5038d7SDag-Erling Smørgrav ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet)); 317*7b5038d7SDag-Erling Smørgrav edata[0] = ldns_pkt_edns_extended_rcode(packet); 318*7b5038d7SDag-Erling Smørgrav edata[1] = ldns_pkt_edns_version(packet); 319*7b5038d7SDag-Erling Smørgrav ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet)); 320*7b5038d7SDag-Erling Smørgrav ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata)); 321*7b5038d7SDag-Erling Smørgrav /* don't forget to add the edns rdata (if any) */ 322*7b5038d7SDag-Erling Smørgrav if (packet->_edns_data) 323*7b5038d7SDag-Erling Smørgrav ldns_rr_push_rdf (edns_rr, packet->_edns_data); 324*7b5038d7SDag-Erling Smørgrav (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL); 325*7b5038d7SDag-Erling Smørgrav /* take the edns rdata back out of the rr before we free rr */ 326*7b5038d7SDag-Erling Smørgrav if (packet->_edns_data) 327*7b5038d7SDag-Erling Smørgrav (void)ldns_rr_pop_rdf (edns_rr); 328*7b5038d7SDag-Erling Smørgrav ldns_rr_free(edns_rr); 329*7b5038d7SDag-Erling Smørgrav } 330*7b5038d7SDag-Erling Smørgrav 331*7b5038d7SDag-Erling Smørgrav /* add TSIG to additional if it is there */ 332*7b5038d7SDag-Erling Smørgrav if (ldns_pkt_tsig(packet)) { 333*7b5038d7SDag-Erling Smørgrav (void) ldns_rr2buffer_wire(buffer, 334*7b5038d7SDag-Erling Smørgrav ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL); 335*7b5038d7SDag-Erling Smørgrav } 336*7b5038d7SDag-Erling Smørgrav 337*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 338*7b5038d7SDag-Erling Smørgrav } 339*7b5038d7SDag-Erling Smørgrav 340*7b5038d7SDag-Erling Smørgrav ldns_status 341*7b5038d7SDag-Erling Smørgrav ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size) 342*7b5038d7SDag-Erling Smørgrav { 343*7b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 344*7b5038d7SDag-Erling Smørgrav uint8_t *result = NULL; 345*7b5038d7SDag-Erling Smørgrav ldns_status status; 346*7b5038d7SDag-Erling Smørgrav *result_size = 0; 347*7b5038d7SDag-Erling Smørgrav *dest = NULL; 348*7b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 349*7b5038d7SDag-Erling Smørgrav 350*7b5038d7SDag-Erling Smørgrav status = ldns_rdf2buffer_wire(buffer, rdf); 351*7b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 352*7b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 353*7b5038d7SDag-Erling Smørgrav result = (uint8_t *) ldns_buffer_export(buffer); 354*7b5038d7SDag-Erling Smørgrav } else { 355*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 356*7b5038d7SDag-Erling Smørgrav return status; 357*7b5038d7SDag-Erling Smørgrav } 358*7b5038d7SDag-Erling Smørgrav 359*7b5038d7SDag-Erling Smørgrav if (result) { 360*7b5038d7SDag-Erling Smørgrav *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer)); 361*7b5038d7SDag-Erling Smørgrav if(!*dest) { 362*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 363*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 364*7b5038d7SDag-Erling Smørgrav } 365*7b5038d7SDag-Erling Smørgrav memcpy(*dest, result, ldns_buffer_position(buffer)); 366*7b5038d7SDag-Erling Smørgrav } 367*7b5038d7SDag-Erling Smørgrav 368*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 369*7b5038d7SDag-Erling Smørgrav return status; 370*7b5038d7SDag-Erling Smørgrav } 371*7b5038d7SDag-Erling Smørgrav 372*7b5038d7SDag-Erling Smørgrav ldns_status 373*7b5038d7SDag-Erling Smørgrav ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size) 374*7b5038d7SDag-Erling Smørgrav { 375*7b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 376*7b5038d7SDag-Erling Smørgrav uint8_t *result = NULL; 377*7b5038d7SDag-Erling Smørgrav ldns_status status; 378*7b5038d7SDag-Erling Smørgrav *result_size = 0; 379*7b5038d7SDag-Erling Smørgrav *dest = NULL; 380*7b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 381*7b5038d7SDag-Erling Smørgrav 382*7b5038d7SDag-Erling Smørgrav status = ldns_rr2buffer_wire(buffer, rr, section); 383*7b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 384*7b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 385*7b5038d7SDag-Erling Smørgrav result = (uint8_t *) ldns_buffer_export(buffer); 386*7b5038d7SDag-Erling Smørgrav } else { 387*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 388*7b5038d7SDag-Erling Smørgrav return status; 389*7b5038d7SDag-Erling Smørgrav } 390*7b5038d7SDag-Erling Smørgrav 391*7b5038d7SDag-Erling Smørgrav if (result) { 392*7b5038d7SDag-Erling Smørgrav *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer)); 393*7b5038d7SDag-Erling Smørgrav if(!*dest) { 394*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 395*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 396*7b5038d7SDag-Erling Smørgrav } 397*7b5038d7SDag-Erling Smørgrav memcpy(*dest, result, ldns_buffer_position(buffer)); 398*7b5038d7SDag-Erling Smørgrav } 399*7b5038d7SDag-Erling Smørgrav 400*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 401*7b5038d7SDag-Erling Smørgrav return status; 402*7b5038d7SDag-Erling Smørgrav } 403*7b5038d7SDag-Erling Smørgrav 404*7b5038d7SDag-Erling Smørgrav ldns_status 405*7b5038d7SDag-Erling Smørgrav ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size) 406*7b5038d7SDag-Erling Smørgrav { 407*7b5038d7SDag-Erling Smørgrav ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); 408*7b5038d7SDag-Erling Smørgrav uint8_t *result = NULL; 409*7b5038d7SDag-Erling Smørgrav ldns_status status; 410*7b5038d7SDag-Erling Smørgrav *result_size = 0; 411*7b5038d7SDag-Erling Smørgrav *dest = NULL; 412*7b5038d7SDag-Erling Smørgrav if(!buffer) return LDNS_STATUS_MEM_ERR; 413*7b5038d7SDag-Erling Smørgrav 414*7b5038d7SDag-Erling Smørgrav status = ldns_pkt2buffer_wire(buffer, packet); 415*7b5038d7SDag-Erling Smørgrav if (status == LDNS_STATUS_OK) { 416*7b5038d7SDag-Erling Smørgrav *result_size = ldns_buffer_position(buffer); 417*7b5038d7SDag-Erling Smørgrav result = (uint8_t *) ldns_buffer_export(buffer); 418*7b5038d7SDag-Erling Smørgrav } else { 419*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 420*7b5038d7SDag-Erling Smørgrav return status; 421*7b5038d7SDag-Erling Smørgrav } 422*7b5038d7SDag-Erling Smørgrav 423*7b5038d7SDag-Erling Smørgrav if (result) { 424*7b5038d7SDag-Erling Smørgrav *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer)); 425*7b5038d7SDag-Erling Smørgrav if(!*dest) { 426*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 427*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 428*7b5038d7SDag-Erling Smørgrav } 429*7b5038d7SDag-Erling Smørgrav memcpy(*dest, result, ldns_buffer_position(buffer)); 430*7b5038d7SDag-Erling Smørgrav } 431*7b5038d7SDag-Erling Smørgrav 432*7b5038d7SDag-Erling Smørgrav ldns_buffer_free(buffer); 433*7b5038d7SDag-Erling Smørgrav return status; 434*7b5038d7SDag-Erling Smørgrav } 435