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