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