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 #include <netinet/in.h>
00021 #include <sys/socket.h>
00022 #include <netdb.h>
00023 #include <arpa/inet.h>
00024
00025 ldns_rdf *
00026 ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
00027 {
00028 ldns_rdf *new;
00029 uint16_t new_size;
00030 uint8_t *buf;
00031 uint16_t left_size;
00032
00033 if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
00034 ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
00035 return NULL;
00036 }
00037
00038
00039
00040
00041 left_size = ldns_rdf_size(rd1);
00042 if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
00043 left_size--;
00044 }
00045
00046
00047 new_size = left_size + ldns_rdf_size(rd2);
00048 buf = LDNS_XMALLOC(uint8_t, new_size);
00049 if (!buf) {
00050 return NULL;
00051 }
00052
00053
00054 memcpy(buf, ldns_rdf_data(rd1), left_size);
00055 memcpy(buf + left_size, ldns_rdf_data(rd2), ldns_rdf_size(rd2));
00056
00057 new = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, new_size, buf);
00058
00059 LDNS_FREE(buf);
00060 return new;
00061 }
00062
00063 ldns_status
00064 ldns_dname_cat(ldns_rdf *rd1, ldns_rdf *rd2)
00065 {
00066 uint16_t left_size;
00067 uint16_t size;
00068
00069 if (ldns_rdf_get_type(rd1) != LDNS_RDF_TYPE_DNAME ||
00070 ldns_rdf_get_type(rd2) != LDNS_RDF_TYPE_DNAME) {
00071 return LDNS_STATUS_ERR;
00072 }
00073
00074
00075
00076
00077 left_size = ldns_rdf_size(rd1);
00078 if (left_size > 0 &&ldns_rdf_data(rd1)[left_size - 1] == 0) {
00079 left_size--;
00080 }
00081
00082 size = left_size + ldns_rdf_size(rd2);
00083
00084 ldns_rdf_set_data(rd1, LDNS_XREALLOC(ldns_rdf_data(rd1), uint8_t, size));
00085 memcpy(ldns_rdf_data(rd1) + left_size, ldns_rdf_data(rd2),
00086 ldns_rdf_size(rd2));
00087 ldns_rdf_set_size(rd1, size);
00088
00089 return LDNS_STATUS_OK;
00090 }
00091
00092 ldns_rdf *
00093 ldns_dname_reverse(const ldns_rdf *d)
00094 {
00095 ldns_rdf *new;
00096 ldns_rdf *tmp;
00097 ldns_rdf *d_tmp;
00098 ldns_status status;
00099
00100 d_tmp = ldns_rdf_clone(d);
00101
00102 new = ldns_dname_new_frm_str(".");
00103
00104 while(ldns_dname_label_count(d_tmp) > 0) {
00105 tmp = ldns_dname_label(d_tmp, 0);
00106 status = ldns_dname_cat(tmp, new);
00107 ldns_rdf_deep_free(new);
00108 new = tmp;
00109 tmp = ldns_dname_left_chop(d_tmp);
00110 ldns_rdf_deep_free(d_tmp);
00111 d_tmp = tmp;
00112 }
00113 ldns_rdf_deep_free(d_tmp);
00114
00115 return new;
00116 }
00117
00118 ldns_rdf *
00119 ldns_dname_left_chop(ldns_rdf *d)
00120 {
00121 uint8_t label_pos;
00122 ldns_rdf *chop;
00123
00124 if (!d) {
00125 return NULL;
00126 }
00127
00128 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
00129 return NULL;
00130 }
00131 if (ldns_dname_label_count(d) == 0) {
00132
00133 return NULL;
00134 }
00135
00136 label_pos = ldns_rdf_data(d)[0];
00137
00138 chop = ldns_dname_new_frm_data(ldns_rdf_size(d) - label_pos - 1,
00139 ldns_rdf_data(d) + label_pos + 1);
00140 return chop;
00141 }
00142
00143 uint8_t
00144 ldns_dname_label_count(const ldns_rdf *r)
00145 {
00146 uint16_t src_pos;
00147 uint16_t len;
00148 uint8_t i;
00149 size_t r_size;
00150
00151 if (!r) {
00152 return 0;
00153 }
00154
00155 i = 0;
00156 src_pos = 0;
00157 r_size = ldns_rdf_size(r);
00158
00159 if (ldns_rdf_get_type(r) != LDNS_RDF_TYPE_DNAME) {
00160 return 0;
00161 } else {
00162 len = ldns_rdf_data(r)[src_pos];
00163
00164
00165 if (1 == r_size) {
00166 return 0;
00167 } else {
00168 while ((len > 0) && src_pos < r_size) {
00169 src_pos++;
00170 src_pos += len;
00171 len = ldns_rdf_data(r)[src_pos];
00172 i++;
00173 }
00174 }
00175 return i;
00176 }
00177 }
00178
00179 ldns_rdf *
00180 ldns_dname_new(uint16_t s, void *d)
00181 {
00182 ldns_rdf *rd;
00183
00184 rd = LDNS_MALLOC(ldns_rdf);
00185 if (!rd) {
00186 return NULL;
00187 }
00188 ldns_rdf_set_size(rd, s);
00189 ldns_rdf_set_type(rd, LDNS_RDF_TYPE_DNAME);
00190 ldns_rdf_set_data(rd, d);
00191 return rd;
00192 }
00193
00194 ldns_rdf *
00195 ldns_dname_new_frm_str(const char *str)
00196 {
00197 return ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, str);
00198 }
00199
00200 ldns_rdf *
00201 ldns_dname_new_frm_data(uint16_t size, const void *data)
00202 {
00203 return ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, size, data);
00204 }
00205
00206 void
00207 ldns_dname2canonical(const ldns_rdf *rd)
00208 {
00209 uint8_t *rdd;
00210 uint16_t i;
00211
00212 if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_DNAME) {
00213 return;
00214 }
00215
00216 rdd = (uint8_t*)ldns_rdf_data(rd);
00217 for (i = 0; i < ldns_rdf_size(rd); i++, rdd++) {
00218 *rdd = (uint8_t)LDNS_DNAME_NORMALIZE((int)*rdd);
00219 }
00220 }
00221
00222 bool
00223 ldns_dname_is_subdomain(const ldns_rdf *sub, const ldns_rdf *parent)
00224 {
00225 uint8_t sub_lab;
00226 uint8_t par_lab;
00227 int8_t i, j;
00228 ldns_rdf *tmp_sub;
00229 ldns_rdf *tmp_par;
00230
00231 if (ldns_rdf_get_type(sub) != LDNS_RDF_TYPE_DNAME ||
00232 ldns_rdf_get_type(parent) != LDNS_RDF_TYPE_DNAME ||
00233 ldns_rdf_compare(sub, parent) == 0) {
00234 return false;
00235 }
00236
00237 sub_lab = ldns_dname_label_count(sub);
00238 par_lab = ldns_dname_label_count(parent);
00239
00240
00241 if (sub_lab < par_lab) {
00242 return false;
00243 }
00244
00245
00246
00247
00248 j = sub_lab - 1;
00249 for (i = par_lab -1; i >= 0; i--) {
00250 tmp_sub = ldns_dname_label(sub, j);
00251 tmp_par = ldns_dname_label(parent, i);
00252
00253 if (ldns_rdf_compare(tmp_sub, tmp_par) != 0) {
00254
00255 ldns_rdf_deep_free(tmp_sub);
00256 ldns_rdf_deep_free(tmp_par);
00257 return false;
00258 }
00259 ldns_rdf_deep_free(tmp_sub);
00260 ldns_rdf_deep_free(tmp_par);
00261 j--;
00262 }
00263 return true;
00264 }
00265
00266 int
00267 ldns_dname_compare(const ldns_rdf *dname1, const ldns_rdf *dname2)
00268 {
00269 size_t lc1, lc2, lc1f, lc2f;
00270 size_t i;
00271 int result = 0;
00272 uint8_t *lp1, *lp2;
00273
00274
00275
00276
00277
00278 if (!dname1 && !dname2) {
00279 return 0;
00280 }
00281 if (!dname1 || !dname2) {
00282 return -1;
00283 }
00284
00285
00286
00287
00288 assert(ldns_rdf_get_type(dname1) == LDNS_RDF_TYPE_DNAME);
00289 assert(ldns_rdf_get_type(dname2) == LDNS_RDF_TYPE_DNAME);
00290
00291
00292 lc1 = ldns_dname_label_count(dname1);
00293 lc2 = ldns_dname_label_count(dname2);
00294
00295 if (lc1 == 0 && lc2 == 0) {
00296 return 0;
00297 }
00298 if (lc1 == 0) {
00299 return -1;
00300 }
00301 if (lc2 == 0) {
00302 return 1;
00303 }
00304 lc1--;
00305 lc2--;
00306
00307 while (true) {
00308
00309 lc1f = lc1;
00310 lp1 = ldns_rdf_data(dname1);
00311 while (lc1f > 0) {
00312 lp1 += *lp1 + 1;
00313 lc1f--;
00314 }
00315
00316
00317 lc2f = lc2;
00318 lp2 = ldns_rdf_data(dname2);
00319 while (lc2f > 0) {
00320 lp2 += *lp2 + 1;
00321 lc2f--;
00322 }
00323
00324
00325 for (i = 1; i < (size_t)(*lp1 + 1); i++) {
00326 if (i > *lp2) {
00327
00328 result = 1;
00329 goto done;
00330 }
00331 if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) <
00332 LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
00333 result = -1;
00334 goto done;
00335 } else if (LDNS_DNAME_NORMALIZE((int) *(lp1 + i)) >
00336 LDNS_DNAME_NORMALIZE((int) *(lp2 + i))) {
00337 result = 1;
00338 goto done;
00339 }
00340 }
00341 if (*lp1 < *lp2) {
00342
00343 result = -1;
00344 goto done;
00345 }
00346 if (lc1 == 0 && lc2 > 0) {
00347 result = -1;
00348 goto done;
00349 } else if (lc1 > 0 && lc2 == 0) {
00350 result = 1;
00351 goto done;
00352 } else if (lc1 == 0 && lc2 == 0) {
00353 result = 0;
00354 goto done;
00355 }
00356 lc1--;
00357 lc2--;
00358 }
00359
00360
00361 done:
00362 return result;
00363 }
00364
00365
00366
00367
00368
00369
00370 int
00371 ldns_dname_interval(const ldns_rdf *prev, const ldns_rdf *middle,
00372 const ldns_rdf *next)
00373 {
00374 int prev_check, next_check;
00375
00376 assert(ldns_rdf_get_type(prev) == LDNS_RDF_TYPE_DNAME);
00377 assert(ldns_rdf_get_type(middle) == LDNS_RDF_TYPE_DNAME);
00378 assert(ldns_rdf_get_type(next) == LDNS_RDF_TYPE_DNAME);
00379
00380 prev_check = ldns_dname_compare(prev, middle);
00381 next_check = ldns_dname_compare(middle, next);
00382
00383
00384
00385 if (next_check == 0) {
00386 return 0;
00387 }
00388
00389
00390 if ((prev_check == -1 || prev_check == 0) &&
00391
00392 next_check == -1) {
00393 return -1;
00394 } else {
00395 return 1;
00396 }
00397 }
00398
00399
00400 bool
00401 ldns_dname_str_absolute(const char *dname_str)
00402 {
00403 return (dname_str &&
00404 strlen(dname_str) > 1 &&
00405 dname_str[strlen(dname_str) - 1] == '.' &&
00406 dname_str[strlen(dname_str) - 2] != '\\');
00407 }
00408
00409 ldns_rdf *
00410 ldns_dname_label(const ldns_rdf *rdf, uint8_t labelpos)
00411 {
00412 uint8_t labelcnt;
00413 uint16_t src_pos;
00414 uint16_t len;
00415 ldns_rdf *tmpnew;
00416 size_t s;
00417
00418 if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_DNAME) {
00419 return NULL;
00420 }
00421
00422 labelcnt = 0;
00423 src_pos = 0;
00424 s = ldns_rdf_size(rdf);
00425
00426 len = ldns_rdf_data(rdf)[src_pos];
00427 while ((len > 0) && src_pos < s) {
00428 if (labelcnt == labelpos) {
00429
00430 tmpnew = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len + 1,
00431 (ldns_rdf_data(rdf) + src_pos));
00432 return tmpnew;
00433 }
00434 src_pos++;
00435 src_pos += len;
00436 len = ldns_rdf_data(rdf)[src_pos];
00437 labelcnt++;
00438 }
00439 return NULL;
00440 }