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 uint8_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 = (uint8_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 *q = val;
00272 return 3;
00273 } else {
00274 s++;
00275 if (*s == '\0' || isdigit((int) *s)) {
00276
00277
00278
00279 return 0;
00280 }
00281 *q = *s;
00282 return 1;
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291 ldns_status
00292 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
00293 {
00294 size_t len;
00295
00296 int esc;
00297 uint8_t *s, *q, *pq, label_len;
00298 uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
00299 *d = NULL;
00300
00301 len = strlen((char*)str);
00302
00303 if (len > LDNS_MAX_DOMAINLEN * 4) {
00304 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00305 }
00306 if (0 == len) {
00307 return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
00308 }
00309
00310
00311 if (1 == len && *str == '.') {
00312 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
00313 return LDNS_STATUS_OK;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323 len = 0;
00324 q = buf+1;
00325 pq = buf;
00326 label_len = 0;
00327 for (s = (uint8_t *)str; *s; s++, q++) {
00328 if (q > buf + LDNS_MAX_DOMAINLEN) {
00329 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00330 }
00331 *q = 0;
00332 switch (*s) {
00333 case '.':
00334 if (label_len > LDNS_MAX_LABELLEN) {
00335 return LDNS_STATUS_LABEL_OVERFLOW;
00336 }
00337 if (label_len == 0) {
00338 return LDNS_STATUS_EMPTY_LABEL;
00339 }
00340 len += label_len + 1;
00341 *pq = label_len;
00342 label_len = 0;
00343 pq = q;
00344 break;
00345 case '\\':
00346
00347 esc = parse_escape(s, q);
00348 if (esc > 0) {
00349 s += esc;
00350 label_len++;
00351 } else {
00352 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00353 }
00354 break;
00355 default:
00356 *q = *s;
00357 label_len++;
00358 }
00359 }
00360
00361
00362 if (!ldns_dname_str_absolute(str)) {
00363 if (q > buf + LDNS_MAX_DOMAINLEN) {
00364 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00365 }
00366 if (label_len > LDNS_MAX_LABELLEN) {
00367 return LDNS_STATUS_LABEL_OVERFLOW;
00368 }
00369 if (label_len == 0) {
00370 return LDNS_STATUS_EMPTY_LABEL;
00371 }
00372 len += label_len + 1;
00373 *pq = label_len;
00374 *q = 0;
00375 }
00376 len++;
00377
00378 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
00379 return LDNS_STATUS_OK;
00380 }
00381
00382 ldns_status
00383 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
00384 {
00385 in_addr_t address;
00386 if (inet_pton(AF_INET, (char*)str, &address) != 1) {
00387 return LDNS_STATUS_INVALID_IP4;
00388 } else {
00389 *rd = ldns_rdf_new_frm_data(
00390 LDNS_RDF_TYPE_A, sizeof(address), &address);
00391 }
00392 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00393 }
00394
00395 ldns_status
00396 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
00397 {
00398 uint8_t address[LDNS_IP6ADDRLEN + 1];
00399
00400 if (inet_pton(AF_INET6, (char*)str, address) != 1) {
00401 return LDNS_STATUS_INVALID_IP6;
00402 } else {
00403 *rd = ldns_rdf_new_frm_data(
00404 LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
00405 }
00406 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00407 }
00408
00409 ldns_status
00410 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
00411 {
00412 uint8_t *data;
00413 size_t i, str_i, esc_i;
00414
00415 if (strlen(str) > 255) {
00416 return LDNS_STATUS_INVALID_STR;
00417 }
00418
00419 data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
00420 if(!data) return LDNS_STATUS_MEM_ERR;
00421 i = 1;
00422
00423 for (str_i = 0; str_i < strlen(str); str_i++) {
00424 if (str[str_i] == '\\') {
00425
00426 esc_i = (size_t) parse_escape((uint8_t*) &str[str_i], (uint8_t*) &data[i]);
00427 if (esc_i == 0) {
00428 LDNS_FREE(data);
00429 return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
00430 }
00431 str_i += esc_i;
00432 } else {
00433 data[i] = (uint8_t) str[str_i];
00434 }
00435 i++;
00436 }
00437 data[0] = i - 1;
00438 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
00439
00440 LDNS_FREE(data);
00441 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00442 }
00443
00444 ldns_status
00445 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
00446 {
00447 const char *my_str = str;
00448
00449 char *my_ip_str;
00450 size_t ip_str_len;
00451
00452 uint16_t family;
00453 bool negation;
00454 uint8_t afdlength = 0;
00455 uint8_t *afdpart;
00456 uint8_t prefix;
00457
00458 uint8_t *data;
00459
00460 size_t i = 0;
00461
00462
00463 if (strlen(my_str) < 2
00464 || strchr(my_str, ':') == NULL
00465 || strchr(my_str, '/') == NULL
00466 || strchr(my_str, ':') > strchr(my_str, '/')) {
00467 return LDNS_STATUS_INVALID_STR;
00468 }
00469
00470 if (my_str[0] == '!') {
00471 negation = true;
00472 my_str += 1;
00473 } else {
00474 negation = false;
00475 }
00476
00477 family = (uint16_t) atoi(my_str);
00478
00479 my_str = strchr(my_str, ':') + 1;
00480
00481
00482 ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
00483 my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
00484 if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
00485 strncpy(my_ip_str, my_str, ip_str_len + 1);
00486 my_ip_str[ip_str_len] = '\0';
00487
00488 if (family == 1) {
00489
00490 afdpart = LDNS_XMALLOC(uint8_t, 4);
00491 if(!afdpart) {
00492 LDNS_FREE(my_ip_str);
00493 return LDNS_STATUS_MEM_ERR;
00494 }
00495 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
00496 LDNS_FREE(my_ip_str);
00497 LDNS_FREE(afdpart);
00498 return LDNS_STATUS_INVALID_STR;
00499 }
00500 for (i = 0; i < 4; i++) {
00501 if (afdpart[i] != 0) {
00502 afdlength = i + 1;
00503 }
00504 }
00505 } else if (family == 2) {
00506
00507 afdpart = LDNS_XMALLOC(uint8_t, 16);
00508 if(!afdpart) {
00509 LDNS_FREE(my_ip_str);
00510 return LDNS_STATUS_MEM_ERR;
00511 }
00512 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
00513 LDNS_FREE(my_ip_str);
00514 LDNS_FREE(afdpart);
00515 return LDNS_STATUS_INVALID_STR;
00516 }
00517 for (i = 0; i < 16; i++) {
00518 if (afdpart[i] != 0) {
00519 afdlength = i + 1;
00520 }
00521 }
00522 } else {
00523
00524 LDNS_FREE(my_ip_str);
00525 return LDNS_STATUS_INVALID_STR;
00526 }
00527
00528 my_str = strchr(my_str, '/') + 1;
00529 prefix = (uint8_t) atoi(my_str);
00530
00531 data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
00532 if(!data) {
00533 LDNS_FREE(my_ip_str);
00534 return LDNS_STATUS_INVALID_STR;
00535 }
00536 ldns_write_uint16(data, family);
00537 data[2] = prefix;
00538 data[3] = afdlength;
00539 if (negation) {
00540
00541 data[3] = data[3] | 0x80;
00542 }
00543
00544 memcpy(data + 4, afdpart, afdlength);
00545
00546 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00547 LDNS_FREE(afdpart);
00548 LDNS_FREE(data);
00549 LDNS_FREE(my_ip_str);
00550
00551 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00552 }
00553
00554 ldns_status
00555 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00556 {
00557 uint8_t *buffer;
00558 int16_t i;
00559
00560 buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
00561 if(!buffer) {
00562 return LDNS_STATUS_MEM_ERR;
00563 }
00564
00565 i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
00566 ldns_b64_ntop_calculate_size(strlen(str)));
00567 if (-1 == i) {
00568 LDNS_FREE(buffer);
00569 return LDNS_STATUS_INVALID_B64;
00570 } else {
00571 *rd = ldns_rdf_new_frm_data(
00572 LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00573 }
00574 LDNS_FREE(buffer);
00575
00576 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00577 }
00578
00579 ldns_status
00580 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00581 {
00582 uint8_t *buffer;
00583 int i;
00584
00585 uint8_t len = ldns_b32_pton_calculate_size(strlen(str));
00586 buffer = LDNS_XMALLOC(uint8_t, len + 1);
00587 if(!buffer) {
00588 return LDNS_STATUS_MEM_ERR;
00589 }
00590 buffer[0] = len;
00591
00592 i = ldns_b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00593 ldns_b32_ntop_calculate_size(strlen(str)));
00594 if (i < 0) {
00595 LDNS_FREE(buffer);
00596 return LDNS_STATUS_INVALID_B32_EXT;
00597 } else {
00598 *rd = ldns_rdf_new_frm_data(
00599 LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00600 }
00601 LDNS_FREE(buffer);
00602
00603 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00604 }
00605
00606 ldns_status
00607 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00608 {
00609 uint8_t *t, *t_orig;
00610 int i;
00611 size_t len;
00612
00613 len = strlen(str);
00614
00615 if (len > LDNS_MAX_RDFLEN * 2) {
00616 return LDNS_STATUS_LABEL_OVERFLOW;
00617 } else {
00618 t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
00619 if(!t) {
00620 return LDNS_STATUS_MEM_ERR;
00621 }
00622 t_orig = t;
00623
00624 while (*str) {
00625 *t = 0;
00626 if (isspace((int) *str)) {
00627 str++;
00628 } else {
00629 for (i = 16; i >= 1; i -= 15) {
00630 while (*str && isspace((int) *str)) { str++; }
00631 if (*str) {
00632 if (isxdigit((int) *str)) {
00633 *t += ldns_hexdigit_to_int(*str) * i;
00634 } else {
00635 LDNS_FREE(t_orig);
00636 return LDNS_STATUS_ERR;
00637 }
00638 ++str;
00639 }
00640 }
00641 ++t;
00642 }
00643 }
00644 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX,
00645 (size_t) (t - t_orig),
00646 t_orig);
00647 LDNS_FREE(t_orig);
00648 }
00649 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00650 }
00651
00652 ldns_status
00653 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00654 {
00655 const char *delimiters = "\n\t ";
00656 char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00657 ldns_buffer *str_buf;
00658 ssize_t c;
00659 uint16_t cur_type;
00660 size_t type_count = 0;
00661 ldns_rr_type type_list[65536];
00662 if(!token) return LDNS_STATUS_MEM_ERR;
00663 if(rd == NULL) {
00664 LDNS_FREE(token);
00665 return LDNS_STATUS_NULL;
00666 }
00667
00668 str_buf = LDNS_MALLOC(ldns_buffer);
00669 if(!str_buf) {
00670 LDNS_FREE(token);
00671 return LDNS_STATUS_MEM_ERR;
00672 }
00673 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00674 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
00675 LDNS_FREE(str_buf);
00676 LDNS_FREE(token);
00677 return LDNS_STATUS_MEM_ERR;
00678 }
00679
00680 while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
00681 if(type_count >= sizeof(type_list)) {
00682 LDNS_FREE(str_buf);
00683 LDNS_FREE(token);
00684 return LDNS_STATUS_ERR;
00685 }
00686 cur_type = ldns_get_rr_type_by_name(token);
00687 type_list[type_count] = cur_type;
00688 type_count++;
00689 }
00690
00691 *rd = ldns_dnssec_create_nsec_bitmap(type_list,
00692 type_count,
00693 LDNS_RR_TYPE_NSEC);
00694
00695 LDNS_FREE(token);
00696 ldns_buffer_free(str_buf);
00697 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00698 }
00699
00700 ldns_status
00701 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00702 {
00703 uint16_t type;
00704 type = htons(ldns_get_rr_type_by_name(str));
00705
00706 *rd = ldns_rdf_new_frm_data(
00707 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00708 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00709 }
00710
00711 ldns_status
00712 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00713 {
00714 uint16_t klass;
00715 klass = htons(ldns_get_rr_class_by_name(str));
00716
00717 *rd = ldns_rdf_new_frm_data(
00718 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00719 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
00720 }
00721
00722
00723
00724
00725 ldns_status
00726 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00727 {
00728 ldns_lookup_table *lt;
00729 ldns_status st;
00730 uint8_t idd[2];
00731 lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00732 st = LDNS_STATUS_OK;
00733
00734 if (lt) {
00735 ldns_write_uint16(idd, (uint16_t) lt->id);
00736 *rd = ldns_rdf_new_frm_data(
00737 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00738 if (!*rd) {
00739 st = LDNS_STATUS_ERR;
00740 }
00741 } else {
00742
00743 st = ldns_str2rdf_int16(rd, str);
00744 if (st == LDNS_STATUS_OK &&
00745 ldns_rdf2native_int16(*rd) == 0) {
00746 st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00747 }
00748 }
00749
00750 return st;
00751 }
00752
00753
00754
00755
00756 ldns_status
00757 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00758 {
00759 ldns_lookup_table *lt;
00760 ldns_status st;
00761
00762 lt = ldns_lookup_by_name(ldns_algorithms, str);
00763 st = LDNS_STATUS_OK;
00764
00765 if (lt) {
00766
00767 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00768 if (!*rd) {
00769 st = LDNS_STATUS_ERR;
00770 }
00771 } else {
00772
00773 st = ldns_str2rdf_int8(rd, str);
00774 }
00775 return st;
00776 }
00777
00778 ldns_status
00779 ldns_str2rdf_unknown(ldns_rdf **rd, const char *str)
00780 {
00781
00782
00783 rd = rd;
00784 str = str;
00785 return LDNS_STATUS_NOT_IMPL;
00786 }
00787
00788 ldns_status
00789 ldns_str2rdf_tsig(ldns_rdf **rd, const char *str)
00790 {
00791
00792 rd = rd;
00793 str = str;
00794 return LDNS_STATUS_NOT_IMPL;
00795 }
00796
00797 ldns_status
00798 ldns_str2rdf_service(ldns_rdf **rd, const char *str)
00799 {
00800
00801 rd = rd;
00802 str = str;
00803 return LDNS_STATUS_NOT_IMPL;
00804 }
00805
00806 static int
00807 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00808 {
00809
00810
00811 uint32_t meters = 0, cm = 0, val;
00812 while (isblank(*my_str)) {
00813 my_str++;
00814 }
00815 meters = (uint32_t)strtol(my_str, &my_str, 10);
00816 if (*my_str == '.') {
00817 my_str++;
00818 cm = (uint32_t)strtol(my_str, &my_str, 10);
00819 }
00820 if (meters >= 1) {
00821 *e = 2;
00822 val = meters;
00823 } else {
00824 *e = 0;
00825 val = cm;
00826 }
00827 while(val >= 10) {
00828 (*e)++;
00829 val /= 10;
00830 }
00831 *m = (uint8_t)val;
00832
00833 if (*e > 9)
00834 return 0;
00835 if (*my_str == 'm' || *my_str == 'M') {
00836 my_str++;
00837 }
00838 *endstr = my_str;
00839 return 1;
00840 }
00841
00842 ldns_status
00843 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00844 {
00845 uint32_t latitude = 0;
00846 uint32_t longitude = 0;
00847 uint32_t altitude = 0;
00848
00849 uint8_t *data;
00850 uint32_t equator = (uint32_t) ldns_power(2, 31);
00851
00852 uint32_t h = 0;
00853 uint32_t m = 0;
00854 uint8_t size_b = 1, size_e = 2;
00855 uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00856 uint8_t vert_pre_b = 1, vert_pre_e = 3;
00857
00858 double s = 0.0;
00859 bool northerness;
00860 bool easterness;
00861
00862 char *my_str = (char *) str;
00863
00864
00865 if (isdigit((int) *my_str)) {
00866 h = (uint32_t) strtol(my_str, &my_str, 10);
00867 } else {
00868 return LDNS_STATUS_INVALID_STR;
00869 }
00870
00871 while (isblank((int) *my_str)) {
00872 my_str++;
00873 }
00874
00875 if (isdigit((int) *my_str)) {
00876 m = (uint32_t) strtol(my_str, &my_str, 10);
00877 } else if (*my_str == 'N' || *my_str == 'S') {
00878 goto north;
00879 } else {
00880 return LDNS_STATUS_INVALID_STR;
00881 }
00882
00883 while (isblank((int) *my_str)) {
00884 my_str++;
00885 }
00886
00887 if (isdigit((int) *my_str)) {
00888 s = strtod(my_str, &my_str);
00889 }
00890 north:
00891 while (isblank((int) *my_str)) {
00892 my_str++;
00893 }
00894
00895 if (*my_str == 'N') {
00896 northerness = true;
00897 } else if (*my_str == 'S') {
00898 northerness = false;
00899 } else {
00900 return LDNS_STATUS_INVALID_STR;
00901 }
00902
00903 my_str++;
00904
00905
00906 s = 1000.0 * s;
00907
00908 s += 0.0005;
00909 latitude = (uint32_t) s;
00910 latitude += 1000 * 60 * m;
00911 latitude += 1000 * 60 * 60 * h;
00912 if (northerness) {
00913 latitude = equator + latitude;
00914 } else {
00915 latitude = equator - latitude;
00916 }
00917 while (isblank(*my_str)) {
00918 my_str++;
00919 }
00920
00921 if (isdigit((int) *my_str)) {
00922 h = (uint32_t) strtol(my_str, &my_str, 10);
00923 } else {
00924 return LDNS_STATUS_INVALID_STR;
00925 }
00926
00927 while (isblank((int) *my_str)) {
00928 my_str++;
00929 }
00930
00931 if (isdigit((int) *my_str)) {
00932 m = (uint32_t) strtol(my_str, &my_str, 10);
00933 } else if (*my_str == 'E' || *my_str == 'W') {
00934 goto east;
00935 } else {
00936 return LDNS_STATUS_INVALID_STR;
00937 }
00938
00939 while (isblank(*my_str)) {
00940 my_str++;
00941 }
00942
00943 if (isdigit((int) *my_str)) {
00944 s = strtod(my_str, &my_str);
00945 }
00946
00947 east:
00948 while (isblank(*my_str)) {
00949 my_str++;
00950 }
00951
00952 if (*my_str == 'E') {
00953 easterness = true;
00954 } else if (*my_str == 'W') {
00955 easterness = false;
00956 } else {
00957 return LDNS_STATUS_INVALID_STR;
00958 }
00959
00960 my_str++;
00961
00962
00963 s *= 1000.0;
00964
00965 s += 0.0005;
00966 longitude = (uint32_t) s;
00967 longitude += 1000 * 60 * m;
00968 longitude += 1000 * 60 * 60 * h;
00969
00970 if (easterness) {
00971 longitude += equator;
00972 } else {
00973 longitude = equator - longitude;
00974 }
00975
00976 altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00977 10000000.0 + 0.5);
00978 if (*my_str == 'm' || *my_str == 'M') {
00979 my_str++;
00980 }
00981
00982 if (strlen(my_str) > 0) {
00983 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00984 return LDNS_STATUS_INVALID_STR;
00985 }
00986
00987 if (strlen(my_str) > 0) {
00988 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00989 return LDNS_STATUS_INVALID_STR;
00990 }
00991
00992 if (strlen(my_str) > 0) {
00993 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00994 return LDNS_STATUS_INVALID_STR;
00995 }
00996
00997 data = LDNS_XMALLOC(uint8_t, 16);
00998 if(!data) {
00999 return LDNS_STATUS_MEM_ERR;
01000 }
01001 data[0] = 0;
01002 data[1] = 0;
01003 data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
01004 data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
01005 data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
01006 ldns_write_uint32(data + 4, latitude);
01007 ldns_write_uint32(data + 8, longitude);
01008 ldns_write_uint32(data + 12, altitude);
01009
01010 *rd = ldns_rdf_new_frm_data(
01011 LDNS_RDF_TYPE_LOC, 16, data);
01012
01013 LDNS_FREE(data);
01014 return *rd?LDNS_STATUS_OK:LDNS_STATUS_MEM_ERR;
01015 }
01016
01017 ldns_status
01018 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
01019 {
01020 uint8_t *bitmap = NULL;
01021 uint8_t *data;
01022 int bm_len = 0;
01023
01024 struct protoent *proto = NULL;
01025 struct servent *serv = NULL;
01026 int serv_port;
01027
01028 ldns_buffer *str_buf;
01029
01030 char *proto_str = NULL;
01031 char *token;
01032 if(strlen(str) == 0)
01033 token = LDNS_XMALLOC(char, 50);
01034 else token = LDNS_XMALLOC(char, strlen(str)+2);
01035 if(!token) return LDNS_STATUS_MEM_ERR;
01036
01037 str_buf = LDNS_MALLOC(ldns_buffer);
01038 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01039 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01040 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01041 LDNS_FREE(str_buf);
01042 LDNS_FREE(token);
01043 return LDNS_STATUS_MEM_ERR;
01044 }
01045
01046 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01047 if (!proto_str) {
01048 proto_str = strdup(token);
01049 if (!proto_str) {
01050 LDNS_FREE(bitmap);
01051 LDNS_FREE(token);
01052 ldns_buffer_free(str_buf);
01053 return LDNS_STATUS_INVALID_STR;
01054 }
01055 } else {
01056 serv = getservbyname(token, proto_str);
01057 if (serv) {
01058 serv_port = (int) ntohs((uint16_t) serv->s_port);
01059 } else {
01060 serv_port = atoi(token);
01061 }
01062 if (serv_port / 8 >= bm_len) {
01063 uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
01064 if(!b2) {
01065 LDNS_FREE(bitmap);
01066 LDNS_FREE(token);
01067 ldns_buffer_free(str_buf);
01068 free(proto_str);
01069 return LDNS_STATUS_INVALID_STR;
01070 }
01071 bitmap = b2;
01072
01073 for (; bm_len <= serv_port / 8; bm_len++) {
01074 bitmap[bm_len] = 0;
01075 }
01076 }
01077 ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
01078 }
01079 }
01080
01081 if (!proto_str || !bitmap) {
01082 LDNS_FREE(bitmap);
01083 LDNS_FREE(token);
01084 ldns_buffer_free(str_buf);
01085 free(proto_str);
01086 return LDNS_STATUS_INVALID_STR;
01087 }
01088
01089 data = LDNS_XMALLOC(uint8_t, bm_len + 1);
01090 if(!data) {
01091 LDNS_FREE(token);
01092 ldns_buffer_free(str_buf);
01093 LDNS_FREE(bitmap);
01094 free(proto_str);
01095 return LDNS_STATUS_INVALID_STR;
01096 }
01097 if (proto_str)
01098 proto = getprotobyname(proto_str);
01099 if (proto) {
01100 data[0] = (uint8_t) proto->p_proto;
01101 } else if (proto_str) {
01102 data[0] = (uint8_t) atoi(proto_str);
01103 } else {
01104 data[0] = 0;
01105 }
01106 memcpy(data + 1, bitmap, (size_t) bm_len);
01107
01108 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
01109
01110 LDNS_FREE(data);
01111 LDNS_FREE(token);
01112 ldns_buffer_free(str_buf);
01113 LDNS_FREE(bitmap);
01114 free(proto_str);
01115 #ifdef HAVE_ENDSERVENT
01116 endservent();
01117 #endif
01118 #ifdef HAVE_ENDPROTOENT
01119 endprotoent();
01120 #endif
01121
01122 if(!*rd) return LDNS_STATUS_MEM_ERR;
01123
01124 return LDNS_STATUS_OK;
01125 }
01126
01127 ldns_status
01128 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01129 {
01130 size_t len, i;
01131 char* nsap_str = (char*) str;
01132
01133
01134 if (str[0] != '0' || str[1] != 'x') {
01135 return LDNS_STATUS_INVALID_STR;
01136 } else {
01137 len = strlen(str);
01138 for (i=0; i < len; i++) {
01139 if (nsap_str[i] == '.')
01140 nsap_str[i] = ' ';
01141 }
01142 return ldns_str2rdf_hex(rd, str+2);
01143 }
01144 }
01145
01146 ldns_status
01147 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
01148 {
01149 size_t len, i;
01150 char* atma_str = (char*) str;
01151 ldns_status status;
01152
01153
01154 len = strlen(str);
01155 for (i=0; i < len; i++) {
01156 if (atma_str[i] == '.')
01157 atma_str[i] = ' ';
01158 }
01159 status = ldns_str2rdf_hex(rd, str);
01160 if (status != LDNS_STATUS_OK) {
01161 ;
01162 }
01163 return status;
01164 }
01165
01166 ldns_status
01167 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
01168 {
01169 uint8_t precedence = 0;
01170 uint8_t gateway_type = 0;
01171 uint8_t algorithm = 0;
01172 char* gateway = NULL;
01173 char* publickey = NULL;
01174 uint8_t *data;
01175 ldns_buffer *str_buf;
01176 char *token;
01177 int token_count = 0;
01178 int ipseckey_len = 0;
01179 ldns_rdf* gateway_rdf = NULL;
01180 ldns_rdf* publickey_rdf = NULL;
01181 ldns_status status = LDNS_STATUS_OK;
01182
01183 if(strlen(str) == 0)
01184 token = LDNS_XMALLOC(char, 256);
01185 else token = LDNS_XMALLOC(char, strlen(str)+2);
01186 if(!token) return LDNS_STATUS_MEM_ERR;
01187
01188 str_buf = LDNS_MALLOC(ldns_buffer);
01189 if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
01190 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
01191 if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
01192 LDNS_FREE(str_buf);
01193 LDNS_FREE(token);
01194 return LDNS_STATUS_MEM_ERR;
01195 }
01196 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
01197 switch (token_count) {
01198 case 0:
01199 precedence = (uint8_t)atoi(token);
01200 break;
01201 case 1:
01202 gateway_type = (uint8_t)atoi(token);
01203 break;
01204 case 2:
01205 algorithm = (uint8_t)atoi(token);
01206 break;
01207 case 3:
01208 gateway = strdup(token);
01209 if (!gateway || (gateway_type == 0 &&
01210 (token[0] != '.' || token[1] != '\0'))) {
01211 LDNS_FREE(gateway);
01212 LDNS_FREE(token);
01213 ldns_buffer_free(str_buf);
01214 return LDNS_STATUS_INVALID_STR;
01215 }
01216 break;
01217 case 4:
01218 publickey = strdup(token);
01219 break;
01220 default:
01221 LDNS_FREE(token);
01222 ldns_buffer_free(str_buf);
01223 return LDNS_STATUS_INVALID_STR;
01224 break;
01225 }
01226 token_count++;
01227 }
01228
01229 if (!gateway || !publickey) {
01230 if (gateway)
01231 LDNS_FREE(gateway);
01232 if (publickey)
01233 LDNS_FREE(publickey);
01234 LDNS_FREE(token);
01235 ldns_buffer_free(str_buf);
01236 return LDNS_STATUS_INVALID_STR;
01237 }
01238
01239 if (gateway_type == 1) {
01240 status = ldns_str2rdf_a(&gateway_rdf, gateway);
01241 } else if (gateway_type == 2) {
01242 status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
01243 } else if (gateway_type == 3) {
01244 status = ldns_str2rdf_dname(&gateway_rdf, gateway);
01245 }
01246
01247 if (status != LDNS_STATUS_OK) {
01248 if (gateway)
01249 LDNS_FREE(gateway);
01250 if (publickey)
01251 LDNS_FREE(publickey);
01252 LDNS_FREE(token);
01253 ldns_buffer_free(str_buf);
01254 return LDNS_STATUS_INVALID_STR;
01255 }
01256
01257 status = ldns_str2rdf_b64(&publickey_rdf, publickey);
01258
01259 if (status != LDNS_STATUS_OK) {
01260 if (gateway)
01261 LDNS_FREE(gateway);
01262 if (publickey)
01263 LDNS_FREE(publickey);
01264 LDNS_FREE(token);
01265 ldns_buffer_free(str_buf);
01266 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01267 return LDNS_STATUS_INVALID_STR;
01268 }
01269
01270
01271 if (gateway_type)
01272 ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
01273 else
01274 ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
01275
01276 data = LDNS_XMALLOC(uint8_t, ipseckey_len);
01277 if(!data) {
01278 if (gateway)
01279 LDNS_FREE(gateway);
01280 if (publickey)
01281 LDNS_FREE(publickey);
01282 LDNS_FREE(token);
01283 ldns_buffer_free(str_buf);
01284 if (gateway_rdf) ldns_rdf_free(gateway_rdf);
01285 if (publickey_rdf) ldns_rdf_free(publickey_rdf);
01286 return LDNS_STATUS_MEM_ERR;
01287 }
01288
01289 data[0] = precedence;
01290 data[1] = gateway_type;
01291 data[2] = algorithm;
01292
01293 if (gateway_type) {
01294 memcpy(data + 3,
01295 ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
01296 memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
01297 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01298 } else {
01299 memcpy(data + 3,
01300 ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
01301 }
01302
01303 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
01304
01305 if (gateway)
01306 LDNS_FREE(gateway);
01307 if (publickey)
01308 LDNS_FREE(publickey);
01309 LDNS_FREE(token);
01310 ldns_buffer_free(str_buf);
01311 ldns_rdf_free(gateway_rdf);
01312 ldns_rdf_free(publickey_rdf);
01313 LDNS_FREE(data);
01314 if(!*rd) return LDNS_STATUS_MEM_ERR;
01315 return LDNS_STATUS_OK;
01316 }