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
00085 ldns_status
00086 ldns_rr2buffer_wire_canonical(ldns_buffer *buffer,
00087 const ldns_rr *rr,
00088 int section)
00089 {
00090 uint16_t i;
00091 uint16_t rdl_pos = 0;
00092 bool pre_rfc3597 = false;
00093 switch (ldns_rr_get_type(rr)) {
00094 case LDNS_RR_TYPE_NS:
00095 case LDNS_RR_TYPE_MD:
00096 case LDNS_RR_TYPE_MF:
00097 case LDNS_RR_TYPE_CNAME:
00098 case LDNS_RR_TYPE_SOA:
00099 case LDNS_RR_TYPE_MB:
00100 case LDNS_RR_TYPE_MG:
00101 case LDNS_RR_TYPE_MR:
00102 case LDNS_RR_TYPE_PTR:
00103 case LDNS_RR_TYPE_HINFO:
00104 case LDNS_RR_TYPE_MINFO:
00105 case LDNS_RR_TYPE_MX:
00106 case LDNS_RR_TYPE_RP:
00107 case LDNS_RR_TYPE_AFSDB:
00108 case LDNS_RR_TYPE_RT:
00109 case LDNS_RR_TYPE_SIG:
00110 case LDNS_RR_TYPE_PX:
00111 case LDNS_RR_TYPE_NXT:
00112 case LDNS_RR_TYPE_NAPTR:
00113 case LDNS_RR_TYPE_KX:
00114 case LDNS_RR_TYPE_SRV:
00115 case LDNS_RR_TYPE_DNAME:
00116 case LDNS_RR_TYPE_A6:
00117 case LDNS_RR_TYPE_RRSIG:
00118 pre_rfc3597 = true;
00119 break;
00120 default:
00121 break;
00122 }
00123
00124 if (ldns_rr_owner(rr)) {
00125 (void) ldns_rdf2buffer_wire_canonical(buffer, ldns_rr_owner(rr));
00126 }
00127
00128 if (ldns_buffer_reserve(buffer, 4)) {
00129 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_type(rr));
00130 (void) ldns_buffer_write_u16(buffer, ldns_rr_get_class(rr));
00131 }
00132
00133 if (section != LDNS_SECTION_QUESTION) {
00134 if (ldns_buffer_reserve(buffer, 6)) {
00135 ldns_buffer_write_u32(buffer, ldns_rr_ttl(rr));
00136
00137 rdl_pos = ldns_buffer_position(buffer);
00138 ldns_buffer_write_u16(buffer, 0);
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 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 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00181 (void) ldns_rdf2buffer_wire(
00182 buffer, ldns_rr_rdf(rr, i));
00183 }
00184 if (rdl_pos != 0) {
00185 ldns_buffer_write_u16_at(buffer, rdl_pos,
00186 ldns_buffer_position(buffer)
00187 - rdl_pos - 2);
00188 }
00189 }
00190 return ldns_buffer_status(buffer);
00191 }
00192
00193 ldns_status
00194 ldns_rrsig2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00195 {
00196 uint16_t i;
00197
00198
00199 if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
00200 return LDNS_STATUS_ERR;
00201 }
00202
00203
00204
00205 for (i = 0; i < ldns_rr_rd_count(rr) - 1; i++) {
00206 (void) ldns_rdf2buffer_wire_canonical(buffer,
00207 ldns_rr_rdf(rr, i));
00208 }
00209
00210 return ldns_buffer_status(buffer);
00211 }
00212
00213 ldns_status
00214 ldns_rr_rdata2buffer_wire(ldns_buffer *buffer, const ldns_rr *rr)
00215 {
00216 uint16_t i;
00217
00218 for (i = 0; i < ldns_rr_rd_count(rr); i++) {
00219 (void) ldns_rdf2buffer_wire(buffer, ldns_rr_rdf(rr,i));
00220 }
00221 return ldns_buffer_status(buffer);
00222 }
00223
00224
00225
00226
00227 static ldns_status
00228 ldns_hdr2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00229 {
00230 uint8_t flags;
00231 uint16_t arcount;
00232
00233 if (ldns_buffer_reserve(buffer, 12)) {
00234 ldns_buffer_write_u16(buffer, ldns_pkt_id(packet));
00235
00236 flags = ldns_pkt_qr(packet) << 7
00237 | ldns_pkt_get_opcode(packet) << 3
00238 | ldns_pkt_aa(packet) << 2
00239 | ldns_pkt_tc(packet) << 1 | ldns_pkt_rd(packet);
00240 ldns_buffer_write_u8(buffer, flags);
00241
00242 flags = ldns_pkt_ra(packet) << 7
00243
00244 | ldns_pkt_ad(packet) << 5
00245 | ldns_pkt_cd(packet) << 4
00246 | ldns_pkt_get_rcode(packet);
00247 ldns_buffer_write_u8(buffer, flags);
00248
00249 ldns_buffer_write_u16(buffer, ldns_pkt_qdcount(packet));
00250 ldns_buffer_write_u16(buffer, ldns_pkt_ancount(packet));
00251 ldns_buffer_write_u16(buffer, ldns_pkt_nscount(packet));
00252
00253 arcount = ldns_pkt_arcount(packet);
00254 if (ldns_pkt_tsig(packet)) {
00255 arcount++;
00256 }
00257 if (ldns_pkt_edns(packet)) {
00258 arcount++;
00259 }
00260 ldns_buffer_write_u16(buffer, arcount);
00261 }
00262
00263 return ldns_buffer_status(buffer);
00264 }
00265
00266 ldns_status
00267 ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
00268 {
00269 ldns_rr_list *rr_list;
00270 uint16_t i;
00271
00272
00273 ldns_rr *edns_rr;
00274 uint8_t edata[4];
00275
00276 (void) ldns_hdr2buffer_wire(buffer, packet);
00277
00278 rr_list = ldns_pkt_question(packet);
00279 if (rr_list) {
00280 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00281 (void) ldns_rr2buffer_wire(buffer,
00282 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
00283 }
00284 }
00285 rr_list = ldns_pkt_answer(packet);
00286 if (rr_list) {
00287 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00288 (void) ldns_rr2buffer_wire(buffer,
00289 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
00290 }
00291 }
00292 rr_list = ldns_pkt_authority(packet);
00293 if (rr_list) {
00294 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00295 (void) ldns_rr2buffer_wire(buffer,
00296 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
00297 }
00298 }
00299 rr_list = ldns_pkt_additional(packet);
00300 if (rr_list) {
00301 for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
00302 (void) ldns_rr2buffer_wire(buffer,
00303 ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
00304 }
00305 }
00306
00307
00308 if (ldns_pkt_edns(packet)) {
00309 edns_rr = ldns_rr_new();
00310 if(!edns_rr) return LDNS_STATUS_MEM_ERR;
00311 ldns_rr_set_owner(edns_rr,
00312 ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
00313 ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
00314 ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
00315 edata[0] = ldns_pkt_edns_extended_rcode(packet);
00316 edata[1] = ldns_pkt_edns_version(packet);
00317 ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
00318 ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
00319
00320 if (packet->_edns_data)
00321 ldns_rr_push_rdf (edns_rr, packet->_edns_data);
00322 (void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
00323
00324 if (packet->_edns_data)
00325 (void)ldns_rr_pop_rdf (edns_rr);
00326 ldns_rr_free(edns_rr);
00327 }
00328
00329
00330 if (ldns_pkt_tsig(packet)) {
00331 (void) ldns_rr2buffer_wire(buffer,
00332 ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
00333 }
00334
00335 return LDNS_STATUS_OK;
00336 }
00337
00338 ldns_status
00339 ldns_rdf2wire(uint8_t **dest, const ldns_rdf *rdf, size_t *result_size)
00340 {
00341 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00342 ldns_status status;
00343 *result_size = 0;
00344 *dest = NULL;
00345 if(!buffer) return LDNS_STATUS_MEM_ERR;
00346
00347 status = ldns_rdf2buffer_wire(buffer, rdf);
00348 if (status == LDNS_STATUS_OK) {
00349 *result_size = ldns_buffer_position(buffer);
00350 *dest = (uint8_t *) ldns_buffer_export(buffer);
00351 }
00352 ldns_buffer_free(buffer);
00353 return status;
00354 }
00355
00356 ldns_status
00357 ldns_rr2wire(uint8_t **dest, const ldns_rr *rr, int section, size_t *result_size)
00358 {
00359 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00360 ldns_status status;
00361 *result_size = 0;
00362 *dest = NULL;
00363 if(!buffer) return LDNS_STATUS_MEM_ERR;
00364
00365 status = ldns_rr2buffer_wire(buffer, rr, section);
00366 if (status == LDNS_STATUS_OK) {
00367 *result_size = ldns_buffer_position(buffer);
00368 *dest = (uint8_t *) ldns_buffer_export(buffer);
00369 }
00370 ldns_buffer_free(buffer);
00371 return status;
00372 }
00373
00374 ldns_status
00375 ldns_pkt2wire(uint8_t **dest, const ldns_pkt *packet, size_t *result_size)
00376 {
00377 ldns_buffer *buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00378 ldns_status status;
00379 *result_size = 0;
00380 *dest = NULL;
00381 if(!buffer) return LDNS_STATUS_MEM_ERR;
00382
00383 status = ldns_pkt2buffer_wire(buffer, packet);
00384 if (status == LDNS_STATUS_OK) {
00385 *result_size = ldns_buffer_position(buffer);
00386 *dest = (uint8_t *) ldns_buffer_export(buffer);
00387 }
00388 ldns_buffer_free(buffer);
00389 return status;
00390 }