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 pre_rfc3597 = true;
00117 break;
00118 default:
00119 break;
00120 }
00121
00122 if (ldns_rr_owner(rr)) {
00123 (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
00124 }
00125
00126 if (ldns_buffer_reserve(buffer, 4)) {
00127 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00128 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00129 }
00130
00131 if (section != LDNS_SECTION_QUESTION) {
00132 if (ldns_buffer_reserve(buffer, 6)) {
00133 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00134
00135 rdl_pos = ldns_buffer_position(buffer);
00136 ldns_buffer_write_u16(buffer, 0);
00137 }
00138
00139 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00140 if (pre_rfc3597) {
00141 (void) ldns_rdf2buffer_wire_canonical(
00142 buffer, ldns_rr_rdf(rr, i));
00143 } else {
00144 (void) ldns_rdf2buffer_wire(
00145 buffer, ldns_rr_rdf(rr, i));
00146 }
00147 }
00148
00149 if (rdl_pos != 0) {
00150 ldns_buffer_write_u16_at(buffer, rdl_pos,
00151 ldns_buffer_position(buffer)
00152 - rdl_pos - 2);
00153 }
00154 }
00155 return ldns_buffer_status(buffer);
00156 }
00157
00158 ldns_status
00159 ldns_rr2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr, int section)
00160 {
00161 uint16_t i;
00162 uint16_t rdl_pos = 0;
00163
00164 if (ldns_rr_owner(rr)) {
00165 (void) ldns_dname2buffer_wire(buffer, ldns_rr_owner(rr));
00166 }
00167
00168 if (ldns_buffer_reserve(buffer, 4)) {
00169 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00170 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00171 }
00172
00173 if (section != LDNS_SECTION_QUESTION) {
00174 if (ldns_buffer_reserve(buffer, 6)) {
00175 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00176
00177 rdl_pos = ldns_buffer_position(buffer);
00178 ldns_buffer_write_u16(buffer, 0);
00179 }
00180
00181 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00182 (void) ldns_rdf2buffer_wire(
00183 buffer, ldns_rr_rdf(rr, i));
00184 }
00185
00186 if (rdl_pos != 0) {
00187 ldns_buffer_write_u16_at(buffer, rdl_pos,
00188 ldns_buffer_position(buffer)
00189 - rdl_pos - 2);
00190 }
00191 }
00192 return ldns_buffer_status(buffer);
00193 }
00194
00195 ldns_status
00196 ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00197 {
00198 uint16_t i;
00199
00200
00201 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00202 return LDNS_STATUS_ERR;
00203 }
00204
00205
00206
00207 for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
00208 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00209 }
00210
00211 return ldns_buffer_status(buffer);
00212 }
00213
00214 ldns_status
00215 ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00216 {
00217 uint16_t i;
00218
00219 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00220 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr, i));
00221 }
00222
00223 return ldns_buffer_status(buffer);
00224 }
00225
00226
00227
00228
00229 static ldns_status
00230 ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00231 {
00232 uint8_t flags;
00233 uint16_t arcount;
00234
00235 if (ldns_buffer_reserve(buffer, 12)) {
00236 ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
00237
00238 flags = ldns_pkt_qr(packet) << 7
00239 | ldns_pkt_get_opcode(packet) << 3
00240 | ldns_pkt_aa(packet) << 2
00241 | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
00242 ldns_buffer_write_u8(buffer, flags);
00243
00244 flags = ldns_pkt_ra(packet) << 7
00245
00246 | ldns_pkt_ad(packet) << 5
00247 | ldns_pkt_cd(packet) << 4 | ldns_pkt_get_rcode(packet);
00248 ldns_buffer_write_u8(buffer, flags);
00249
00250 ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
00251 ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
00252 ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
00253
00254 arcount = ldns_pkt_arcount(packet);
00255 if (ldns_pkt_tsig(packet)) {
00256 arcount++;
00257 }
00258 if (ldns_pkt_edns(packet)) {
00259 arcount++;
00260 }
00261 ldns_buffer_write_u16(buffer, arcount);
00262 }
00263
00264 return ldns_buffer_status(buffer);
00265 }
00266
00267 ldns_status
00268 ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00269 {
00270 ldns_rr_list *rr_list;
00271 uint16_t i;
00272
00273
00274 ldns_rr *edns_rr;
00275 uint8_t edata[4];
00276
00277 (void) ldns_hdr2buffer_wire(buffer, packet);
00278
00279 rr_list = ldns_pkt_question(packet);
00280 if (rr_list) {
00281 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00282 (void) ldns_rr2buffer_wire(buffer,
00283 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
00284 }
00285 }
00286 rr_list = ldns_pkt_answer(packet);
00287 if (rr_list) {
00288 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00289 (void) ldns_rr2buffer_wire(buffer,
00290 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
00291 }
00292 }
00293 rr_list = ldns_pkt_authority(packet);
00294 if (rr_list) {
00295 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00296 (void) ldns_rr2buffer_wire(buffer,
00297 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
00298 }
00299 }
00300 rr_list = ldns_pkt_additional(packet);
00301 if (rr_list) {
00302 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00303 (void) ldns_rr2buffer_wire(buffer,
00304 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
00305 }
00306 }
00307
00308
00309 if (ldns_pkt_edns(packet)) {
00310 edns_rr = ldns_rr_new();
00311 if(!edns_rr) return LDNS_STATUS_MEM_ERR;
00312 ldns_rr_set_owner(edns_rr,
00313 ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
00314 ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
00315 ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
00316 edata[0] = ldns_pkt_edns_extended_rcode(packet);
00317 edata[1] = ldns_pkt_edns_version(packet);
00318 ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
00319 ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
00320
00321 if (packet->_edns_data)
00322 ldns_rr_push_rdf (edns_rr, packet->_edns_data);
00323 (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
00324
00325 if (packet->_edns_data)
00326 (void)ldns_rr_pop_rdf (edns_rr);
00327 ldns_rr_free(edns_rr);
00328 }
00329
00330
00331 if (ldns_pkt_tsig(packet)) {
00332 (void) ldns_rr2buffer_wire(buffer,
00333 ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
00334 }
00335
00336 return LDNS_STATUS_OK;
00337 }
00338
00339 ldns_status
00340 ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
00341 {
00342 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00343 uint8_t *result = NULL;
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 result = (uint8_t *) ldns_buffer_export(buffer);
00353 } else {
00354 ldns_buffer_free(buffer);
00355 return status;
00356 }
00357
00358 if (result) {
00359 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00360 if(!*dest) {
00361 ldns_buffer_free(buffer);
00362 return LDNS_STATUS_MEM_ERR;
00363 }
00364 memcpy(*dest, result, ldns_buffer_position(buffer));
00365 }
00366
00367 ldns_buffer_free(buffer);
00368 return status;
00369 }
00370
00371 ldns_status
00372 ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
00373 {
00374 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00375 uint8_t *result = NULL;
00376 ldns_status status;
00377 *result_size = 0;
00378 *dest = NULL;
00379 if(!buffer) return LDNS_STATUS_MEM_ERR;
00380
00381 status = ldns_rr2buffer_wire(buffer, rr, section);
00382 if (status == LDNS_STATUS_OK) {
00383 *result_size = ldns_buffer_position(buffer);
00384 result = (uint8_t *) ldns_buffer_export(buffer);
00385 } else {
00386 ldns_buffer_free(buffer);
00387 return status;
00388 }
00389
00390 if (result) {
00391 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00392 if(!*dest) {
00393 ldns_buffer_free(buffer);
00394 return LDNS_STATUS_MEM_ERR;
00395 }
00396 memcpy(*dest, result, ldns_buffer_position(buffer));
00397 }
00398
00399 ldns_buffer_free(buffer);
00400 return status;
00401 }
00402
00403 ldns_status
00404 ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
00405 {
00406 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00407 uint8_t *result = NULL;
00408 ldns_status status;
00409 *result_size = 0;
00410 *dest = NULL;
00411 if(!buffer) return LDNS_STATUS_MEM_ERR;
00412
00413 status = ldns_pkt2buffer_wire(buffer, packet);
00414 if (status == LDNS_STATUS_OK) {
00415 *result_size = ldns_buffer_position(buffer);
00416 result = (uint8_t *) ldns_buffer_export(buffer);
00417 } else {
00418 ldns_buffer_free(buffer);
00419 return status;
00420 }
00421
00422 if (result) {
00423 *dest = LDNS_XMALLOC(uint8_t, ldns_buffer_position(buffer));
00424 if(!*dest) {
00425 ldns_buffer_free(buffer);
00426 return LDNS_STATUS_MEM_ERR;
00427 }
00428 memcpy(*dest, result, ldns_buffer_position(buffer));
00429 }
00430
00431 ldns_buffer_free(buffer);
00432 return status;
00433 }