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