4 * conversion routines from the presentation format
7 * a Net::DNS like library for C
9 * (c) NLnet Labs, 2004-2006
11 * See the file LICENSE for the license
13 #include <ldns/config.h>
15 #include <ldns/ldns.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 #include <sys/socket.h>
20 #ifdef HAVE_ARPA_INET_H
21 #include <arpa/inet.h>
31 #ifdef HAVE_SYS_PARAM_H
32 #include <sys/param.h>
36 ldns_str2rdf_int16(ldns_rdf
**rd
, const char *shortstr
)
40 r
= LDNS_MALLOC(uint16_t);
41 if(!r
) return LDNS_STATUS_MEM_ERR
;
43 *r
= htons((uint16_t)strtol((char *)shortstr
, &end
, 10));
47 return LDNS_STATUS_INVALID_INT
;
49 *rd
= ldns_rdf_new_frm_data(
50 LDNS_RDF_TYPE_INT16
, sizeof(uint16_t), r
);
52 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
57 ldns_str2rdf_time(ldns_rdf
**rd
, const char *time
)
59 /* convert a time YYYYDDMMHHMMSS to wireformat */
65 /* Try to scan the time... */
66 r
= (uint16_t*)LDNS_MALLOC(uint32_t);
67 if(!r
) return LDNS_STATUS_MEM_ERR
;
69 memset(&tm
, 0, sizeof(tm
));
71 if (strlen(time
) == 14 &&
72 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
77 if (tm
.tm_year
< 70) {
80 if (tm
.tm_mon
< 0 || tm
.tm_mon
> 11) {
83 if (tm
.tm_mday
< 1 || tm
.tm_mday
> 31) {
87 if (tm
.tm_hour
< 0 || tm
.tm_hour
> 23) {
91 if (tm
.tm_min
< 0 || tm
.tm_min
> 59) {
95 if (tm
.tm_sec
< 0 || tm
.tm_sec
> 59) {
99 l
= htonl(ldns_mktime_from_utc(&tm
));
100 memcpy(r
, &l
, sizeof(uint32_t));
101 *rd
= ldns_rdf_new_frm_data(
102 LDNS_RDF_TYPE_TIME
, sizeof(uint32_t), r
);
104 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
106 /* handle it as 32 bits timestamp */
107 l
= htonl((uint32_t)strtol((char*)time
, &end
, 10));
110 return LDNS_STATUS_ERR
;
112 memcpy(r
, &l
, sizeof(uint32_t));
113 *rd
= ldns_rdf_new_frm_data(
114 LDNS_RDF_TYPE_INT32
, sizeof(uint32_t), r
);
116 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
122 return LDNS_STATUS_INVALID_TIME
;
126 ldns_str2rdf_nsec3_salt(ldns_rdf
**rd
, const char *salt_str
)
135 return LDNS_STATUS_NULL
;
138 salt_length_str
= (int)strlen(salt_str
);
139 if (salt_length_str
== 1 && salt_str
[0] == '-') {
141 } else if (salt_length_str
% 2 != 0) {
142 return LDNS_STATUS_INVALID_HEX
;
144 if (salt_length_str
> 512) {
145 return LDNS_STATUS_INVALID_HEX
;
148 salt
= LDNS_XMALLOC(uint8_t, salt_length_str
/ 2);
150 return LDNS_STATUS_MEM_ERR
;
152 for (c
= 0; c
< salt_length_str
; c
+= 2) {
153 if (isxdigit((int) salt_str
[c
]) && isxdigit((int) salt_str
[c
+1])) {
154 salt
[c
/2] = (uint8_t) ldns_hexdigit_to_int(salt_str
[c
]) * 16 +
155 ldns_hexdigit_to_int(salt_str
[c
+1]);
158 return LDNS_STATUS_INVALID_HEX
;
161 salt_length
= (uint8_t) (salt_length_str
/ 2);
163 data
= LDNS_XMALLOC(uint8_t, 1 + salt_length
);
166 return LDNS_STATUS_MEM_ERR
;
168 data
[0] = salt_length
;
169 memcpy(&data
[1], salt
, salt_length
);
170 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_NSEC3_SALT
, 1 + salt_length
, data
);
174 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
178 ldns_str2rdf_period(ldns_rdf
**rd
,const char *period
)
183 /* Allocate required space... */
184 p
= ldns_str2period(period
, &end
);
187 return LDNS_STATUS_ERR
;
189 p
= (uint32_t) htonl(p
);
190 *rd
= ldns_rdf_new_frm_data(
191 LDNS_RDF_TYPE_PERIOD
, sizeof(uint32_t), &p
);
193 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
197 ldns_str2rdf_int32(ldns_rdf
**rd
, const char *longstr
)
203 r
= (uint16_t*)LDNS_MALLOC(uint32_t);
204 if(!r
) return LDNS_STATUS_MEM_ERR
;
205 errno
= 0; /* must set to zero before call,
206 note race condition on errno */
208 l
= htonl((uint32_t)strtol((char*)longstr
, &end
, 10));
209 else l
= htonl((uint32_t)strtoul((char*)longstr
, &end
, 10));
213 return LDNS_STATUS_ERR
;
215 if (errno
== ERANGE
) {
217 return LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW
;
219 memcpy(r
, &l
, sizeof(uint32_t));
220 *rd
= ldns_rdf_new_frm_data(
221 LDNS_RDF_TYPE_INT32
, sizeof(uint32_t), r
);
223 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
228 ldns_str2rdf_int8(ldns_rdf
**rd
, const char *bytestr
)
233 r
= LDNS_MALLOC(uint8_t);
234 if(!r
) return LDNS_STATUS_MEM_ERR
;
236 *r
= (uint8_t)strtol((char*)bytestr
, &end
, 10);
240 return LDNS_STATUS_ERR
;
242 *rd
= ldns_rdf_new_frm_data(
243 LDNS_RDF_TYPE_INT8
, sizeof(uint8_t), r
);
245 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
251 * Checks whether the escaped value at **s is an octal value or
252 * a 'normally' escaped character (and not eos)
254 * The string pointer at *s is increased by either 0 (on error), 1 (on
255 * normal escapes), or 3 (on octals)
257 * Returns the number of bytes read from the escaped string, or
261 parse_escape(uint8_t *s
, uint8_t *q
) {
263 if (strlen((char *)s
) > 3 &&
264 isdigit((int) s
[1]) &&
265 isdigit((int) s
[2]) &&
266 isdigit((int) s
[3])) {
267 /* cast this so it fits */
268 val
= (uint16_t) ldns_hexdigit_to_int((char) s
[1]) * 100 +
269 ldns_hexdigit_to_int((char) s
[2]) * 10 +
270 ldns_hexdigit_to_int((char) s
[3]);
279 if (*s
== '\0' || isdigit((int) *s
)) {
280 /* apparently the string terminator
281 * or a digit has been escaped...
291 * No special care is taken, all dots are translated into
293 * Could be made more efficient....we do 3 memcpy's in total...
296 ldns_str2rdf_dname(ldns_rdf
**d
, const char *str
)
301 uint8_t *s
, *q
, *pq
, label_len
;
302 uint8_t buf
[LDNS_MAX_DOMAINLEN
+ 1];
305 len
= strlen((char*)str
);
306 /* octet representation can make strings a lot longer than actual length */
307 if (len
> LDNS_MAX_DOMAINLEN
* 4) {
308 return LDNS_STATUS_DOMAINNAME_OVERFLOW
;
311 return LDNS_STATUS_DOMAINNAME_UNDERFLOW
;
315 if (1 == len
&& *str
== '.') {
316 *d
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME
, 1, "\0");
317 return LDNS_STATUS_OK
;
320 /* get on with the rest */
322 /* s is on the current character in the string
323 * pq points to where the labellength is going to go
324 * label_len keeps track of the current label's length
325 * q builds the dname inside the buf array
331 for (s
= (uint8_t *)str
; *s
; s
++, q
++) {
332 if (q
> buf
+ LDNS_MAX_DOMAINLEN
) {
333 return LDNS_STATUS_DOMAINNAME_OVERFLOW
;
338 if (label_len
> LDNS_MAX_LABELLEN
) {
339 return LDNS_STATUS_LABEL_OVERFLOW
;
341 if (label_len
== 0) {
342 return LDNS_STATUS_EMPTY_LABEL
;
344 len
+= label_len
+ 1;
350 /* octet value or literal char */
351 esc
= parse_escape(s
, q
);
356 return LDNS_STATUS_SYNTAX_BAD_ESCAPE
;
365 /* add root label if last char was not '.' */
366 if (!ldns_dname_str_absolute(str
)) {
367 if (q
> buf
+ LDNS_MAX_DOMAINLEN
) {
368 return LDNS_STATUS_DOMAINNAME_OVERFLOW
;
370 if (label_len
> LDNS_MAX_LABELLEN
) {
371 return LDNS_STATUS_LABEL_OVERFLOW
;
373 if (label_len
== 0) { /* label_len 0 but not . at end? */
374 return LDNS_STATUS_EMPTY_LABEL
;
376 len
+= label_len
+ 1;
382 *d
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_DNAME
, len
, buf
);
383 return LDNS_STATUS_OK
;
387 ldns_str2rdf_a(ldns_rdf
**rd
, const char *str
)
390 if (inet_pton(AF_INET
, (char*)str
, &address
) != 1) {
391 return LDNS_STATUS_INVALID_IP4
;
393 *rd
= ldns_rdf_new_frm_data(
394 LDNS_RDF_TYPE_A
, sizeof(address
), &address
);
396 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
400 ldns_str2rdf_aaaa(ldns_rdf
**rd
, const char *str
)
402 uint8_t address
[LDNS_IP6ADDRLEN
+ 1];
404 if (inet_pton(AF_INET6
, (char*)str
, address
) != 1) {
405 return LDNS_STATUS_INVALID_IP6
;
407 *rd
= ldns_rdf_new_frm_data(
408 LDNS_RDF_TYPE_AAAA
, sizeof(address
) - 1, &address
);
410 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
414 ldns_str2rdf_str(ldns_rdf
**rd
, const char *str
)
417 size_t i
, str_i
, esc_i
;
419 if (strlen(str
) > 255) {
420 return LDNS_STATUS_INVALID_STR
;
423 data
= LDNS_XMALLOC(uint8_t, strlen(str
) + 1);
424 if(!data
) return LDNS_STATUS_MEM_ERR
;
427 for (str_i
= 0; str_i
< strlen(str
); str_i
++) {
428 if (str
[str_i
] == '\\') {
429 /* octet value or literal char */
430 esc_i
= (size_t) parse_escape((uint8_t*) &str
[str_i
], (uint8_t*) &data
[i
]);
433 return LDNS_STATUS_SYNTAX_BAD_ESCAPE
;
437 data
[i
] = (uint8_t) str
[str_i
];
442 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_STR
, i
, data
);
445 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
449 ldns_str2rdf_apl(ldns_rdf
**rd
, const char *str
)
451 const char *my_str
= str
;
458 uint8_t afdlength
= 0;
466 /* [!]afi:address/prefix */
467 if (strlen(my_str
) < 2
468 || strchr(my_str
, ':') == NULL
469 || strchr(my_str
, '/') == NULL
470 || strchr(my_str
, ':') > strchr(my_str
, '/')) {
471 return LDNS_STATUS_INVALID_STR
;
474 if (my_str
[0] == '!') {
481 family
= (uint16_t) atoi(my_str
);
483 my_str
= strchr(my_str
, ':') + 1;
485 /* need ip addr and only ip addr for inet_pton */
486 ip_str_len
= (size_t) (strchr(my_str
, '/') - my_str
);
487 my_ip_str
= LDNS_XMALLOC(char, ip_str_len
+ 1);
488 if(!my_ip_str
) return LDNS_STATUS_MEM_ERR
;
489 strncpy(my_ip_str
, my_str
, ip_str_len
+ 1);
490 my_ip_str
[ip_str_len
] = '\0';
494 afdpart
= LDNS_XMALLOC(uint8_t, 4);
496 LDNS_FREE(my_ip_str
);
497 return LDNS_STATUS_MEM_ERR
;
499 if (inet_pton(AF_INET
, my_ip_str
, afdpart
) == 0) {
500 LDNS_FREE(my_ip_str
);
502 return LDNS_STATUS_INVALID_STR
;
504 for (i
= 0; i
< 4; i
++) {
505 if (afdpart
[i
] != 0) {
509 } else if (family
== 2) {
511 afdpart
= LDNS_XMALLOC(uint8_t, 16);
513 LDNS_FREE(my_ip_str
);
514 return LDNS_STATUS_MEM_ERR
;
516 if (inet_pton(AF_INET6
, my_ip_str
, afdpart
) == 0) {
517 LDNS_FREE(my_ip_str
);
519 return LDNS_STATUS_INVALID_STR
;
521 for (i
= 0; i
< 16; i
++) {
522 if (afdpart
[i
] != 0) {
528 LDNS_FREE(my_ip_str
);
529 return LDNS_STATUS_INVALID_STR
;
532 my_str
= strchr(my_str
, '/') + 1;
533 prefix
= (uint8_t) atoi(my_str
);
535 data
= LDNS_XMALLOC(uint8_t, 4 + afdlength
);
538 LDNS_FREE(my_ip_str
);
539 return LDNS_STATUS_INVALID_STR
;
541 ldns_write_uint16(data
, family
);
545 /* set bit 1 of byte 3 */
546 data
[3] = data
[3] | 0x80;
549 memcpy(data
+ 4, afdpart
, afdlength
);
551 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL
, afdlength
+ 4, data
);
554 LDNS_FREE(my_ip_str
);
556 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
560 ldns_str2rdf_b64(ldns_rdf
**rd
, const char *str
)
565 buffer
= LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str
)));
567 return LDNS_STATUS_MEM_ERR
;
570 i
= (uint16_t)ldns_b64_pton((const char*)str
, buffer
,
571 ldns_b64_ntop_calculate_size(strlen(str
)));
574 return LDNS_STATUS_INVALID_B64
;
576 *rd
= ldns_rdf_new_frm_data(
577 LDNS_RDF_TYPE_B64
, (uint16_t) i
, buffer
);
581 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
585 ldns_str2rdf_b32_ext(ldns_rdf
**rd
, const char *str
)
589 /* first byte contains length of actual b32 data */
590 uint8_t len
= ldns_b32_pton_calculate_size(strlen(str
));
591 buffer
= LDNS_XMALLOC(uint8_t, len
+ 1);
593 return LDNS_STATUS_MEM_ERR
;
597 i
= ldns_b32_pton_extended_hex((const char*)str
, strlen(str
), buffer
+ 1,
598 ldns_b32_ntop_calculate_size(strlen(str
)));
601 return LDNS_STATUS_INVALID_B32_EXT
;
603 *rd
= ldns_rdf_new_frm_data(
604 LDNS_RDF_TYPE_B32_EXT
, (uint16_t) i
+ 1, buffer
);
608 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
612 ldns_str2rdf_hex(ldns_rdf
**rd
, const char *str
)
620 if (len
> LDNS_MAX_RDFLEN
* 2) {
621 return LDNS_STATUS_LABEL_OVERFLOW
;
623 t
= LDNS_XMALLOC(uint8_t, (len
/ 2) + 1);
625 return LDNS_STATUS_MEM_ERR
;
628 /* Now process octet by octet... */
631 if (isspace((int) *str
)) {
634 for (i
= 16; i
>= 1; i
-= 15) {
635 while (*str
&& isspace((int) *str
)) { str
++; }
637 if (isxdigit((int) *str
)) {
638 *t
+= ldns_hexdigit_to_int(*str
) * i
;
641 return LDNS_STATUS_ERR
;
649 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_HEX
,
650 (size_t) (t
- t_orig
),
654 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
658 ldns_str2rdf_nsec(ldns_rdf
**rd
, const char *str
)
660 const char *delimiters
= "\n\t ";
661 char *token
= LDNS_XMALLOC(char, LDNS_MAX_RDFLEN
);
662 ldns_buffer
*str_buf
;
665 size_t type_count
= 0;
666 ldns_rr_type type_list
[65536];
667 if(!token
) return LDNS_STATUS_MEM_ERR
;
670 return LDNS_STATUS_NULL
;
673 str_buf
= LDNS_MALLOC(ldns_buffer
);
676 return LDNS_STATUS_MEM_ERR
;
678 ldns_buffer_new_frm_data(str_buf
, (char *)str
, strlen(str
));
679 if(ldns_buffer_status(str_buf
) != LDNS_STATUS_OK
) {
682 return LDNS_STATUS_MEM_ERR
;
685 while ((c
= ldns_bget_token(str_buf
, token
, delimiters
, LDNS_MAX_RDFLEN
)) != -1 && c
!= 0) {
686 if(type_count
>= sizeof(type_list
)) {
689 return LDNS_STATUS_ERR
;
691 cur_type
= ldns_get_rr_type_by_name(token
);
692 type_list
[type_count
] = cur_type
;
696 *rd
= ldns_dnssec_create_nsec_bitmap(type_list
,
701 ldns_buffer_free(str_buf
);
702 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
706 ldns_str2rdf_type(ldns_rdf
**rd
, const char *str
)
709 type
= htons(ldns_get_rr_type_by_name(str
));
710 /* ldns_rr_type is a 16 bit value */
711 *rd
= ldns_rdf_new_frm_data(
712 LDNS_RDF_TYPE_TYPE
, sizeof(uint16_t), &type
);
713 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
717 ldns_str2rdf_class(ldns_rdf
**rd
, const char *str
)
720 klass
= htons(ldns_get_rr_class_by_name(str
));
721 /* class is 16 bit */
722 *rd
= ldns_rdf_new_frm_data(
723 LDNS_RDF_TYPE_CLASS
, sizeof(uint16_t), &klass
);
724 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
727 /* An certificate alg field can either be specified as a 8 bits number
728 * or by its symbolic name. Handle both
731 ldns_str2rdf_cert_alg(ldns_rdf
**rd
, const char *str
)
733 ldns_lookup_table
*lt
;
736 lt
= ldns_lookup_by_name(ldns_cert_algorithms
, str
);
740 ldns_write_uint16(idd
, (uint16_t) lt
->id
);
741 *rd
= ldns_rdf_new_frm_data(
742 LDNS_RDF_TYPE_INT16
, sizeof(uint16_t), idd
);
744 st
= LDNS_STATUS_ERR
;
747 /* try as-is (a number) */
748 st
= ldns_str2rdf_int16(rd
, str
);
749 if (st
== LDNS_STATUS_OK
&&
750 ldns_rdf2native_int16(*rd
) == 0) {
751 st
= LDNS_STATUS_CERT_BAD_ALGORITHM
;
758 /* An alg field can either be specified as a 8 bits number
759 * or by its symbolic name. Handle both
762 ldns_str2rdf_alg(ldns_rdf
**rd
, const char *str
)
764 ldns_lookup_table
*lt
;
767 lt
= ldns_lookup_by_name(ldns_algorithms
, str
);
771 /* it was given as a integer */
772 *rd
= ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8
, (uint8_t) lt
->id
);
774 st
= LDNS_STATUS_ERR
;
777 /* try as-is (a number) */
778 st
= ldns_str2rdf_int8(rd
, str
);
784 ldns_str2rdf_unknown( ATTR_UNUSED(ldns_rdf
**rd
)
785 , ATTR_UNUSED(const char *str
)
788 /* this should be caught in an earlier time (general str2host for
790 return LDNS_STATUS_NOT_IMPL
;
794 ldns_str2rdf_tsig( ATTR_UNUSED(ldns_rdf
**rd
)
795 , ATTR_UNUSED(const char *str
)
798 /* there is no string representation for TSIG rrs */
799 return LDNS_STATUS_NOT_IMPL
;
803 ldns_str2rdf_service( ATTR_UNUSED(ldns_rdf
**rd
)
804 , ATTR_UNUSED(const char *str
)
807 /* is this used? is this actually WKS? or SRV? */
808 return LDNS_STATUS_NOT_IMPL
;
812 loc_parse_cm(char* my_str
, char** endstr
, uint8_t* m
, uint8_t* e
)
814 /* read <digits>[.<digits>][mM] */
815 /* into mantissa exponent format for LOC type */
816 uint32_t meters
= 0, cm
= 0, val
;
817 while (isblank(*my_str
)) {
820 meters
= (uint32_t)strtol(my_str
, &my_str
, 10);
821 if (*my_str
== '.') {
823 cm
= (uint32_t)strtol(my_str
, &my_str
, 10);
840 if (*my_str
== 'm' || *my_str
== 'M') {
848 ldns_str2rdf_loc(ldns_rdf
**rd
, const char *str
)
850 uint32_t latitude
= 0;
851 uint32_t longitude
= 0;
852 uint32_t altitude
= 0;
855 uint32_t equator
= (uint32_t) ldns_power(2, 31);
859 uint8_t size_b
= 1, size_e
= 2;
860 uint8_t horiz_pre_b
= 1, horiz_pre_e
= 6;
861 uint8_t vert_pre_b
= 1, vert_pre_e
= 3;
867 char *my_str
= (char *) str
;
869 /* only support version 0 */
870 if (isdigit((int) *my_str
)) {
871 h
= (uint32_t) strtol(my_str
, &my_str
, 10);
873 return LDNS_STATUS_INVALID_STR
;
876 while (isblank((int) *my_str
)) {
880 if (isdigit((int) *my_str
)) {
881 m
= (uint32_t) strtol(my_str
, &my_str
, 10);
882 } else if (*my_str
== 'N' || *my_str
== 'S') {
885 return LDNS_STATUS_INVALID_STR
;
888 while (isblank((int) *my_str
)) {
892 if (isdigit((int) *my_str
)) {
893 s
= strtod(my_str
, &my_str
);
896 while (isblank((int) *my_str
)) {
900 if (*my_str
== 'N') {
902 } else if (*my_str
== 'S') {
905 return LDNS_STATUS_INVALID_STR
;
912 /* add a little to make floor in conversion a round */
914 latitude
= (uint32_t) s
;
915 latitude
+= 1000 * 60 * m
;
916 latitude
+= 1000 * 60 * 60 * h
;
918 latitude
= equator
+ latitude
;
920 latitude
= equator
- latitude
;
922 while (isblank(*my_str
)) {
926 if (isdigit((int) *my_str
)) {
927 h
= (uint32_t) strtol(my_str
, &my_str
, 10);
929 return LDNS_STATUS_INVALID_STR
;
932 while (isblank((int) *my_str
)) {
936 if (isdigit((int) *my_str
)) {
937 m
= (uint32_t) strtol(my_str
, &my_str
, 10);
938 } else if (*my_str
== 'E' || *my_str
== 'W') {
941 return LDNS_STATUS_INVALID_STR
;
944 while (isblank(*my_str
)) {
948 if (isdigit((int) *my_str
)) {
949 s
= strtod(my_str
, &my_str
);
953 while (isblank(*my_str
)) {
957 if (*my_str
== 'E') {
959 } else if (*my_str
== 'W') {
962 return LDNS_STATUS_INVALID_STR
;
969 /* add a little to make floor in conversion a round */
971 longitude
= (uint32_t) s
;
972 longitude
+= 1000 * 60 * m
;
973 longitude
+= 1000 * 60 * 60 * h
;
976 longitude
+= equator
;
978 longitude
= equator
- longitude
;
981 altitude
= (uint32_t)(strtod(my_str
, &my_str
)*100.0 +
983 if (*my_str
== 'm' || *my_str
== 'M') {
987 if (strlen(my_str
) > 0) {
988 if(!loc_parse_cm(my_str
, &my_str
, &size_b
, &size_e
))
989 return LDNS_STATUS_INVALID_STR
;
992 if (strlen(my_str
) > 0) {
993 if(!loc_parse_cm(my_str
, &my_str
, &horiz_pre_b
, &horiz_pre_e
))
994 return LDNS_STATUS_INVALID_STR
;
997 if (strlen(my_str
) > 0) {
998 if(!loc_parse_cm(my_str
, &my_str
, &vert_pre_b
, &vert_pre_e
))
999 return LDNS_STATUS_INVALID_STR
;
1002 data
= LDNS_XMALLOC(uint8_t, 16);
1004 return LDNS_STATUS_MEM_ERR
;
1008 data
[1] = ((size_b
<< 4) & 0xf0) | (size_e
& 0x0f);
1009 data
[2] = ((horiz_pre_b
<< 4) & 0xf0) | (horiz_pre_e
& 0x0f);
1010 data
[3] = ((vert_pre_b
<< 4) & 0xf0) | (vert_pre_e
& 0x0f);
1011 ldns_write_uint32(data
+ 4, latitude
);
1012 ldns_write_uint32(data
+ 8, longitude
);
1013 ldns_write_uint32(data
+ 12, altitude
);
1015 *rd
= ldns_rdf_new_frm_data(
1016 LDNS_RDF_TYPE_LOC
, 16, data
);
1019 return *rd
?LDNS_STATUS_OK
:LDNS_STATUS_MEM_ERR
;
1023 ldns_str2rdf_wks(ldns_rdf
**rd
, const char *str
)
1025 uint8_t *bitmap
= NULL
;
1029 struct protoent
*proto
= NULL
;
1030 struct servent
*serv
= NULL
;
1033 ldns_buffer
*str_buf
;
1035 char *proto_str
= NULL
;
1037 if(strlen(str
) == 0)
1038 token
= LDNS_XMALLOC(char, 50);
1039 else token
= LDNS_XMALLOC(char, strlen(str
)+2);
1040 if(!token
) return LDNS_STATUS_MEM_ERR
;
1042 str_buf
= LDNS_MALLOC(ldns_buffer
);
1043 if(!str_buf
) {LDNS_FREE(token
); return LDNS_STATUS_MEM_ERR
;}
1044 ldns_buffer_new_frm_data(str_buf
, (char *)str
, strlen(str
));
1045 if(ldns_buffer_status(str_buf
) != LDNS_STATUS_OK
) {
1048 return LDNS_STATUS_MEM_ERR
;
1051 while(ldns_bget_token(str_buf
, token
, "\t\n ", strlen(str
)) > 0) {
1053 proto_str
= strdup(token
);
1057 ldns_buffer_free(str_buf
);
1058 return LDNS_STATUS_INVALID_STR
;
1061 serv
= getservbyname(token
, proto_str
);
1063 serv_port
= (int) ntohs((uint16_t) serv
->s_port
);
1065 serv_port
= atoi(token
);
1067 if (serv_port
/ 8 >= bm_len
) {
1068 uint8_t *b2
= LDNS_XREALLOC(bitmap
, uint8_t, (serv_port
/ 8) + 1);
1072 ldns_buffer_free(str_buf
);
1074 return LDNS_STATUS_INVALID_STR
;
1077 /* set to zero to be sure */
1078 for (; bm_len
<= serv_port
/ 8; bm_len
++) {
1082 ldns_set_bit(bitmap
+ (serv_port
/ 8), 7 - (serv_port
% 8), true);
1086 if (!proto_str
|| !bitmap
) {
1089 ldns_buffer_free(str_buf
);
1091 return LDNS_STATUS_INVALID_STR
;
1094 data
= LDNS_XMALLOC(uint8_t, bm_len
+ 1);
1097 ldns_buffer_free(str_buf
);
1100 return LDNS_STATUS_INVALID_STR
;
1103 proto
= getprotobyname(proto_str
);
1105 data
[0] = (uint8_t) proto
->p_proto
;
1106 } else if (proto_str
) {
1107 data
[0] = (uint8_t) atoi(proto_str
);
1109 memcpy(data
+ 1, bitmap
, (size_t) bm_len
);
1111 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS
, (uint16_t) (bm_len
+ 1), data
);
1115 ldns_buffer_free(str_buf
);
1118 #ifdef HAVE_ENDSERVENT
1121 #ifdef HAVE_ENDPROTOENT
1125 if(!*rd
) return LDNS_STATUS_MEM_ERR
;
1127 return LDNS_STATUS_OK
;
1131 ldns_str2rdf_nsap(ldns_rdf
**rd
, const char *str
)
1134 char* nsap_str
= (char*) str
;
1136 /* just a hex string with optional dots? */
1137 if (str
[0] != '0' || str
[1] != 'x') {
1138 return LDNS_STATUS_INVALID_STR
;
1141 for (i
=0; i
< len
; i
++) {
1142 if (nsap_str
[i
] == '.')
1145 return ldns_str2rdf_hex(rd
, str
+2);
1150 ldns_str2rdf_atma(ldns_rdf
**rd
, const char *str
)
1153 char* atma_str
= (char*) str
;
1156 /* just a hex string with optional dots? */
1158 for (i
=0; i
< len
; i
++) {
1159 if (atma_str
[i
] == '.')
1162 status
= ldns_str2rdf_hex(rd
, str
);
1163 if (status
!= LDNS_STATUS_OK
) {
1164 ; /* probably in e.164 format than */
1170 ldns_str2rdf_ipseckey(ldns_rdf
**rd
, const char *str
)
1172 uint8_t precedence
= 0;
1173 uint8_t gateway_type
= 0;
1174 uint8_t algorithm
= 0;
1175 char* gateway
= NULL
;
1176 char* publickey
= NULL
;
1178 ldns_buffer
*str_buf
;
1180 int token_count
= 0;
1181 int ipseckey_len
= 0;
1182 ldns_rdf
* gateway_rdf
= NULL
;
1183 ldns_rdf
* publickey_rdf
= NULL
;
1184 ldns_status status
= LDNS_STATUS_OK
;
1186 if(strlen(str
) == 0)
1187 token
= LDNS_XMALLOC(char, 256);
1188 else token
= LDNS_XMALLOC(char, strlen(str
)+2);
1189 if(!token
) return LDNS_STATUS_MEM_ERR
;
1191 str_buf
= LDNS_MALLOC(ldns_buffer
);
1192 if(!str_buf
) {LDNS_FREE(token
); return LDNS_STATUS_MEM_ERR
;}
1193 ldns_buffer_new_frm_data(str_buf
, (char *)str
, strlen(str
));
1194 if(ldns_buffer_status(str_buf
) != LDNS_STATUS_OK
) {
1197 return LDNS_STATUS_MEM_ERR
;
1199 while(ldns_bget_token(str_buf
, token
, "\t\n ", strlen(str
)) > 0) {
1200 switch (token_count
) {
1202 precedence
= (uint8_t)atoi(token
);
1205 gateway_type
= (uint8_t)atoi(token
);
1208 algorithm
= (uint8_t)atoi(token
);
1211 gateway
= strdup(token
);
1212 if (!gateway
|| (gateway_type
== 0 &&
1213 (token
[0] != '.' || token
[1] != '\0'))) {
1216 ldns_buffer_free(str_buf
);
1217 return LDNS_STATUS_INVALID_STR
;
1221 publickey
= strdup(token
);
1225 ldns_buffer_free(str_buf
);
1226 return LDNS_STATUS_INVALID_STR
;
1232 if (!gateway
|| !publickey
) {
1236 LDNS_FREE(publickey
);
1238 ldns_buffer_free(str_buf
);
1239 return LDNS_STATUS_INVALID_STR
;
1242 if (gateway_type
== 1) {
1243 status
= ldns_str2rdf_a(&gateway_rdf
, gateway
);
1244 } else if (gateway_type
== 2) {
1245 status
= ldns_str2rdf_aaaa(&gateway_rdf
, gateway
);
1246 } else if (gateway_type
== 3) {
1247 status
= ldns_str2rdf_dname(&gateway_rdf
, gateway
);
1250 if (status
!= LDNS_STATUS_OK
) {
1254 LDNS_FREE(publickey
);
1256 ldns_buffer_free(str_buf
);
1257 return LDNS_STATUS_INVALID_STR
;
1260 status
= ldns_str2rdf_b64(&publickey_rdf
, publickey
);
1262 if (status
!= LDNS_STATUS_OK
) {
1266 LDNS_FREE(publickey
);
1268 ldns_buffer_free(str_buf
);
1269 if (gateway_rdf
) ldns_rdf_free(gateway_rdf
);
1270 return LDNS_STATUS_INVALID_STR
;
1273 /* now copy all into one ipseckey rdf */
1275 ipseckey_len
= 3 + (int)ldns_rdf_size(gateway_rdf
) + (int)ldns_rdf_size(publickey_rdf
);
1277 ipseckey_len
= 3 + (int)ldns_rdf_size(publickey_rdf
);
1279 data
= LDNS_XMALLOC(uint8_t, ipseckey_len
);
1284 LDNS_FREE(publickey
);
1286 ldns_buffer_free(str_buf
);
1287 if (gateway_rdf
) ldns_rdf_free(gateway_rdf
);
1288 if (publickey_rdf
) ldns_rdf_free(publickey_rdf
);
1289 return LDNS_STATUS_MEM_ERR
;
1292 data
[0] = precedence
;
1293 data
[1] = gateway_type
;
1294 data
[2] = algorithm
;
1298 ldns_rdf_data(gateway_rdf
), ldns_rdf_size(gateway_rdf
));
1299 memcpy(data
+ 3 + ldns_rdf_size(gateway_rdf
),
1300 ldns_rdf_data(publickey_rdf
), ldns_rdf_size(publickey_rdf
));
1303 ldns_rdf_data(publickey_rdf
), ldns_rdf_size(publickey_rdf
));
1306 *rd
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY
, (uint16_t) ipseckey_len
, data
);
1311 LDNS_FREE(publickey
);
1313 ldns_buffer_free(str_buf
);
1314 ldns_rdf_free(gateway_rdf
);
1315 ldns_rdf_free(publickey_rdf
);
1317 if(!*rd
) return LDNS_STATUS_MEM_ERR
;
1318 return LDNS_STATUS_OK
;