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