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(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(my_ip_str);
00538 return LDNS_STATUS_INVALID_STR;
00539 }
00540 ldns_write_uint16(data, family);
00541 data[2] = prefix;
00542 data[3] = afdlength;
00543 if (negation) {
00544
00545 data[3] = data[3] | 0x80;
00546 }
00547
00548 memcpy(data + 4, afdpart, afdlength);
00549
00550 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00551 LDNS_FREE(afdpart);
00552 LDNS_FREE(data);
00553 LDNS_FREE(my_ip_str);
00554
00555 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00556 }
00557
00558 ldns_status
00559 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00560 {
00561 uint8_t *buffer;
00562 int16_t i;
00563
00564 buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
00565 if(!buffer) {
00566 return LDNS_STATUS_MEM_ERR;
00567 }
00568
00569 i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
00570 ldns_b64_ntop_calculate_size(strlen(str)));
00571 if (-1 == i) {
00572 LDNS_FREE(buffer);
00573 return LDNS_STATUS_INVALID_B64;
00574 } else {
00575 *rd = ldns_rdf_new_frm_data(
00576 LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00577 }
00578 LDNS_FREE(buffer);
00579
00580 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00581 }
00582
00583 ldns_status
00584 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00585 {
00586 uint8_t *buffer;
00587 int i;
00588
00589 uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
00590 buffer = LDNS_XMALLOC(uint8_t, len + 1);
00591 if(!buffer) {
00592 return LDNS_STATUS_MEM_ERR;
00593 }
00594 buffer[0] = len;
00595
00596 i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00597 ldns_b32_ntop_calculate_size(strlen(str)));
00598 if (i < 0) {
00599 LDNS_FREE(buffer);
00600 return LDNS_STATUS_INVALID_B32_EXT;
00601 } else {
00602 *rd = ldns_rdf_new_frm_data(
00603 LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00604 }
00605 LDNS_FREE(buffer);
00606
00607 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00608 }
00609
00610 ldns_status
00611 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00612 {
00613 uint8_t *t, *t_orig;
00614 int i;
00615 size_t len;
00616
00617 len = strlen(str);
00618
00619 if (len > LDNS_MAX_RDFLEN * 2) {
00620 return LDNS_STATUS_LABEL_OVERFLOW;
00621 } else {
00622 t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
00623 if(!t) {
00624 return LDNS_STATUS_MEM_ERR;
00625 }
00626 t_orig = t;
00627
00628 while (*str) {
00629 *t = 0;
00630 if (isspace((int) *str)) {
00631 str++;
00632 } else {
00633 for (i = 16; i >= 1; i -= 15) {
00634 while (*str && isspace((int) *str)) { str++; }
00635 if (*str) {
00636 if (isxdigit((int) *str)) {
00637 *t += ldns_hexdigit_to_int(*str) * i;
00638 } else {
00639 LDNS_FREE(t_orig);
00640 return LDNS_STATUS_ERR;
00641 }
00642 ++str;
00643 }
00644 }
00645 ++t;
00646 }
00647 }
00648 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
00649 (size_t) (t - t_orig),
00650 t_orig);
00651 LDNS_FREE(t_orig);
00652 }
00653 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00654 }
00655
00656 ldns_status
00657 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00658 {
00659 const char *delimiters = "\n\t ";
00660 char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00661 ldns_buffer *str_buf;
00662 ssize_t c;
00663 uint16_t cur_type;
00664 size_t type_count = 0;
00665 ldns_rr_type type_list[65536];
00666 if(!token) return LDNS_STATUS_MEM_ERR;
00667 if(rd == NULL) {
00668 LDNS_FREE(token);
00669 return LDNS_STATUS_NULL;
00670 }
00671
00672 str_buf = LDNS_MALLOC(ldns_buffer);
00673 if(!str_buf) {
00674 LDNS_FREE(token);
00675 return LDNS_STATUS_MEM_ERR;
00676 }
00677 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00678 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
00679 LDNS_FREE(str_buf);
00680 LDNS_FREE(token);
00681 return LDNS_STATUS_MEM_ERR;
00682 }
00683
00684 while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
00685 if(type_count >= sizeof(type_list)) {
00686 LDNS_FREE(str_buf);
00687 LDNS_FREE(token);
00688 return LDNS_STATUS_ERR;
00689 }
00690 cur_type = ldns_get_rr_type_by_name(token);
00691 type_list[type_count] = cur_type;
00692 type_count++;
00693 }
00694
00695 *rd = ldns_dnssec_create_nsec_bitmap(type_list,
00696 type_count,
00697 LDNS_RR_TYPE_NSEC);
00698
00699 LDNS_FREE(token);
00700 ldns_buffer_free(str_buf);
00701 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00702 }
00703
00704 ldns_status
00705 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00706 {
00707 uint16_t type;
00708 type = htons(ldns_get_rr_type_by_name(str));
00709
00710 *rd = ldns_rdf_new_frm_data(
00711 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00712 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00713 }
00714
00715 ldns_status
00716 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00717 {
00718 uint16_t klass;
00719 klass = htons(ldns_get_rr_class_by_name(str));
00720
00721 *rd = ldns_rdf_new_frm_data(
00722 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00723 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00724 }
00725
00726
00727
00728
00729 ldns_status
00730 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00731 {
00732 ldns_lookup_table *lt;
00733 ldns_status st;
00734 uint8_t idd[2];
00735 lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00736 st = LDNS_STATUS_OK;
00737
00738 if (lt) {
00739 ldns_write_uint16(idd, (uint16_t) lt->id);
00740 *rd = ldns_rdf_new_frm_data(
00741 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00742 if (!*rd) {
00743 st = LDNS_STATUS_ERR;
00744 }
00745 } else {
00746
00747 st = ldns_str2rdf_int16(rd, str);
00748 if (st == LDNS_STATUS_OK &&
00749 ldns_rdf2native_int16(*rd) == 0) {
00750 st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00751 }
00752 }
00753
00754 return st;
00755 }
00756
00757
00758
00759
00760 ldns_status
00761 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00762 {
00763 ldns_lookup_table *lt;
00764 ldns_status st;
00765
00766 lt = ldns_lookup_by_name(ldns_algorithms, str);
00767 st = LDNS_STATUS_OK;
00768
00769 if (lt) {
00770
00771 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00772 if (!*rd) {
00773 st = LDNS_STATUS_ERR;
00774 }
00775 } else {
00776
00777 st = ldns_str2rdf_int8(rd, str);
00778 }
00779 return st;
00780 }
00781
00782 ldns_status
00783 ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf **rd)
00784 , ATTR_UNUSED(const char *str)
00785 )
00786 {
00787
00788
00789 return LDNS_STATUS_NOT_IMPL;
00790 }
00791
00792 ldns_status
00793 ldns_str2rdf_tsig( ATTR_UNUSED(ldns_rdf **rd)
00794 , ATTR_UNUSED(const char *str)
00795 )
00796 {
00797
00798 return LDNS_STATUS_NOT_IMPL;
00799 }
00800
00801 ldns_status
00802 ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf **rd)
00803 , ATTR_UNUSED(const char *str)
00804 )
00805 {
00806
00807 return LDNS_STATUS_NOT_IMPL;
00808 }
00809
00810 static int
00811 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00812 {
00813
00814
00815 uint32_t meters = 0, cm = 0, val;
00816 while (isblank(*my_str)) {
00817 my_str++;
00818 }
00819 meters = (uint32_t)strtol(my_str, &my_str, 10);
00820 if (*my_str == '.') {
00821 my_str++;
00822 cm = (uint32_t)strtol(my_str, &my_str, 10);
00823 }
00824 if (meters >= 1) {
00825 *e = 2;
00826 val = meters;
00827 } else {
00828 *e = 0;
00829 val = cm;
00830 }
00831 while(val >= 10) {
00832 (*e)++;
00833 val /= 10;
00834 }
00835 *m = (uint8_t)val;
00836
00837 if (*e > 9)
00838 return 0;
00839 if (*my_str == 'm' || *my_str == 'M') {
00840 my_str++;
00841 }
00842 *endstr = my_str;
00843 return 1;
00844 }
00845
00846 ldns_status
00847 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00848 {
00849 uint32_t latitude = 0;
00850 uint32_t longitude = 0;
00851 uint32_t altitude = 0;
00852
00853 uint8_t *data;
00854 uint32_t equator = (uint32_t) ldns_power(2, 31);
00855
00856 uint32_t h = 0;
00857 uint32_t m = 0;
00858 uint8_t size_b = 1, size_e = 2;
00859 uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00860 uint8_t vert_pre_b = 1, vert_pre_e = 3;
00861
00862 double s = 0.0;
00863 bool northerness;
00864 bool easterness;
00865
00866 char *my_str = (char *) str;
00867
00868
00869 if (isdigit((int) *my_str)) {
00870 h = (uint32_t) strtol(my_str, &my_str, 10);
00871 } else {
00872 return LDNS_STATUS_INVALID_STR;
00873 }
00874
00875 while (isblank((int) *my_str)) {
00876 my_str++;
00877 }
00878
00879 if (isdigit((int) *my_str)) {
00880 m = (uint32_t) strtol(my_str, &my_str, 10);
00881 } else if (*my_str == 'N' || *my_str == 'S') {
00882 goto north;
00883 } else {
00884 return LDNS_STATUS_INVALID_STR;
00885 }
00886
00887 while (isblank((int) *my_str)) {
00888 my_str++;
00889 }
00890
00891 if (isdigit((int) *my_str)) {
00892 s = strtod(my_str, &my_str);
00893 }
00894 north:
00895 while (isblank((int) *my_str)) {
00896 my_str++;
00897 }
00898
00899 if (*my_str == 'N') {
00900 northerness = true;
00901 } else if (*my_str == 'S') {
00902 northerness = false;
00903 } else {
00904 return LDNS_STATUS_INVALID_STR;
00905 }
00906
00907 my_str++;
00908
00909
00910 s = 1000.0 * s;
00911
00912 s += 0.0005;
00913 latitude = (uint32_t) s;
00914 latitude += 1000 * 60 * m;
00915 latitude += 1000 * 60 * 60 * h;
00916 if (northerness) {
00917 latitude = equator + latitude;
00918 } else {
00919 latitude = equator - latitude;
00920 }
00921 while (isblank(*my_str)) {
00922 my_str++;
00923 }
00924
00925 if (isdigit((int) *my_str)) {
00926 h = (uint32_t) strtol(my_str, &my_str, 10);
00927 } else {
00928 return LDNS_STATUS_INVALID_STR;
00929 }
00930
00931 while (isblank((int) *my_str)) {
00932 my_str++;
00933 }
00934
00935 if (isdigit((int) *my_str)) {
00936 m = (uint32_t) strtol(my_str, &my_str, 10);
00937 } else if (*my_str == 'E' || *my_str == 'W') {
00938 goto east;
00939 } else {
00940 return LDNS_STATUS_INVALID_STR;
00941 }
00942
00943 while (isblank(*my_str)) {
00944 my_str++;
00945 }
00946
00947 if (isdigit((int) *my_str)) {
00948 s = strtod(my_str, &my_str);
00949 }
00950
00951 east:
00952 while (isblank(*my_str)) {
00953 my_str++;
00954 }
00955
00956 if (*my_str == 'E') {
00957 easterness = true;
00958 } else if (*my_str == 'W') {
00959 easterness = false;
00960 } else {
00961 return LDNS_STATUS_INVALID_STR;
00962 }
00963
00964 my_str++;
00965
00966
00967 s *= 1000.0;
00968
00969 s += 0.0005;
00970 longitude = (uint32_t) s;
00971 longitude += 1000 * 60 * m;
00972 longitude += 1000 * 60 * 60 * h;
00973
00974 if (easterness) {
00975 longitude += equator;
00976 } else {
00977 longitude = equator - longitude;
00978 }
00979
00980 altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00981 10000000.0 + 0.5);
00982 if (*my_str == 'm' || *my_str == 'M') {
00983 my_str++;
00984 }
00985
00986 if (strlen(my_str) > 0) {
00987 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00988 return LDNS_STATUS_INVALID_STR;
00989 }
00990
00991 if (strlen(my_str) > 0) {
00992 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00993 return LDNS_STATUS_INVALID_STR;
00994 }
00995
00996 if (strlen(my_str) > 0) {
00997 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00998 return LDNS_STATUS_INVALID_STR;
00999 }
01000
01001 data = LDNS_XMALLOC(uint8_t, 16);
01002 if(!data) {
01003 return LDNS_STATUS_MEM_ERR;
01004 }
01005 data[0] = 0;
01006 data[1] = 0;
01007 data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
01008 data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
01009 data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
01010 ldns_write_uint32(data + 4, latitude);
01011 ldns_write_uint32(data + 8, longitude);
01012 ldns_write_uint32(data + 12, altitude);
01013
01014 *rd = ldns_rdf_new_frm_data(
01015 LDNS_RDF_TYPE_LOC, 16, data);
01016
01017 LDNS_FREE(data);
01018 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
01019 }
01020
01021 ldns_status
01022 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
01023 {
01024 uint8_t *bitmap = NULL;
01025 uint8_t *data;
01026 int bm_len = 0;
01027
01028 struct protoent *proto = NULL;
01029 struct servent *serv = NULL;
01030 int serv_port;
01031
01032 ldns_buffer *str_buf;
01033
01034 char *proto_str = NULL;
01035 char *token;
01036 if(strlen(str) == 0)
01037 token = LDNS_XMALLOC(char, 50);
01038 else token = LDNS_XMALLOC(char, strlen(str)+2);
01039 if(!token) return LDNS_STATUS_MEM_ERR;
01040
01041 str_buf = LDNS_MALLOC(ldns_buffer);
01042 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01043 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01044 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01045 LDNS_FREE(str_buf);
01046 LDNS_FREE(token);
01047 return LDNS_STATUS_MEM_ERR;
01048 }
01049
01050 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01051 if (!proto_str) {
01052 proto_str = strdup(token);
01053 if (!proto_str) {
01054 LDNS_FREE(bitmap);
01055 LDNS_FREE(token);
01056 ldns_buffer_free(str_buf);
01057 return LDNS_STATUS_INVALID_STR;
01058 }
01059 } else {
01060 serv = getservbyname(token, proto_str);
01061 if (serv) {
01062 serv_port = (int) ntohs((uint16_t) serv->s_port);
01063 } else {
01064 serv_port = atoi(token);
01065 }
01066 if (serv_port / 8 >= bm_len) {
01067 uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
01068 if(!b2) {
01069 LDNS_FREE(bitmap);
01070 LDNS_FREE(token);
01071 ldns_buffer_free(str_buf);
01072 free(proto_str);
01073 return LDNS_STATUS_INVALID_STR;
01074 }
01075 bitmap = b2;
01076
01077 for (; bm_len <= serv_port / 8; bm_len++) {
01078 bitmap[bm_len] = 0;
01079 }
01080 }
01081 ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
01082 }
01083 }
01084
01085 if (!proto_str || !bitmap) {
01086 LDNS_FREE(bitmap);
01087 LDNS_FREE(token);
01088 ldns_buffer_free(str_buf);
01089 free(proto_str);
01090 return LDNS_STATUS_INVALID_STR;
01091 }
01092
01093 data = LDNS_XMALLOC(uint8_t, bm_len + 1);
01094 if(!data) {
01095 LDNS_FREE(token);
01096 ldns_buffer_free(str_buf);
01097 LDNS_FREE(bitmap);
01098 free(proto_str);
01099 return LDNS_STATUS_INVALID_STR;
01100 }
01101 if (proto_str)
01102 proto = getprotobyname(proto_str);
01103 if (proto) {
01104 data[0] = (uint8_t) proto->p_proto;
01105 } else if (proto_str) {
01106 data[0] = (uint8_t) atoi(proto_str);
01107 } else {
01108 data[0] = 0;
01109 }
01110 memcpy(data + 1, bitmap, (size_t) bm_len);
01111
01112 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
01113
01114 LDNS_FREE(data);
01115 LDNS_FREE(token);
01116 ldns_buffer_free(str_buf);
01117 LDNS_FREE(bitmap);
01118 free(proto_str);
01119 #ifdef HAVE_ENDSERVENT
01120 endservent();
01121 #endif
01122 #ifdef HAVE_ENDPROTOENT
01123 endprotoent();
01124 #endif
01125
01126 if(!*rd) return LDNS_STATUS_MEM_ERR;
01127
01128 return LDNS_STATUS_OK;
01129 }
01130
01131 ldns_status
01132 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01133 {
01134 size_t len, i;
01135 char* nsap_str = (char*) str;
01136
01137
01138 if (str[0] != '0' || str[1] != 'x') {
01139 return LDNS_STATUS_INVALID_STR;
01140 } else {
01141 len = strlen(str);
01142 for (i=0; i < len; i++) {
01143 if (nsap_str[i] == '.')
01144 nsap_str[i] = ' ';
01145 }
01146 return ldns_str2rdf_hex(rd, str+2);
01147 }
01148 }
01149
01150 ldns_status
01151 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
01152 {
01153 size_t len, i;
01154 char* atma_str = (char*) str;
01155 ldns_status status;
01156
01157
01158 len = strlen(str);
01159 for (i=0; i < len; i++) {
01160 if (atma_str[i] == '.')
01161 atma_str[i] = ' ';
01162 }
01163 status = ldns_str2rdf_hex(rd, str);
01164 if (status != LDNS_STATUS_OK) {
01165 ;
01166 }
01167 return status;
01168 }
01169
01170 ldns_status
01171 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
01172 {
01173 uint8_t precedence = 0;
01174 uint8_t gateway_type = 0;
01175 uint8_t algorithm = 0;
01176 char* gateway = NULL;
01177 char* publickey = NULL;
01178 uint8_t *data;
01179 ldns_buffer *str_buf;
01180 char *token;
01181 int token_count = 0;
01182 int ipseckey_len = 0;
01183 ldns_rdf* gateway_rdf = NULL;
01184 ldns_rdf* publickey_rdf = NULL;
01185 ldns_status status = LDNS_STATUS_OK;
01186
01187 if(strlen(str) == 0)
01188 token = LDNS_XMALLOC(char, 256);
01189 else token = LDNS_XMALLOC(char, strlen(str)+2);
01190 if(!token) return LDNS_STATUS_MEM_ERR;
01191
01192 str_buf = LDNS_MALLOC(ldns_buffer);
01193 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01194 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01195 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01196 LDNS_FREE(str_buf);
01197 LDNS_FREE(token);
01198 return LDNS_STATUS_MEM_ERR;
01199 }
01200 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01201 switch (token_count) {
01202 case 0:
01203 precedence = (uint8_t)atoi(token);
01204 break;
01205 case 1:
01206 gateway_type = (uint8_t)atoi(token);
01207 break;
01208 case 2:
01209 algorithm = (uint8_t)atoi(token);
01210 break;
01211 case 3:
01212 gateway = strdup(token);
01213 if (!gateway || (gateway_type == 0 &&
01214 (token[0] != '.' || token[1] != '\0'))) {
01215 LDNS_FREE(gateway);
01216 LDNS_FREE(token);
01217 ldns_buffer_free(str_buf);
01218 return LDNS_STATUS_INVALID_STR;
01219 }
01220 break;
01221 case 4:
01222 publickey = strdup(token);
01223 break;
01224 default:
01225 LDNS_FREE(token);
01226 ldns_buffer_free(str_buf);
01227 return LDNS_STATUS_INVALID_STR;
01228 break;
01229 }
01230 token_count++;
01231 }
01232
01233 if (!gateway || !publickey) {
01234 if (gateway)
01235 LDNS_FREE(gateway);
01236 if (publickey)
01237 LDNS_FREE(publickey);
01238 LDNS_FREE(token);
01239 ldns_buffer_free(str_buf);
01240 return LDNS_STATUS_INVALID_STR;
01241 }
01242
01243 if (gateway_type == 1) {
01244 status = ldns_str2rdf_a(&gateway_rdf, gateway);
01245 } else if (gateway_type == 2) {
01246 status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
01247 } else if (gateway_type == 3) {
01248 status = ldns_str2rdf_dname(&gateway_rdf, gateway);
01249 }
01250
01251 if (status != LDNS_STATUS_OK) {
01252 if (gateway)
01253 LDNS_FREE(gateway);
01254 if (publickey)
01255 LDNS_FREE(publickey);
01256 LDNS_FREE(token);
01257 ldns_buffer_free(str_buf);
01258 return LDNS_STATUS_INVALID_STR;
01259 }
01260
01261 status = ldns_str2rdf_b64(&publickey_rdf, publickey);
01262
01263 if (status != LDNS_STATUS_OK) {
01264 if (gateway)
01265 LDNS_FREE(gateway);
01266 if (publickey)
01267 LDNS_FREE(publickey);
01268 LDNS_FREE(token);
01269 ldns_buffer_free(str_buf);
01270 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01271 return LDNS_STATUS_INVALID_STR;
01272 }
01273
01274
01275 if (gateway_type)
01276 ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
01277 else
01278 ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
01279
01280 data = LDNS_XMALLOC(uint8_t, ipseckey_len);
01281 if(!data) {
01282 if (gateway)
01283 LDNS_FREE(gateway);
01284 if (publickey)
01285 LDNS_FREE(publickey);
01286 LDNS_FREE(token);
01287 ldns_buffer_free(str_buf);
01288 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01289 if (publickey_rdf) ldns_rdf_free(publickey_rdf);
01290 return LDNS_STATUS_MEM_ERR;
01291 }
01292
01293 data[0] = precedence;
01294 data[1] = gateway_type;
01295 data[2] = algorithm;
01296
01297 if (gateway_type) {
01298 memcpy(data + 3,
01299 ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
01300 memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
01301 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01302 } else {
01303 memcpy(data + 3,
01304 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01305 }
01306
01307 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
01308
01309 if (gateway)
01310 LDNS_FREE(gateway);
01311 if (publickey)
01312 LDNS_FREE(publickey);
01313 LDNS_FREE(token);
01314 ldns_buffer_free(str_buf);
01315 ldns_rdf_free(gateway_rdf);
01316 ldns_rdf_free(publickey_rdf);
01317 LDNS_FREE(data);
01318 if(!*rd) return LDNS_STATUS_MEM_ERR;
01319 return LDNS_STATUS_OK;
01320 }