00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <ldns/config.h>
00018
00019 #include <ldns/ldns.h>
00020
00021
00022 #include <strings.h>
00023 #include <limits.h>
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 ldns_status
00056 ldns_wire2dname(ldns_rdf **dname, const uint8_t *wire, size_t max, size_t *pos)
00057 {
00058 uint8_t label_size;
00059 uint16_t pointer_target;
00060 uint8_t pointer_target_buf[2];
00061 size_t dname_pos = 0;
00062 size_t uncompressed_length = 0;
00063 size_t compression_pos = 0;
00064 uint8_t tmp_dname[LDNS_MAX_DOMAINLEN];
00065 unsigned int pointer_count = 0;
00066
00067 if (*pos >= max) {
00068 return LDNS_STATUS_PACKET_OVERFLOW;
00069 }
00070
00071 label_size = wire[*pos];
00072 while (label_size > 0) {
00073
00074 while (label_size >= 192) {
00075 if (compression_pos == 0) {
00076 compression_pos = *pos + 2;
00077 }
00078
00079 pointer_count++;
00080
00081
00082 if (*pos + 2 > max) {
00083 return LDNS_STATUS_PACKET_OVERFLOW;
00084 }
00085 pointer_target_buf[0] = wire[*pos] & 63;
00086 pointer_target_buf[1] = wire[*pos + 1];
00087 pointer_target = ldns_read_uint16(pointer_target_buf);
00088
00089 if (pointer_target == 0) {
00090 return LDNS_STATUS_INVALID_POINTER;
00091 } else if (pointer_target >= max) {
00092 return LDNS_STATUS_INVALID_POINTER;
00093 } else if (pointer_count > LDNS_MAX_POINTERS) {
00094 return LDNS_STATUS_INVALID_POINTER;
00095 }
00096 *pos = pointer_target;
00097 label_size = wire[*pos];
00098 }
00099 if(label_size == 0)
00100 break;
00101 if (label_size > LDNS_MAX_LABELLEN) {
00102 return LDNS_STATUS_LABEL_OVERFLOW;
00103 }
00104 if (*pos + 1 + label_size > max) {
00105 return LDNS_STATUS_LABEL_OVERFLOW;
00106 }
00107
00108
00109 if (dname_pos + 1 > LDNS_MAX_DOMAINLEN) {
00110 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00111 }
00112 tmp_dname[dname_pos] = label_size;
00113 if (label_size > 0) {
00114 dname_pos++;
00115 }
00116 *pos = *pos + 1;
00117 if (dname_pos + label_size > LDNS_MAX_DOMAINLEN) {
00118 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00119 }
00120 memcpy(&tmp_dname[dname_pos], &wire[*pos], label_size);
00121 uncompressed_length += label_size + 1;
00122 dname_pos += label_size;
00123 *pos = *pos + label_size;
00124
00125 if (*pos < max) {
00126 label_size = wire[*pos];
00127 }
00128 }
00129
00130 if (compression_pos > 0) {
00131 *pos = compression_pos;
00132 } else {
00133 *pos = *pos + 1;
00134 }
00135
00136 if (dname_pos >= LDNS_MAX_DOMAINLEN) {
00137 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00138 }
00139
00140 tmp_dname[dname_pos] = 0;
00141 dname_pos++;
00142
00143 *dname = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
00144 (uint16_t) dname_pos, tmp_dname);
00145 if (!*dname) {
00146 return LDNS_STATUS_MEM_ERR;
00147 }
00148 return LDNS_STATUS_OK;
00149 }
00150
00151
00152 #define LDNS_STATUS_CHECK_RETURN(st) {if (st != LDNS_STATUS_OK) { return st; }}
00153 #define LDNS_STATUS_CHECK_GOTO(st, label) {if (st != LDNS_STATUS_OK) { goto label; }}
00154
00155 ldns_status
00156 ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
00157 {
00158 size_t end;
00159 size_t cur_rdf_length;
00160 uint8_t rdf_index;
00161 uint8_t *data;
00162 uint16_t rd_length;
00163 ldns_rdf *cur_rdf = NULL;
00164 ldns_rdf_type cur_rdf_type;
00165 const ldns_rr_descriptor *descriptor = ldns_rr_descript(ldns_rr_get_type(rr));
00166 ldns_status status;
00167
00168 if (*pos + 2 > max) {
00169 return LDNS_STATUS_PACKET_OVERFLOW;
00170 }
00171
00172 rd_length = ldns_read_uint16(&wire[*pos]);
00173 *pos = *pos + 2;
00174
00175 if (*pos + rd_length > max) {
00176 return LDNS_STATUS_PACKET_OVERFLOW;
00177 }
00178
00179 end = *pos + (size_t) rd_length;
00180
00181 for (rdf_index = 0;
00182 rdf_index < ldns_rr_descriptor_maximum(descriptor); rdf_index++) {
00183 if (*pos >= end) {
00184 break;
00185 }
00186 cur_rdf_length = 0;
00187
00188 cur_rdf_type = ldns_rr_descriptor_field_type(descriptor, rdf_index);
00189
00190
00191 switch (cur_rdf_type) {
00192 case LDNS_RDF_TYPE_DNAME:
00193 status = ldns_wire2dname(&cur_rdf, wire, max, pos);
00194 LDNS_STATUS_CHECK_RETURN(status);
00195 break;
00196 case LDNS_RDF_TYPE_CLASS:
00197 case LDNS_RDF_TYPE_ALG:
00198 case LDNS_RDF_TYPE_INT8:
00199 cur_rdf_length = LDNS_RDF_SIZE_BYTE;
00200 break;
00201 case LDNS_RDF_TYPE_TYPE:
00202 case LDNS_RDF_TYPE_INT16:
00203 case LDNS_RDF_TYPE_CERT_ALG:
00204 cur_rdf_length = LDNS_RDF_SIZE_WORD;
00205 break;
00206 case LDNS_RDF_TYPE_TIME:
00207 case LDNS_RDF_TYPE_INT32:
00208 case LDNS_RDF_TYPE_A:
00209 case LDNS_RDF_TYPE_PERIOD:
00210 cur_rdf_length = LDNS_RDF_SIZE_DOUBLEWORD;
00211 break;
00212 case LDNS_RDF_TYPE_TSIGTIME:
00213 cur_rdf_length = LDNS_RDF_SIZE_6BYTES;
00214 break;
00215 case LDNS_RDF_TYPE_AAAA:
00216 cur_rdf_length = LDNS_RDF_SIZE_16BYTES;
00217 break;
00218 case LDNS_RDF_TYPE_STR:
00219 case LDNS_RDF_TYPE_NSEC3_SALT:
00220
00221
00222
00223
00224 cur_rdf_length = ((size_t) wire[*pos]) + 1;
00225 break;
00226 case LDNS_RDF_TYPE_INT16_DATA:
00227 cur_rdf_length = (size_t) ldns_read_uint16(&wire[*pos]) + 2;
00228 break;
00229 case LDNS_RDF_TYPE_B32_EXT:
00230 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
00231
00232 cur_rdf_length = ((size_t) wire[*pos]) + 1;
00233 break;
00234 case LDNS_RDF_TYPE_APL:
00235 case LDNS_RDF_TYPE_B64:
00236 case LDNS_RDF_TYPE_HEX:
00237 case LDNS_RDF_TYPE_NSEC:
00238 case LDNS_RDF_TYPE_UNKNOWN:
00239 case LDNS_RDF_TYPE_SERVICE:
00240 case LDNS_RDF_TYPE_LOC:
00241 case LDNS_RDF_TYPE_WKS:
00242 case LDNS_RDF_TYPE_NSAP:
00243 case LDNS_RDF_TYPE_ATMA:
00244 case LDNS_RDF_TYPE_IPSECKEY:
00245 case LDNS_RDF_TYPE_TSIG:
00246 case LDNS_RDF_TYPE_NONE:
00247
00248
00249
00250 cur_rdf_length = end - *pos;
00251 break;
00252 }
00253
00254
00255 if (cur_rdf_length > 0) {
00256 if (cur_rdf_length + *pos > end) {
00257 return LDNS_STATUS_PACKET_OVERFLOW;
00258 }
00259 data = LDNS_XMALLOC(uint8_t, rd_length);
00260 if (!data) {
00261 return LDNS_STATUS_MEM_ERR;
00262 }
00263 memcpy(data, &wire[*pos], cur_rdf_length);
00264
00265 cur_rdf = ldns_rdf_new(cur_rdf_type, cur_rdf_length, data);
00266 *pos = *pos + cur_rdf_length;
00267 }
00268
00269 if (cur_rdf) {
00270 ldns_rr_push_rdf(rr, cur_rdf);
00271 cur_rdf = NULL;
00272 }
00273 }
00274
00275 return LDNS_STATUS_OK;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284 ldns_status
00285 ldns_wire2rr(ldns_rr **rr_p, const uint8_t *wire, size_t max,
00286 size_t *pos, ldns_pkt_section section)
00287 {
00288 ldns_rdf *owner = NULL;
00289 ldns_rr *rr = ldns_rr_new();
00290 ldns_status status;
00291
00292 status = ldns_wire2dname(&owner, wire, max, pos);
00293 LDNS_STATUS_CHECK_GOTO(status, status_error);
00294
00295 ldns_rr_set_owner(rr, owner);
00296
00297 if (*pos + 4 > max) {
00298 status = LDNS_STATUS_PACKET_OVERFLOW;
00299 goto status_error;
00300 }
00301
00302 ldns_rr_set_type(rr, ldns_read_uint16(&wire[*pos]));
00303 *pos = *pos + 2;
00304
00305 ldns_rr_set_class(rr, ldns_read_uint16(&wire[*pos]));
00306 *pos = *pos + 2;
00307
00308 if (section != LDNS_SECTION_QUESTION) {
00309 if (*pos + 4 > max) {
00310 status = LDNS_STATUS_PACKET_OVERFLOW;
00311 goto status_error;
00312 }
00313 ldns_rr_set_ttl(rr, ldns_read_uint32(&wire[*pos]));
00314
00315 *pos = *pos + 4;
00316 status = ldns_wire2rdf(rr, wire, max, pos);
00317
00318 LDNS_STATUS_CHECK_GOTO(status, status_error);
00319 ldns_rr_set_question(rr, false);
00320 } else {
00321 ldns_rr_set_question(rr, true);
00322 }
00323
00324 *rr_p = rr;
00325 return LDNS_STATUS_OK;
00326
00327 status_error:
00328 ldns_rr_free(rr);
00329 return status;
00330 }
00331
00332 static ldns_status
00333 ldns_wire2pkt_hdr(ldns_pkt *packet, const uint8_t *wire, size_t max, size_t *pos)
00334 {
00335 if (*pos + LDNS_HEADER_SIZE > max) {
00336 return LDNS_STATUS_WIRE_INCOMPLETE_HEADER;
00337 } else {
00338 ldns_pkt_set_id(packet, LDNS_ID_WIRE(wire));
00339 ldns_pkt_set_qr(packet, LDNS_QR_WIRE(wire));
00340 ldns_pkt_set_opcode(packet, LDNS_OPCODE_WIRE(wire));
00341 ldns_pkt_set_aa(packet, LDNS_AA_WIRE(wire));
00342 ldns_pkt_set_tc(packet, LDNS_TC_WIRE(wire));
00343 ldns_pkt_set_rd(packet, LDNS_RD_WIRE(wire));
00344 ldns_pkt_set_ra(packet, LDNS_RA_WIRE(wire));
00345 ldns_pkt_set_ad(packet, LDNS_AD_WIRE(wire));
00346 ldns_pkt_set_cd(packet, LDNS_CD_WIRE(wire));
00347 ldns_pkt_set_rcode(packet, LDNS_RCODE_WIRE(wire));
00348
00349 ldns_pkt_set_qdcount(packet, LDNS_QDCOUNT(wire));
00350 ldns_pkt_set_ancount(packet, LDNS_ANCOUNT(wire));
00351 ldns_pkt_set_nscount(packet, LDNS_NSCOUNT(wire));
00352 ldns_pkt_set_arcount(packet, LDNS_ARCOUNT(wire));
00353
00354 *pos += LDNS_HEADER_SIZE;
00355
00356 return LDNS_STATUS_OK;
00357 }
00358 }
00359
00360 ldns_status
00361 ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer)
00362 {
00363
00364 return ldns_wire2pkt(packet, ldns_buffer_begin(buffer),
00365 ldns_buffer_limit(buffer));
00366
00367 }
00368
00369 ldns_status
00370 ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
00371 {
00372 size_t pos = 0;
00373 uint16_t i;
00374 ldns_rr *rr;
00375 ldns_pkt *packet = ldns_pkt_new();
00376 ldns_status status = LDNS_STATUS_OK;
00377 int have_edns = 0;
00378
00379 uint8_t data[4];
00380
00381 status = ldns_wire2pkt_hdr(packet, wire, max, &pos);
00382 LDNS_STATUS_CHECK_GOTO(status, status_error);
00383
00384 for (i = 0; i < ldns_pkt_qdcount(packet); i++) {
00385
00386 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_QUESTION);
00387 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00388 status = LDNS_STATUS_WIRE_INCOMPLETE_QUESTION;
00389 }
00390 LDNS_STATUS_CHECK_GOTO(status, status_error);
00391 if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
00392 ldns_pkt_free(packet);
00393 return LDNS_STATUS_INTERNAL_ERR;
00394 }
00395 }
00396 for (i = 0; i < ldns_pkt_ancount(packet); i++) {
00397 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ANSWER);
00398 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00399 status = LDNS_STATUS_WIRE_INCOMPLETE_ANSWER;
00400 }
00401 LDNS_STATUS_CHECK_GOTO(status, status_error);
00402 if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
00403 ldns_pkt_free(packet);
00404 return LDNS_STATUS_INTERNAL_ERR;
00405 }
00406 }
00407 for (i = 0; i < ldns_pkt_nscount(packet); i++) {
00408 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_AUTHORITY);
00409 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00410 status = LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY;
00411 }
00412 LDNS_STATUS_CHECK_GOTO(status, status_error);
00413 if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
00414 ldns_pkt_free(packet);
00415 return LDNS_STATUS_INTERNAL_ERR;
00416 }
00417 }
00418 for (i = 0; i < ldns_pkt_arcount(packet); i++) {
00419 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ADDITIONAL);
00420 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00421 status = LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL;
00422 }
00423 LDNS_STATUS_CHECK_GOTO(status, status_error);
00424
00425 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_OPT) {
00426 ldns_pkt_set_edns_udp_size(packet, ldns_rr_get_class(rr));
00427 ldns_write_uint32(data, ldns_rr_ttl(rr));
00428 ldns_pkt_set_edns_extended_rcode(packet, data[0]);
00429 ldns_pkt_set_edns_version(packet, data[1]);
00430 ldns_pkt_set_edns_z(packet, ldns_read_uint16(&data[2]));
00431
00432 if (ldns_rr_rdf(rr, 0)) {
00433 ldns_pkt_set_edns_data(packet, ldns_rdf_clone(ldns_rr_rdf(rr, 0)));
00434 }
00435 ldns_rr_free(rr);
00436 have_edns += 1;
00437 } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_TSIG) {
00438 ldns_pkt_set_tsig(packet, rr);
00439 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1);
00440 } else if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
00441 ldns_pkt_free(packet);
00442 return LDNS_STATUS_INTERNAL_ERR;
00443 }
00444 }
00445 ldns_pkt_set_size(packet, max);
00446 if(have_edns)
00447 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet)
00448 - have_edns);
00449
00450 *packet_p = packet;
00451 return status;
00452
00453 status_error:
00454 ldns_pkt_free(packet);
00455 return status;
00456 }