00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <ldns/config.h>
00017
00018 #include <ldns/ldns.h>
00019
00020 #ifdef HAVE_NETINET_IN_H
00021 #include <netinet/in.h>
00022 #endif
00023 #ifdef HAVE_SYS_SOCKET_H
00024 #include <sys/socket.h>
00025 #endif
00026 #ifdef HAVE_NETDB_H
00027 #include <netdb.h>
00028 #endif
00029 #ifdef HAVE_ARPA_INET_H
00030 #include <arpa/inet.h>
00031 #endif
00032
00033
00034
00035
00036
00037 static bool
00038 ldns_dname_last_label_is_root_label(const ldns_rdf* dname)
00039 {
00040 size_t src_pos;
00041 size_t len = 0;
00042
00043 for (src_pos = 0; src_pos < ldns_rdf_size(dname); src_pos += len + 1) {
00044 len = ldns_rdf_data(dname)[src_pos];
00045 }
00046 assert(src_pos == ldns_rdf_size(dname));
00047
00048 return src_pos > 0 && len == 0;
00049 }
00050
00051 ldns_rdf *
00052 ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
00053 {
00054 ldns_rdf *new;
00055 uint16_t new_size;
00056 uint8_t *buf;
00057 uint16_t left_size;
00058
00059 if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
00060 ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
00061 return NULL;
00062 }
00063
00064
00065
00066
00067 left_size = ldns_rdf_size(rd1);
00068 if (ldns_dname_last_label_is_root_label(rd1)) {
00069 left_size--;
00070 }
00071
00072
00073 new_size = left_size + ldns_rdf_size(rd2);
00074 buf = LDNS_XMALLOC(uint8_t, new_size);
00075 if (!buf) {
00076 return NULL;
00077 }
00078
00079
00080 memcpy(buf, ldns_rdf_data(rd1), left_size);
00081 memcpy(buf + left_size, ldns_rdf_data(rd2), ldns_rdf_size(rd2));
00082
00083 new = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, new_size, buf);
00084
00085 LDNS_FREE(buf);
00086 return new;
00087 }
00088
00089 ldns_status
00090 ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
00091 {
00092 uint16_t left_size;
00093 uint16_t size;
00094 uint8_t* newd;
00095
00096 if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
00097 ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
00098 return LDNS_STATUS_ERR;
00099 }
00100
00101
00102
00103
00104 left_size = ldns_rdf_size(rd1);
00105 if (ldns_dname_last_label_is_root_label(rd1)) {
00106 left_size--;
00107 }
00108
00109 size = left_size + ldns_rdf_size(rd2);
00110 newd = LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size);
00111 if(!newd) {
00112 return LDNS_STATUS_MEM_ERR;
00113 }
00114
00115 ldns_rdf_set_data(rd1, newd);
00116 memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
00117 ldns_rdf_size(rd2));
00118 ldns_rdf_set_size(rd1, size);
00119
00120 return LDNS_STATUS_OK;
00121 }
00122
00123 ldns_rdf*
00124 ldns_dname_reverse(const ldns_rdf *dname)
00125 {
00126 size_t rd_size;
00127 uint8_t* buf;
00128 ldns_rdf* new;
00129 size_t src_pos;
00130 size_t len ;
00131
00132 assert(ldns_rdf_get_type(dname) == LDNS_RDF_TYPE_DNAME);
00133
00134 rd_size = ldns_rdf_size(dname);
00135 buf = LDNS_XMALLOC(uint8_t, rd_size);
00136 if (! buf) {
00137 return NULL;
00138 }
00139 new = ldns_rdf_new(LDNS_RDF_TYPE_DNAME, rd_size, buf);
00140 if (! new) {
00141 LDNS_FREE(buf);
00142 return NULL;
00143 }
00144
00145
00146
00147 if (ldns_dname_last_label_is_root_label(dname)) {
00148 buf[rd_size - 1] = 0;
00149 rd_size -= 1;
00150 }
00151 for (src_pos = 0; src_pos < rd_size; src_pos += len + 1) {
00152 len = ldns_rdf_data(dname)[src_pos];
00153 memcpy(&buf[rd_size - src_pos - len - 1],
00154 &ldns_rdf_data(dname)[src_pos], len + 1);
00155 }
00156 return new;
00157 }
00158
00159 ldns_rdf *
00160 ldns_dname_clone_from(const ldns_rdf *d, uint16_t n)
00161 {
00162 uint8_t *data;
00163 uint8_t label_size;
00164 size_t data_size;
00165
00166 if (!d ||
00167 ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME ||
00168 ldns_dname_label_count(d) < n) {
00169 return NULL;
00170 }
00171
00172 data = ldns_rdf_data(d);
00173 data_size = ldns_rdf_size(d);
00174 while (n > 0) {
00175 label_size = data[0] + 1;
00176 data += label_size;
00177 if (data_size < label_size) {
00178
00179 return NULL;
00180 }
00181 data_size -= label_size;
00182 n--;
00183 }
00184
00185 return ldns_dname_new_frm_data(data_size, data);
00186 }
00187
00188 ldns_rdf *
00189 ldns_dname_left_chop(const ldns_rdf *d)
00190 {
00191 uint8_t label_pos;
00192 ldns_rdf *chop;
00193
00194 if (!d) {
00195 return NULL;
00196 }
00197
00198 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
00199 return NULL;
00200 }
00201 if (ldns_dname_label_count(d) == 0) {
00202
00203 return NULL;
00204 }
00205
00206 label_pos = ldns_rdf_data(d)[0];
00207
00208 chop = ldns_dname_new_frm_data(ldns_rdf_size(d) - label_pos - 1,
00209 ldns_rdf_data(d) + label_pos + 1);
00210 return chop;
00211 }
00212
00213 uint8_t
00214 ldns_dname_label_count(const ldns_rdf *r)
00215 {
00216 uint16_t src_pos;
00217 uint16_t len;
00218 uint8_t i;
00219 size_t r_size;
00220
00221 if (!r) {
00222 return 0;
00223 }
00224
00225 i = 0;
00226 src_pos = 0;
00227 r_size = ldns_rdf_size(r);
00228
00229 if (ldns_rdf_get_type(r) != LDNS_RDF_TYPE_DNAME) {
00230 return 0;
00231 } else {
00232 len = ldns_rdf_data(r)[src_pos];
00233
00234
00235 if (1 == r_size) {
00236 return 0;
00237 } else {
00238 while ((len > 0) && src_pos < r_size) {
00239 src_pos++;
00240 src_pos += len;
00241 len = ldns_rdf_data(r)[src_pos];
00242 i++;
00243 }
00244 }
00245 }
00246 return i;
00247 }
00248
00249 ldns_rdf *
00250 ldns_dname_new(uint16_t s, void *d)
00251 {
00252 ldns_rdf *rd;
00253
00254 rd = LDNS_MALLOC(ldns_rdf);
00255 if (!rd) {
00256 return NULL;
00257 }
00258 ldns_rdf_set_size(rd, s);
00259 ldns_rdf_set_type(rd, LDNS_RDF_TYPE_DNAME);
00260 ldns_rdf_set_data(rd, d);
00261 return rd;
00262 }
00263
00264 ldns_rdf *
00265 ldns_dname_new_frm_str(const char *str)
00266 {
00267 return ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, str);
00268 }
00269
00270 ldns_rdf *
00271 ldns_dname_new_frm_data(uint16_t size, const void *data)
00272 {
00273 return ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, size, data);
00274 }
00275
00276 void
00277 ldns_dname2canonical(const ldns_rdf *rd)
00278 {
00279 uint8_t *rdd;
00280 uint16_t i;
00281
00282 if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_DNAME) {
00283 return;
00284 }
00285
00286 rdd = (uint8_t*)ldns_rdf_data(rd);
00287 for (i = 0; i < ldns_rdf_size(rd); i++, rdd++) {
00288 *rdd = (uint8_t)LDNS_DNAME_NORMALIZE((int)*rdd);
00289 }
00290 }
00291
00292 bool
00293 ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
00294 {
00295 uint8_t sub_lab;
00296 uint8_t par_lab;
00297 int8_t i, j;
00298 ldns_rdf *tmp_sub = NULL;
00299 ldns_rdf *tmp_par = NULL;
00300 ldns_rdf *sub_clone;
00301 ldns_rdf *parent_clone;
00302 bool result = true;
00303
00304 if (ldns_rdf_get_type(sub) != LDNS_RDF_TYPE_DNAME ||
00305 ldns_rdf_get_type(parent) != LDNS_RDF_TYPE_DNAME ||
00306 ldns_rdf_compare(sub, parent) == 0) {
00307 return false;
00308 }
00309
00310
00311 sub_clone = ldns_dname_clone_from(sub, 0);
00312 parent_clone = ldns_dname_clone_from(parent, 0);
00313 ldns_dname2canonical(sub_clone);
00314 ldns_dname2canonical(parent_clone);
00315
00316 sub_lab = ldns_dname_label_count(sub_clone);
00317 par_lab = ldns_dname_label_count(parent_clone);
00318
00319
00320 if (sub_lab < par_lab) {
00321 result = false;
00322 } else {
00323
00324
00325
00326 j = sub_lab - 1;
00327 for (i = par_lab -1; i >= 0; i--) {
00328 tmp_sub = ldns_dname_label(sub_clone, j);
00329 tmp_par = ldns_dname_label(parent_clone, i);
00330 if (!tmp_sub || !tmp_par) {
00331
00332 ldns_rdf_deep_free(tmp_sub);
00333 ldns_rdf_deep_free(tmp_par);
00334 result = false;
00335 break;
00336 }
00337
00338 if (ldns_rdf_compare(tmp_sub, tmp_par) != 0) {
00339
00340 ldns_rdf_deep_free(tmp_sub);
00341 ldns_rdf_deep_free(tmp_par);
00342 result = false;
00343 break;
00344 }
00345 ldns_rdf_deep_free(tmp_sub);
00346 ldns_rdf_deep_free(tmp_par);
00347 j--;
00348 }
00349 }
00350 ldns_rdf_deep_free(sub_clone);
00351 ldns_rdf_deep_free(parent_clone);
00352 return result;
00353 }
00354
00355 int
00356 ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
00357 {
00358 size_t lc1, lc2, lc1f, lc2f;
00359 size_t i;
00360 int result = 0;
00361 uint8_t *lp1, *lp2;
00362
00363
00364
00365
00366
00367 if (!dname1 && !dname2) {
00368 return 0;
00369 }
00370 if (!dname1 || !dname2) {
00371 return -1;
00372 }
00373
00374
00375
00376
00377 assert(ldns_rdf_get_type(dname1) == LDNS_RDF_TYPE_DNAME);
00378 assert(ldns_rdf_get_type(dname2) == LDNS_RDF_TYPE_DNAME);
00379
00380 lc1 = ldns_dname_label_count(dname1);
00381 lc2 = ldns_dname_label_count(dname2);
00382
00383 if (lc1 == 0 && lc2 == 0) {
00384 return 0;
00385 }
00386 if (lc1 == 0) {
00387 return -1;
00388 }
00389 if (lc2 == 0) {
00390 return 1;
00391 }
00392 lc1--;
00393 lc2--;
00394
00395 while (true) {
00396
00397 lc1f = lc1;
00398 lp1 = ldns_rdf_data(dname1);
00399 while (lc1f > 0) {
00400 lp1 += *lp1 + 1;
00401 lc1f--;
00402 }
00403
00404
00405 lc2f = lc2;
00406 lp2 = ldns_rdf_data(dname2);
00407 while (lc2f > 0) {
00408 lp2 += *lp2 + 1;
00409 lc2f--;
00410 }
00411
00412
00413 for (i = 1; i < (size_t)(*lp1 + 1); i++) {
00414 if (i > *lp2) {
00415
00416 result = 1;
00417 goto done;
00418 }
00419 if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) <
00420 LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
00421 result = -1;
00422 goto done;
00423 } else if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) >
00424 LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
00425 result = 1;
00426 goto done;
00427 }
00428 }
00429 if (*lp1 < *lp2) {
00430
00431 result = -1;
00432 goto done;
00433 }
00434 if (lc1 == 0 && lc2 > 0) {
00435 result = -1;
00436 goto done;
00437 } else if (lc1 > 0 && lc2 == 0) {
00438 result = 1;
00439 goto done;
00440 } else if (lc1 == 0 && lc2 == 0) {
00441 result = 0;
00442 goto done;
00443 }
00444 lc1--;
00445 lc2--;
00446 }
00447
00448 done:
00449 return result;
00450 }
00451
00452 int
00453 ldns_dname_is_wildcard(const ldns_rdf* dname)
00454 {
00455 return ( ldns_dname_label_count(dname) > 0 &&
00456 ldns_rdf_data(dname)[0] == 1 &&
00457 ldns_rdf_data(dname)[1] == '*');
00458 }
00459
00460 int
00461 ldns_dname_match_wildcard(const ldns_rdf *dname, const ldns_rdf *wildcard)
00462 {
00463 ldns_rdf *wc_chopped;
00464 int result;
00465
00466 if (ldns_dname_is_wildcard(wildcard)) {
00467
00468
00469
00470 wc_chopped = ldns_dname_left_chop(wildcard);
00471 result = (int) ldns_dname_is_subdomain(dname, wc_chopped);
00472 ldns_rdf_deep_free(wc_chopped);
00473 } else {
00474 result = (ldns_dname_compare(dname, wildcard) == 0);
00475 }
00476 return result;
00477 }
00478
00479
00480
00481
00482
00483
00484 int
00485 ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
00486 const ldns_rdf *next)
00487 {
00488 int prev_check, next_check;
00489
00490 assert(ldns_rdf_get_type(prev) == LDNS_RDF_TYPE_DNAME);
00491 assert(ldns_rdf_get_type(middle) == LDNS_RDF_TYPE_DNAME);
00492 assert(ldns_rdf_get_type(next) == LDNS_RDF_TYPE_DNAME);
00493
00494 prev_check = ldns_dname_compare(prev, middle);
00495 next_check = ldns_dname_compare(middle, next);
00496
00497
00498
00499 if (next_check == 0) {
00500 return 0;
00501 }
00502
00503
00504 if ((prev_check == -1 || prev_check == 0) &&
00505
00506 next_check == -1) {
00507 return -1;
00508 } else {
00509 return 1;
00510 }
00511 }
00512
00513
00514 bool
00515 ldns_dname_str_absolute(const char *dname_str)
00516 {
00517 const char* s;
00518 if(dname_str && strcmp(dname_str, ".") == 0)
00519 return 1;
00520 if(!dname_str || strlen(dname_str) < 2)
00521 return 0;
00522 if(dname_str[strlen(dname_str) - 1] != '.')
00523 return 0;
00524 if(dname_str[strlen(dname_str) - 2] != '\\')
00525 return 1;
00526
00527 for(s=dname_str; *s; s++) {
00528 if(*s == '\\') {
00529 if(s[1] && s[2] && s[3]
00530 && isdigit(s[1]) && isdigit(s[2]) &&
00531 isdigit(s[3]))
00532 s += 3;
00533 else if(!s[1] || isdigit(s[1]))
00534 return 0;
00535 else s++;
00536 }
00537 else if(!*(s+1) && *s == '.')
00538 return 1;
00539 }
00540 return 0;
00541 }
00542
00543 bool
00544 ldns_dname_absolute(const ldns_rdf *rdf)
00545 {
00546 char *str = ldns_rdf2str(rdf);
00547 if (str) {
00548 bool r = ldns_dname_str_absolute(str);
00549 LDNS_FREE(str);
00550 return r;
00551 }
00552 return false;
00553 }
00554
00555 ldns_rdf *
00556 ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
00557 {
00558 uint8_t labelcnt;
00559 uint16_t src_pos;
00560 uint16_t len;
00561 ldns_rdf *tmpnew;
00562 size_t s;
00563 uint8_t *data;
00564
00565 if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_DNAME) {
00566 return NULL;
00567 }
00568
00569 labelcnt = 0;
00570 src_pos = 0;
00571 s = ldns_rdf_size(rdf);
00572
00573 len = ldns_rdf_data(rdf)[src_pos];
00574 while ((len > 0) && src_pos < s) {
00575 if (labelcnt == labelpos) {
00576
00577 data = LDNS_XMALLOC(uint8_t, len + 2);
00578 if (!data) {
00579 return NULL;
00580 }
00581 memcpy(data, ldns_rdf_data(rdf) + src_pos, len + 1);
00582 data[len + 2 - 1] = 0;
00583
00584 tmpnew = ldns_rdf_new( LDNS_RDF_TYPE_DNAME
00585 , len + 2, data);
00586 if (!tmpnew) {
00587 LDNS_FREE(data);
00588 return NULL;
00589 }
00590 return tmpnew;
00591 }
00592 src_pos++;
00593 src_pos += len;
00594 len = ldns_rdf_data(rdf)[src_pos];
00595 labelcnt++;
00596 }
00597 return NULL;
00598 }