17#ifdef HAVE_SYS_SOCKET_H
18#include <sys/socket.h>
20#ifdef HAVE_ARPA_INET_H
31#ifdef HAVE_SYS_PARAM_H
43 *r = htons((uint16_t)strtol((
char *)shortstr, &end, 10));
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) {
100 memcpy(r, &l,
sizeof(uint32_t));
107 l = htonl((uint32_t)strtol((
char*)time, &end, 10));
112 memcpy(r, &l,
sizeof(uint32_t));
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) {
144 if (salt_length_str > 512) {
152 for (c = 0; c < salt_length_str; c += 2) {
153 if (isxdigit((
int) salt_str[c]) && isxdigit((
int) salt_str[c+1])) {
161 salt_length = (uint8_t) (salt_length_str / 2);
168 data[0] = salt_length;
169 memcpy(&data[1], salt, salt_length);
189 p = (uint32_t) htonl(p);
208 l = htonl((uint32_t)strtol((
char*)longstr, &end, 10));
209 else l = htonl((uint32_t)strtoul((
char*)longstr, &end, 10));
215 if (errno == ERANGE) {
219 memcpy(r, &l,
sizeof(uint32_t));
228# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
229# define htonll(x) (x)
230# define ntohll(x) (x)
232# define htonll(x) (((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
233# define ntohll(x) (((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
236# define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((x) >> 32))
237# define ntohll(x) ((1==ntohl(1)) ? (x) : ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((x) >> 32))
244 uint8_t r[
sizeof(uint64_t)];
245 char left[21], *right;
247 if(strlen(ipnstr) > 21)
251 if((right = strchr(ipnstr,
'.'))) {
252 uint32_t u32 = strtoul(right + 1, &end, 10);
261 memcpy(r +
sizeof(uint32_t), &u32,
sizeof(uint32_t));
262 memcpy(left, ipnstr, right - ipnstr);
263 left[right - ipnstr] = 0;
265 u32 = strtoul(left, &end, 10);
273 memcpy(r, &u32,
sizeof(uint32_t));
275 uint64_t u64 = strtoull(ipnstr, &end, 10);
280 if(u64 == ULLONG_MAX && errno == ERANGE)
284 memcpy(r, &u64,
sizeof(uint64_t));
299 *r = (uint8_t)strtol((
char*)bytestr, &end, 10);
324parse_escape(uint8_t *ch_p,
const char** str_p)
328 if ((*str_p)[0] && isdigit((
unsigned char)(*str_p)[0]) &&
329 (*str_p)[1] && isdigit((
unsigned char)(*str_p)[1]) &&
330 (*str_p)[2] && isdigit((
unsigned char)(*str_p)[2])) {
332 val = (uint16_t)(((*str_p)[0] -
'0') * 100 +
333 ((*str_p)[1] -
'0') * 10 +
334 ((*str_p)[2] -
'0'));
339 *ch_p = (uint8_t)val;
343 }
else if ((*str_p)[0] && !isdigit((
unsigned char)(*str_p)[0])) {
345 *ch_p = (uint8_t)*(*str_p)++;
354parse_char(uint8_t *ch_p,
const char** str_p)
358 case '\0':
return false;
360 case '\\': *str_p += 1;
361 return parse_escape(ch_p, str_p);
363 default: *ch_p = (uint8_t)*(*str_p)++;
379 uint8_t *q, *pq, label_len;
383 len = strlen((
char*)str);
393 if (1 == len && *str ==
'.') {
409 for (s = str; *s; s++, q++) {
419 if (label_len == 0) {
422 len += label_len + 1;
430 if (! parse_escape(q, &s)) {
450 if (label_len == 0) {
453 len += label_len + 1;
467 if (inet_pton(AF_INET, (
char*)str, &address) != 1) {
481 if (inet_pton(AF_INET6, (
char*)str, address) != 1) {
493 uint8_t *data, *dp, ch = 0;
497 dp = data =
LDNS_XMALLOC(uint8_t, strlen(str) > 255 ? 256 : (strlen(str) + 1));
503 while (parse_char(&ch, &str)) {
504 if (dp - data >= 255) {
514 length = (size_t)(dp - data);
516 data[0] = (uint8_t)length;
537 const char *my_str = str;
544 uint8_t afdlength = 0;
553 if (strlen(my_str) < 2
554 || strchr(my_str,
':') == NULL
555 || strchr(my_str,
'/') == NULL
556 || strchr(my_str,
':') > strchr(my_str,
'/')) {
560 if (my_str[0] ==
'!') {
567 family = (uint16_t) atoi(my_str);
569 my_str = strchr(my_str,
':') + 1;
572 ip_str_len = (size_t) (strchr(my_str,
'/') - my_str);
575 strncpy(my_ip_str, my_str, ip_str_len + 1);
576 my_ip_str[ip_str_len] =
'\0';
585 if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
590 for (i = 0; i < 4; i++) {
591 if (afdpart[i] != 0) {
595 }
else if (family == 2) {
602 if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
607 for (i = 0; i < 16; i++) {
608 if (afdpart[i] != 0) {
618 my_str = strchr(my_str,
'/') + 1;
619 prefix = (uint8_t) atoi(my_str);
627 ldns_write_uint16(data, family);
632 data[3] = data[3] | 0x80;
635 memcpy(data + 4, afdpart, afdlength);
651 if ((*str ==
'-' || *str ==
'0') && str[1] ==
'\0') {
656 buffer =
LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
662 ldns_b64_ntop_calculate_size(strlen(str)));
681 size_t slen = strlen(str);
682 size_t len = ldns_b32_pton_calculate_size(slen);
693 ldns_b32_ntop_calculate_size(slen));
726 if (isspace((
int) *str)) {
729 for (i = 16; i >= 1; i -= 15) {
730 while (*str && isspace((
int) *str)) { str++; }
732 if (isxdigit((
int) *str)) {
745 (
size_t) (t - t_orig),
755 const char *delimiters =
"\n\t ";
760 size_t type_count = 0;
781 if(type_count >=
sizeof(type_list)) {
787 type_list[type_count] = cur_type;
835 ldns_write_uint16(idd, (uint16_t) lt->
id);
904 return ldns_str2rdf_mnemonic4int8(
905 ldns_tlsa_certificate_usages, rd, str);
911 return ldns_str2rdf_mnemonic4int8(ldns_tlsa_selectors, rd, str);
917 return ldns_str2rdf_mnemonic4int8(ldns_tlsa_matching_types, rd, str);
940loc_parse_cm(
char* my_str,
char** endstr, uint8_t* m, uint8_t* e)
944 uint32_t meters = 0, cm = 0, val;
946 while (isblank((
unsigned char)*my_str)) {
949 meters = (uint32_t)strtol(my_str, &my_str, 10);
950 if (*my_str ==
'.') {
952 cm = (uint32_t)strtol(my_str, &cm_endstr, 10);
953 if (cm_endstr - my_str == 1) cm *= 10;
971 if (*my_str ==
'm' || *my_str ==
'M') {
981 uint32_t latitude = 0;
982 uint32_t longitude = 0;
983 uint32_t altitude = 0;
986 uint32_t equator = (uint32_t) ldns_power(2, 31);
990 uint8_t size_b = 1, size_e = 2;
991 uint8_t horiz_pre_b = 1, horiz_pre_e = 6;
992 uint8_t vert_pre_b = 1, vert_pre_e = 3;
995 bool northern_hemisphere;
996 bool eastern_hemisphere;
998 char *my_str = (
char *) str;
1001 if (isdigit((
int) *my_str)) {
1002 h = (uint32_t) strtol(my_str, &my_str, 10);
1007 while (isblank((
int) *my_str)) {
1011 if (isdigit((
int) *my_str)) {
1012 m = (uint32_t) strtol(my_str, &my_str, 10);
1013 }
else if (*my_str ==
'N' || *my_str ==
'S') {
1019 while (isblank((
int) *my_str)) {
1023 if (isdigit((
int) *my_str)) {
1024 s = strtod(my_str, &my_str);
1027 while (isblank((
int) *my_str)) {
1031 if (*my_str ==
'N') {
1032 northern_hemisphere =
true;
1033 }
else if (*my_str ==
'S') {
1034 northern_hemisphere =
false;
1045 latitude = (uint32_t) s;
1046 latitude += 1000 * 60 * m;
1047 latitude += 1000 * 60 * 60 * h;
1048 if (northern_hemisphere) {
1049 latitude = equator + latitude;
1051 latitude = equator - latitude;
1053 while (isblank((
unsigned char)*my_str)) {
1057 if (isdigit((
int) *my_str)) {
1058 h = (uint32_t) strtol(my_str, &my_str, 10);
1063 while (isblank((
int) *my_str)) {
1067 if (isdigit((
int) *my_str)) {
1068 m = (uint32_t) strtol(my_str, &my_str, 10);
1069 }
else if (*my_str ==
'E' || *my_str ==
'W') {
1075 while (isblank((
unsigned char)*my_str)) {
1079 if (isdigit((
int) *my_str)) {
1080 s = strtod(my_str, &my_str);
1084 while (isblank((
unsigned char)*my_str)) {
1088 if (*my_str ==
'E') {
1089 eastern_hemisphere =
true;
1090 }
else if (*my_str ==
'W') {
1091 eastern_hemisphere =
false;
1102 longitude = (uint32_t) s;
1103 longitude += 1000 * 60 * m;
1104 longitude += 1000 * 60 * 60 * h;
1106 if (eastern_hemisphere) {
1107 longitude += equator;
1109 longitude = equator - longitude;
1112 altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
1114 if (*my_str ==
'm' || *my_str ==
'M') {
1118 if (strlen(my_str) > 0) {
1119 if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
1123 if (strlen(my_str) > 0) {
1124 if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
1128 if (strlen(my_str) > 0) {
1129 if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
1139 data[1] = ((size_b << 4) & 0xf0) | (size_e & 0x0f);
1140 data[2] = ((horiz_pre_b << 4) & 0xf0) | (horiz_pre_e & 0x0f);
1141 data[3] = ((vert_pre_b << 4) & 0xf0) | (vert_pre_e & 0x0f);
1142 ldns_write_uint32(data + 4, latitude);
1143 ldns_write_uint32(data + 8, longitude);
1144 ldns_write_uint32(data + 12, altitude);
1156 uint8_t *bitmap = NULL;
1160 struct protoent *proto = NULL;
1161 struct servent *serv = NULL;
1166 char *proto_str = NULL;
1167 char *lc_proto_str = NULL;
1171 if(strlen(str) == 0)
1187 proto_str = strdup(token);
1188 lc_proto_str = strdup(token);
1189 for (c = lc_proto_str; *c; c++) {
1190 *c = tolower((
unsigned char)*c);
1192 if (!proto_str || !lc_proto_str) {
1201 serv = getservbyname(token, proto_str);
1203 serv = getservbyname(token, lc_proto_str);
1205 if (!serv && (lc_token = strdup(token))) {
1206 for (c = lc_token; *c; c++) {
1207 *c = tolower((
unsigned char)*c);
1209 serv = getservbyname(lc_token, proto_str);
1211 serv = getservbyname(lc_token, lc_proto_str);
1216 serv_port = (int) ntohs((uint16_t) serv->s_port);
1218 serv_port = atoi(token);
1220 if (serv_port < 0 || serv_port > 65535) {
1228 if (serv_port / 8 >= bm_len) {
1229 uint8_t *b2 =
LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
1240 for (; bm_len <= serv_port / 8; bm_len++) {
1244 ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8),
true);
1248 if (!proto_str || !bitmap) {
1267 proto = getprotobyname(proto_str);
1269 proto = getprotobyname(lc_proto_str);
1272 data[0] = (uint8_t) proto->p_proto;
1273 }
else if (proto_str) {
1274 data[0] = (uint8_t) atoi(proto_str);
1276 memcpy(data + 1, bitmap, (
size_t) bm_len);
1286#ifdef HAVE_ENDSERVENT
1289#ifdef HAVE_ENDPROTOENT
1302 char* nsap_str = (
char*) str;
1305 if (str[0] !=
'0' || str[1] !=
'x') {
1309 for (i=0; i < len; i++) {
1310 if (nsap_str[i] ==
'.')
1321 char* atma_str = (
char*) str;
1326 for (i=0; i < len; i++) {
1327 if (atma_str[i] ==
'.')
1340 uint8_t precedence = 0;
1341 uint8_t gateway_type = 0;
1342 uint8_t algorithm = 0;
1343 char* gateway = NULL;
1344 char* publickey = NULL;
1348 int token_count = 0;
1349 int ipseckey_len = 0;
1354 if(strlen(str) == 0)
1368 switch (token_count) {
1370 precedence = (uint8_t)atoi(token);
1373 gateway_type = (uint8_t)atoi(token);
1376 algorithm = (uint8_t)atoi(token);
1379 gateway = strdup(token);
1380 if (!gateway || (gateway_type == 0 &&
1381 (token[0] !=
'.' || token[1] !=
'\0'))) {
1389 publickey = strdup(token);
1400 if (!gateway || !publickey) {
1410 if (gateway_type == 1) {
1412 }
else if (gateway_type == 2) {
1414 }
else if (gateway_type == 3) {
1416 }
else if (gateway_type > 3) {
1462 data[0] = precedence;
1463 data[1] = gateway_type;
1464 data[2] = algorithm;
1494 unsigned int a, b, c, d;
1498 if (sscanf(str,
"%4x:%4x:%4x:%4x%n", &a, &b, &c, &d, &l) != 4 ||
1499 l != (
int)strlen(str) ||
1504 shorts[0] = htons(a);
1505 shorts[1] = htons(b);
1506 shorts[2] = htons(c);
1507 shorts[3] = htons(d);
1517 unsigned int a, b, c, d, e, f;
1521 if (sscanf(str,
"%2x-%2x-%2x-%2x-%2x-%2x%n",
1522 &a, &b, &c, &d, &e, &f, &l) != 6 ||
1523 l != (
int)strlen(str)) {
1540 unsigned int a, b, c, d, e, f, g, h;
1544 if (sscanf(str,
"%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n",
1545 &a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 ||
1546 l != (
int)strlen(str)) {
1568 if (strlen(str) > 255) {
1571 for (ptr = str; *ptr; ptr++) {
1572 if (! isalnum((
unsigned char)*ptr)) {
1580 data[0] = strlen(str);
1581 memcpy(data + 1, str, strlen(str));
1594 uint8_t *data, *dp, ch = 0;
1604 while (parse_char(&ch, &str)) {
1615 if (!(length = (
size_t)(dp - data))) {
1641 const char *hit = str == NULL ? NULL : strchr(str,
' ');
1642 const char *pk = hit == NULL ? NULL : strchr(hit + 1,
' ');
1643 size_t hit_size = hit == NULL ? 0
1644 : pk == NULL ? strlen(hit + 1) : (size_t) (pk - hit) - 1;
1645 size_t pk_size = pk == NULL ? 0 : strlen(pk + 1);
1646 size_t hit_wire_size = (hit_size + 1) / 2;
1647 size_t pk_wire_size = ldns_b64_pton_calculate_size(pk_size);
1648 size_t rdf_size = 4 + hit_wire_size + pk_wire_size;
1651 int algorithm = str == NULL ? 0 : strtol(str, &endptr, 10);
1654 int hi, lo, written;
1656 if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255
1658 || algorithm < 0 || algorithm > 255
1659 || (errno != 0 && algorithm == 0)
1660 || endptr == str ) {
1666 if ((data =
LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) {
1697 data[0] = (uint8_t) hit_wire_size;
1698 data[1] = (uint8_t) algorithm;
1700 for (dp = data + 4; *hit && *hit !=
' '; dp++) {
1708 *dp = (uint8_t) hi << 4 | lo;
1719 pk_wire_size = (uint16_t) written;
1720 ldns_write_uint16(data + 2, pk_wire_size);
1721 rdf_size = 4 + hit_wire_size + pk_wire_size;
1749 uint8_t precedence = 0;
1750 uint8_t relay_type = 0;
1751 uint8_t discovery_optional = 0;
1756 int token_count = 0;
1757 int amtrelay_len = 0;
1761 if(strlen(str) == 0)
1775 switch (token_count) {
1777 precedence = (uint8_t)atoi(token);
1780 discovery_optional = (uint8_t)atoi(token);
1781 if (discovery_optional != 0 &&
1782 discovery_optional != 1) {
1790 relay_type = (uint8_t)atoi(token);
1793 relay = strdup(token);
1794 if (!relay || (relay_type == 0 &&
1795 (token[0] !=
'.' || token[1] !=
'\0'))) {
1810 if (!relay && relay_type > 0) {
1818 if (relay_type == 1) {
1820 }
else if (relay_type == 2) {
1822 }
else if (relay_type == 3) {
1824 }
else if (relay_type > 3) {
1853 data[0] = precedence;
1854 data[1] = relay_type;
1855 data[1] |= (discovery_optional << 7);
1862 , (uint16_t) amtrelay_len, data);
1874#ifdef RRTYPE_SVCB_HTTPS
1876network_uint16_cmp(
const void *a,
const void *b)
1878 return ((
int)ldns_read_uint16(a)) - ((int)ldns_read_uint16(b));
1883parse_svcparam_mandatory(
const char **s, uint8_t **dp, uint8_t *eod)
1885 bool quoted =
false;
1886 uint8_t *keys = *dp;
1897 if ((st = parse_svcparam_key(s, &key)))
1903 ldns_write_uint16(*dp, key);
1916 if (*dp - keys == 0)
1919 if (**s && !isspace((
unsigned char)**s))
1927 qsort(keys, (*dp - keys) / 2, 2, network_uint16_cmp);
1934 while (keys < *dp) {
1935 uint16_t key = ldns_read_uint16(keys);
1937 if (key == prev_key) {
1946 memmove(keys - 2, keys, *dp - keys);
1956INLINE bool parse_escape2(uint8_t *ch_p,
const char** str_p)
1957{ *str_p += 1;
return parse_escape(ch_p, str_p); }
1960parse_svcparam_alpn(
const char **s, uint8_t **dp, uint8_t *eod)
1971 while (**s !=
'"') {
1975 else if (**s ==
',') {
1977 if (len == 0 || len > 255)
1986 }
else if (*dp + 1 > eod)
1989 else if (**s !=
'\\')
1990 *(*dp)++ = (uint8_t)*(*s)++;
1992 else if (!parse_escape2(*dp, s))
1999 }
else while (**s && !isspace((
unsigned char)**s)) {
2002 if (len == 0 || len > 255)
2011 }
else if (*dp + 1 > eod)
2014 else if (**s !=
'\\')
2015 *(*dp)++ = (uint8_t)*(*s)++;
2017 else if (!parse_escape2(*dp, s))
2023 if (len == 0 || len > 255)
2026 return **s && !isspace((
unsigned char)**s)
2032parse_svcparam_value(
const char **s, uint8_t **dp, uint8_t *eod)
2036 while (**s !=
'"') {
2040 else if (*dp + 1 > eod)
2043 else if (**s !=
'\\')
2044 *(*dp)++ = (uint8_t)*(*s)++;
2046 else if (!parse_escape2(*dp, s))
2053 }
else while (**s && !isspace((
unsigned char)**s)) {
2057 else if (**s !=
'\\')
2058 *(*dp)++ = (uint8_t)*(*s)++;
2060 else if (!parse_escape2(*dp, s))
2065 return **s && !isspace((
unsigned char)**s)
2071parse_svcparam_port(
const char **s, uint8_t **dp, uint8_t *eod)
2078 unsigned long int num;
2080 if ((st = parse_svcparam_value(s, dp, eod)))
2083 if (len == 0 || len > 5)
2086 memcpy(num_str, val, len);
2088 num = strtoul(num_str, &endptr, 10);
2092 ldns_write_uint16(val, num);
2098parse_svcparam_ipv4hint(
const char **s, uint8_t **dp, uint8_t *eod)
2100 bool quoted =
false;
2107 const char *ipv4_start = *s;
2111 while (isdigit((
unsigned char)**s) || **s ==
'.')
2114 len = *s - ipv4_start;
2115 if (len == 0 || len > 15)
2121 memcpy(ipv4_str, ipv4_start, len);
2123 if (inet_pton(AF_INET, ipv4_str, *dp) != 1)
2137 return **s && !isspace((
unsigned char)**s)
2143parse_svcparam_ech(
const char **s, uint8_t **dp, uint8_t *eod)
2145 bool quoted =
false;
2146 const char *b64_str;
2147 size_t len, pad, out_len;
2157 while (isalnum((
unsigned char)**s) || **s ==
'+'
2164 pad = pad ? 4 - pad : 0;
2165 if (len == 0 || pad == 3)
2173 if (**s && !isspace((
unsigned char)**s))
2176 out_len = ldns_b64_pton_calculate_size(len);
2177 if (*dp + out_len > eod)
2180 if (len + pad >
sizeof(in_buf) - 1
2184 memcpy(in, b64_str, len);
2200parse_svcparam_ipv6hint(
const char **s, uint8_t **dp, uint8_t *eod)
2202 bool quoted =
false;
2209 const char *ipv6_start = *s;
2213 while (isxdigit((
unsigned char)**s) || **s ==
':' || **s ==
'.')
2216 len = *s - ipv6_start;
2223 memcpy(ipv6_str, ipv6_start, len);
2225 if (inet_pton(AF_INET6, ipv6_str, *dp) != 1)
2239 return **s && !isspace((
unsigned char)**s)
2252 , {
"no-default-alpn", 15 }
2254 , {
"ipv4hint" , 8 }
2256 , {
"ipv6hint" , 8 }
2257 , {
"dohpath" , 7 } };
2259static const size_t svcparam_key_defs_len =
sizeof(svcparam_key_defs)
2268 ldns_buffer_write_string(output, svcparam_key_defs[key].
str);
2271 return ldns_buffer_status(output);
2278 const char *key_str = *s;
2281 unsigned long int num;
2284 while (islower((
unsigned char)**s) || isdigit((
unsigned char)**s)
2289 for (i = 0; i < svcparam_key_defs_len; i++) {
2290 if (
len == svcparam_key_defs[i].
len
2291 && !strncmp(key_str, svcparam_key_defs[i].
str,
len)) {
2297 if (
len == 9 && !strncmp(key_str,
"echconfig", 9)) {
2301 if (len < 4 || len > 8 || strncmp(key_str,
"key", 3))
2304 memcpy(num_str, key_str + 3,
len - 3);
2305 num_str[
len - 3] = 0;
2306 num = strtoul(num_str, &endptr, 10);
2307 if (*endptr || num > 65535)
2323parse_svcparam(
const char **s, uint8_t **dp, uint8_t *eod)
2332 if ((st = parse_svcparam_key(s, &key)))
2335 ldns_write_uint16(*dp, key);
2336 ldns_write_uint16(*dp + 2, 0);
2338 if (isspace((
unsigned char)**s) || !**s)
2341 else if (**s !=
'=')
2347 st = parse_svcparam_mandatory(s, dp, eod);
2350 st = parse_svcparam_alpn(s, dp, eod);
2355 st = parse_svcparam_port(s, dp, eod);
2358 st = parse_svcparam_ipv4hint(s, dp, eod);
2361 st = parse_svcparam_ech(s, dp, eod);
2364 st = parse_svcparam_ipv6hint(s, dp, eod);
2367 st = parse_svcparam_value(s, dp, eod);
2372 ldns_write_uint16(val - 2, *dp - val);
2377svcparam_ptr_cmp(
const void *a,
const void *b)
2379 uint8_t *x = *(uint8_t **)a , *y = *(uint8_t **)b;
2380 uint16_t x_type = ldns_read_uint16(x), y_type = ldns_read_uint16(y);
2381 uint16_t x_len , y_len;
2383 if (x_type != y_type)
2384 return x_type > y_type ? 1 : -1;
2386 x_len = ldns_read_uint16(x + 2);
2387 y_len = ldns_read_uint16(y + 2);
2389 return x_len != y_len
2390 ? (x_len > y_len ? 1 : -1)
2391 : (x_len == 0 ? 0 : memcmp(x + 4, y + 4, x_len));
2397 uint8_t *data, *dp, *eod, *p, *new_data;
2401 uint8_t **svcparams;
2407 length = strlen(
str);
2411 eod = data + length * 4;
2415 while (isspace((
unsigned char)*
str))
2419 if ((st = parse_svcparam(&
str, &dp, eod))) {
2437 for ( p = data, i = 0
2438 ; p < dp && i < nparams
2439 ; p += 4 + ldns_read_uint16(p + 2))
2442 qsort(svcparams, i,
sizeof(uint8_t *), svcparam_ptr_cmp);
2454 for ( p = new_data, i = 0
2455 ; p < new_data + length && i < nparams
2456 ; p += 4 + ldns_read_uint16(p + 2), i += 1) {
2457 uint16_t key = ldns_read_uint16(svcparams[i]);
2472 if (key == prev_key && ldns_read_uint16(svcparams[i] + 2)
2473 == ldns_read_uint16(svcparams[i - 1] + 2)
2474 && 0 == memcmp( svcparams[i ] + 4
2475 , svcparams[i - 1] + 4
2476 , ldns_read_uint16(svcparams[i] + 2))) {
2477 p -= 4 + ldns_read_uint16(svcparams[i] + 2);
2480 memcpy(p, svcparams[i], 4 + ldns_read_uint16(svcparams[i] + 2));
2498 (void)rd; (void)
str;
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
int ldns_buffer_printf(ldns_buffer *buffer, const char *format,...)
prints to the buffer, increasing the capacity if required using buffer_reserve().
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
@ LDNS_TLSA_SELECTOR_PRIVSEL
Reserved for Private Use.
@ LDNS_TLSA_SELECTOR_SPKI
SubjectPublicKeyInfo: DER-encoded binary structure as defined in [RFC5280].
@ LDNS_TLSA_SELECTOR_CERT
Full certificate: the Certificate binary structure as defined in [RFC5280].
@ LDNS_TLSA_USAGE_PRIVCERT
Reserved for Private Use.
@ LDNS_TLSA_USAGE_DANE_EE
Domain issued certificate.
@ LDNS_TLSA_USAGE_PKIX_EE
Service certificate constraint.
@ LDNS_TLSA_USAGE_PKIX_TA
CA constraint.
@ LDNS_TLSA_USAGE_DANE_TA
Trust anchor assertion.
@ LDNS_TLSA_MATCHING_TYPE_FULL
Exact match on selected content.
@ LDNS_TLSA_MATCHING_TYPE_SHA2_512
SHA-512 hash of selected content [RFC6234].
@ LDNS_TLSA_MATCHING_TYPE_SHA2_256
SHA-256 hash of selected content [RFC6234].
@ LDNS_TLSA_MATCHING_TYPE_PRIVMATCH
Reserved for Private Use.
signed char ldns_dname_str_absolute(const char *dname_str)
Checks whether the given dname string is absolute (i.e.
ldns_rdf * ldns_dnssec_create_nsec_bitmap(ldns_rr_type rr_type_list[], size_t size, ldns_rr_type nsec_type)
Create the type bitmap for an NSEC(3) record.
@ LDNS_STATUS_INVALID_STR
@ LDNS_STATUS_DOMAINNAME_UNDERFLOW
@ LDNS_STATUS_INVALID_EUI48
@ LDNS_STATUS_INVALID_IP4
@ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW
@ LDNS_STATUS_SYNTAX_SVCPARAM_KEY_ERR
@ LDNS_STATUS_INVALID_TIME
@ LDNS_STATUS_INVALID_EUI64
@ LDNS_STATUS_INVALID_B32_EXT
@ LDNS_STATUS_LABEL_OVERFLOW
@ LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED
@ LDNS_STATUS_INVALID_IP6
@ LDNS_STATUS_INVALID_ILNP64
@ LDNS_STATUS_INVALID_HEX
@ LDNS_STATUS_SYNTAX_BAD_ESCAPE
@ LDNS_STATUS_SYNTAX_SVCPARAM_VALUE_ERR
@ LDNS_STATUS_INVALID_INT
@ LDNS_STATUS_EMPTY_LABEL
@ LDNS_STATUS_DOMAINNAME_OVERFLOW
@ LDNS_STATUS_INVALID_B64
@ LDNS_STATUS_INVALID_TAG
@ LDNS_STATUS_RDATA_OVERFLOW
@ LDNS_STATUS_CERT_BAD_ALGORITHM
enum ldns_enum_status ldns_status
Including this file will include all ldns files, and define some lookup tables.
ldns_lookup_table ldns_algorithms[]
Taken from RFC 2535, section 7.
ldns_lookup_table ldns_cert_algorithms[]
Taken from RFC 2538.
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
returns a token/char from the buffer b.
uint32_t ldns_str2period(const char *nptr, const char **endptr)
converts a ttl value (like 5d2h) to a long.
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
ldns_rdf * ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
allocates a new rdf structure and fills it.
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
enum ldns_enum_svcparam_key ldns_svcparam_key
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
@ LDNS_RDF_TYPE_INT32
32 bits
@ LDNS_RDF_TYPE_TAG
A non-zero sequence of US-ASCII letters and numbers in lower case.
@ LDNS_RDF_TYPE_HIP
Represents the Public Key Algorithm, HIT and Public Key fields for the HIP RR types.
@ LDNS_RDF_TYPE_IPN
draft-johnson-dns-ipn-cla-07
@ LDNS_RDF_TYPE_B32_EXT
b32 string
@ LDNS_RDF_TYPE_EUI48
6 * 8 bit hex numbers separated by dashes.
@ LDNS_RDF_TYPE_EUI64
8 * 8 bit hex numbers separated by dashes.
@ LDNS_RDF_TYPE_PERIOD
period
@ LDNS_RDF_TYPE_B64
b64 string
@ LDNS_RDF_TYPE_AAAA
AAAA record.
@ LDNS_RDF_TYPE_WKS
well known services
@ LDNS_RDF_TYPE_DNAME
domain name
@ LDNS_RDF_TYPE_TIME
time (32 bits)
@ LDNS_RDF_TYPE_SVCPARAMS
draft-ietf-dnsop-svcb-https
@ LDNS_RDF_TYPE_NSEC3_SALT
nsec3 hash salt
@ LDNS_RDF_TYPE_APL
apl data
@ LDNS_RDF_TYPE_A
A record.
@ LDNS_RDF_TYPE_LONG_STR
A <character-string> encoding of the value field as specified [RFC1035], Section 5....
@ LDNS_RDF_TYPE_LOC
location data
@ LDNS_RDF_TYPE_ILNP64
4 shorts represented as 4 * 16 bit hex numbers separated by colons.
@ LDNS_RDF_TYPE_HEX
hex string
@ LDNS_RDF_TYPE_CLASS
a class
@ LDNS_RDF_TYPE_INT8
8 bits
@ LDNS_RDF_TYPE_IPSECKEY
IPSECKEY.
@ LDNS_RDF_TYPE_STR
txt string
@ LDNS_RDF_TYPE_INT16
16 bits
@ LDNS_RDF_TYPE_AMTRELAY
draft-ietf-mboned-driad-amt-discovery
@ LDNS_RDF_TYPE_TYPE
a RR type
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
@ LDNS_SVCPARAM_KEY_MANDATORY
@ LDNS_SVCPARAM_KEY_IPV4HINT
@ LDNS_SVCPARAM_KEY_IPV6HINT
@ LDNS_SVCPARAM_KEY_LAST_KEY
@ LDNS_SVCPARAM_KEY_NO_DEFAULT_ALPN
ldns_rr_class ldns_get_rr_class_by_name(const char *name)
retrieves a class by looking up its name.
#define LDNS_MAX_LABELLEN
Maximum length of a dname label.
enum ldns_enum_rr_type ldns_rr_type
#define LDNS_MAX_DOMAINLEN
Maximum length of a complete dname.
ldns_rr_type ldns_get_rr_type_by_name(const char *name)
retrieves a rrtype by looking up its name.
ldns_status ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
convert a hex value into wireformat
ldns_status ldns_str2rdf_amtrelay(ldns_rdf **rd, const char *str)
Convert a "<precedence> <D-bit> <type> <relay>" encoding of the value field as specified in Section 4...
ldns_status ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
convert a byte into wireformat
ldns_status ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str)
convert a tlsa certificate usage value into wireformat
ldns_status ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
Convert a "<algorithm> <hit> <pk>" encoding of the value field as specified in Section 6.
ldns_status ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
convert a str with a ATMA RR into wireformat
ldns_status ldns_str2rdf_type(ldns_rdf **rd, const char *str)
convert a rrtype into wireformat
ldns_status ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
ldns_status ldns_str2rdf_svcparams(ldns_rdf **rd, const char *str)
Convert a series of "key[=<value>]" encodings to wireformat as described in [draft-ietf-dnsop-svcb-ht...
ldns_status ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
convert the str with an AAAA record into wireformat
ldns_status ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
convert the string with the b32 ext hex data into wireformat
ldns_status ldns_str2rdf_period(ldns_rdf **rd, const char *period)
ldns_status ldns_str2rdf_long_str(ldns_rdf **rd, const char *str)
Convert a <character-string> encoding of the value field as specified [RFC1035], Section 5....
ldns_status ldns_str2rdf_class(ldns_rdf **rd, const char *str)
convert string with a classname into wireformat
ldns_status svcparam_key2buffer_str(ldns_buffer *output, uint16_t key)
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
ldns_status ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
convert an algorithm value into wireformat
ldns_status ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
convert string with nsec into wireformat
ldns_status ldns_str2rdf_a(ldns_rdf **rd, const char *str)
convert str with an A record into wireformat
ldns_status ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str)
convert a tlsa matching type value into wireformat
ldns_status ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
convert string with a WKS RR into wireformat
ldns_status ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str)
convert 4 * 16bit hex separated by colons into wireformat
ldns_status ldns_str2rdf_unknown(ldns_rdf **rd __attribute__((unused)), const char *str __attribute__((unused)))
ldns_status ldns_str2rdf_service(ldns_rdf **rd __attribute__((unused)), const char *str __attribute__((unused)))
ldns_status ldns_str2rdf_time(ldns_rdf **rd, const char *time)
convert a time string to a time value in wireformat
ldns_status ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
convert a str with a NSAP RR into wireformat
ldns_status ldns_str2rdf_eui64(ldns_rdf **rd, const char *str)
convert 8 hex bytes separated by dashes into wireformat
ldns_status ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
convert a string with a LOC RR into wireformat
ldns_status ldns_str2rdf_str(ldns_rdf **rd, const char *str)
convert a string into wireformat (think txt record)
ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
convert a str with a IPSECKEY RR into wireformat
ldns_status ldns_str2rdf_selector(ldns_rdf **rd, const char *str)
convert a tlsa selector value into wireformat
ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str)
Convert a non-zero sequence of US-ASCII letters and numbers into wireformat.
ldns_status ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
convert str with the apl record into wireformat
ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
convert the string with the b64 data into wireformat
ldns_status ldns_str2rdf_ipn(ldns_rdf **rd, const char *ipnstr)
Convert either two unsigned 32 bit decimal numbers seperated by a '.
ldns_status ldns_str2rdf_eui48(ldns_rdf **rd, const char *str)
convert 6 hex bytes separated by dashes into wireformat
ldns_status ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
convert a strings into a 4 byte int in wireformat
ldns_status ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
convert a string to a int16 in wireformat
ldns_status ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
convert an certificate algorithm value into wireformat
implementation of buffers to ease operations
A general purpose lookup table.
Resource record data field.
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
int ldns_b32_pton_extended_hex(const char *src_text, size_t src_text_length, uint8_t *target_data_buffer, size_t target_data_buffer_size)
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
ldns_lookup_table * ldns_lookup_by_name(ldns_lookup_table table[], const char *name)
Looks up the table entry by name, returns NULL if not found.
#define INLINE
splint static inline workaround
#define LDNS_MALLOC(type)
Memory management macros.
void ldns_set_bit(uint8_t *byte, int bit_nr, signed char value)
sets the specified bit in the specified byte to 1 if value is true, 0 if false The bits are counted f...
#define LDNS_XMALLOC(type, count)
#define LDNS_XREALLOC(ptr, type, count)