00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <ldns/config.h>
00014
00015 #include <ldns/ldns.h>
00016
00017 #ifdef HAVE_SYS_SOCKET_H
00018 #include <sys/socket.h>
00019 #endif
00020 #ifdef HAVE_ARPA_INET_H
00021 #include <arpa/inet.h>
00022 #endif
00023 #include <time.h>
00024
00025 #include <errno.h>
00026 #ifdef HAVE_NETDB_H
00027 #include <netdb.h>
00028 #endif
00029
00030 #include <limits.h>
00031 #ifdef HAVE_SYS_PARAM_H
00032 #include <sys/param.h>
00033 #endif
00034
00035 ldns_status
00036 ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
00037 {
00038 char *end = NULL;
00039 uint16_t *r;
00040 r = LDNS_MALLOC(uint16_t);
00041 if(!r) return LDNS_STATUS_MEM_ERR;
00042
00043 *r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
00044
00045 if(*end != 0) {
00046 LDNS_FREE(r);
00047 return LDNS_STATUS_INVALID_INT;
00048 } else {
00049 *rd = ldns_rdf_new_frm_data(
00050 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
00051 LDNS_FREE(r);
00052 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00053 }
00054 }
00055
00056 ldns_status
00057 ldns_str2rdf_time(ldns_rdf **rd, const char *time)
00058 {
00059
00060 uint16_t *r = NULL;
00061 struct tm tm;
00062 uint32_t l;
00063 char *end;
00064
00065
00066 r = (uint16_t*)LDNS_MALLOC(uint32_t);
00067 if(!r) return LDNS_STATUS_MEM_ERR;
00068
00069 memset(&tm, 0, sizeof(tm));
00070
00071 if (strlen(time) == 14 &&
00072 sscanf(time, "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6
00073 ) {
00074 tm.tm_year -= 1900;
00075 tm.tm_mon--;
00076
00077 if (tm.tm_year < 70) {
00078 goto bad_format;
00079 }
00080 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
00081 goto bad_format;
00082 }
00083 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
00084 goto bad_format;
00085 }
00086
00087 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
00088 goto bad_format;
00089 }
00090
00091 if (tm.tm_min < 0 || tm.tm_min > 59) {
00092 goto bad_format;
00093 }
00094
00095 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
00096 goto bad_format;
00097 }
00098
00099 l = htonl(ldns_mktime_from_utc(&tm));
00100 memcpy(r, &l, sizeof(uint32_t));
00101 *rd = ldns_rdf_new_frm_data(
00102 LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
00103 LDNS_FREE(r);
00104 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00105 } else {
00106
00107 l = htonl((uint32_t)strtol((char*)time, &end, 10));
00108 if(*end != 0) {
00109 LDNS_FREE(r);
00110 return LDNS_STATUS_ERR;
00111 } else {
00112 memcpy(r, &l, sizeof(uint32_t));
00113 *rd = ldns_rdf_new_frm_data(
00114 LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00115 LDNS_FREE(r);
00116 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00117 }
00118 }
00119
00120 bad_format:
00121 LDNS_FREE(r);
00122 return LDNS_STATUS_INVALID_TIME;
00123 }
00124
00125 ldns_status
00126 ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
00127 {
00128 uint8_t salt_length;
00129 int c;
00130 int salt_length_str;
00131
00132 uint8_t *salt;
00133 uint8_t *data;
00134 if(rd == NULL) {
00135 return LDNS_STATUS_NULL;
00136 }
00137
00138 salt_length_str = (int)strlen(salt_str);
00139 if (salt_length_str == 1 && salt_str[0] == '-') {
00140 salt_length_str = 0;
00141 } else if (salt_length_str % 2 != 0) {
00142 return LDNS_STATUS_INVALID_HEX;
00143 }
00144 if (salt_length_str > 512) {
00145 return LDNS_STATUS_INVALID_HEX;
00146 }
00147
00148 salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
00149 if(!salt) {
00150 return LDNS_STATUS_MEM_ERR;
00151 }
00152 for (c = 0; c < salt_length_str; c += 2) {
00153 if (isxdigit((int) salt_str[c]) && isxdigit((int) salt_str[c+1])) {
00154 salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
00155 ldns_hexdigit_to_int(salt_str[c+1]);
00156 } else {
00157 LDNS_FREE(salt);
00158 return LDNS_STATUS_INVALID_HEX;
00159 }
00160 }
00161 salt_length = (uint8_t) (salt_length_str / 2);
00162
00163 data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
00164 if(!data) {
00165 LDNS_FREE(salt);
00166 return LDNS_STATUS_MEM_ERR;
00167 }
00168 data[0] = salt_length;
00169 memcpy(&data[1], salt, salt_length);
00170 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
00171 LDNS_FREE(data);
00172 LDNS_FREE(salt);
00173
00174 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00175 }
00176
00177 ldns_status
00178 ldns_str2rdf_period(ldns_rdf **rd,const char *period)
00179 {
00180 uint32_t p;
00181 const char *end;
00182
00183
00184 p = ldns_str2period(period, &end);
00185
00186 if (*end != 0) {
00187 return LDNS_STATUS_ERR;
00188 } else {
00189 p = (uint32_t) htonl(p);
00190 *rd = ldns_rdf_new_frm_data(
00191 LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
00192 }
00193 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00194 }
00195
00196 ldns_status
00197 ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
00198 {
00199 char *end;
00200 uint16_t *r = NULL;
00201 uint32_t l;
00202
00203 r = (uint16_t*)LDNS_MALLOC(uint32_t);
00204 if(!r) return LDNS_STATUS_MEM_ERR;
00205 errno = 0;
00206
00207 if(*longstr == '-')
00208 l = htonl((uint32_t)strtol((char*)longstr, &end, 10));
00209 else l = htonl((uint32_t)strtoul((char*)longstr, &end, 10));
00210
00211 if(*end != 0) {
00212 LDNS_FREE(r);
00213 return LDNS_STATUS_ERR;
00214 } else {
00215 if (errno == ERANGE) {
00216 LDNS_FREE(r);
00217 return LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW;
00218 }
00219 memcpy(r, &l, sizeof(uint32_t));
00220 *rd = ldns_rdf_new_frm_data(
00221 LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00222 LDNS_FREE(r);
00223 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00224 }
00225 }
00226
00227 ldns_status
00228 ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
00229 {
00230 char *end;
00231 uint8_t *r = NULL;
00232
00233 r = LDNS_MALLOC(uint8_t);
00234 if(!r) return LDNS_STATUS_MEM_ERR;
00235
00236 *r = (uint8_t)strtol((char*)bytestr, &end, 10);
00237
00238 if(*end != 0) {
00239 LDNS_FREE(r);
00240 return LDNS_STATUS_ERR;
00241 } else {
00242 *rd = ldns_rdf_new_frm_data(
00243 LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
00244 LDNS_FREE(r);
00245 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 static int
00261 parse_escape(uint8_t *s, uint8_t *q) {
00262 uint16_t val;
00263 if (strlen((char *)s) > 3 &&
00264 isdigit((int) s[1]) &&
00265 isdigit((int) s[2]) &&
00266 isdigit((int) s[3])) {
00267
00268 val = (uint16_t) ldns_hexdigit_to_int((char) s[1]) * 100 +
00269 ldns_hexdigit_to_int((char) s[2]) * 10 +
00270 ldns_hexdigit_to_int((char) s[3]);
00271 if (val > 255) {
00272
00273 return 0;
00274 }
00275 *q = (uint8_t) val;
00276 return 3;
00277 } else {
00278 s++;
00279 if (*s == '\0' || isdigit((int) *s)) {
00280
00281
00282
00283 return 0;
00284 }
00285 *q = *s;
00286 return 1;
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295 ldns_status
00296 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
00297 {
00298 size_t len;
00299
00300 int esc;
00301 uint8_t *s, *q, *pq, label_len;
00302 uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
00303 *d = NULL;
00304
00305 len = strlen((char*)str);
00306
00307 if (len > LDNS_MAX_DOMAINLEN * 4) {
00308 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00309 }
00310 if (0 == len) {
00311 return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
00312 }
00313
00314
00315 if (1 == len && *str == '.') {
00316 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
00317 return LDNS_STATUS_OK;
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327 len = 0;
00328 q = buf+1;
00329 pq = buf;
00330 label_len = 0;
00331 for (s = (uint8_t *)str; *s; s++, q++) {
00332 if (q > buf + LDNS_MAX_DOMAINLEN) {
00333 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00334 }
00335 *q = 0;
00336 switch (*s) {
00337 case '.':
00338 if (label_len > LDNS_MAX_LABELLEN) {
00339 return LDNS_STATUS_LABEL_OVERFLOW;
00340 }
00341 if (label_len == 0) {
00342 return LDNS_STATUS_EMPTY_LABEL;
00343 }
00344 len += label_len + 1;
00345 *pq = label_len;
00346 label_len = 0;
00347 pq = q;
00348 break;
00349 case '\\':
00350
00351 esc = parse_escape(s, q);
00352 if (esc > 0) {
00353 s += esc;
00354 label_len++;
00355 } else {
00356 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00357 }
00358 break;
00359 default:
00360 *q = *s;
00361 label_len++;
00362 }
00363 }
00364
00365
00366 if (!ldns_dname_str_absolute(str)) {
00367 if (q > buf + LDNS_MAX_DOMAINLEN) {
00368 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00369 }
00370 if (label_len > LDNS_MAX_LABELLEN) {
00371 return LDNS_STATUS_LABEL_OVERFLOW;
00372 }
00373 if (label_len == 0) {
00374 return LDNS_STATUS_EMPTY_LABEL;
00375 }
00376 len += label_len + 1;
00377 *pq = label_len;
00378 *q = 0;
00379 }
00380 len++;
00381
00382 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
00383 return LDNS_STATUS_OK;
00384 }
00385
00386 ldns_status
00387 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
00388 {
00389 in_addr_t address;
00390 if (inet_pton(AF_INET, (char*)str, &address) != 1) {
00391 return LDNS_STATUS_INVALID_IP4;
00392 } else {
00393 *rd = ldns_rdf_new_frm_data(
00394 LDNS_RDF_TYPE_A, sizeof(address), &address);
00395 }
00396 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00397 }
00398
00399 ldns_status
00400 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
00401 {
00402 uint8_t address[LDNS_IP6ADDRLEN + 1];
00403
00404 if (inet_pton(AF_INET6, (char*)str, address) != 1) {
00405 return LDNS_STATUS_INVALID_IP6;
00406 } else {
00407 *rd = ldns_rdf_new_frm_data(
00408 LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
00409 }
00410 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00411 }
00412
00413 ldns_status
00414 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
00415 {
00416 uint8_t *data;
00417 size_t i, str_i, esc_i;
00418
00419 if (strlen(str) > 255) {
00420 return LDNS_STATUS_INVALID_STR;
00421 }
00422
00423 data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
00424 if(!data) return LDNS_STATUS_MEM_ERR;
00425 i = 1;
00426
00427 for (str_i = 0; str_i < strlen(str); str_i++) {
00428 if (str[str_i] == '\\') {
00429
00430 esc_i = (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
00431 if (esc_i == 0) {
00432 LDNS_FREE(data);
00433 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00434 }
00435 str_i += esc_i;
00436 } else {
00437 data[i] = (uint8_t) str[str_i];
00438 }
00439 i++;
00440 }
00441 data[0] = i - 1;
00442 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
00443
00444 LDNS_FREE(data);
00445 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00446 }
00447
00448 ldns_status
00449 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
00450 {
00451 const char *my_str = str;
00452
00453 char *my_ip_str;
00454 size_t ip_str_len;
00455
00456 uint16_t family;
00457 bool negation;
00458 uint8_t afdlength = 0;
00459 uint8_t *afdpart;
00460 uint8_t prefix;
00461
00462 uint8_t *data;
00463
00464 size_t i = 0;
00465
00466
00467 if (strlen(my_str) < 2
00468 || strchr(my_str, ':') == NULL
00469 || strchr(my_str, '/') == NULL
00470 || strchr(my_str, ':') > strchr(my_str, '/')) {
00471 return LDNS_STATUS_INVALID_STR;
00472 }
00473
00474 if (my_str[0] == '!') {
00475 negation = true;
00476 my_str += 1;
00477 } else {
00478 negation = false;
00479 }
00480
00481 family = (uint16_t) atoi(my_str);
00482
00483 my_str = strchr(my_str, ':') + 1;
00484
00485
00486 ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
00487 my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
00488 if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
00489 strncpy(my_ip_str, my_str, ip_str_len + 1);
00490 my_ip_str[ip_str_len] = '\0';
00491
00492 if (family == 1) {
00493
00494 afdpart = LDNS_XMALLOC(uint8_t, 4);
00495 if(!afdpart) {
00496 LDNS_FREE(my_ip_str);
00497 return LDNS_STATUS_MEM_ERR;
00498 }
00499 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
00500 LDNS_FREE(my_ip_str);
00501 LDNS_FREE(afdpart);
00502 return LDNS_STATUS_INVALID_STR;
00503 }
00504 for (i = 0; i < 4; i++) {
00505 if (afdpart[i] != 0) {
00506 afdlength = i + 1;
00507 }
00508 }
00509 } else if (family == 2) {
00510
00511 afdpart = LDNS_XMALLOC(uint8_t, 16);
00512 if(!afdpart) {
00513 LDNS_FREE(my_ip_str);
00514 return LDNS_STATUS_MEM_ERR;
00515 }
00516 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
00517 LDNS_FREE(my_ip_str);
00518 LDNS_FREE(afdpart);
00519 return LDNS_STATUS_INVALID_STR;
00520 }
00521 for (i = 0; i < 16; i++) {
00522 if (afdpart[i] != 0) {
00523 afdlength = i + 1;
00524 }
00525 }
00526 } else {
00527
00528 LDNS_FREE(my_ip_str);
00529 return LDNS_STATUS_INVALID_STR;
00530 }
00531
00532 my_str = strchr(my_str, '/') + 1;
00533 prefix = (uint8_t) atoi(my_str);
00534
00535 data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
00536 if(!data) {
00537 LDNS_FREE(afdpart);
00538 LDNS_FREE(my_ip_str);
00539 return LDNS_STATUS_INVALID_STR;
00540 }
00541 ldns_write_uint16(data, family);
00542 data[2] = prefix;
00543 data[3] = afdlength;
00544 if (negation) {
00545
00546 data[3] = data[3] | 0x80;
00547 }
00548
00549 memcpy(data + 4, afdpart, afdlength);
00550
00551 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00552 LDNS_FREE(afdpart);
00553 LDNS_FREE(data);
00554 LDNS_FREE(my_ip_str);
00555
00556 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00557 }
00558
00559 ldns_status
00560 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00561 {
00562 uint8_t *buffer;
00563 int16_t i;
00564
00565 buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
00566 if(!buffer) {
00567 return LDNS_STATUS_MEM_ERR;
00568 }
00569
00570 i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
00571 ldns_b64_ntop_calculate_size(strlen(str)));
00572 if (-1 == i) {
00573 LDNS_FREE(buffer);
00574 return LDNS_STATUS_INVALID_B64;
00575 } else {
00576 *rd = ldns_rdf_new_frm_data(
00577 LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00578 }
00579 LDNS_FREE(buffer);
00580
00581 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00582 }
00583
00584 ldns_status
00585 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00586 {
00587 uint8_t *buffer;
00588 int i;
00589
00590 uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
00591 buffer = LDNS_XMALLOC(uint8_t, len + 1);
00592 if(!buffer) {
00593 return LDNS_STATUS_MEM_ERR;
00594 }
00595 buffer[0] = len;
00596
00597 i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00598 ldns_b32_ntop_calculate_size(strlen(str)));
00599 if (i < 0) {
00600 LDNS_FREE(buffer);
00601 return LDNS_STATUS_INVALID_B32_EXT;
00602 } else {
00603 *rd = ldns_rdf_new_frm_data(
00604 LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00605 }
00606 LDNS_FREE(buffer);
00607
00608 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00609 }
00610
00611 ldns_status
00612 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00613 {
00614 uint8_t *t, *t_orig;
00615 int i;
00616 size_t len;
00617
00618 len = strlen(str);
00619
00620 if (len > LDNS_MAX_RDFLEN * 2) {
00621 return LDNS_STATUS_LABEL_OVERFLOW;
00622 } else {
00623 t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
00624 if(!t) {
00625 return LDNS_STATUS_MEM_ERR;
00626 }
00627 t_orig = t;
00628
00629 while (*str) {
00630 *t = 0;
00631 if (isspace((int) *str)) {
00632 str++;
00633 } else {
00634 for (i = 16; i >= 1; i -= 15) {
00635 while (*str && isspace((int) *str)) { str++; }
00636 if (*str) {
00637 if (isxdigit((int) *str)) {
00638 *t += ldns_hexdigit_to_int(*str) * i;
00639 } else {
00640 LDNS_FREE(t_orig);
00641 return LDNS_STATUS_ERR;
00642 }
00643 ++str;
00644 }
00645 }
00646 ++t;
00647 }
00648 }
00649 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
00650 (size_t) (t - t_orig),
00651 t_orig);
00652 LDNS_FREE(t_orig);
00653 }
00654 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00655 }
00656
00657 ldns_status
00658 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00659 {
00660 const char *delimiters = "\n\t ";
00661 char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00662 ldns_buffer *str_buf;
00663 ssize_t c;
00664 uint16_t cur_type;
00665 size_t type_count = 0;
00666 ldns_rr_type type_list[65536];
00667 if(!token) return LDNS_STATUS_MEM_ERR;
00668 if(rd == NULL) {
00669 LDNS_FREE(token);
00670 return LDNS_STATUS_NULL;
00671 }
00672
00673 str_buf = LDNS_MALLOC(ldns_buffer);
00674 if(!str_buf) {
00675 LDNS_FREE(token);
00676 return LDNS_STATUS_MEM_ERR;
00677 }
00678 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00679 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
00680 LDNS_FREE(str_buf);
00681 LDNS_FREE(token);
00682 return LDNS_STATUS_MEM_ERR;
00683 }
00684
00685 while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
00686 if(type_count >= sizeof(type_list)) {
00687 LDNS_FREE(str_buf);
00688 LDNS_FREE(token);
00689 return LDNS_STATUS_ERR;
00690 }
00691 cur_type = ldns_get_rr_type_by_name(token);
00692 type_list[type_count] = cur_type;
00693 type_count++;
00694 }
00695
00696 *rd = ldns_dnssec_create_nsec_bitmap(type_list,
00697 type_count,
00698 LDNS_RR_TYPE_NSEC);
00699
00700 LDNS_FREE(token);
00701 ldns_buffer_free(str_buf);
00702 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00703 }
00704
00705 ldns_status
00706 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00707 {
00708 uint16_t type;
00709 type = htons(ldns_get_rr_type_by_name(str));
00710
00711 *rd = ldns_rdf_new_frm_data(
00712 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00713 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00714 }
00715
00716 ldns_status
00717 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00718 {
00719 uint16_t klass;
00720 klass = htons(ldns_get_rr_class_by_name(str));
00721
00722 *rd = ldns_rdf_new_frm_data(
00723 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00724 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00725 }
00726
00727
00728
00729
00730 ldns_status
00731 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00732 {
00733 ldns_lookup_table *lt;
00734 ldns_status st;
00735 uint8_t idd[2];
00736 lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00737 st = LDNS_STATUS_OK;
00738
00739 if (lt) {
00740 ldns_write_uint16(idd, (uint16_t) lt->id);
00741 *rd = ldns_rdf_new_frm_data(
00742 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00743 if (!*rd) {
00744 st = LDNS_STATUS_ERR;
00745 }
00746 } else {
00747
00748 st = ldns_str2rdf_int16(rd, str);
00749 if (st == LDNS_STATUS_OK &&
00750 ldns_rdf2native_int16(*rd) == 0) {
00751 st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00752 }
00753 }
00754
00755 return st;
00756 }
00757
00758
00759
00760
00761 ldns_status
00762 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00763 {
00764 ldns_lookup_table *lt;
00765 ldns_status st;
00766
00767 lt = ldns_lookup_by_name(ldns_algorithms, str);
00768 st = LDNS_STATUS_OK;
00769
00770 if (lt) {
00771
00772 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00773 if (!*rd) {
00774 st = LDNS_STATUS_ERR;
00775 }
00776 } else {
00777
00778 st = ldns_str2rdf_int8(rd, str);
00779 }
00780 return st;
00781 }
00782
00783 ldns_status
00784 ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf **rd)
00785 , ATTR_UNUSED(const char *str)
00786 )
00787 {
00788
00789
00790 return LDNS_STATUS_NOT_IMPL;
00791 }
00792
00793 ldns_status
00794 ldns_str2rdf_tsig( ATTR_UNUSED(ldns_rdf **rd)
00795 , ATTR_UNUSED(const char *str)
00796 )
00797 {
00798
00799 return LDNS_STATUS_NOT_IMPL;
00800 }
00801
00802 ldns_status
00803 ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf **rd)
00804 , ATTR_UNUSED(const char *str)
00805 )
00806 {
00807
00808 return LDNS_STATUS_NOT_IMPL;
00809 }
00810
00811 static int
00812 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00813 {
00814
00815
00816 uint32_t meters = 0, cm = 0, val;
00817 while (isblank(*my_str)) {
00818 my_str++;
00819 }
00820 meters = (uint32_t)strtol(my_str, &my_str, 10);
00821 if (*my_str == '.') {
00822 my_str++;
00823 cm = (uint32_t)strtol(my_str, &my_str, 10);
00824 }
00825 if (meters >= 1) {
00826 *e = 2;
00827 val = meters;
00828 } else {
00829 *e = 0;
00830 val = cm;
00831 }
00832 while(val >= 10) {
00833 (*e)++;
00834 val /= 10;
00835 }
00836 *m = (uint8_t)val;
00837
00838 if (*e > 9)
00839 return 0;
00840 if (*my_str == 'm' || *my_str == 'M') {
00841 my_str++;
00842 }
00843 *endstr = my_str;
00844 return 1;
00845 }
00846
00847 ldns_status
00848 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00849 {
00850 uint32_t latitude = 0;
00851 uint32_t longitude = 0;
00852 uint32_t altitude = 0;
00853
00854 uint8_t *data;
00855 uint32_t equator = (uint32_t) ldns_power(2, 31);
00856
00857 uint32_t h = 0;
00858 uint32_t m = 0;
00859 uint8_t size_b = 1, size_e = 2;
00860 uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00861 uint8_t vert_pre_b = 1, vert_pre_e = 3;
00862
00863 double s = 0.0;
00864 bool northerness;
00865 bool easterness;
00866
00867 char *my_str = (char *) str;
00868
00869
00870 if (isdigit((int) *my_str)) {
00871 h = (uint32_t) strtol(my_str, &my_str, 10);
00872 } else {
00873 return LDNS_STATUS_INVALID_STR;
00874 }
00875
00876 while (isblank((int) *my_str)) {
00877 my_str++;
00878 }
00879
00880 if (isdigit((int) *my_str)) {
00881 m = (uint32_t) strtol(my_str, &my_str, 10);
00882 } else if (*my_str == 'N' || *my_str == 'S') {
00883 goto north;
00884 } else {
00885 return LDNS_STATUS_INVALID_STR;
00886 }
00887
00888 while (isblank((int) *my_str)) {
00889 my_str++;
00890 }
00891
00892 if (isdigit((int) *my_str)) {
00893 s = strtod(my_str, &my_str);
00894 }
00895 north:
00896 while (isblank((int) *my_str)) {
00897 my_str++;
00898 }
00899
00900 if (*my_str == 'N') {
00901 northerness = true;
00902 } else if (*my_str == 'S') {
00903 northerness = false;
00904 } else {
00905 return LDNS_STATUS_INVALID_STR;
00906 }
00907
00908 my_str++;
00909
00910
00911 s = 1000.0 * s;
00912
00913 s += 0.0005;
00914 latitude = (uint32_t) s;
00915 latitude += 1000 * 60 * m;
00916 latitude += 1000 * 60 * 60 * h;
00917 if (northerness) {
00918 latitude = equator + latitude;
00919 } else {
00920 latitude = equator - latitude;
00921 }
00922 while (isblank(*my_str)) {
00923 my_str++;
00924 }
00925
00926 if (isdigit((int) *my_str)) {
00927 h = (uint32_t) strtol(my_str, &my_str, 10);
00928 } else {
00929 return LDNS_STATUS_INVALID_STR;
00930 }
00931
00932 while (isblank((int) *my_str)) {
00933 my_str++;
00934 }
00935
00936 if (isdigit((int) *my_str)) {
00937 m = (uint32_t) strtol(my_str, &my_str, 10);
00938 } else if (*my_str == 'E' || *my_str == 'W') {
00939 goto east;
00940 } else {
00941 return LDNS_STATUS_INVALID_STR;
00942 }
00943
00944 while (isblank(*my_str)) {
00945 my_str++;
00946 }
00947
00948 if (isdigit((int) *my_str)) {
00949 s = strtod(my_str, &my_str);
00950 }
00951
00952 east:
00953 while (isblank(*my_str)) {
00954 my_str++;
00955 }
00956
00957 if (*my_str == 'E') {
00958 easterness = true;
00959 } else if (*my_str == 'W') {
00960 easterness = false;
00961 } else {
00962 return LDNS_STATUS_INVALID_STR;
00963 }
00964
00965 my_str++;
00966
00967
00968 s *= 1000.0;
00969
00970 s += 0.0005;
00971 longitude = (uint32_t) s;
00972 longitude += 1000 * 60 * m;
00973 longitude += 1000 * 60 * 60 * h;
00974
00975 if (easterness) {
00976 longitude += equator;
00977 } else {
00978 longitude = equator - longitude;
00979 }
00980
00981 altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00982 10000000.0 + 0.5);
00983 if (*my_str == 'm' || *my_str == 'M') {
00984 my_str++;
00985 }
00986
00987 if (strlen(my_str) > 0) {
00988 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00989 return LDNS_STATUS_INVALID_STR;
00990 }
00991
00992 if (strlen(my_str) > 0) {
00993 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00994 return LDNS_STATUS_INVALID_STR;
00995 }
00996
00997 if (strlen(my_str) > 0) {
00998 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00999 return LDNS_STATUS_INVALID_STR;
01000 }
01001
01002 data = LDNS_XMALLOC(uint8_t, 16);
01003 if(!data) {
01004 return LDNS_STATUS_MEM_ERR;
01005 }
01006 data[0] = 0;
01007 data[1] = 0;
01008 data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
01009 data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
01010 data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
01011 ldns_write_uint32(data + 4, latitude);
01012 ldns_write_uint32(data + 8, longitude);
01013 ldns_write_uint32(data + 12, altitude);
01014
01015 *rd = ldns_rdf_new_frm_data(
01016 LDNS_RDF_TYPE_LOC, 16, data);
01017
01018 LDNS_FREE(data);
01019 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
01020 }
01021
01022 ldns_status
01023 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
01024 {
01025 uint8_t *bitmap = NULL;
01026 uint8_t *data;
01027 int bm_len = 0;
01028
01029 struct protoent *proto = NULL;
01030 struct servent *serv = NULL;
01031 int serv_port;
01032
01033 ldns_buffer *str_buf;
01034
01035 char *proto_str = NULL;
01036 char *token;
01037 if(strlen(str) == 0)
01038 token = LDNS_XMALLOC(char, 50);
01039 else token = LDNS_XMALLOC(char, strlen(str)+2);
01040 if(!token) return LDNS_STATUS_MEM_ERR;
01041
01042 str_buf = LDNS_MALLOC(ldns_buffer);
01043 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01044 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01045 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01046 LDNS_FREE(str_buf);
01047 LDNS_FREE(token);
01048 return LDNS_STATUS_MEM_ERR;
01049 }
01050
01051 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01052 if (!proto_str) {
01053 proto_str = strdup(token);
01054 if (!proto_str) {
01055 LDNS_FREE(bitmap);
01056 LDNS_FREE(token);
01057 ldns_buffer_free(str_buf);
01058 return LDNS_STATUS_INVALID_STR;
01059 }
01060 } else {
01061 serv = getservbyname(token, proto_str);
01062 if (serv) {
01063 serv_port = (int) ntohs((uint16_t) serv->s_port);
01064 } else {
01065 serv_port = atoi(token);
01066 }
01067 if (serv_port / 8 >= bm_len) {
01068 uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
01069 if(!b2) {
01070 LDNS_FREE(bitmap);
01071 LDNS_FREE(token);
01072 ldns_buffer_free(str_buf);
01073 free(proto_str);
01074 return LDNS_STATUS_INVALID_STR;
01075 }
01076 bitmap = b2;
01077
01078 for (; bm_len <= serv_port / 8; bm_len++) {
01079 bitmap[bm_len] = 0;
01080 }
01081 }
01082 ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
01083 }
01084 }
01085
01086 if (!proto_str || !bitmap) {
01087 LDNS_FREE(bitmap);
01088 LDNS_FREE(token);
01089 ldns_buffer_free(str_buf);
01090 free(proto_str);
01091 return LDNS_STATUS_INVALID_STR;
01092 }
01093
01094 data = LDNS_XMALLOC(uint8_t, bm_len + 1);
01095 if(!data) {
01096 LDNS_FREE(token);
01097 ldns_buffer_free(str_buf);
01098 LDNS_FREE(bitmap);
01099 free(proto_str);
01100 return LDNS_STATUS_INVALID_STR;
01101 }
01102 if (proto_str)
01103 proto = getprotobyname(proto_str);
01104 if (proto) {
01105 data[0] = (uint8_t) proto->p_proto;
01106 } else if (proto_str) {
01107 data[0] = (uint8_t) atoi(proto_str);
01108 }
01109 memcpy(data + 1, bitmap, (size_t) bm_len);
01110
01111 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
01112
01113 LDNS_FREE(data);
01114 LDNS_FREE(token);
01115 ldns_buffer_free(str_buf);
01116 LDNS_FREE(bitmap);
01117 free(proto_str);
01118 #ifdef HAVE_ENDSERVENT
01119 endservent();
01120 #endif
01121 #ifdef HAVE_ENDPROTOENT
01122 endprotoent();
01123 #endif
01124
01125 if(!*rd) return LDNS_STATUS_MEM_ERR;
01126
01127 return LDNS_STATUS_OK;
01128 }
01129
01130 ldns_status
01131 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01132 {
01133 size_t len, i;
01134 char* nsap_str = (char*) str;
01135
01136
01137 if (str[0] != '0' || str[1] != 'x') {
01138 return LDNS_STATUS_INVALID_STR;
01139 } else {
01140 len = strlen(str);
01141 for (i=0; i < len; i++) {
01142 if (nsap_str[i] == '.')
01143 nsap_str[i] = ' ';
01144 }
01145 return ldns_str2rdf_hex(rd, str+2);
01146 }
01147 }
01148
01149 ldns_status
01150 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
01151 {
01152 size_t len, i;
01153 char* atma_str = (char*) str;
01154 ldns_status status;
01155
01156
01157 len = strlen(str);
01158 for (i=0; i < len; i++) {
01159 if (atma_str[i] == '.')
01160 atma_str[i] = ' ';
01161 }
01162 status = ldns_str2rdf_hex(rd, str);
01163 if (status != LDNS_STATUS_OK) {
01164 ;
01165 }
01166 return status;
01167 }
01168
01169 ldns_status
01170 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
01171 {
01172 uint8_t precedence = 0;
01173 uint8_t gateway_type = 0;
01174 uint8_t algorithm = 0;
01175 char* gateway = NULL;
01176 char* publickey = NULL;
01177 uint8_t *data;
01178 ldns_buffer *str_buf;
01179 char *token;
01180 int token_count = 0;
01181 int ipseckey_len = 0;
01182 ldns_rdf* gateway_rdf = NULL;
01183 ldns_rdf* publickey_rdf = NULL;
01184 ldns_status status = LDNS_STATUS_OK;
01185
01186 if(strlen(str) == 0)
01187 token = LDNS_XMALLOC(char, 256);
01188 else token = LDNS_XMALLOC(char, strlen(str)+2);
01189 if(!token) return LDNS_STATUS_MEM_ERR;
01190
01191 str_buf = LDNS_MALLOC(ldns_buffer);
01192 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01193 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01194 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01195 LDNS_FREE(str_buf);
01196 LDNS_FREE(token);
01197 return LDNS_STATUS_MEM_ERR;
01198 }
01199 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01200 switch (token_count) {
01201 case 0:
01202 precedence = (uint8_t)atoi(token);
01203 break;
01204 case 1:
01205 gateway_type = (uint8_t)atoi(token);
01206 break;
01207 case 2:
01208 algorithm = (uint8_t)atoi(token);
01209 break;
01210 case 3:
01211 gateway = strdup(token);
01212 if (!gateway || (gateway_type == 0 &&
01213 (token[0] != '.' || token[1] != '\0'))) {
01214 LDNS_FREE(gateway);
01215 LDNS_FREE(token);
01216 ldns_buffer_free(str_buf);
01217 return LDNS_STATUS_INVALID_STR;
01218 }
01219 break;
01220 case 4:
01221 publickey = strdup(token);
01222 break;
01223 default:
01224 LDNS_FREE(token);
01225 ldns_buffer_free(str_buf);
01226 return LDNS_STATUS_INVALID_STR;
01227 break;
01228 }
01229 token_count++;
01230 }
01231
01232 if (!gateway || !publickey) {
01233 if (gateway)
01234 LDNS_FREE(gateway);
01235 if (publickey)
01236 LDNS_FREE(publickey);
01237 LDNS_FREE(token);
01238 ldns_buffer_free(str_buf);
01239 return LDNS_STATUS_INVALID_STR;
01240 }
01241
01242 if (gateway_type == 1) {
01243 status = ldns_str2rdf_a(&gateway_rdf, gateway);
01244 } else if (gateway_type == 2) {
01245 status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
01246 } else if (gateway_type == 3) {
01247 status = ldns_str2rdf_dname(&gateway_rdf, gateway);
01248 }
01249
01250 if (status != LDNS_STATUS_OK) {
01251 if (gateway)
01252 LDNS_FREE(gateway);
01253 if (publickey)
01254 LDNS_FREE(publickey);
01255 LDNS_FREE(token);
01256 ldns_buffer_free(str_buf);
01257 return LDNS_STATUS_INVALID_STR;
01258 }
01259
01260 status = ldns_str2rdf_b64(&publickey_rdf, publickey);
01261
01262 if (status != LDNS_STATUS_OK) {
01263 if (gateway)
01264 LDNS_FREE(gateway);
01265 if (publickey)
01266 LDNS_FREE(publickey);
01267 LDNS_FREE(token);
01268 ldns_buffer_free(str_buf);
01269 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01270 return LDNS_STATUS_INVALID_STR;
01271 }
01272
01273
01274 if (gateway_type)
01275 ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
01276 else
01277 ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
01278
01279 data = LDNS_XMALLOC(uint8_t, ipseckey_len);
01280 if(!data) {
01281 if (gateway)
01282 LDNS_FREE(gateway);
01283 if (publickey)
01284 LDNS_FREE(publickey);
01285 LDNS_FREE(token);
01286 ldns_buffer_free(str_buf);
01287 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01288 if (publickey_rdf) ldns_rdf_free(publickey_rdf);
01289 return LDNS_STATUS_MEM_ERR;
01290 }
01291
01292 data[0] = precedence;
01293 data[1] = gateway_type;
01294 data[2] = algorithm;
01295
01296 if (gateway_type) {
01297 memcpy(data + 3,
01298 ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
01299 memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
01300 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01301 } else {
01302 memcpy(data + 3,
01303 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01304 }
01305
01306 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
01307
01308 if (gateway)
01309 LDNS_FREE(gateway);
01310 if (publickey)
01311 LDNS_FREE(publickey);
01312 LDNS_FREE(token);
01313 ldns_buffer_free(str_buf);
01314 ldns_rdf_free(gateway_rdf);
01315 ldns_rdf_free(publickey_rdf);
01316 LDNS_FREE(data);
01317 if(!*rd) return LDNS_STATUS_MEM_ERR;
01318 return LDNS_STATUS_OK;
01319 }