00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <ldns/config.h>
00016
00017 #include <ldns/ldns.h>
00018
00019
00020
00021
00022
00023
00024
00025
00026 ldns_status
00027 ldns_dname2buffer_wire(ldns_buffer *buffer, const ldns_rdf *name)
00028 {
00029 if (ldns_buffer_reserve(buffer, ldns_rdf_size(name))) {
00030 ldns_buffer_write(buffer, ldns_rdf_data(name), ldns_rdf_size(name));
00031 }
00032 return ldns_buffer_status(buffer);
00033 }
00034
00035 ldns_status
00036 ldns_rdf2buffer_wire(ldns_buffer *buffer, const ldns_rdf *rdf)
00037 {
00038 if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
00039 ldns_buffer_write(buffer, ldns_rdf_data(rdf), ldns_rdf_size(rdf));
00040 }
00041 return ldns_buffer_status(buffer);
00042 }
00043
00044 ldns_status
00045 ldns_rdf2buffer_wire_canonical(ldns_buffer *buffer, const ldns_rdf *rdf)
00046 {
00047 size_t i;
00048 uint8_t *rdf_data;
00049
00050 if (ldns_rdf_get_type(rdf) == LDNS_RDF_TYPE_DNAME) {
00051 if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
00052 rdf_data = ldns_rdf_data(rdf);
00053 for (i = 0; i < ldns_rdf_size(rdf); i++) {
00054 ldns_buffer_write_u8(buffer,
00055 (uint8_t) LDNS_DNAME_NORMALIZE((int)rdf_data[i]));
00056 }
00057 }
00058 } else {
00059
00060 if (ldns_buffer_reserve(buffer, ldns_rdf_size(rdf))) {
00061 ldns_buffer_write(buffer,
00062 ldns_rdf_data(rdf),
00063 ldns_rdf_size(rdf));
00064 }
00065 }
00066 return ldns_buffer_status(buffer);
00067 }
00068
00069
00070 ldns_status
00071 ldns_rr_list2buffer_wire(ldns_buffer *buffer,const ldns_rr_list *rr_list)
00072 {
00073 uint16_t rr_count;
00074 uint16_t i;
00075
00076 rr_count = ldns_rr_list_rr_count(rr_list);
00077 for(i = 0; i < rr_count; i++) {
00078 (void)ldns_rr2buffer_wire(buffer, ldns_rr_list_rr(rr_list, i),
00079 LDNS_SECTION_ANY);
00080 }
00081 return ldns_buffer_status(buffer);
00082 }
00083
00084 ldns_status
00085 ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
00086 const ldns_rr *rr,
00087 int section)
00088 {
00089 uint16_t i;
00090 uint16_t rdl_pos = 0;
00091 bool pre_rfc3597 = false;
00092 switch (ldns_rr_get_type(rr)) {
00093 case LDNS_RR_TYPE_NS:
00094 case LDNS_RR_TYPE_MD:
00095 case LDNS_RR_TYPE_MF:
00096 case LDNS_RR_TYPE_CNAME:
00097 case LDNS_RR_TYPE_SOA:
00098 case LDNS_RR_TYPE_MB:
00099 case LDNS_RR_TYPE_MG:
00100 case LDNS_RR_TYPE_MR:
00101 case LDNS_RR_TYPE_PTR:
00102 case LDNS_RR_TYPE_HINFO:
00103 case LDNS_RR_TYPE_MINFO:
00104 case LDNS_RR_TYPE_MX:
00105 case LDNS_RR_TYPE_RP:
00106 case LDNS_RR_TYPE_AFSDB:
00107 case LDNS_RR_TYPE_RT:
00108 case LDNS_RR_TYPE_SIG:
00109 case LDNS_RR_TYPE_PX:
00110 case LDNS_RR_TYPE_NXT:
00111 case LDNS_RR_TYPE_NAPTR:
00112 case LDNS_RR_TYPE_KX:
00113 case LDNS_RR_TYPE_SRV:
00114 case LDNS_RR_TYPE_DNAME:
00115 case LDNS_RR_TYPE_A6:
00116 case LDNS_RR_TYPE_RRSIG:
00117 pre_rfc3597 = true;
00118 break;
00119 default:
00120 break;
00121 }
00122
00123 if (ldns_rr_owner(rr)) {
00124 (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
00125 }
00126
00127 if (ldns_buffer_reserve(buffer, 4)) {
00128 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00129 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00130 }
00131
00132 if (section != LDNS_SECTION_QUESTION) {
00133 if (ldns_buffer_reserve(buffer, 6)) {
00134 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00135
00136 rdl_pos = ldns_buffer_position(buffer);
00137 ldns_buffer_write_u16(buffer, 0);
00138 }
00139
00140 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00141 if (pre_rfc3597) {
00142 (void) ldns_rdf2buffer_wire_canonical(
00143 buffer, ldns_rr_rdf(rr, i));
00144 } else {
00145 (void) ldns_rdf2buffer_wire(
00146 buffer, ldns_rr_rdf(rr, i));
00147 }
00148 }
00149
00150 if (rdl_pos != 0) {
00151 ldns_buffer_write_u16_at(buffer, rdl_pos,
00152 ldns_buffer_position(buffer)
00153 - rdl_pos - 2);
00154 }
00155 }
00156 return ldns_buffer_status(buffer);
00157 }
00158
00159 ldns_status
00160 ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
00161 {
00162 uint16_t i;
00163 uint16_t rdl_pos = 0;
00164
00165 if (ldns_rr_owner(rr)) {
00166 (void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr));
00167 }
00168
00169 if (ldns_buffer_reserve(buffer, 4)) {
00170 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00171 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00172 }
00173
00174 if (section != LDNS_SECTION_QUESTION) {
00175 if (ldns_buffer_reserve(buffer, 6)) {
00176 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00177
00178 rdl_pos = ldns_buffer_position(buffer);
00179 ldns_buffer_write_u16(buffer, 0);
00180 }
00181
00182 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00183 (void) ldns_rdf2buffer_wire(
00184 buffer, ldns_rr_rdf(rr, i));
00185 }
00186
00187 if (rdl_pos != 0) {
00188 ldns_buffer_write_u16_at(buffer, rdl_pos,
00189 ldns_buffer_position(buffer)
00190 - rdl_pos - 2);
00191 }
00192 }
00193 return ldns_buffer_status(buffer);
00194 }
00195
00196 ldns_status
00197 ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00198 {
00199 uint16_t i;
00200
00201
00202 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00203 return LDNS_STATUS_ERR;
00204 }
00205
00206
00207
00208 for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
00209 (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_rdf(rr, i));
00210 }
00211
00212 return ldns_buffer_status(buffer);
00213 }
00214
00215 ldns_status
00216 ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00217 {
00218 uint16_t i;
00219
00220 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00221 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00222 }
00223
00224 return ldns_buffer_status(buffer);
00225 }
00226
00227
00228
00229
00230 static ldns_status
00231 ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00232 {
00233 uint8_t flags;
00234 uint16_t arcount;
00235
00236 if (ldns_buffer_reserve(buffer, 12)) {
00237 ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
00238
00239 flags = ldns_pkt_qr(packet) << 7
00240 | ldns_pkt_get_opcode(packet) << 3
00241 | ldns_pkt_aa(packet) << 2
00242 | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
00243 ldns_buffer_write_u8(buffer, flags);
00244
00245 flags = ldns_pkt_ra(packet) << 7
00246
00247 | ldns_pkt_ad(packet) << 5
00248 | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet);
00249 ldns_buffer_write_u8(buffer, flags);
00250
00251 ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
00252 ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
00253 ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
00254
00255 arcount = ldns_pkt_arcount(packet);
00256 if (ldns_pkt_tsig(packet)) {
00257 arcount++;
00258 }
00259 if (ldns_pkt_edns(packet)) {
00260 arcount++;
00261 }
00262 ldns_buffer_write_u16(buffer, arcount);
00263 }
00264
00265 return ldns_buffer_status(buffer);
00266 }
00267
00268 ldns_status
00269 ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00270 {
00271 ldns_rr_list *rr_list;
00272 uint16_t i;
00273
00274
00275 ldns_rr *edns_rr;
00276 uint8_t edata[4];
00277
00278 (void) ldns_hdr2buffer_wire(buffer, packet);
00279
00280 rr_list = ldns_pkt_question(packet);
00281 if (rr_list) {
00282 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00283 (void) ldns_rr2buffer_wire(buffer,
00284 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
00285 }
00286 }
00287 rr_list = ldns_pkt_answer(packet);
00288 if (rr_list) {
00289 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00290 (void) ldns_rr2buffer_wire(buffer,
00291 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
00292 }
00293 }
00294 rr_list = ldns_pkt_authority(packet);
00295 if (rr_list) {
00296 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00297 (void) ldns_rr2buffer_wire(buffer,
00298 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
00299 }
00300 }
00301 rr_list = ldns_pkt_additional(packet);
00302 if (rr_list) {
00303 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00304 (void) ldns_rr2buffer_wire(buffer,
00305 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
00306 }
00307 }
00308
00309
00310 if (ldns_pkt_edns(packet)) {
00311 edns_rr = ldns_rr_new();
00312 if(!edns_rr) return LDNS_STATUS_MEM_ERR;
00313 ldns_rr_set_owner(edns_rr,
00314 ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
00315 ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
00316 ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
00317 edata[0] = ldns_pkt_edns_extended_rcode(packet);
00318 edata[1] = ldns_pkt_edns_version(packet);
00319 ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
00320 ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
00321
00322 if (packet->_edns_data)
00323 ldns_rr_push_rdf (edns_rr, packet->_edns_data);
00324 (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
00325
00326 if (packet->_edns_data)
00327 (void)ldns_rr_pop_rdf (edns_rr);
00328 ldns_rr_free(edns_rr);
00329 }
00330
00331
00332 if (ldns_pkt_tsig(packet)) {
00333 (void) ldns_rr2buffer_wire(buffer,
00334 ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
00335 }
00336
00337 return LDNS_STATUS_OK;
00338 }
00339
00340 ldns_status
00341 ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
00342 {
00343 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00344 ldns_status status;
00345 *result_size = 0;
00346 *dest = NULL;
00347 if(!buffer) return LDNS_STATUS_MEM_ERR;
00348
00349 status = ldns_rdf2buffer_wire(buffer, rdf);
00350 if (status == LDNS_STATUS_OK) {
00351 *result_size = ldns_buffer_position(buffer);
00352 *dest = (uint8_t *) ldns_buffer_export(buffer);
00353 }
00354 ldns_buffer_free(buffer);
00355 return status;
00356 }
00357
00358 ldns_status
00359 ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
00360 {
00361 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00362 ldns_status status;
00363 *result_size = 0;
00364 *dest = NULL;
00365 if(!buffer) return LDNS_STATUS_MEM_ERR;
00366
00367 status = ldns_rr2buffer_wire(buffer, rr, section);
00368 if (status == LDNS_STATUS_OK) {
00369 *result_size = ldns_buffer_position(buffer);
00370 *dest = (uint8_t *) ldns_buffer_export(buffer);
00371 }
00372 ldns_buffer_free(buffer);
00373 return status;
00374 }
00375
00376 ldns_status
00377 ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
00378 {
00379 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00380 ldns_status status;
00381 *result_size = 0;
00382 *dest = NULL;
00383 if(!buffer) return LDNS_STATUS_MEM_ERR;
00384
00385 status = ldns_pkt2buffer_wire(buffer, packet);
00386 if (status == LDNS_STATUS_OK) {
00387 *result_size = ldns_buffer_position(buffer);
00388 *dest = (uint8_t *) ldns_buffer_export(buffer);
00389 }
00390 ldns_buffer_free(buffer);
00391 return status;
00392 }