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 + label_size > max) {
00105 return LDNS_STATUS_LABEL_OVERFLOW;
00106 }
00107
00108 tmp_dname[dname_pos] = label_size;
00109 if (label_size > 0) {
00110 dname_pos++;
00111 }
00112 *pos = *pos + 1;
00113 if (dname_pos + label_size > LDNS_MAX_DOMAINLEN) {
00114 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00115 }
00116 memcpy(&tmp_dname[dname_pos], &wire[*pos], label_size);
00117 uncompressed_length += label_size + 1;
00118 dname_pos += label_size;
00119 *pos = *pos + label_size;
00120
00121 if (*pos < max) {
00122 label_size = wire[*pos];
00123 }
00124 }
00125
00126 if (compression_pos > 0) {
00127 *pos = compression_pos;
00128 } else {
00129 *pos = *pos + 1;
00130 }
00131
00132 tmp_dname[dname_pos] = 0;
00133 dname_pos++;
00134
00135 *dname = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME,
00136 (uint16_t) dname_pos, tmp_dname);
00137 if (!*dname) {
00138 return LDNS_STATUS_MEM_ERR;
00139 }
00140 return LDNS_STATUS_OK;
00141 }
00142
00143
00144 #define LDNS_STATUS_CHECK_RETURN(st) {if (st != LDNS_STATUS_OK) { return st; }}
00145 #define LDNS_STATUS_CHECK_GOTO(st, label) {if (st != LDNS_STATUS_OK) { goto label; }}
00146
00147 ldns_status
00148 ldns_wire2rdf(ldns_rr *rr, const uint8_t *wire, size_t max, size_t *pos)
00149 {
00150 size_t end;
00151 size_t cur_rdf_length;
00152 uint8_t rdf_index;
00153 uint8_t *data;
00154 uint16_t rd_length;
00155 ldns_rdf *cur_rdf = NULL;
00156 ldns_rdf_type cur_rdf_type;
00157 const ldns_rr_descriptor *descriptor = ldns_rr_descript(ldns_rr_get_type(rr));
00158 ldns_status status;
00159
00160 if (*pos + 2 > max) {
00161 return LDNS_STATUS_PACKET_OVERFLOW;
00162 }
00163
00164 rd_length = ldns_read_uint16(&wire[*pos]);
00165 *pos = *pos + 2;
00166
00167 if (*pos + rd_length > max) {
00168 return LDNS_STATUS_PACKET_OVERFLOW;
00169 }
00170
00171 end = *pos + (size_t) rd_length;
00172
00173 for (rdf_index = 0;
00174 rdf_index < ldns_rr_descriptor_maximum(descriptor); rdf_index++) {
00175 if (*pos >= end) {
00176 break;
00177 }
00178 cur_rdf_length = 0;
00179
00180 cur_rdf_type = ldns_rr_descriptor_field_type(descriptor, rdf_index);
00181
00182
00183 switch (cur_rdf_type) {
00184 case LDNS_RDF_TYPE_DNAME:
00185 status = ldns_wire2dname(&cur_rdf, wire, max, pos);
00186 LDNS_STATUS_CHECK_RETURN(status);
00187 break;
00188 case LDNS_RDF_TYPE_CLASS:
00189 case LDNS_RDF_TYPE_ALG:
00190 case LDNS_RDF_TYPE_INT8:
00191 cur_rdf_length = LDNS_RDF_SIZE_BYTE;
00192 break;
00193 case LDNS_RDF_TYPE_TYPE:
00194 case LDNS_RDF_TYPE_INT16:
00195 case LDNS_RDF_TYPE_CERT_ALG:
00196 cur_rdf_length = LDNS_RDF_SIZE_WORD;
00197 break;
00198 case LDNS_RDF_TYPE_TIME:
00199 case LDNS_RDF_TYPE_INT32:
00200 case LDNS_RDF_TYPE_A:
00201 case LDNS_RDF_TYPE_PERIOD:
00202 cur_rdf_length = LDNS_RDF_SIZE_DOUBLEWORD;
00203 break;
00204 case LDNS_RDF_TYPE_TSIGTIME:
00205 cur_rdf_length = LDNS_RDF_SIZE_6BYTES;
00206 break;
00207 case LDNS_RDF_TYPE_AAAA:
00208 cur_rdf_length = LDNS_RDF_SIZE_16BYTES;
00209 break;
00210 case LDNS_RDF_TYPE_STR:
00211 case LDNS_RDF_TYPE_NSEC3_SALT:
00212
00213
00214
00215
00216 cur_rdf_length = ((size_t) wire[*pos]) + 1;
00217 break;
00218 case LDNS_RDF_TYPE_INT16_DATA:
00219 cur_rdf_length = (size_t) ldns_read_uint16(&wire[*pos]) + 2;
00220 break;
00221 case LDNS_RDF_TYPE_B32_EXT:
00222 case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
00223
00224 cur_rdf_length = ((size_t) wire[*pos]) + 1;
00225 break;
00226 case LDNS_RDF_TYPE_APL:
00227 case LDNS_RDF_TYPE_B64:
00228 case LDNS_RDF_TYPE_HEX:
00229 case LDNS_RDF_TYPE_NSEC:
00230 case LDNS_RDF_TYPE_UNKNOWN:
00231 case LDNS_RDF_TYPE_SERVICE:
00232 case LDNS_RDF_TYPE_LOC:
00233 case LDNS_RDF_TYPE_WKS:
00234 case LDNS_RDF_TYPE_NSAP:
00235 case LDNS_RDF_TYPE_IPSECKEY:
00236 case LDNS_RDF_TYPE_TSIG:
00237 case LDNS_RDF_TYPE_NONE:
00238
00239
00240
00241 cur_rdf_length = end - *pos;
00242 break;
00243 }
00244
00245
00246 if (cur_rdf_length > 0) {
00247 if (cur_rdf_length + *pos > end) {
00248 return LDNS_STATUS_PACKET_OVERFLOW;
00249 }
00250 data = LDNS_XMALLOC(uint8_t, rd_length);
00251 if (!data) {
00252 return LDNS_STATUS_MEM_ERR;
00253 }
00254 memcpy(data, &wire[*pos], cur_rdf_length);
00255
00256 cur_rdf = ldns_rdf_new(cur_rdf_type, cur_rdf_length, data);
00257 *pos = *pos + cur_rdf_length;
00258 }
00259
00260 if (cur_rdf) {
00261 ldns_rr_push_rdf(rr, cur_rdf);
00262 cur_rdf = NULL;
00263 }
00264 }
00265
00266 return LDNS_STATUS_OK;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 ldns_status
00276 ldns_wire2rr(ldns_rr **rr_p, const uint8_t *wire, size_t max,
00277 size_t *pos, ldns_pkt_section section)
00278 {
00279 ldns_rdf *owner = NULL;
00280 ldns_rr *rr = ldns_rr_new();
00281 ldns_status status;
00282
00283 status = ldns_wire2dname(&owner, wire, max, pos);
00284 LDNS_STATUS_CHECK_GOTO(status, status_error);
00285
00286 ldns_rr_set_owner(rr, owner);
00287
00288 if (*pos + 4 > max) {
00289 status = LDNS_STATUS_PACKET_OVERFLOW;
00290 goto status_error;
00291 }
00292
00293 ldns_rr_set_type(rr, ldns_read_uint16(&wire[*pos]));
00294 *pos = *pos + 2;
00295
00296 ldns_rr_set_class(rr, ldns_read_uint16(&wire[*pos]));
00297 *pos = *pos + 2;
00298
00299 if (section != LDNS_SECTION_QUESTION) {
00300 if (*pos + 4 > max) {
00301 status = LDNS_STATUS_PACKET_OVERFLOW;
00302 goto status_error;
00303 }
00304 ldns_rr_set_ttl(rr, ldns_read_uint32(&wire[*pos]));
00305
00306 *pos = *pos + 4;
00307 status = ldns_wire2rdf(rr, wire, max, pos);
00308
00309 LDNS_STATUS_CHECK_GOTO(status, status_error);
00310 }
00311
00312 *rr_p = rr;
00313 return LDNS_STATUS_OK;
00314
00315 status_error:
00316 ldns_rr_free(rr);
00317 return status;
00318 }
00319
00320 static ldns_status
00321 ldns_wire2pkt_hdr(ldns_pkt *packet, const uint8_t *wire, size_t max, size_t *pos)
00322 {
00323 if (*pos + LDNS_HEADER_SIZE > max) {
00324 return LDNS_STATUS_WIRE_INCOMPLETE_HEADER;
00325 } else {
00326 ldns_pkt_set_id(packet, LDNS_ID_WIRE(wire));
00327 ldns_pkt_set_qr(packet, LDNS_QR_WIRE(wire));
00328 ldns_pkt_set_opcode(packet, LDNS_OPCODE_WIRE(wire));
00329 ldns_pkt_set_aa(packet, LDNS_AA_WIRE(wire));
00330 ldns_pkt_set_tc(packet, LDNS_TC_WIRE(wire));
00331 ldns_pkt_set_rd(packet, LDNS_RD_WIRE(wire));
00332 ldns_pkt_set_ra(packet, LDNS_RA_WIRE(wire));
00333 ldns_pkt_set_ad(packet, LDNS_AD_WIRE(wire));
00334 ldns_pkt_set_cd(packet, LDNS_CD_WIRE(wire));
00335 ldns_pkt_set_rcode(packet, LDNS_RCODE_WIRE(wire));
00336
00337 ldns_pkt_set_qdcount(packet, LDNS_QDCOUNT(wire));
00338 ldns_pkt_set_ancount(packet, LDNS_ANCOUNT(wire));
00339 ldns_pkt_set_nscount(packet, LDNS_NSCOUNT(wire));
00340 ldns_pkt_set_arcount(packet, LDNS_ARCOUNT(wire));
00341
00342 *pos += LDNS_HEADER_SIZE;
00343
00344 return LDNS_STATUS_OK;
00345 }
00346 }
00347
00348 ldns_status
00349 ldns_buffer2pkt_wire(ldns_pkt **packet, ldns_buffer *buffer)
00350 {
00351
00352 return ldns_wire2pkt(packet, ldns_buffer_begin(buffer),
00353 ldns_buffer_limit(buffer));
00354
00355 }
00356
00357 ldns_status
00358 ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
00359 {
00360 size_t pos = 0;
00361 uint16_t i;
00362 ldns_rr *rr;
00363 ldns_pkt *packet = ldns_pkt_new();
00364 ldns_status status = LDNS_STATUS_OK;
00365 int have_edns = 0;
00366
00367 uint8_t data[4];
00368
00369 status = ldns_wire2pkt_hdr(packet, wire, max, &pos);
00370 LDNS_STATUS_CHECK_GOTO(status, status_error);
00371
00372 for (i = 0; i < ldns_pkt_qdcount(packet); i++) {
00373
00374 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_QUESTION);
00375 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00376 status = LDNS_STATUS_WIRE_INCOMPLETE_QUESTION;
00377 }
00378 LDNS_STATUS_CHECK_GOTO(status, status_error);
00379 if (!ldns_rr_list_push_rr(ldns_pkt_question(packet), rr)) {
00380 ldns_pkt_free(packet);
00381 return LDNS_STATUS_INTERNAL_ERR;
00382 }
00383 }
00384 for (i = 0; i < ldns_pkt_ancount(packet); i++) {
00385 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ANSWER);
00386 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00387 status = LDNS_STATUS_WIRE_INCOMPLETE_ANSWER;
00388 }
00389 LDNS_STATUS_CHECK_GOTO(status, status_error);
00390 if (!ldns_rr_list_push_rr(ldns_pkt_answer(packet), rr)) {
00391 ldns_pkt_free(packet);
00392 return LDNS_STATUS_INTERNAL_ERR;
00393 }
00394 }
00395 for (i = 0; i < ldns_pkt_nscount(packet); i++) {
00396 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_AUTHORITY);
00397 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00398 status = LDNS_STATUS_WIRE_INCOMPLETE_AUTHORITY;
00399 }
00400 LDNS_STATUS_CHECK_GOTO(status, status_error);
00401 if (!ldns_rr_list_push_rr(ldns_pkt_authority(packet), rr)) {
00402 ldns_pkt_free(packet);
00403 return LDNS_STATUS_INTERNAL_ERR;
00404 }
00405 }
00406 for (i = 0; i < ldns_pkt_arcount(packet); i++) {
00407 status = ldns_wire2rr(&rr, wire, max, &pos, LDNS_SECTION_ADDITIONAL);
00408 if (status == LDNS_STATUS_PACKET_OVERFLOW) {
00409 status = LDNS_STATUS_WIRE_INCOMPLETE_ADDITIONAL;
00410 }
00411 LDNS_STATUS_CHECK_GOTO(status, status_error);
00412
00413 if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_OPT) {
00414 ldns_pkt_set_edns_udp_size(packet, ldns_rr_get_class(rr));
00415 ldns_write_uint32(data, ldns_rr_ttl(rr));
00416 ldns_pkt_set_edns_extended_rcode(packet, data[0]);
00417 ldns_pkt_set_edns_version(packet, data[1]);
00418 ldns_pkt_set_edns_z(packet, ldns_read_uint16(&data[2]));
00419
00420 if (ldns_rr_rdf(rr, 0)) {
00421 ldns_pkt_set_edns_data(packet, ldns_rdf_clone(ldns_rr_rdf(rr, 0)));
00422 }
00423 ldns_rr_free(rr);
00424 have_edns = 1;
00425 } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_TSIG) {
00426 ldns_pkt_set_tsig(packet, rr);
00427 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1);
00428 } else if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {
00429 ldns_pkt_free(packet);
00430 return LDNS_STATUS_INTERNAL_ERR;
00431 }
00432 }
00433 ldns_pkt_set_size(packet, max);
00434 if(have_edns)
00435 ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1);
00436
00437 *packet_p = packet;
00438 return status;
00439
00440 status_error:
00441 ldns_pkt_free(packet);
00442 return status;
00443 }