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 #include <sys/socket.h>
00018 #include <arpa/inet.h>
00019 #include <time.h>
00020
00021 #include <errno.h>
00022 #include <netdb.h>
00023
00024 #include <limits.h>
00025 #ifdef HAVE_SYS_PARAM_H
00026 #include <sys/param.h>
00027 #endif
00028
00029 ldns_status
00030 ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
00031 {
00032 char *end = NULL;
00033 uint16_t *r;
00034 r = LDNS_MALLOC(uint16_t);
00035
00036 *r = htons((uint16_t)strtol((char *)shortstr, &end, 0));
00037
00038 if(*end != 0) {
00039 LDNS_FREE(r);
00040 return LDNS_STATUS_INVALID_INT;
00041 } else {
00042 *rd = ldns_rdf_new_frm_data(
00043 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
00044 LDNS_FREE(r);
00045 return LDNS_STATUS_OK;
00046 }
00047 }
00048
00049 ldns_status
00050 ldns_str2rdf_time(ldns_rdf **rd, const char *time)
00051 {
00052
00053 uint16_t *r = NULL;
00054 struct tm tm;
00055 uint32_t l;
00056 char *end;
00057
00058
00059 r = (uint16_t*)LDNS_MALLOC(uint32_t);
00060
00061 memset(&tm, 0, sizeof(tm));
00062
00063 if (strlen(time) == 14 &&
00064 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
00065 ) {
00066 tm.tm_year -= 1900;
00067 tm.tm_mon--;
00068
00069 if (tm.tm_year < 70) {
00070 goto bad_format;
00071 }
00072 if (tm.tm_mon < 0 || tm.tm_mon > 11) {
00073 goto bad_format;
00074 }
00075 if (tm.tm_mday < 1 || tm.tm_mday > 31) {
00076 goto bad_format;
00077 }
00078
00079 if (tm.tm_hour < 0 || tm.tm_hour > 23) {
00080 goto bad_format;
00081 }
00082
00083 if (tm.tm_min < 0 || tm.tm_min > 59) {
00084 goto bad_format;
00085 }
00086
00087 if (tm.tm_sec < 0 || tm.tm_sec > 59) {
00088 goto bad_format;
00089 }
00090
00091 l = htonl(mktime_from_utc(&tm));
00092 memcpy(r, &l, sizeof(uint32_t));
00093 *rd = ldns_rdf_new_frm_data(
00094 LDNS_RDF_TYPE_TIME, sizeof(uint32_t), r);
00095 LDNS_FREE(r);
00096 return LDNS_STATUS_OK;
00097 } else {
00098
00099 l = htonl((uint32_t)strtol((char*)time, &end, 0));
00100 if(*end != 0) {
00101 LDNS_FREE(r);
00102 return LDNS_STATUS_ERR;
00103 } else {
00104 memcpy(r, &l, sizeof(uint32_t));
00105 *rd = ldns_rdf_new_frm_data(
00106 LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00107 LDNS_FREE(r);
00108 return LDNS_STATUS_OK;
00109 }
00110 }
00111
00112 bad_format:
00113 LDNS_FREE(r);
00114 return LDNS_STATUS_INVALID_TIME;
00115 }
00116
00117 ldns_status
00118 ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
00119 {
00120 uint8_t salt_length;
00121 uint8_t c;
00122
00123 uint8_t *salt;
00124 uint8_t *data;
00125
00126 salt_length = (uint8_t) strlen(salt_str);
00127 if (salt_length == 1 && salt_str[0] == '-') {
00128 salt_length = 0;
00129 } else if (salt_length % 2 != 0) {
00130 return LDNS_STATUS_INVALID_HEX;
00131 }
00132
00133 salt = LDNS_XMALLOC(uint8_t, salt_length / 2);
00134 for (c = 0; c < salt_length; c += 2) {
00135 if (isxdigit(salt_str[c]) && isxdigit(salt_str[c+1])) {
00136 salt[c/2] = (uint8_t) ldns_hexdigit_to_int(salt_str[c]) * 16 +
00137 ldns_hexdigit_to_int(salt_str[c+1]);
00138 } else {
00139 LDNS_FREE(salt);
00140 return LDNS_STATUS_INVALID_HEX;
00141 }
00142 }
00143 salt_length = salt_length / 2;
00144
00145 data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
00146 data[0] = salt_length;
00147 memcpy(&data[1], salt, salt_length);
00148 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT, 1 + salt_length, data);
00149 LDNS_FREE(data);
00150 LDNS_FREE(salt);
00151
00152 return LDNS_STATUS_OK;
00153 }
00154
00155 ldns_status
00156 ldns_str2rdf_period(ldns_rdf **rd,const char *period)
00157 {
00158 uint32_t p;
00159 const char *end;
00160
00161
00162 p = ldns_str2period(period, &end);
00163
00164 if (*end != 0) {
00165 return LDNS_STATUS_ERR;
00166 } else {
00167 p = (uint32_t) htonl(p);
00168 *rd = ldns_rdf_new_frm_data(
00169 LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
00170 }
00171 return LDNS_STATUS_OK;
00172 }
00173
00174 ldns_status
00175 ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
00176 {
00177 char *end;
00178 uint16_t *r = NULL;
00179 uint32_t l;
00180
00181 r = (uint16_t*)LDNS_MALLOC(uint32_t);
00182 l = htonl((uint32_t)strtol((char*)longstr, &end, 0));
00183
00184 if(*end != 0) {
00185 LDNS_FREE(r);
00186 return LDNS_STATUS_ERR;
00187 } else {
00188 memcpy(r, &l, sizeof(uint32_t));
00189 *rd = ldns_rdf_new_frm_data(
00190 LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
00191 LDNS_FREE(r);
00192 return LDNS_STATUS_OK;
00193 }
00194 }
00195
00196 ldns_status
00197 ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
00198 {
00199 char *end;
00200 uint8_t *r = NULL;
00201
00202 r = LDNS_MALLOC(uint8_t);
00203
00204 *r = (uint8_t)strtol((char*)bytestr, &end, 0);
00205
00206 if(*end != 0) {
00207 LDNS_FREE(r);
00208 return LDNS_STATUS_ERR;
00209 } else {
00210 *rd = ldns_rdf_new_frm_data(
00211 LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
00212 LDNS_FREE(r);
00213 return LDNS_STATUS_OK;
00214 }
00215 }
00216
00217
00218
00219
00220
00221
00222 ldns_status
00223 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
00224 {
00225 size_t len;
00226
00227 uint8_t *s,*p,*q, *pq, val, label_len;
00228 uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
00229 *d = NULL;
00230
00231 len = strlen((char*)str);
00232
00233 if (len > LDNS_MAX_DOMAINLEN * 3) {
00234 return LDNS_STATUS_DOMAINNAME_OVERFLOW;
00235 }
00236 if (0 == len) {
00237 return LDNS_STATUS_DOMAINNAME_UNDERFLOW;
00238 }
00239
00240
00241 if (1 == len && *str == '.') {
00242 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, 1, "\0");
00243 return LDNS_STATUS_OK;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252 len = 0;
00253 q = buf+1;
00254 pq = buf;
00255 label_len = 0;
00256 for (s = p = (uint8_t *) str; *s; s++, q++) {
00257 *q = 0;
00258 switch (*s) {
00259 case '.':
00260 if (label_len > LDNS_MAX_LABELLEN) {
00261 return LDNS_STATUS_LABEL_OVERFLOW;
00262 }
00263 if (label_len == 0) {
00264 return LDNS_STATUS_EMPTY_LABEL;
00265 }
00266 len += label_len + 1;
00267 *pq = label_len;
00268 label_len = 0;
00269 pq = q;
00270 p = s+1;
00271 break;
00272 case '\\':
00273
00274 if (strlen((char *)s) > 3 &&
00275 isdigit((int) s[1]) &&
00276 isdigit((int) s[2]) &&
00277 isdigit((int) s[3])) {
00278
00279 val = (uint8_t) ldns_hexdigit_to_int((char) s[1]) * 100 +
00280 ldns_hexdigit_to_int((char) s[2]) * 10 +
00281 ldns_hexdigit_to_int((char) s[3]);
00282 *q = val;
00283 s += 3;
00284 } else {
00285 s++;
00286 *q = *s;
00287 }
00288 label_len++;
00289 break;
00290 default:
00291 *q = *s;
00292 label_len++;
00293 }
00294 }
00295
00296
00297 if (!ldns_dname_str_absolute(str)) {
00298 len += label_len + 1;
00299 *pq = label_len;
00300 *q = 0;
00301 }
00302 len++;
00303
00304 *d = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME, len, buf);
00305 return LDNS_STATUS_OK;
00306 }
00307
00308 ldns_status
00309 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
00310 {
00311 in_addr_t address;
00312 if (inet_pton(AF_INET, (char*)str, &address) != 1) {
00313 return LDNS_STATUS_INVALID_IP4;
00314 } else {
00315 *rd = ldns_rdf_new_frm_data(
00316 LDNS_RDF_TYPE_A, sizeof(address), &address);
00317 }
00318 return LDNS_STATUS_OK;
00319 }
00320
00321 ldns_status
00322 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
00323 {
00324 uint8_t address[LDNS_IP6ADDRLEN + 1];
00325
00326 if (inet_pton(AF_INET6, (char*)str, address) != 1) {
00327 return LDNS_STATUS_INVALID_IP6;
00328 } else {
00329 *rd = ldns_rdf_new_frm_data(
00330 LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
00331 }
00332 return LDNS_STATUS_OK;
00333 }
00334
00335 ldns_status
00336 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
00337 {
00338 uint8_t *data;
00339 uint8_t val;
00340 size_t i, str_i;
00341
00342 if (strlen(str) > 255) {
00343 return LDNS_STATUS_INVALID_STR;
00344 }
00345
00346 data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
00347 i = 1;
00348 for (str_i = 0; str_i < strlen(str); str_i++) {
00349 if (str[str_i] == '\\') {
00350 if(str_i + 3 < strlen(str) &&
00351 isdigit(str[str_i + 1]) &&
00352 isdigit(str[str_i + 2]) &&
00353 isdigit(str[str_i + 3])) {
00354 val = (uint8_t) ldns_hexdigit_to_int((char) str[str_i + 1]) * 100 +
00355 ldns_hexdigit_to_int((char) str[str_i + 2]) * 10 +
00356 ldns_hexdigit_to_int((char) str[str_i + 3]);
00357 data[i] = val;
00358 i++;
00359 str_i += 3;
00360 } else {
00361 str_i++;
00362 data[i] = (uint8_t) str[str_i];
00363 i++;
00364 }
00365 } else {
00366 data[i] = (uint8_t) str[str_i];
00367 i++;
00368 }
00369 }
00370 data[0] = i - 1;
00371 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR, i, data);
00372 LDNS_FREE(data);
00373 return LDNS_STATUS_OK;
00374 }
00375
00376 ldns_status
00377 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
00378 {
00379 const char *my_str = str;
00380
00381 char *my_ip_str;
00382 size_t ip_str_len;
00383
00384 uint16_t family;
00385 bool negation;
00386 uint8_t afdlength = 0;
00387 uint8_t *afdpart;
00388 uint8_t prefix;
00389
00390 uint8_t *data;
00391
00392 size_t i = 0;
00393
00394
00395 if (strlen(my_str) < 2) {
00396 return LDNS_STATUS_INVALID_STR;
00397 }
00398
00399 if (my_str[0] == '!') {
00400 negation = true;
00401 my_str += 1;
00402 } else {
00403 negation = false;
00404 }
00405
00406 family = (uint16_t) atoi(my_str);
00407
00408 my_str = strchr(my_str, ':') + 1;
00409
00410
00411 ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
00412 my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
00413 strncpy(my_ip_str, my_str, ip_str_len + 1);
00414 my_ip_str[ip_str_len] = '\0';
00415
00416 if (family == 1) {
00417
00418 afdpart = LDNS_XMALLOC(uint8_t, 4);
00419 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
00420 return LDNS_STATUS_INVALID_STR;
00421 }
00422 for (i = 0; i < 4; i++) {
00423 if (afdpart[i] != 0) {
00424 afdlength = i + 1;
00425 }
00426 }
00427 } else if (family == 2) {
00428
00429 afdpart = LDNS_XMALLOC(uint8_t, 16);
00430 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
00431 return LDNS_STATUS_INVALID_STR;
00432 }
00433 for (i = 0; i < 16; i++) {
00434 if (afdpart[i] != 0) {
00435 afdlength = i + 1;
00436 }
00437 }
00438 } else {
00439
00440 LDNS_FREE(my_ip_str);
00441 return LDNS_STATUS_INVALID_STR;
00442 }
00443
00444 my_str = strchr(my_str, '/') + 1;
00445 prefix = (uint8_t) atoi(my_str);
00446
00447 data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
00448 ldns_write_uint16(data, family);
00449 data[2] = prefix;
00450 data[3] = afdlength;
00451 if (negation) {
00452
00453 data[3] = data[3] | 0x80;
00454 }
00455
00456 memcpy(data + 4, afdpart, afdlength);
00457
00458 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
00459 LDNS_FREE(afdpart);
00460 LDNS_FREE(data);
00461 LDNS_FREE(my_ip_str);
00462
00463 return LDNS_STATUS_OK;
00464 }
00465
00466 ldns_status
00467 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
00468 {
00469 uint8_t *buffer;
00470 int16_t i;
00471
00472 buffer = LDNS_XMALLOC(uint8_t, b64_ntop_calculate_size(strlen(str)));
00473
00474 i = (uint16_t)b64_pton((const char*)str, buffer,
00475 b64_ntop_calculate_size(strlen(str)));
00476 if (-1 == i) {
00477 LDNS_FREE(buffer);
00478 return LDNS_STATUS_INVALID_B64;
00479 } else {
00480 *rd = ldns_rdf_new_frm_data(
00481 LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
00482 }
00483 LDNS_FREE(buffer);
00484
00485 return LDNS_STATUS_OK;
00486 }
00487
00488 ldns_status
00489 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
00490 {
00491 uint8_t *buffer;
00492 int i;
00493
00494 uint8_t len = b32_pton_calculate_size(strlen(str));
00495 buffer = LDNS_XMALLOC(uint8_t, len + 1);
00496 buffer[0] = len;
00497
00498 i = b32_pton_extended_hex((const char*)str, strlen(str), buffer + 1,
00499 b32_ntop_calculate_size(strlen(str)));
00500 if (i < 0) {
00501 return LDNS_STATUS_INVALID_B32_EXT;
00502 } else {
00503 *rd = ldns_rdf_new_frm_data(
00504 LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
00505 }
00506 LDNS_FREE(buffer);
00507
00508 return LDNS_STATUS_OK;
00509 }
00510
00511 ldns_status
00512 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
00513 {
00514 uint8_t *t, *t_orig;
00515 int i;
00516 size_t len;
00517
00518 len = strlen(str);
00519
00520 if (len % 2 != 0) {
00521 return LDNS_STATUS_INVALID_HEX;
00522 } else if (len > LDNS_MAX_RDFLEN * 2) {
00523 return LDNS_STATUS_LABEL_OVERFLOW;
00524 } else {
00525 t = LDNS_XMALLOC(uint8_t, (len / 2));
00526 t_orig = t;
00527
00528 while (*str) {
00529 *t = 0;
00530 for (i = 16; i >= 1; i -= 15) {
00531 if (isxdigit(*str)) {
00532 *t += ldns_hexdigit_to_int(*str) * i;
00533 } else {
00534
00535
00536 }
00537 ++str;
00538 }
00539 ++t;
00540 }
00541 t = t_orig;
00542 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX, len / 2, t);
00543 LDNS_FREE(t);
00544 }
00545 return LDNS_STATUS_OK;
00546 }
00547
00548 ldns_status
00549 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
00550 {
00551 const char *delimiters = "\n\t ";
00552 char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
00553 uint8_t *bitmap = LDNS_XMALLOC(uint8_t, 1);
00554 uint16_t bm_len = 0;
00555 ldns_buffer *str_buf;
00556 ssize_t c;
00557 uint16_t cur_type;
00558 uint8_t cur_data[32];
00559 uint8_t cur_window = 0;
00560 uint8_t cur_window_max = 0;
00561 uint16_t cur_data_size = 0;
00562 uint16_t i;
00563 uint8_t *data = NULL;
00564
00565 str_buf = LDNS_MALLOC(ldns_buffer);
00566 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00567
00568 bitmap[0] = 0;
00569 while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1) {
00570 cur_type = ldns_get_rr_type_by_name(token);
00571 if ((cur_type / 8) + 1 > bm_len) {
00572 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (cur_type / 8) + 1);
00573
00574 for (; bm_len <= cur_type / 8; bm_len++) {
00575 bitmap[bm_len] = 0;
00576 }
00577 }
00578 ldns_set_bit(bitmap + (int) cur_type / 8, (int) (7 - (cur_type % 8)), true);
00579 }
00580
00581 memset(cur_data, 0, 32);
00582 for (i = 0; i < bm_len; i++) {
00583 if (i / 32 > cur_window) {
00584
00585 if (cur_window_max > 0) {
00586
00587 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
00588 data[cur_data_size] = cur_window;
00589 data[cur_data_size + 1] = cur_window_max + 1;
00590 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00591 cur_data_size += cur_window_max + 3;
00592 }
00593 cur_window++;
00594 cur_window_max = 0;
00595 memset(cur_data, 0, 32);
00596 } else {
00597 cur_data[i%32] = bitmap[i];
00598 if (bitmap[i] > 0) {
00599 cur_window_max = i%32;
00600 }
00601 }
00602 }
00603 if (cur_window_max > 0) {
00604
00605 data = LDNS_XREALLOC(data, uint8_t, cur_data_size + cur_window_max + 3);
00606 data[cur_data_size] = cur_window;
00607 data[cur_data_size + 1] = cur_window_max + 1;
00608 memcpy(data + cur_data_size + 2, cur_data, cur_window_max+1);
00609 cur_data_size += cur_window_max + 3;
00610 }
00611
00612 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC, cur_data_size, data);
00613 if(data)
00614 LDNS_FREE(data);
00615 if (token)
00616 LDNS_FREE(token);
00617 if(bitmap)
00618 LDNS_FREE(bitmap);
00619 ldns_buffer_free(str_buf);
00620 return LDNS_STATUS_OK;
00621 }
00622
00623 ldns_status
00624 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
00625 {
00626 uint16_t type;
00627 type = htons(ldns_get_rr_type_by_name(str));
00628
00629 *rd = ldns_rdf_new_frm_data(
00630 LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
00631 return LDNS_STATUS_OK;
00632 }
00633
00634 ldns_status
00635 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
00636 {
00637 uint16_t klass;
00638 klass = htons(ldns_get_rr_class_by_name(str));
00639
00640 *rd = ldns_rdf_new_frm_data(
00641 LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
00642 return LDNS_STATUS_OK;
00643 }
00644
00645
00646
00647
00648 ldns_status
00649 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
00650 {
00651 ldns_lookup_table *lt;
00652 ldns_status st;
00653 uint8_t idd[2];
00654 lt = ldns_lookup_by_name(ldns_cert_algorithms, str);
00655 st = LDNS_STATUS_OK;
00656
00657 if (lt) {
00658 ldns_write_uint16(idd, (uint16_t) lt->id);
00659 *rd = ldns_rdf_new_frm_data(
00660 LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
00661 if (!*rd) {
00662 st = LDNS_STATUS_ERR;
00663 }
00664 } else {
00665
00666 st = ldns_str2rdf_int16(rd, str);
00667 if (st == LDNS_STATUS_OK &&
00668 ldns_rdf2native_int16(*rd) == 0) {
00669 st = LDNS_STATUS_CERT_BAD_ALGORITHM;
00670 }
00671 }
00672
00673 return st;
00674 }
00675
00676
00677
00678
00679 ldns_status
00680 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
00681 {
00682 ldns_lookup_table *lt;
00683 ldns_status st;
00684
00685 lt = ldns_lookup_by_name(ldns_algorithms, str);
00686 st = LDNS_STATUS_OK;
00687
00688 if (lt) {
00689
00690 *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
00691 if (!*rd) {
00692 st = LDNS_STATUS_ERR;
00693 }
00694 } else {
00695
00696 st = ldns_str2rdf_int8(rd, str);
00697 }
00698 return st;
00699 }
00700
00701 ldns_status
00702 ldns_str2rdf_unknown(ldns_rdf **rd, const char *str)
00703 {
00704
00705
00706 rd = rd;
00707 str = str;
00708 return LDNS_STATUS_NOT_IMPL;
00709 }
00710
00711 ldns_status
00712 ldns_str2rdf_tsig(ldns_rdf **rd, const char *str)
00713 {
00714
00715 rd = rd;
00716 str = str;
00717 return LDNS_STATUS_NOT_IMPL;
00718 }
00719
00720 ldns_status
00721 ldns_str2rdf_service(ldns_rdf **rd, const char *str)
00722 {
00723
00724 rd = rd;
00725 str = str;
00726 return LDNS_STATUS_NOT_IMPL;
00727 }
00728
00729 static int
00730 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
00731 {
00732
00733
00734 uint32_t meters = 0, cm = 0, val;
00735 while (isblank(*my_str)) {
00736 my_str++;
00737 }
00738 meters = (uint32_t)strtol(my_str, &my_str, 10);
00739 if (*my_str == '.') {
00740 my_str++;
00741 cm = (uint32_t)strtol(my_str, &my_str, 10);
00742 }
00743 if (meters >= 1) {
00744 *e = 2;
00745 val = meters;
00746 } else {
00747 *e = 0;
00748 val = cm;
00749 }
00750 while(val >= 10) {
00751 (*e)++;
00752 val /= 10;
00753 }
00754 *m = (uint8_t)val;
00755
00756 if (*e > 9)
00757 return 0;
00758 if (*my_str == 'm' || *my_str == 'M') {
00759 my_str++;
00760 }
00761 *endstr = my_str;
00762 return 1;
00763 }
00764
00765 ldns_status
00766 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
00767 {
00768 uint32_t latitude = 0;
00769 uint32_t longitude = 0;
00770 uint32_t altitude = 0;
00771
00772 uint8_t *data;
00773 uint32_t equator = (uint32_t) ldns_power(2, 31);
00774
00775 uint32_t h = 0;
00776 uint32_t m = 0;
00777 uint8_t size_b = 1, size_e = 2;
00778 uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
00779 uint8_t vert_pre_b = 1, vert_pre_e = 3;
00780
00781 double s = 0.0;
00782 bool northerness;
00783 bool easterness;
00784
00785 char *my_str = (char *) str;
00786
00787
00788 if (isdigit(*my_str)) {
00789 h = (uint32_t) strtol(my_str, &my_str, 10);
00790 } else {
00791 return LDNS_STATUS_INVALID_STR;
00792 }
00793
00794 while (isblank(*my_str)) {
00795 my_str++;
00796 }
00797
00798 if (isdigit(*my_str)) {
00799 m = (uint32_t) strtol(my_str, &my_str, 10);
00800 } else if (*my_str == 'N' || *my_str == 'S') {
00801 goto north;
00802 } else {
00803 return LDNS_STATUS_INVALID_STR;
00804 }
00805
00806 while (isblank(*my_str)) {
00807 my_str++;
00808 }
00809
00810 if (isdigit(*my_str)) {
00811 s = strtod(my_str, &my_str);
00812 }
00813 north:
00814 while (isblank(*my_str)) {
00815 my_str++;
00816 }
00817
00818 if (*my_str == 'N') {
00819 northerness = true;
00820 } else if (*my_str == 'S') {
00821 northerness = false;
00822 } else {
00823 return LDNS_STATUS_INVALID_STR;
00824 }
00825
00826 my_str++;
00827
00828
00829 s = 1000.0 * s;
00830
00831 s += 0.0005;
00832 latitude = (uint32_t) s;
00833 latitude += 1000 * 60 * m;
00834 latitude += 1000 * 60 * 60 * h;
00835 if (northerness) {
00836 latitude = equator + latitude;
00837 } else {
00838 latitude = equator - latitude;
00839 }
00840 while (isblank(*my_str)) {
00841 my_str++;
00842 }
00843
00844 if (isdigit(*my_str)) {
00845 h = (uint32_t) strtol(my_str, &my_str, 10);
00846 } else {
00847 return LDNS_STATUS_INVALID_STR;
00848 }
00849
00850 while (isblank(*my_str)) {
00851 my_str++;
00852 }
00853
00854 if (isdigit(*my_str)) {
00855 m = (uint32_t) strtol(my_str, &my_str, 10);
00856 } else if (*my_str == 'E' || *my_str == 'W') {
00857 goto east;
00858 } else {
00859 return LDNS_STATUS_INVALID_STR;
00860 }
00861
00862 while (isblank(*my_str)) {
00863 my_str++;
00864 }
00865
00866 if (isdigit(*my_str)) {
00867 s = strtod(my_str, &my_str);
00868 }
00869
00870 east:
00871 while (isblank(*my_str)) {
00872 my_str++;
00873 }
00874
00875 if (*my_str == 'E') {
00876 easterness = true;
00877 } else if (*my_str == 'W') {
00878 easterness = false;
00879 } else {
00880 return LDNS_STATUS_INVALID_STR;
00881 }
00882
00883 my_str++;
00884
00885
00886 s *= 1000.0;
00887
00888 s += 0.0005;
00889 longitude = (uint32_t) s;
00890 longitude += 1000 * 60 * m;
00891 longitude += 1000 * 60 * 60 * h;
00892
00893 if (easterness) {
00894 longitude += equator;
00895 } else {
00896 longitude = equator - longitude;
00897 }
00898
00899 altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
00900 10000000.0 + 0.5);
00901 if (*my_str == 'm' || *my_str == 'M') {
00902 my_str++;
00903 }
00904
00905 if (strlen(my_str) > 0) {
00906 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
00907 return LDNS_STATUS_INVALID_STR;
00908 }
00909
00910 if (strlen(my_str) > 0) {
00911 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
00912 return LDNS_STATUS_INVALID_STR;
00913 }
00914
00915 if (strlen(my_str) > 0) {
00916 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
00917 return LDNS_STATUS_INVALID_STR;
00918 }
00919
00920 data = LDNS_XMALLOC(uint8_t, 16);
00921 data[0] = 0;
00922 data[1] = 0;
00923 data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
00924 data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
00925 data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
00926 ldns_write_uint32(data + 4, latitude);
00927 ldns_write_uint32(data + 8, longitude);
00928 ldns_write_uint32(data + 12, altitude);
00929
00930 *rd = ldns_rdf_new_frm_data(
00931 LDNS_RDF_TYPE_LOC, 16, data);
00932
00933 LDNS_FREE(data);
00934 return LDNS_STATUS_OK;
00935 }
00936
00937 ldns_status
00938 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
00939 {
00940 uint8_t *bitmap = NULL;
00941 uint8_t *data;
00942 int bm_len = 0;
00943
00944 struct protoent *proto = NULL;
00945 struct servent *serv = NULL;
00946 int serv_port;
00947
00948 ldns_buffer *str_buf;
00949
00950 char *proto_str = NULL;
00951 char *token = LDNS_XMALLOC(char, 50);
00952
00953 str_buf = LDNS_MALLOC(ldns_buffer);
00954 ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
00955
00956 while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
00957 if (!proto_str) {
00958 proto_str = strdup(token);
00959 if (!proto_str) {
00960 LDNS_FREE(token);
00961 LDNS_FREE(str_buf);
00962 return LDNS_STATUS_INVALID_STR;
00963 }
00964 } else {
00965 serv = getservbyname(token, proto_str);
00966 if (serv) {
00967 serv_port = (int) ntohs((uint16_t) serv->s_port);
00968 } else {
00969 serv_port = atoi(token);
00970 }
00971 if (serv_port / 8 > bm_len) {
00972 bitmap = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
00973
00974 for (; bm_len <= serv_port / 8; bm_len++) {
00975 bitmap[bm_len] = 0;
00976 }
00977 }
00978 ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
00979 }
00980 }
00981
00982 data = LDNS_XMALLOC(uint8_t, bm_len + 1);
00983 proto = getprotobyname(proto_str);
00984 if (proto) {
00985 data[0] = (uint8_t) proto->p_proto;
00986 } else {
00987 data[0] = (uint8_t) atoi(proto_str);
00988 }
00989 memcpy(data + 1, bitmap, (size_t) bm_len);
00990
00991 *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
00992
00993 LDNS_FREE(token);
00994 ldns_buffer_free(str_buf);
00995 LDNS_FREE(bitmap);
00996 LDNS_FREE(data);
00997 free(proto_str);
00998 endservent();
00999 endprotoent();
01000
01001 return LDNS_STATUS_OK;
01002 }
01003
01004 ldns_status
01005 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
01006 {
01007
01008 if (str[0] != '0' || str[1] != 'x') {
01009 return LDNS_STATUS_INVALID_STR;
01010 } else {
01011 return ldns_str2rdf_hex(rd, str+2);
01012 }
01013 }