ldns  1.9.2
str2host.c
Go to the documentation of this file.
1 /*
2  * str2host.c
3  *
4  * conversion routines from the presentation format
5  * to the host format
6  *
7  * a Net::DNS like library for C
8  *
9  * (c) NLnet Labs, 2004-2006
10  *
11  * See the file LICENSE for the license
12  */
13 #include <ldns/config.h>
14 
15 #include <ldns/ldns.h>
16 
17 #ifdef HAVE_SYS_SOCKET_H
18 #include <sys/socket.h>
19 #endif
20 #ifdef HAVE_ARPA_INET_H
21 #include <arpa/inet.h>
22 #endif
23 #include <time.h>
24 
25 #include <errno.h>
26 #ifdef HAVE_NETDB_H
27 #include <netdb.h>
28 #endif
29 
30 #include <limits.h>
31 #ifdef HAVE_SYS_PARAM_H
32 #include <sys/param.h>
33 #endif
34 
36 ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
37 {
38  char *end = NULL;
39  uint16_t *r;
40  r = LDNS_MALLOC(uint16_t);
41  if(!r) return LDNS_STATUS_MEM_ERR;
42 
43  *r = htons((uint16_t)strtol((char *)shortstr, &end, 10));
44 
45  if(*end != 0) {
46  LDNS_FREE(r);
48  } else {
50  LDNS_RDF_TYPE_INT16, sizeof(uint16_t), r);
51  LDNS_FREE(r);
53  }
54 }
55 
57 ldns_str2rdf_time(ldns_rdf **rd, const char *time)
58 {
59  /* convert a time YYYYDDMMHHMMSS to wireformat */
60  uint32_t *r = NULL;
61  struct tm tm;
62  uint32_t l;
63  char *end;
64 
65  /* Try to scan the time... */
66  r = (uint32_t *)LDNS_MALLOC(uint32_t);
67  if(!r) return LDNS_STATUS_MEM_ERR;
68 
69  memset(&tm, 0, sizeof(tm));
70 
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
73  ) {
74  tm.tm_year -= 1900;
75  tm.tm_mon--;
76  /* Check values */
77  if (tm.tm_year < 70) {
78  goto bad_format;
79  }
80  if (tm.tm_mon < 0 || tm.tm_mon > 11) {
81  goto bad_format;
82  }
83  if (tm.tm_mday < 1 || tm.tm_mday > 31) {
84  goto bad_format;
85  }
86 
87  if (tm.tm_hour < 0 || tm.tm_hour > 23) {
88  goto bad_format;
89  }
90 
91  if (tm.tm_min < 0 || tm.tm_min > 59) {
92  goto bad_format;
93  }
94 
95  if (tm.tm_sec < 0 || tm.tm_sec > 59) {
96  goto bad_format;
97  }
98 
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);
103  LDNS_FREE(r);
105  } else {
106  /* handle it as 32 bits timestamp */
107  l = htonl((uint32_t)strtol((char*)time, &end, 10));
108  if(*end != 0) {
109  LDNS_FREE(r);
110  return LDNS_STATUS_ERR;
111  } else {
112  memcpy(r, &l, sizeof(uint32_t));
113  *rd = ldns_rdf_new_frm_data(
114  LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
115  LDNS_FREE(r);
117  }
118  }
119 
120  bad_format:
121  LDNS_FREE(r);
123 }
124 
126 ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
127 {
128  uint8_t salt_length;
129  int c;
130  int salt_length_str;
131 
132  uint8_t *salt;
133  uint8_t *data;
134  if(rd == NULL) {
135  return LDNS_STATUS_NULL;
136  }
137 
138  salt_length_str = (int)strlen(salt_str);
139  if (salt_length_str == 1 && salt_str[0] == '-') {
140  salt_length_str = 0;
141  } else if (salt_length_str % 2 != 0) {
143  }
144  if (salt_length_str > 512) {
146  }
147 
148  salt = LDNS_XMALLOC(uint8_t, salt_length_str / 2);
149  if(!salt) {
150  return LDNS_STATUS_MEM_ERR;
151  }
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]);
156  } else {
157  LDNS_FREE(salt);
159  }
160  }
161  salt_length = (uint8_t) (salt_length_str / 2);
162 
163  data = LDNS_XMALLOC(uint8_t, 1 + salt_length);
164  if(!data) {
165  LDNS_FREE(salt);
166  return LDNS_STATUS_MEM_ERR;
167  }
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);
171  LDNS_FREE(data);
172  LDNS_FREE(salt);
173 
175 }
176 
178 ldns_str2rdf_period(ldns_rdf **rd,const char *period)
179 {
180  uint32_t p;
181  const char *end;
182 
183  /* Allocate required space... */
184  p = ldns_str2period(period, &end);
185 
186  if (*end != 0) {
187  return LDNS_STATUS_ERR;
188  } else {
189  p = (uint32_t) htonl(p);
190  *rd = ldns_rdf_new_frm_data(
191  LDNS_RDF_TYPE_PERIOD, sizeof(uint32_t), &p);
192  }
194 }
195 
197 ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
198 {
199  char *end;
200  uint32_t *r = NULL;
201  uint32_t l;
202 
203  r = (uint32_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 */
207  if(*longstr == '-')
208  l = htonl((uint32_t)strtol((char*)longstr, &end, 10));
209  else l = htonl((uint32_t)strtoul((char*)longstr, &end, 10));
210 
211  if(*end != 0) {
212  LDNS_FREE(r);
213  return LDNS_STATUS_ERR;
214  } else {
215  if (errno == ERANGE) {
216  LDNS_FREE(r);
218  }
219  memcpy(r, &l, sizeof(uint32_t));
220  *rd = ldns_rdf_new_frm_data(
221  LDNS_RDF_TYPE_INT32, sizeof(uint32_t), r);
222  LDNS_FREE(r);
224  }
225 }
226 
227 #ifdef __BYTE_ORDER__
228 # if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
229 # define htonll(x) (x)
230 # define ntohll(x) (x)
231 # else
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))
234 # endif
235 #else
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))
238 #endif
239 
241 ldns_str2rdf_ipn(ldns_rdf **rd, const char *ipnstr)
242 {
243  char *end;
244  uint8_t r[sizeof(uint64_t)];
245  char left[21], *right;
246 
247  if(strlen(ipnstr) > 21)
249  errno = 0; /* must set to zero before call,
250  note race condition on errno */
251  if((right = strchr(ipnstr, '.'))) {
252  uint32_t u32 = strtoul(right + 1, &end, 10);
253 
254  if(*end != 0)
255  return LDNS_STATUS_ERR;
256 
257  if(errno == ERANGE)
259 
260  u32 = htonl(u32);
261  memcpy(r + sizeof(uint32_t), &u32, sizeof(uint32_t));
262  memcpy(left, ipnstr, right - ipnstr);
263  left[right - ipnstr] = 0;
264 
265  u32 = strtoul(left, &end, 10);
266  if(*end != 0)
267  return LDNS_STATUS_ERR;
268 
269  if(errno == ERANGE)
271 
272  u32 = htonl(u32);
273  memcpy(r, &u32, sizeof(uint32_t));
274  } else {
275  uint64_t u64 = strtoull(ipnstr, &end, 10);
276 
277  if(*end != 0)
278  return LDNS_STATUS_ERR;
279 
280  if(u64 == ULLONG_MAX && errno == ERANGE)
282 
283  u64 = htonll(u64);
284  memcpy(r, &u64, sizeof(uint64_t));
285  }
286  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPN, sizeof(r), r);
287  return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
288 }
289 
291 ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
292 {
293  char *end;
294  uint8_t *r = NULL;
295 
296  r = LDNS_MALLOC(uint8_t);
297  if(!r) return LDNS_STATUS_MEM_ERR;
298 
299  *r = (uint8_t)strtol((char*)bytestr, &end, 10);
300 
301  if(*end != 0) {
302  LDNS_FREE(r);
303  return LDNS_STATUS_ERR;
304  } else {
305  *rd = ldns_rdf_new_frm_data(
306  LDNS_RDF_TYPE_INT8, sizeof(uint8_t), r);
307  LDNS_FREE(r);
309  }
310 }
311 
312 
313 /*
314  * Checks whether the escaped value at **s is an decimal value or
315  * a 'normally' escaped character (and not eos)
316  *
317  * The string pointer at *s is increased by either 0 (on error), 1 (on
318  * normal escapes), or 3 (on decimals)
319  *
320  * Returns the number of bytes read from the escaped string, or
321  * 0 on error
322  */
323 INLINE bool
324 parse_escape(uint8_t *ch_p, const char** str_p)
325 {
326  uint16_t val;
327 
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])) {
331 
332  val = (uint16_t)(((*str_p)[0] - '0') * 100 +
333  ((*str_p)[1] - '0') * 10 +
334  ((*str_p)[2] - '0'));
335 
336  if (val > 255) {
337  goto error;
338  }
339  *ch_p = (uint8_t)val;
340  *str_p += 3;
341  return true;
342 
343  } else if ((*str_p)[0] && !isdigit((unsigned char)(*str_p)[0])) {
344 
345  *ch_p = (uint8_t)*(*str_p)++;
346  return true;
347  }
348 error:
349  *str_p = NULL;
350  return false; /* LDNS_STATUS_SYNTAX_BAD_ESCAPE */
351 }
352 
353 INLINE bool
354 parse_char(uint8_t *ch_p, const char** str_p)
355 {
356  switch (**str_p) {
357 
358  case '\0': return false;
359 
360  case '\\': *str_p += 1;
361  return parse_escape(ch_p, str_p);
362 
363  default: *ch_p = (uint8_t)*(*str_p)++;
364  return true;
365  }
366 }
367 
368 /*
369  * No special care is taken, all dots are translated into
370  * label separators.
371  * Could be made more efficient....we do 3 memcpy's in total...
372  */
374 ldns_str2rdf_dname(ldns_rdf **d, const char *str)
375 {
376  size_t len;
377 
378  const char *s;
379  uint8_t *q, *pq, label_len;
380  uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
381  *d = NULL;
382 
383  len = strlen((char*)str);
384  /* octet representation can make strings a lot longer than actual length */
385  if (len > LDNS_MAX_DOMAINLEN * 4) {
387  }
388  if (0 == len) {
390  }
391 
392  /* root label */
393  if (1 == len && *str == '.') {
395  return LDNS_STATUS_OK;
396  }
397 
398  /* get on with the rest */
399 
400  /* s is on the current character in the string
401  * pq points to where the labellength is going to go
402  * label_len keeps track of the current label's length
403  * q builds the dname inside the buf array
404  */
405  len = 0;
406  q = buf+1;
407  pq = buf;
408  label_len = 0;
409  for (s = str; *s; s++, q++) {
410  if (q >= buf + LDNS_MAX_DOMAINLEN) {
412  }
413  *q = 0;
414  switch (*s) {
415  case '.':
416  if (label_len > LDNS_MAX_LABELLEN) {
418  }
419  if (label_len == 0) {
421  }
422  len += label_len + 1;
423  *pq = label_len;
424  label_len = 0;
425  pq = q;
426  break;
427  case '\\':
428  /* octet value or literal char */
429  s += 1;
430  if (! parse_escape(q, &s)) {
432  }
433  s -= 1;
434  label_len++;
435  break;
436  default:
437  *q = (uint8_t)*s;
438  label_len++;
439  }
440  }
441 
442  /* add root label if last char was not '.' */
443  if (!ldns_dname_str_absolute(str)) {
444  if (q >= buf + LDNS_MAX_DOMAINLEN) {
446  }
447  if (label_len > LDNS_MAX_LABELLEN) {
449  }
450  if (label_len == 0) { /* label_len 0 but not . at end? */
452  }
453  len += label_len + 1;
454  *pq = label_len;
455  *q = 0;
456  }
457  len++;
458 
460  return LDNS_STATUS_OK;
461 }
462 
464 ldns_str2rdf_a(ldns_rdf **rd, const char *str)
465 {
466  in_addr_t address;
467  if (inet_pton(AF_INET, (char*)str, &address) != 1) {
469  } else {
470  *rd = ldns_rdf_new_frm_data(
471  LDNS_RDF_TYPE_A, sizeof(address), &address);
472  }
474 }
475 
477 ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
478 {
479  uint8_t address[LDNS_IP6ADDRLEN + 1];
480 
481  if (inet_pton(AF_INET6, (char*)str, address) != 1) {
483  } else {
484  *rd = ldns_rdf_new_frm_data(
485  LDNS_RDF_TYPE_AAAA, sizeof(address) - 1, &address);
486  }
488 }
489 
491 ldns_str2rdf_str(ldns_rdf **rd, const char *str)
492 {
493  uint8_t *data, *dp, ch = 0;
494  size_t length;
495 
496  /* Worst case space requirement. We'll realloc to actual size later. */
497  dp = data = LDNS_XMALLOC(uint8_t, strlen(str) > 255 ? 256 : (strlen(str) + 1));
498  if (! data) {
499  return LDNS_STATUS_MEM_ERR;
500  }
501 
502  /* Fill data (up to 255 characters) */
503  while (parse_char(&ch, &str)) {
504  if (dp - data >= 255) {
505  LDNS_FREE(data);
507  }
508  *++dp = ch;
509  }
510  if (! str) {
511  LDNS_FREE(data);
513  }
514  length = (size_t)(dp - data);
515  /* Fix last length byte */
516  data[0] = (uint8_t)length;
517 
518  /* Lose the overmeasure */
519  data = LDNS_XREALLOC(dp = data, uint8_t, length + 1);
520  if (! data) {
521  LDNS_FREE(dp);
522  return LDNS_STATUS_MEM_ERR;
523  }
524 
525  /* Create rdf */
526  *rd = ldns_rdf_new(LDNS_RDF_TYPE_STR, length + 1, data);
527  if (! *rd) {
528  LDNS_FREE(data);
529  return LDNS_STATUS_MEM_ERR;
530  }
531  return LDNS_STATUS_OK;
532 }
533 
535 ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
536 {
537  const char *my_str = str;
538 
539  char *my_ip_str;
540  size_t ip_str_len;
541 
542  uint16_t family;
543  bool negation;
544  uint8_t afdlength = 0;
545  uint8_t *afdpart;
546  uint8_t prefix;
547 
548  uint8_t *data;
549 
550  size_t i = 0;
551 
552  /* [!]afi:address/prefix */
553  if (strlen(my_str) < 2
554  || strchr(my_str, ':') == NULL
555  || strchr(my_str, '/') == NULL
556  || strchr(my_str, ':') > strchr(my_str, '/')) {
558  }
559 
560  if (my_str[0] == '!') {
561  negation = true;
562  my_str += 1;
563  } else {
564  negation = false;
565  }
566 
567  family = (uint16_t) atoi(my_str);
568 
569  my_str = strchr(my_str, ':') + 1;
570 
571  /* need ip addr and only ip addr for inet_pton */
572  ip_str_len = (size_t) (strchr(my_str, '/') - my_str);
573  my_ip_str = LDNS_XMALLOC(char, ip_str_len + 1);
574  if(!my_ip_str) return LDNS_STATUS_MEM_ERR;
575  strncpy(my_ip_str, my_str, ip_str_len + 1);
576  my_ip_str[ip_str_len] = '\0';
577 
578  if (family == 1) {
579  /* ipv4 */
580  afdpart = LDNS_XMALLOC(uint8_t, 4);
581  if(!afdpart) {
582  LDNS_FREE(my_ip_str);
583  return LDNS_STATUS_MEM_ERR;
584  }
585  if (inet_pton(AF_INET, my_ip_str, afdpart) == 0) {
586  LDNS_FREE(my_ip_str);
587  LDNS_FREE(afdpart);
589  }
590  for (i = 0; i < 4; i++) {
591  if (afdpart[i] != 0) {
592  afdlength = i + 1;
593  }
594  }
595  } else if (family == 2) {
596  /* ipv6 */
597  afdpart = LDNS_XMALLOC(uint8_t, 16);
598  if(!afdpart) {
599  LDNS_FREE(my_ip_str);
600  return LDNS_STATUS_MEM_ERR;
601  }
602  if (inet_pton(AF_INET6, my_ip_str, afdpart) == 0) {
603  LDNS_FREE(my_ip_str);
604  LDNS_FREE(afdpart);
606  }
607  for (i = 0; i < 16; i++) {
608  if (afdpart[i] != 0) {
609  afdlength = i + 1;
610  }
611  }
612  } else {
613  /* unknown family */
614  LDNS_FREE(my_ip_str);
616  }
617 
618  my_str = strchr(my_str, '/') + 1;
619  prefix = (uint8_t) atoi(my_str);
620 
621  data = LDNS_XMALLOC(uint8_t, 4 + afdlength);
622  if(!data) {
623  LDNS_FREE(afdpart);
624  LDNS_FREE(my_ip_str);
626  }
627  ldns_write_uint16(data, family);
628  data[2] = prefix;
629  data[3] = afdlength;
630  if (negation) {
631  /* set bit 1 of byte 3 */
632  data[3] = data[3] | 0x80;
633  }
634 
635  memcpy(data + 4, afdpart, afdlength);
636 
637  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_APL, afdlength + 4, data);
638  LDNS_FREE(afdpart);
639  LDNS_FREE(data);
640  LDNS_FREE(my_ip_str);
641 
643 }
644 
646 ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
647 {
648  uint8_t *buffer;
649  int16_t i;
650 
651  if ((*str == '-' || *str == '0') && str[1] == '\0') {
653  return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
654  }
655 
656  buffer = LDNS_XMALLOC(uint8_t, ldns_b64_ntop_calculate_size(strlen(str)));
657  if(!buffer) {
658  return LDNS_STATUS_MEM_ERR;
659  }
660 
661  i = (uint16_t)ldns_b64_pton((const char*)str, buffer,
662  ldns_b64_ntop_calculate_size(strlen(str)));
663  if (-1 == i) {
664  LDNS_FREE(buffer);
666  } else {
667  *rd = ldns_rdf_new_frm_data(
668  LDNS_RDF_TYPE_B64, (uint16_t) i, buffer);
669  }
670  LDNS_FREE(buffer);
671 
673 }
674 
676 ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
677 {
678  uint8_t *buffer;
679  int i;
680  /* first byte contains length of actual b32 data */
681  size_t slen = strlen(str);
682  size_t len = ldns_b32_pton_calculate_size(slen);
683  if (len > 255) {
685  }
686  buffer = LDNS_XMALLOC(uint8_t, len + 1);
687  if(!buffer) {
688  return LDNS_STATUS_MEM_ERR;
689  }
690  buffer[0] = len;
691 
692  i = ldns_b32_pton_extended_hex((const char*)str, slen, buffer + 1,
693  ldns_b32_ntop_calculate_size(slen));
694  if (i < 0) {
695  LDNS_FREE(buffer);
697  } else {
698  *rd = ldns_rdf_new_frm_data(
699  LDNS_RDF_TYPE_B32_EXT, (uint16_t) i + 1, buffer);
700  }
701  LDNS_FREE(buffer);
702 
704 }
705 
707 ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
708 {
709  uint8_t *t, *t_orig;
710  int i;
711  size_t len;
712 
713  len = strlen(str);
714 
715  if (len > LDNS_MAX_RDFLEN * 2) {
717  } else {
718  t = LDNS_XMALLOC(uint8_t, (len / 2) + 1);
719  if(!t) {
720  return LDNS_STATUS_MEM_ERR;
721  }
722  t_orig = t;
723  /* Now process octet by octet... */
724  while (*str) {
725  *t = 0;
726  if (isspace((int) *str)) {
727  str++;
728  } else {
729  for (i = 16; i >= 1; i -= 15) {
730  while (*str && isspace((int) *str)) { str++; }
731  if (*str) {
732  if (isxdigit((int) *str)) {
733  *t += ldns_hexdigit_to_int(*str) * i;
734  } else {
735  LDNS_FREE(t_orig);
736  return LDNS_STATUS_ERR;
737  }
738  ++str;
739  }
740  }
741  ++t;
742  }
743  }
745  (size_t) (t - t_orig),
746  t_orig);
747  LDNS_FREE(t_orig);
748  }
750 }
751 
753 ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
754 {
755  const char *delimiters = "\n\t ";
756  char *token = LDNS_XMALLOC(char, LDNS_MAX_RDFLEN);
757  ldns_buffer *str_buf;
758  ssize_t c;
759  uint16_t cur_type;
760  size_t type_count = 0;
761  ldns_rr_type type_list[65536];
762  if(!token) return LDNS_STATUS_MEM_ERR;
763  if(rd == NULL) {
764  LDNS_FREE(token);
765  return LDNS_STATUS_NULL;
766  }
767 
768  str_buf = LDNS_MALLOC(ldns_buffer);
769  if(!str_buf) {
770  LDNS_FREE(token);
771  return LDNS_STATUS_MEM_ERR;
772  }
773  ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
774  if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
775  LDNS_FREE(str_buf);
776  LDNS_FREE(token);
777  return LDNS_STATUS_MEM_ERR;
778  }
779 
780  while ((c = ldns_bget_token(str_buf, token, delimiters, LDNS_MAX_RDFLEN)) != -1 && c != 0) {
781  if(type_count >= sizeof(type_list)) {
782  LDNS_FREE(str_buf);
783  LDNS_FREE(token);
784  return LDNS_STATUS_ERR;
785  }
786  cur_type = ldns_get_rr_type_by_name(token);
787  type_list[type_count] = cur_type;
788  type_count++;
789  }
790 
791  *rd = ldns_dnssec_create_nsec_bitmap(type_list,
792  type_count,
794 
795  LDNS_FREE(token);
796  ldns_buffer_free(str_buf);
798 }
799 
801 ldns_str2rdf_type(ldns_rdf **rd, const char *str)
802 {
803  uint16_t type;
804  type = htons(ldns_get_rr_type_by_name(str));
805  /* ldns_rr_type is a 16 bit value */
806  *rd = ldns_rdf_new_frm_data(
807  LDNS_RDF_TYPE_TYPE, sizeof(uint16_t), &type);
809 }
810 
812 ldns_str2rdf_class(ldns_rdf **rd, const char *str)
813 {
814  uint16_t klass;
815  klass = htons(ldns_get_rr_class_by_name(str));
816  /* class is 16 bit */
817  *rd = ldns_rdf_new_frm_data(
818  LDNS_RDF_TYPE_CLASS, sizeof(uint16_t), &klass);
820 }
821 
822 /* An certificate alg field can either be specified as a 8 bits number
823  * or by its symbolic name. Handle both
824  */
826 ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
827 {
828  ldns_lookup_table *lt;
829  ldns_status st;
830  uint8_t idd[2];
832  st = LDNS_STATUS_OK;
833 
834  if (lt) {
835  ldns_write_uint16(idd, (uint16_t) lt->id);
836  *rd = ldns_rdf_new_frm_data(
837  LDNS_RDF_TYPE_INT16, sizeof(uint16_t), idd);
838  if (!*rd) {
839  st = LDNS_STATUS_ERR;
840  }
841  } else {
842  /* try as-is (a number) */
843  st = ldns_str2rdf_int16(rd, str);
844  if (st == LDNS_STATUS_OK &&
845  ldns_rdf2native_int16(*rd) == 0) {
847  }
848  }
849 
850  return st;
851 }
852 
853 static ldns_lookup_table ldns_tlsa_certificate_usages[] = {
854  { LDNS_TLSA_USAGE_PKIX_TA , "PKIX-TA" },
855  { LDNS_TLSA_USAGE_PKIX_EE , "PKIX-EE" },
856  { LDNS_TLSA_USAGE_DANE_TA , "DANE-TA" },
857  { LDNS_TLSA_USAGE_DANE_EE , "DANE-EE" },
858  { LDNS_TLSA_USAGE_PRIVCERT , "PrivCert" },
859  { 0, NULL }
860 };
861 
862 static ldns_lookup_table ldns_tlsa_selectors[] = {
863  { LDNS_TLSA_SELECTOR_CERT , "Cert" },
864  { LDNS_TLSA_SELECTOR_SPKI , "SPKI" },
865  { LDNS_TLSA_SELECTOR_PRIVSEL , "PrivSel" },
866  { 0, NULL }
867 };
868 
869 static ldns_lookup_table ldns_tlsa_matching_types[] = {
870  { LDNS_TLSA_MATCHING_TYPE_FULL , "Full" },
871  { LDNS_TLSA_MATCHING_TYPE_SHA2_256 , "SHA2-256" },
872  { LDNS_TLSA_MATCHING_TYPE_SHA2_512 , "SHA2-512" },
873  { LDNS_TLSA_MATCHING_TYPE_PRIVMATCH , "PrivMatch" },
874  { 0, NULL }
875 };
876 
877 static ldns_status
878 ldns_str2rdf_mnemonic4int8(ldns_lookup_table *lt,
879  ldns_rdf **rd, const char *str)
880 {
881  if ((lt = ldns_lookup_by_name(lt, str))) {
882  /* it was given as a integer */
883  *rd = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, (uint8_t) lt->id);
884  if (!*rd)
885  return LDNS_STATUS_ERR;
886  else
887  return LDNS_STATUS_OK;
888  }
889  return ldns_str2rdf_int8(rd, str);
890 }
891 
892 /* An alg field can either be specified as a 8 bits number
893  * or by its symbolic name. Handle both
894  */
896 ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
897 {
898  return ldns_str2rdf_mnemonic4int8(ldns_algorithms, rd, str);
899 }
900 
903 {
904  return ldns_str2rdf_mnemonic4int8(
905  ldns_tlsa_certificate_usages, rd, str);
906 }
907 
909 ldns_str2rdf_selector(ldns_rdf **rd, const char *str)
910 {
911  return ldns_str2rdf_mnemonic4int8(ldns_tlsa_selectors, rd, str);
912 }
913 
915 ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str)
916 {
917  return ldns_str2rdf_mnemonic4int8(ldns_tlsa_matching_types, rd, str);
918 }
919 
922  , ATTR_UNUSED(const char *str)
923  )
924 {
925  /* this should be caught in an earlier time (general str2host for
926  rr's */
927  return LDNS_STATUS_NOT_IMPL;
928 }
929 
932  , ATTR_UNUSED(const char *str)
933  )
934 {
935  /* is this used? is this actually WKS? or SRV? */
936  return LDNS_STATUS_NOT_IMPL;
937 }
938 
939 static int
940 loc_parse_cm(char* my_str, char** endstr, uint8_t* m, uint8_t* e)
941 {
942  /* read <digits>[.<digits>][mM] */
943  /* into mantissa exponent format for LOC type */
944  uint32_t meters = 0, cm = 0, val;
945  char* cm_endstr;
946  while (isblank((unsigned char)*my_str)) {
947  my_str++;
948  }
949  meters = (uint32_t)strtol(my_str, &my_str, 10);
950  if (*my_str == '.') {
951  my_str++;
952  cm = (uint32_t)strtol(my_str, &cm_endstr, 10);
953  if (cm_endstr - my_str == 1) cm *= 10;
954  my_str = cm_endstr;
955  }
956  if (meters >= 1) {
957  *e = 2;
958  val = meters;
959  } else {
960  *e = 0;
961  val = cm;
962  }
963  while(val >= 10) {
964  (*e)++;
965  val /= 10;
966  }
967  *m = (uint8_t)val;
968 
969  if (*e > 9)
970  return 0;
971  if (*my_str == 'm' || *my_str == 'M') {
972  my_str++;
973  }
974  *endstr = my_str;
975  return 1;
976 }
977 
979 ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
980 {
981  uint32_t latitude = 0;
982  uint32_t longitude = 0;
983  uint32_t altitude = 0;
984 
985  uint8_t *data;
986  uint32_t equator = (uint32_t) ldns_power(2, 31);
987 
988  uint32_t h = 0;
989  uint32_t m = 0;
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;
993 
994  double s = 0.0;
995  bool northern_hemisphere;
996  bool eastern_hemisphere;
997 
998  char *my_str = (char *) str;
999 
1000  /* only support version 0 */
1001  if (isdigit((int) *my_str)) {
1002  h = (uint32_t) strtol(my_str, &my_str, 10);
1003  } else {
1004  return LDNS_STATUS_INVALID_STR;
1005  }
1006 
1007  while (isblank((int) *my_str)) {
1008  my_str++;
1009  }
1010 
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') {
1014  goto north;
1015  } else {
1016  return LDNS_STATUS_INVALID_STR;
1017  }
1018 
1019  while (isblank((int) *my_str)) {
1020  my_str++;
1021  }
1022 
1023  if (isdigit((int) *my_str)) {
1024  s = strtod(my_str, &my_str);
1025  }
1026 north:
1027  while (isblank((int) *my_str)) {
1028  my_str++;
1029  }
1030 
1031  if (*my_str == 'N') {
1032  northern_hemisphere = true;
1033  } else if (*my_str == 'S') {
1034  northern_hemisphere = false;
1035  } else {
1036  return LDNS_STATUS_INVALID_STR;
1037  }
1038 
1039  my_str++;
1040 
1041  /* store number */
1042  s = 1000.0 * s;
1043  /* add a little to make floor in conversion a round */
1044  s += 0.0005;
1045  latitude = (uint32_t) s;
1046  latitude += 1000 * 60 * m;
1047  latitude += 1000 * 60 * 60 * h;
1048  if (northern_hemisphere) {
1049  latitude = equator + latitude;
1050  } else {
1051  latitude = equator - latitude;
1052  }
1053  while (isblank((unsigned char)*my_str)) {
1054  my_str++;
1055  }
1056 
1057  if (isdigit((int) *my_str)) {
1058  h = (uint32_t) strtol(my_str, &my_str, 10);
1059  } else {
1060  return LDNS_STATUS_INVALID_STR;
1061  }
1062 
1063  while (isblank((int) *my_str)) {
1064  my_str++;
1065  }
1066 
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') {
1070  goto east;
1071  } else {
1072  return LDNS_STATUS_INVALID_STR;
1073  }
1074 
1075  while (isblank((unsigned char)*my_str)) {
1076  my_str++;
1077  }
1078 
1079  if (isdigit((int) *my_str)) {
1080  s = strtod(my_str, &my_str);
1081  }
1082 
1083 east:
1084  while (isblank((unsigned char)*my_str)) {
1085  my_str++;
1086  }
1087 
1088  if (*my_str == 'E') {
1089  eastern_hemisphere = true;
1090  } else if (*my_str == 'W') {
1091  eastern_hemisphere = false;
1092  } else {
1093  return LDNS_STATUS_INVALID_STR;
1094  }
1095 
1096  my_str++;
1097 
1098  /* store number */
1099  s *= 1000.0;
1100  /* add a little to make floor in conversion a round */
1101  s += 0.0005;
1102  longitude = (uint32_t) s;
1103  longitude += 1000 * 60 * m;
1104  longitude += 1000 * 60 * 60 * h;
1105 
1106  if (eastern_hemisphere) {
1107  longitude += equator;
1108  } else {
1109  longitude = equator - longitude;
1110  }
1111 
1112  altitude = (uint32_t)(strtod(my_str, &my_str)*100.0 +
1113  10000000.0 + 0.5);
1114  if (*my_str == 'm' || *my_str == 'M') {
1115  my_str++;
1116  }
1117 
1118  if (strlen(my_str) > 0) {
1119  if(!loc_parse_cm(my_str, &my_str, &size_b, &size_e))
1120  return LDNS_STATUS_INVALID_STR;
1121  }
1122 
1123  if (strlen(my_str) > 0) {
1124  if(!loc_parse_cm(my_str, &my_str, &horiz_pre_b, &horiz_pre_e))
1125  return LDNS_STATUS_INVALID_STR;
1126  }
1127 
1128  if (strlen(my_str) > 0) {
1129  if(!loc_parse_cm(my_str, &my_str, &vert_pre_b, &vert_pre_e))
1130  return LDNS_STATUS_INVALID_STR;
1131  }
1132 
1133  data = LDNS_XMALLOC(uint8_t, 16);
1134  if(!data) {
1135  return LDNS_STATUS_MEM_ERR;
1136  }
1137  data[0] = 0;
1138  data[1] = 0;
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);
1145 
1146  *rd = ldns_rdf_new_frm_data(
1147  LDNS_RDF_TYPE_LOC, 16, data);
1148 
1149  LDNS_FREE(data);
1151 }
1152 
1154 ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
1155 {
1156  uint8_t *bitmap = NULL;
1157  uint8_t *data;
1158  int bm_len = 0;
1159 
1160  struct protoent *proto = NULL;
1161  struct servent *serv = NULL;
1162  int serv_port;
1163 
1164  ldns_buffer *str_buf;
1165 
1166  char *proto_str = NULL;
1167  char *lc_proto_str = NULL;
1168  char *token;
1169  char *lc_token;
1170  char *c;
1171  if(strlen(str) == 0)
1172  token = LDNS_XMALLOC(char, 50);
1173  else token = LDNS_XMALLOC(char, strlen(str)+2);
1174  if(!token) return LDNS_STATUS_MEM_ERR;
1175 
1176  str_buf = LDNS_MALLOC(ldns_buffer);
1177  if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
1178  ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
1179  if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
1180  LDNS_FREE(str_buf);
1181  LDNS_FREE(token);
1182  return LDNS_STATUS_MEM_ERR;
1183  }
1184 
1185  while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
1186  if (!proto_str) {
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);
1191  }
1192  if (!proto_str || !lc_proto_str) {
1193  free(proto_str);
1194  free(lc_proto_str);
1195  LDNS_FREE(bitmap);
1196  LDNS_FREE(token);
1197  ldns_buffer_free(str_buf);
1198  return LDNS_STATUS_INVALID_STR;
1199  }
1200  } else {
1201  serv = getservbyname(token, proto_str);
1202  if (!serv) {
1203  serv = getservbyname(token, lc_proto_str);
1204  }
1205  if (!serv && (lc_token = strdup(token))) {
1206  for (c = lc_token; *c; c++) {
1207  *c = tolower((unsigned char)*c);
1208  }
1209  serv = getservbyname(lc_token, proto_str);
1210  if (!serv) {
1211  serv = getservbyname(lc_token, lc_proto_str);
1212  }
1213  free(lc_token);
1214  }
1215  if (serv) {
1216  serv_port = (int) ntohs((uint16_t) serv->s_port);
1217  } else {
1218  serv_port = atoi(token);
1219  }
1220  if (serv_port < 0 || serv_port > 65535) {
1221  LDNS_FREE(bitmap);
1222  LDNS_FREE(token);
1223  ldns_buffer_free(str_buf);
1224  free(proto_str);
1225  free(lc_proto_str);
1226  return LDNS_STATUS_INVALID_STR;
1227  }
1228  if (serv_port / 8 >= bm_len) {
1229  uint8_t *b2 = LDNS_XREALLOC(bitmap, uint8_t, (serv_port / 8) + 1);
1230  if(!b2) {
1231  LDNS_FREE(bitmap);
1232  LDNS_FREE(token);
1233  ldns_buffer_free(str_buf);
1234  free(proto_str);
1235  free(lc_proto_str);
1236  return LDNS_STATUS_INVALID_STR;
1237  }
1238  bitmap = b2;
1239  /* set to zero to be sure */
1240  for (; bm_len <= serv_port / 8; bm_len++) {
1241  bitmap[bm_len] = 0;
1242  }
1243  }
1244  ldns_set_bit(bitmap + (serv_port / 8), 7 - (serv_port % 8), true);
1245  }
1246  }
1247 
1248  if (!proto_str || !bitmap) {
1249  LDNS_FREE(bitmap);
1250  LDNS_FREE(token);
1251  ldns_buffer_free(str_buf);
1252  free(proto_str);
1253  free(lc_proto_str);
1254  return LDNS_STATUS_INVALID_STR;
1255  }
1256 
1257  data = LDNS_XMALLOC(uint8_t, bm_len + 1);
1258  if(!data) {
1259  LDNS_FREE(token);
1260  ldns_buffer_free(str_buf);
1261  LDNS_FREE(bitmap);
1262  free(proto_str);
1263  free(lc_proto_str);
1264  return LDNS_STATUS_INVALID_STR;
1265  }
1266  if (proto_str)
1267  proto = getprotobyname(proto_str);
1268  if (!proto) {
1269  proto = getprotobyname(lc_proto_str);
1270  }
1271  if (proto) {
1272  data[0] = (uint8_t) proto->p_proto;
1273  } else if (proto_str) {
1274  data[0] = (uint8_t) atoi(proto_str);
1275  }
1276  memcpy(data + 1, bitmap, (size_t) bm_len);
1277 
1278  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_WKS, (uint16_t) (bm_len + 1), data);
1279 
1280  LDNS_FREE(data);
1281  LDNS_FREE(token);
1282  ldns_buffer_free(str_buf);
1283  LDNS_FREE(bitmap);
1284  free(proto_str);
1285  free(lc_proto_str);
1286 #ifdef HAVE_ENDSERVENT
1287  endservent();
1288 #endif
1289 #ifdef HAVE_ENDPROTOENT
1290  endprotoent();
1291 #endif
1292 
1293  if(!*rd) return LDNS_STATUS_MEM_ERR;
1294 
1295  return LDNS_STATUS_OK;
1296 }
1297 
1299 ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
1300 {
1301  size_t len, i;
1302  char* nsap_str = (char*) str;
1303 
1304  /* just a hex string with optional dots? */
1305  if (str[0] != '0' || str[1] != 'x') {
1306  return LDNS_STATUS_INVALID_STR;
1307  } else {
1308  len = strlen(str);
1309  for (i=0; i < len; i++) {
1310  if (nsap_str[i] == '.')
1311  nsap_str[i] = ' ';
1312  }
1313  return ldns_str2rdf_hex(rd, str+2);
1314  }
1315 }
1316 
1318 ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
1319 {
1320  size_t len, i;
1321  char* atma_str = (char*) str;
1322  ldns_status status;
1323 
1324  /* just a hex string with optional dots? */
1325  len = strlen(str);
1326  for (i=0; i < len; i++) {
1327  if (atma_str[i] == '.')
1328  atma_str[i] = ' ';
1329  }
1330  status = ldns_str2rdf_hex(rd, str);
1331  if (status != LDNS_STATUS_OK) {
1332  ; /* probably in e.164 format than */
1333  }
1334  return status;
1335 }
1336 
1338 ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
1339 {
1340  uint8_t precedence = 0;
1341  uint8_t gateway_type = 0;
1342  uint8_t algorithm = 0;
1343  char* gateway = NULL;
1344  char* publickey = NULL;
1345  uint8_t *data;
1346  ldns_buffer *str_buf;
1347  char *token;
1348  int token_count = 0;
1349  int ipseckey_len = 0;
1350  ldns_rdf* gateway_rdf = NULL;
1351  ldns_rdf* publickey_rdf = NULL;
1352  ldns_status status = LDNS_STATUS_OK;
1353 
1354  if(strlen(str) == 0)
1355  token = LDNS_XMALLOC(char, 256);
1356  else token = LDNS_XMALLOC(char, strlen(str)+2);
1357  if(!token) return LDNS_STATUS_MEM_ERR;
1358 
1359  str_buf = LDNS_MALLOC(ldns_buffer);
1360  if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
1361  ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
1362  if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
1363  LDNS_FREE(str_buf);
1364  LDNS_FREE(token);
1365  return LDNS_STATUS_MEM_ERR;
1366  }
1367  while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
1368  switch (token_count) {
1369  case 0:
1370  precedence = (uint8_t)atoi(token);
1371  break;
1372  case 1:
1373  gateway_type = (uint8_t)atoi(token);
1374  break;
1375  case 2:
1376  algorithm = (uint8_t)atoi(token);
1377  break;
1378  case 3:
1379  gateway = strdup(token);
1380  if (!gateway || (gateway_type == 0 &&
1381  (token[0] != '.' || token[1] != '\0'))) {
1382  LDNS_FREE(gateway);
1383  LDNS_FREE(token);
1384  ldns_buffer_free(str_buf);
1385  return LDNS_STATUS_INVALID_STR;
1386  }
1387  break;
1388  case 4:
1389  publickey = strdup(token);
1390  break;
1391  default:
1392  LDNS_FREE(token);
1393  ldns_buffer_free(str_buf);
1394  return LDNS_STATUS_INVALID_STR;
1395  break;
1396  }
1397  token_count++;
1398  }
1399 
1400  if (!gateway || !publickey) {
1401  if (gateway)
1402  LDNS_FREE(gateway);
1403  if (publickey)
1404  LDNS_FREE(publickey);
1405  LDNS_FREE(token);
1406  ldns_buffer_free(str_buf);
1407  return LDNS_STATUS_INVALID_STR;
1408  }
1409 
1410  if (gateway_type == 1) {
1411  status = ldns_str2rdf_a(&gateway_rdf, gateway);
1412  } else if (gateway_type == 2) {
1413  status = ldns_str2rdf_aaaa(&gateway_rdf, gateway);
1414  } else if (gateway_type == 3) {
1415  status = ldns_str2rdf_dname(&gateway_rdf, gateway);
1416  } else if (gateway_type > 3) {
1417  status = LDNS_STATUS_INVALID_STR;
1418  }
1419 
1420  if (status != LDNS_STATUS_OK) {
1421  if (gateway)
1422  LDNS_FREE(gateway);
1423  if (publickey)
1424  LDNS_FREE(publickey);
1425  LDNS_FREE(token);
1426  ldns_buffer_free(str_buf);
1427  return LDNS_STATUS_INVALID_STR;
1428  }
1429 
1430  status = ldns_str2rdf_b64(&publickey_rdf, publickey);
1431 
1432  if (status != LDNS_STATUS_OK) {
1433  if (gateway)
1434  LDNS_FREE(gateway);
1435  if (publickey)
1436  LDNS_FREE(publickey);
1437  LDNS_FREE(token);
1438  ldns_buffer_free(str_buf);
1439  if (gateway_rdf) ldns_rdf_free(gateway_rdf);
1440  return LDNS_STATUS_INVALID_STR;
1441  }
1442 
1443  /* now copy all into one ipseckey rdf */
1444  if (gateway_type)
1445  ipseckey_len = 3 + (int)ldns_rdf_size(gateway_rdf) + (int)ldns_rdf_size(publickey_rdf);
1446  else
1447  ipseckey_len = 3 + (int)ldns_rdf_size(publickey_rdf);
1448 
1449  data = LDNS_XMALLOC(uint8_t, ipseckey_len);
1450  if(!data) {
1451  if (gateway)
1452  LDNS_FREE(gateway);
1453  if (publickey)
1454  LDNS_FREE(publickey);
1455  LDNS_FREE(token);
1456  ldns_buffer_free(str_buf);
1457  if (gateway_rdf) ldns_rdf_free(gateway_rdf);
1458  if (publickey_rdf) ldns_rdf_free(publickey_rdf);
1459  return LDNS_STATUS_MEM_ERR;
1460  }
1461 
1462  data[0] = precedence;
1463  data[1] = gateway_type;
1464  data[2] = algorithm;
1465 
1466  if (gateway_type) {
1467  memcpy(data + 3,
1468  ldns_rdf_data(gateway_rdf), ldns_rdf_size(gateway_rdf));
1469  memcpy(data + 3 + ldns_rdf_size(gateway_rdf),
1470  ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
1471  } else {
1472  memcpy(data + 3,
1473  ldns_rdf_data(publickey_rdf), ldns_rdf_size(publickey_rdf));
1474  }
1475 
1476  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_IPSECKEY, (uint16_t) ipseckey_len, data);
1477 
1478  if (gateway)
1479  LDNS_FREE(gateway);
1480  if (publickey)
1481  LDNS_FREE(publickey);
1482  LDNS_FREE(token);
1483  ldns_buffer_free(str_buf);
1484  ldns_rdf_deep_free(gateway_rdf);
1485  ldns_rdf_deep_free(publickey_rdf);
1486  LDNS_FREE(data);
1487  if(!*rd) return LDNS_STATUS_MEM_ERR;
1488  return LDNS_STATUS_OK;
1489 }
1490 
1492 ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str)
1493 {
1494  unsigned int a, b, c, d;
1495  uint16_t shorts[4];
1496  int l;
1497 
1498  if (sscanf(str, "%4x:%4x:%4x:%4x%n", &a, &b, &c, &d, &l) != 4 ||
1499  l != (int)strlen(str) || /* more data to read */
1500  strpbrk(str, "+-") /* signed hexes */
1501  ) {
1503  } else {
1504  shorts[0] = htons(a);
1505  shorts[1] = htons(b);
1506  shorts[2] = htons(c);
1507  shorts[3] = htons(d);
1508  *rd = ldns_rdf_new_frm_data(
1509  LDNS_RDF_TYPE_ILNP64, 4 * sizeof(uint16_t), &shorts);
1510  }
1511  return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
1512 }
1513 
1515 ldns_str2rdf_eui48(ldns_rdf **rd, const char *str)
1516 {
1517  unsigned int a, b, c, d, e, f;
1518  uint8_t bytes[6];
1519  int l;
1520 
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)) {
1525  } else {
1526  bytes[0] = a;
1527  bytes[1] = b;
1528  bytes[2] = c;
1529  bytes[3] = d;
1530  bytes[4] = e;
1531  bytes[5] = f;
1532  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI48, 6, &bytes);
1533  }
1534  return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
1535 }
1536 
1538 ldns_str2rdf_eui64(ldns_rdf **rd, const char *str)
1539 {
1540  unsigned int a, b, c, d, e, f, g, h;
1541  uint8_t bytes[8];
1542  int l;
1543 
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)) {
1548  } else {
1549  bytes[0] = a;
1550  bytes[1] = b;
1551  bytes[2] = c;
1552  bytes[3] = d;
1553  bytes[4] = e;
1554  bytes[5] = f;
1555  bytes[6] = g;
1556  bytes[7] = h;
1557  *rd = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_EUI64, 8, &bytes);
1558  }
1559  return *rd ? LDNS_STATUS_OK : LDNS_STATUS_MEM_ERR;
1560 }
1561 
1563 ldns_str2rdf_tag(ldns_rdf **rd, const char *str)
1564 {
1565  uint8_t *data;
1566  const char* ptr;
1567 
1568  if (strlen(str) > 255) {
1569  return LDNS_STATUS_INVALID_TAG;
1570  }
1571  for (ptr = str; *ptr; ptr++) {
1572  if (! isalnum((unsigned char)*ptr)) {
1573  return LDNS_STATUS_INVALID_TAG;
1574  }
1575  }
1576  data = LDNS_XMALLOC(uint8_t, strlen(str) + 1);
1577  if (!data) {
1578  return LDNS_STATUS_MEM_ERR;
1579  }
1580  data[0] = strlen(str);
1581  memcpy(data + 1, str, strlen(str));
1582 
1583  *rd = ldns_rdf_new(LDNS_RDF_TYPE_TAG, strlen(str) + 1, data);
1584  if (!*rd) {
1585  LDNS_FREE(data);
1586  return LDNS_STATUS_MEM_ERR;
1587  }
1588  return LDNS_STATUS_OK;
1589 }
1590 
1592 ldns_str2rdf_long_str(ldns_rdf **rd, const char *str)
1593 {
1594  uint8_t *data, *dp, ch = 0;
1595  size_t length;
1596 
1597  /* Worst case space requirement. We'll realloc to actual size later. */
1598  dp = data = LDNS_XMALLOC(uint8_t, strlen(str));
1599  if (! data) {
1600  return LDNS_STATUS_MEM_ERR;
1601  }
1602 
1603  /* Fill data with parsed bytes */
1604  while (parse_char(&ch, &str)) {
1605  *dp++ = ch;
1606  if (dp - data > LDNS_MAX_RDFLEN) {
1607  LDNS_FREE(data);
1608  return LDNS_STATUS_INVALID_STR;
1609  }
1610  }
1611  if (! str) {
1612  LDNS_FREE(data);
1614  }
1615  if (!(length = (size_t)(dp - data))) {
1616  /* An empty string is a data buffer of 0 bytes. The rdf for
1617  * this long string has to have length 0 and point to NULL.
1618  */
1619  LDNS_FREE(data);
1620  data = NULL;
1621  } else {
1622  /* Lose the overmeasure */
1623  data = LDNS_XREALLOC(dp = data, uint8_t, length);
1624  if (! data) {
1625  LDNS_FREE(dp);
1626  return LDNS_STATUS_MEM_ERR;
1627  }
1628  }
1629  /* Create rdf */
1630  *rd = ldns_rdf_new(LDNS_RDF_TYPE_LONG_STR, length, data);
1631  if (! *rd) {
1632  LDNS_FREE(data);
1633  return LDNS_STATUS_MEM_ERR;
1634  }
1635  return LDNS_STATUS_OK;
1636 }
1637 
1639 ldns_str2rdf_hip(ldns_rdf **rd, const char *str)
1640 {
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;
1649 
1650  char *endptr; /* utility var for strtol usage */
1651  int algorithm = str == NULL ? 0 : strtol(str, &endptr, 10);
1652 
1653  uint8_t *data, *dp;
1654  int hi, lo, written;
1655 
1656  if (hit_size == 0 || pk_size == 0 || (hit_size + 1) / 2 > 255
1657  || rdf_size > LDNS_MAX_RDFLEN
1658  || algorithm < 0 || algorithm > 255
1659  || (errno != 0 && algorithm == 0) /* out of range */
1660  || endptr == str /* no digits */) {
1661 
1662  return LDNS_STATUS_SYNTAX_ERR;
1663  }
1664  hit += 1;
1665  pk += 1;
1666  if ((data = LDNS_XMALLOC(uint8_t, rdf_size)) == NULL) {
1667 
1668  return LDNS_STATUS_MEM_ERR;
1669  }
1670  /* From RFC 5205 section 5. HIP RR Storage Format:
1671  *************************************************
1672 
1673  0 1 2 3
1674  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1675  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1676  | HIT length | PK algorithm | PK length |
1677  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1678  | |
1679  ~ HIT ~
1680  | |
1681  + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1682  | | |
1683  +-+-+-+-+-+-+-+-+-+-+-+ +
1684  | Public Key |
1685  ~ ~
1686  | |
1687  + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1688  | | |
1689  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
1690  | |
1691  ~ Rendezvous Servers ~
1692  | |
1693  + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1694  | |
1695  +-+-+-+-+-+-+-+ */
1696 
1697  data[0] = (uint8_t) hit_wire_size;
1698  data[1] = (uint8_t) algorithm;
1699 
1700  for (dp = data + 4; *hit && *hit != ' '; dp++) {
1701 
1702  if ((hi = ldns_hexdigit_to_int(*hit++)) == -1 ||
1703  (lo = ldns_hexdigit_to_int(*hit++)) == -1) {
1704 
1705  LDNS_FREE(data);
1706  return LDNS_STATUS_INVALID_HEX;
1707  }
1708  *dp = (uint8_t) hi << 4 | lo;
1709  }
1710  if ((written = ldns_b64_pton(pk, dp, pk_wire_size)) <= 0) {
1711 
1712  LDNS_FREE(data);
1713  return LDNS_STATUS_INVALID_B64;
1714  }
1715 
1716  /* Because ldns_b64_pton_calculate_size isn't always correct:
1717  * (we have to fix it at some point)
1718  */
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;
1722 
1723  /* Create rdf */
1724  if (! (*rd = ldns_rdf_new(LDNS_RDF_TYPE_HIP, rdf_size, data))) {
1725 
1726  LDNS_FREE(data);
1727  return LDNS_STATUS_MEM_ERR;
1728  }
1729  return LDNS_STATUS_OK;
1730 }
1731 
1732 
1733 /* Implementation mimics ldns_str2rdf_ipseckey */
1735 ldns_str2rdf_amtrelay(ldns_rdf **rd, const char *str)
1736 {
1737  /* From draft-ietf-mboned-driad-amt-discovery
1738  * Section 4.2. AMTRELAY RData Format
1739  *************************************************
1740 
1741  0 1 2 3
1742  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1743  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1744  | precedence |D| type | |
1745  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
1746  ~ relay ~
1747  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
1748 
1749  uint8_t precedence = 0;
1750  uint8_t relay_type = 0;
1751  uint8_t discovery_optional = 0;
1752  char* relay = NULL;
1753  uint8_t *data;
1754  ldns_buffer *str_buf;
1755  char *token;
1756  int token_count = 0;
1757  int amtrelay_len = 0;
1758  ldns_rdf* relay_rdf = NULL;
1759  ldns_status status = LDNS_STATUS_OK;
1760 
1761  if(strlen(str) == 0)
1762  token = LDNS_XMALLOC(char, 256);
1763  else token = LDNS_XMALLOC(char, strlen(str)+2);
1764  if(!token) return LDNS_STATUS_MEM_ERR;
1765 
1766  str_buf = LDNS_MALLOC(ldns_buffer);
1767  if(!str_buf) {LDNS_FREE(token); return LDNS_STATUS_MEM_ERR;}
1768  ldns_buffer_new_frm_data(str_buf, (char *)str, strlen(str));
1769  if(ldns_buffer_status(str_buf) != LDNS_STATUS_OK) {
1770  LDNS_FREE(str_buf);
1771  LDNS_FREE(token);
1772  return LDNS_STATUS_MEM_ERR;
1773  }
1774  while(ldns_bget_token(str_buf, token, "\t\n ", strlen(str)) > 0) {
1775  switch (token_count) {
1776  case 0:
1777  precedence = (uint8_t)atoi(token);
1778  break;
1779  case 1:
1780  discovery_optional = (uint8_t)atoi(token);
1781  if (discovery_optional != 0 &&
1782  discovery_optional != 1) {
1783  LDNS_FREE(relay);
1784  LDNS_FREE(token);
1785  ldns_buffer_free(str_buf);
1786  return LDNS_STATUS_INVALID_STR;
1787  }
1788  break;
1789  case 2:
1790  relay_type = (uint8_t)atoi(token);
1791  break;
1792  case 3:
1793  relay = strdup(token);
1794  if (!relay || (relay_type == 0 &&
1795  (token[0] != '.' || token[1] != '\0'))) {
1796  LDNS_FREE(relay);
1797  LDNS_FREE(token);
1798  ldns_buffer_free(str_buf);
1799  return LDNS_STATUS_INVALID_STR;
1800  }
1801  break;
1802  default:
1803  LDNS_FREE(token);
1804  ldns_buffer_free(str_buf);
1805  return LDNS_STATUS_INVALID_STR;
1806  break;
1807  }
1808  token_count++;
1809  }
1810  if (!relay && relay_type > 0) {
1811  if (relay)
1812  LDNS_FREE(relay);
1813  LDNS_FREE(token);
1814  ldns_buffer_free(str_buf);
1815  return LDNS_STATUS_INVALID_STR;
1816  }
1817 
1818  if (relay_type == 1) {
1819  status = ldns_str2rdf_a(&relay_rdf, relay);
1820  } else if (relay_type == 2) {
1821  status = ldns_str2rdf_aaaa(&relay_rdf, relay);
1822  } else if (relay_type == 3) {
1823  status = ldns_str2rdf_dname(&relay_rdf, relay);
1824  } else if (relay_type > 3) {
1825  status = LDNS_STATUS_INVALID_STR;
1826  }
1827 
1828  if (status != LDNS_STATUS_OK) {
1829  if (relay)
1830  LDNS_FREE(relay);
1831  LDNS_FREE(token);
1832  ldns_buffer_free(str_buf);
1833  ldns_rdf_deep_free(relay_rdf);
1834  return LDNS_STATUS_INVALID_STR;
1835  }
1836 
1837  /* now copy all into one amtrelay rdf */
1838  if (relay_type)
1839  amtrelay_len = 2 + (int)ldns_rdf_size(relay_rdf);
1840  else
1841  amtrelay_len = 2;
1842 
1843  data = LDNS_XMALLOC(uint8_t, amtrelay_len);
1844  if(!data) {
1845  if (relay)
1846  LDNS_FREE(relay);
1847  LDNS_FREE(token);
1848  ldns_buffer_free(str_buf);
1849  ldns_rdf_deep_free(relay_rdf);
1850  return LDNS_STATUS_MEM_ERR;
1851  }
1852 
1853  data[0] = precedence;
1854  data[1] = relay_type;
1855  data[1] |= (discovery_optional << 7);
1856 
1857  if (relay_type) {
1858  memcpy(data + 2,
1859  ldns_rdf_data(relay_rdf), ldns_rdf_size(relay_rdf));
1860  }
1862  , (uint16_t) amtrelay_len, data);
1863 
1864  if (relay)
1865  LDNS_FREE(relay);
1866  LDNS_FREE(token);
1867  ldns_buffer_free(str_buf);
1868  ldns_rdf_deep_free(relay_rdf);
1869  LDNS_FREE(data);
1870  if(!*rd) return LDNS_STATUS_MEM_ERR;
1871  return LDNS_STATUS_OK;
1872 }
1873 
1874 #ifdef RRTYPE_SVCB_HTTPS
1875 static int
1876 network_uint16_cmp(const void *a, const void *b)
1877 {
1878  return ((int)ldns_read_uint16(a)) - ((int)ldns_read_uint16(b));
1879 }
1880 
1881 static ldns_status parse_svcparam_key(const char **s, ldns_svcparam_key *key);
1882 static ldns_status
1883 parse_svcparam_mandatory(const char **s, uint8_t **dp, uint8_t *eod)
1884 {
1885  bool quoted = false;
1886  uint8_t *keys = *dp;
1887  int prev_key;
1888 
1889  if (**s == '"') {
1890  *s += 1;
1891  quoted = true;
1892  }
1893  for (;;) {
1894  ldns_status st;
1895  ldns_svcparam_key key;
1896 
1897  if ((st = parse_svcparam_key(s, &key)))
1898  return st;
1899 
1900  if (*dp + 2 > eod)
1902 
1903  ldns_write_uint16(*dp, key);
1904  *dp += 2;
1905 
1906  if (**s == ',')
1907  *s += 1;
1908  else
1909  break;
1910  }
1911  if (quoted) {
1912  if (**s != '"')
1913  return LDNS_STATUS_INVALID_STR;
1914  *s += 1;
1915  }
1916  if (*dp - keys == 0)
1918 
1919  if (**s && !isspace((unsigned char)**s))
1921 
1922  /* In draft-ietf-dnsop-svcb-https-02 Section 7:
1923  *
1924  * In wire format, the keys are represented by their numeric
1925  * values in network byte order, concatenated in ascending order.
1926  */
1927  qsort(keys, (*dp - keys) / 2, 2, network_uint16_cmp);
1928 
1929  /* In draft-ietf-dnsop-svcb-https-02 Section 7:
1930  *
1931  * Keys ...<snip>... MUST NOT appear more than once.
1932  */
1933  prev_key = -1;
1934  while (keys < *dp) {
1935  uint16_t key = ldns_read_uint16(keys);
1936 
1937  if (key == prev_key) {
1938  /* "Be conservative in what you send,
1939  * be liberal in what you accept"
1940  *
1941  * Instead of
1942  * `return LDNS_STATUS_SVCPARAM_KEY_MORE_THAN_ONCE;`,
1943  *
1944  * we eliminate the double occurrence.
1945  */
1946  memmove(keys - 2, keys, *dp - keys);
1947  *dp -= 2;
1948  } else {
1949  prev_key = key;
1950  keys += 2;
1951  }
1952  }
1953  return LDNS_STATUS_OK;
1954 }
1955 
1956 INLINE bool parse_escape2(uint8_t *ch_p, const char** str_p)
1957 { *str_p += 1; return parse_escape(ch_p, str_p); }
1958 
1959 static ldns_status
1960 parse_svcparam_alpn(const char **s, uint8_t **dp, uint8_t *eod)
1961 {
1962  uint8_t *val;
1963  size_t len;
1964 
1965  if (*dp + 1 > eod)
1967  *dp += 1;
1968  val = *dp;
1969  if (**s == '"') {
1970  *s += 1;
1971  while (**s != '"') {
1972  if (**s == 0)
1973  return LDNS_STATUS_INVALID_STR;
1974 
1975  else if (**s == ',') {
1976  len = *dp - val;
1977  if (len == 0 || len > 255)
1978  return LDNS_STATUS_INVALID_STR;
1979  val[-1] = len;
1980  if (*dp + 1 > eod)
1982  *dp += 1;
1983  val = *dp;
1984  *s += 1;
1985 
1986  } else if (*dp + 1 > eod)
1988 
1989  else if (**s != '\\')
1990  *(*dp)++ = (uint8_t)*(*s)++;
1991 
1992  else if (!parse_escape2(*dp, s))
1994  else
1995  *dp += 1;
1996  }
1997  *s += 1;
1998 
1999  } else while (**s && !isspace((unsigned char)**s)) {
2000  if (**s == ',') {
2001  len = *dp - val;
2002  if (len == 0 || len > 255)
2003  return LDNS_STATUS_INVALID_STR;
2004  val[-1] = len;
2005  if (*dp + 1 > eod)
2007  *dp += 1;
2008  val = *dp;
2009  *s += 1;
2010 
2011  } else if (*dp + 1 > eod)
2013 
2014  else if (**s != '\\')
2015  *(*dp)++ = (uint8_t)*(*s)++;
2016 
2017  else if (!parse_escape2(*dp, s))
2019  else
2020  *dp += 1;
2021  }
2022  len = *dp - val;
2023  if (len == 0 || len > 255)
2024  return LDNS_STATUS_INVALID_STR;
2025  val[-1] = len;
2026  return **s && !isspace((unsigned char)**s)
2028  : LDNS_STATUS_OK;
2029 }
2030 
2031 static ldns_status
2032 parse_svcparam_value(const char **s, uint8_t **dp, uint8_t *eod)
2033 {
2034  if (**s == '"') {
2035  *s += 1;
2036  while (**s != '"') {
2037  if (**s == 0)
2038  return LDNS_STATUS_INVALID_STR;
2039 
2040  else if (*dp + 1 > eod)
2042 
2043  else if (**s != '\\')
2044  *(*dp)++ = (uint8_t)*(*s)++;
2045 
2046  else if (!parse_escape2(*dp, s))
2048  else
2049  *dp += 1;
2050  }
2051  *s += 1;
2052 
2053  } else while (**s && !isspace((unsigned char)**s)) {
2054  if (*dp + 1 > eod)
2056 
2057  else if (**s != '\\')
2058  *(*dp)++ = (uint8_t)*(*s)++;
2059 
2060  else if (!parse_escape2(*dp, s))
2062  else
2063  *dp += 1;
2064  }
2065  return **s && !isspace((unsigned char)**s)
2067  : LDNS_STATUS_OK;
2068 }
2069 
2070 static ldns_status
2071 parse_svcparam_port(const char **s, uint8_t **dp, uint8_t *eod)
2072 {
2073  uint8_t *val = *dp;
2074  ldns_status st;
2075  size_t len;
2076  char num_str[6];
2077  char *endptr;
2078  unsigned long int num;
2079 
2080  if ((st = parse_svcparam_value(s, dp, eod)))
2081  return st;
2082  len = *dp - val;
2083  if (len == 0 || len > 5)
2085 
2086  memcpy(num_str, val, len);
2087  num_str[len] = 0;
2088  num = strtoul(num_str, &endptr, 10);
2089  if (*endptr)
2091 
2092  ldns_write_uint16(val, num);
2093  *dp = val + 2;
2094  return LDNS_STATUS_OK;
2095 }
2096 
2097 static ldns_status
2098 parse_svcparam_ipv4hint(const char **s, uint8_t **dp, uint8_t *eod)
2099 {
2100  bool quoted = false;
2101 
2102  if (**s == '"') {
2103  *s += 1;
2104  quoted = true;
2105  }
2106  for (;;) {
2107  const char *ipv4_start = *s;
2108  char ipv4_str[16];
2109  size_t len;
2110 
2111  while (isdigit((unsigned char)**s) || **s == '.')
2112  *s += 1;
2113 
2114  len = *s - ipv4_start;
2115  if (len == 0 || len > 15)
2117 
2118  if (*dp + 4 > eod)
2120 
2121  memcpy(ipv4_str, ipv4_start, len);
2122  ipv4_str[len] = 0;
2123  if (inet_pton(AF_INET, ipv4_str, *dp) != 1)
2125 
2126  *dp += 4;
2127  if (**s == ',')
2128  *s += 1;
2129  else
2130  break;
2131  }
2132  if (quoted) {
2133  if (**s != '"')
2134  return LDNS_STATUS_INVALID_STR;
2135  *s += 1;
2136  }
2137  return **s && !isspace((unsigned char)**s)
2139  : LDNS_STATUS_OK;
2140 }
2141 
2142 static ldns_status
2143 parse_svcparam_ech(const char **s, uint8_t **dp, uint8_t *eod)
2144 {
2145  bool quoted = false;
2146  const char *b64_str;
2147  size_t len, pad, out_len;
2148  char in_buf[4096];
2149  char *in = in_buf;
2150  int out;
2151 
2152  if (**s == '"') {
2153  *s += 1;
2154  quoted = true;
2155  }
2156  b64_str = *s;
2157  while (isalnum((unsigned char)**s) || **s == '+'
2158  || **s == '/'
2159  || **s == '=')
2160  *s += 1;
2161 
2162  len = *s - b64_str;
2163  pad = len % 4;
2164  pad = pad ? 4 - pad : 0;
2165  if (len == 0 || pad == 3)
2167 
2168  if (quoted) {
2169  if (**s != '"')
2170  return LDNS_STATUS_INVALID_STR;
2171  *s += 1;
2172  }
2173  if (**s && !isspace((unsigned char)**s))
2175 
2176  out_len = ldns_b64_pton_calculate_size(len);
2177  if (*dp + out_len > eod)
2179 
2180  if (len + pad > sizeof(in_buf) - 1
2181  && !(in = LDNS_XMALLOC(char, len + pad + 1)))
2182  return LDNS_STATUS_MEM_ERR;
2183 
2184  memcpy(in, b64_str, len);
2185  while (pad--)
2186  in[len++] = '=';
2187  in[len] = 0;
2188  out = ldns_b64_pton(in, *dp, out_len);
2189  if (in != in_buf)
2190  LDNS_FREE(in);
2191 
2192  if (out <= 0)
2194 
2195  *dp += out;
2196  return LDNS_STATUS_OK;
2197 }
2198 
2199 static ldns_status
2200 parse_svcparam_ipv6hint(const char **s, uint8_t **dp, uint8_t *eod)
2201 {
2202  bool quoted = false;
2203 
2204  if (**s == '"') {
2205  *s += 1;
2206  quoted = true;
2207  }
2208  for (;;) {
2209  const char *ipv6_start = *s;
2210  char ipv6_str[INET6_ADDRSTRLEN];
2211  size_t len;
2212 
2213  while (isxdigit((unsigned char)**s) || **s == ':' || **s == '.')
2214  *s += 1;
2215 
2216  len = *s - ipv6_start;
2217  if (len == 0 || len > INET6_ADDRSTRLEN)
2219 
2220  if (*dp + 16 > eod)
2222 
2223  memcpy(ipv6_str, ipv6_start, len);
2224  ipv6_str[len] = 0;
2225  if (inet_pton(AF_INET6, ipv6_str, *dp) != 1)
2227 
2228  *dp += 16;
2229  if (**s == ',')
2230  *s += 1;
2231  else
2232  break;
2233  }
2234  if (quoted) {
2235  if (**s != '"')
2236  return LDNS_STATUS_INVALID_STR;
2237  *s += 1;
2238  }
2239  return **s && !isspace((unsigned char)**s)
2241  : LDNS_STATUS_OK;
2242 }
2243 
2245  const char *str;
2246  size_t len;
2247 };
2249 
2250 static svcparam_key_def svcparam_key_defs[] = { { "mandatory" , 9 }
2251  , { "alpn" , 4 }
2252  , { "no-default-alpn", 15 }
2253  , { "port" , 4 }
2254  , { "ipv4hint" , 8 }
2255  , { "ech" , 3 }
2256  , { "ipv6hint" , 8 }
2257  , { "dohpath" , 7 } };
2258 
2259 static const size_t svcparam_key_defs_len = sizeof(svcparam_key_defs)
2260  / sizeof(svcparam_key_def);
2261 
2262 /* svcparam_key2buffer_str() should actually be in host2str.c, but we need the
2263  * svcparam_key_defs for it and it is not an exposed symbol anyway.
2264  */
2266 {
2267  if (key <= LDNS_SVCPARAM_KEY_LAST_KEY)
2268  ldns_buffer_write_string(output, svcparam_key_defs[key].str);
2269  else
2270  ldns_buffer_printf(output, "key%d", (int)key);
2271  return ldns_buffer_status(output);
2272 }
2273 
2274 static ldns_status
2275 parse_svcparam_key(const char **s, ldns_svcparam_key *key)
2276 {
2277  size_t i, len;
2278  const char *key_str = *s;
2279  char num_str[6];
2280  char *endptr;
2281  unsigned long int num;
2282 
2283  /* parse key */
2284  while (islower((unsigned char)**s) || isdigit((unsigned char)**s)
2285  || **s == '-')
2286  *s += 1;
2287 
2288  len = *s - key_str;
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)) {
2292  *key = i;
2293  return LDNS_STATUS_OK;
2294  }
2295  }
2296  /* Also allow "echconfig" from earlier draft versions. */
2297  if (len == 9 && !strncmp(key_str, "echconfig", 9)) {
2298  *key = LDNS_SVCPARAM_KEY_ECH;
2299  return LDNS_STATUS_OK;
2300  }
2301  if (len < 4 || len > 8 || strncmp(key_str, "key", 3))
2303 
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)
2309 
2310  /* key65535 is Reserved to be an ("Invalid key"), though there is no
2311  * physiological reason to deny usage. We restrict ourselves to the
2312  * anatomical limitations only to maximize serviceability.
2313  * ```
2314  * if (num == 65535)
2315  * return LDNS_STATUS_RESERVED_SVCPARAM_KEY;
2316  * ```
2317  */
2318  *key = num;
2319  return LDNS_STATUS_OK;
2320 }
2321 
2322 static ldns_status
2323 parse_svcparam(const char **s, uint8_t **dp, uint8_t *eod)
2324 {
2325  ldns_svcparam_key key;
2326  ldns_status st;
2327  uint8_t *val;
2328 
2329  if (*dp + 4 > eod)
2331 
2332  if ((st = parse_svcparam_key(s, &key)))
2333  return st;
2334 
2335  ldns_write_uint16(*dp, key);
2336  ldns_write_uint16(*dp + 2, 0);
2337  *dp += 4;
2338  if (isspace((unsigned char)**s) || !**s)
2339  return LDNS_STATUS_OK;
2340 
2341  else if (**s != '=')
2342  return LDNS_STATUS_SYNTAX_ERR;
2343  *s += 1;
2344  val = *dp;
2345  switch(key) {
2347  st = parse_svcparam_mandatory(s, dp, eod);
2348  break;
2350  st = parse_svcparam_alpn(s, dp, eod);
2351  break;
2355  st = parse_svcparam_port(s, dp, eod);
2356  break;
2358  st = parse_svcparam_ipv4hint(s, dp, eod);
2359  break;
2360  case LDNS_SVCPARAM_KEY_ECH:
2361  st = parse_svcparam_ech(s, dp, eod);
2362  break;
2364  st = parse_svcparam_ipv6hint(s, dp, eod);
2365  break;
2366  default:
2367  st = parse_svcparam_value(s, dp, eod);
2368  break;
2369  }
2370  if (st)
2371  return st;
2372  ldns_write_uint16(val - 2, *dp - val);
2373  return LDNS_STATUS_OK;
2374 }
2375 
2376 static int
2377 svcparam_ptr_cmp(const void *a, const void *b)
2378 {
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;
2382 
2383  if (x_type != y_type)
2384  return x_type > y_type ? 1 : -1;
2385 
2386  x_len = ldns_read_uint16(x + 2);
2387  y_len = ldns_read_uint16(y + 2);
2388 
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));
2392 }
2393 
2396 {
2397  uint8_t *data, *dp, *eod, *p, *new_data;
2399  size_t length, i;
2400  size_t nparams = 0;
2401  uint8_t **svcparams;
2402  int prev_key;
2403 
2404  if (!rd || !str)
2405  return LDNS_STATUS_NULL;
2406 
2407  length = strlen(str);
2408  /* Worst case space requirement. We'll realloc to actual size later. */
2409  if (!(dp = data = LDNS_XMALLOC(uint8_t, length * 4)))
2410  return LDNS_STATUS_MEM_ERR;
2411  eod = data + length * 4;
2412 
2413  /* Fill data with parsed bytes */
2414  for (;;) {
2415  while (isspace((unsigned char)*str))
2416  str += 1;
2417  if(!*str)
2418  break;
2419  if ((st = parse_svcparam(&str, &dp, eod))) {
2420  LDNS_FREE(data);
2421  return st;
2422  }
2423  nparams += 1;
2424  }
2425 
2426  /* draft-ietf-dnsop-svcb-https-02 in Section 2.2:
2427  *
2428  * SvcParamKeys SHALL appear in increasing numeric order
2429  *
2430  * A svcparams array (with pointers to the individual key, value pairs)
2431  * is created to qsort the pairs in increasing numeric order.
2432  */
2433  if (!(svcparams = LDNS_XMALLOC(uint8_t *, nparams))) {
2434  LDNS_FREE(data);
2435  return LDNS_STATUS_MEM_ERR;
2436  }
2437  for ( p = data, i = 0
2438  ; p < dp && i < nparams
2439  ; p += 4 + ldns_read_uint16(p + 2))
2440  svcparams[i++] = p;
2441 
2442  qsort(svcparams, i, sizeof(uint8_t *), svcparam_ptr_cmp);
2443 
2444  /* Write out the (key, value) pairs to a newly allocated data in
2445  * sorted order.
2446  */
2447  length = dp - data;
2448  if (!(new_data = LDNS_XMALLOC(uint8_t, length))) {
2449  LDNS_FREE(data);
2450  LDNS_FREE(svcparams);
2451  return LDNS_STATUS_MEM_ERR;
2452  }
2453  prev_key = -1;
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]);
2458 
2459  /* In draft-ietf-dnsop-svcb-https-02 Section 2.1:
2460  *
2461  * SvcParams ...<snip>... keys MUST NOT be repeated.
2462  *
2463  * ldns will not impose this limitation on the library user,
2464  * but we can merge completely equal repetitions into one.
2465  * So, not doing
2466  * ```
2467  * if (key == prev_key)
2468  * return LDNS_STATUS_SVCPARAM_KEY_MORE_THAN_ONCE;
2469  * ```
2470  * but instead:
2471  */
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);
2478  continue;
2479  }
2480  memcpy(p, svcparams[i], 4 + ldns_read_uint16(svcparams[i] + 2));
2481  prev_key = key;
2482  }
2483  LDNS_FREE(data);
2484  LDNS_FREE(svcparams);
2485 
2486  /* Create rdf */
2487  *rd = ldns_rdf_new(LDNS_RDF_TYPE_SVCPARAMS, p - new_data, new_data);
2488  if (! *rd) {
2489  LDNS_FREE(new_data);
2490  return LDNS_STATUS_MEM_ERR;
2491  }
2492  return LDNS_STATUS_OK;
2493 }
2494 #else /* #ifdef RRTYPE_SVCB_HTTPS */
2496 ldns_str2rdf_svcparams(ldns_rdf **rd, const char *str)
2497 {
2498  (void)rd; (void)str;
2499  return LDNS_STATUS_NOT_IMPL;
2500 }
2501 #endif /* #ifdef RRTYPE_SVCB_HTTPS */
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
int ldns_buffer_printf(ldns_buffer *buffer, const char *format,...)
prints to the buffer, increasing the capacity if required using buffer_reserve().
Definition: buffer.c:99
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
Definition: buffer.c:41
#define ATTR_UNUSED(x)
Definition: common.h:72
@ LDNS_TLSA_SELECTOR_PRIVSEL
Reserved for Private Use.
Definition: dane.h:80
@ LDNS_TLSA_SELECTOR_SPKI
SubjectPublicKeyInfo: DER-encoded binary structure as defined in [RFC5280].
Definition: dane.h:76
@ LDNS_TLSA_SELECTOR_CERT
Full certificate: the Certificate binary structure as defined in [RFC5280].
Definition: dane.h:69
@ LDNS_TLSA_USAGE_PRIVCERT
Reserved for Private Use.
Definition: dane.h:56
@ LDNS_TLSA_USAGE_DANE_EE
Domain issued certificate.
Definition: dane.h:53
@ LDNS_TLSA_USAGE_PKIX_EE
Service certificate constraint.
Definition: dane.h:47
@ LDNS_TLSA_USAGE_PKIX_TA
CA constraint.
Definition: dane.h:44
@ LDNS_TLSA_USAGE_DANE_TA
Trust anchor assertion.
Definition: dane.h:50
@ LDNS_TLSA_MATCHING_TYPE_FULL
Exact match on selected content.
Definition: dane.h:90
@ LDNS_TLSA_MATCHING_TYPE_SHA2_512
SHA-512 hash of selected content [RFC6234].
Definition: dane.h:96
@ LDNS_TLSA_MATCHING_TYPE_SHA2_256
SHA-256 hash of selected content [RFC6234].
Definition: dane.h:93
@ LDNS_TLSA_MATCHING_TYPE_PRIVMATCH
Reserved for Private Use.
Definition: dane.h:99
signed char ldns_dname_str_absolute(const char *dname_str)
Checks whether the given dname string is absolute (i.e.
Definition: dname.c:518
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.
Definition: dnssec.c:721
@ LDNS_STATUS_INVALID_STR
Definition: error.h:41
@ LDNS_STATUS_DOMAINNAME_UNDERFLOW
Definition: error.h:30
@ LDNS_STATUS_INVALID_EUI48
Definition: error.h:123
@ LDNS_STATUS_INVALID_IP4
Definition: error.h:39
@ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW
Definition: error.h:94
@ LDNS_STATUS_SYNTAX_ERR
Definition: error.h:97
@ LDNS_STATUS_SYNTAX_SVCPARAM_KEY_ERR
Definition: error.h:139
@ LDNS_STATUS_INVALID_TIME
Definition: error.h:45
@ LDNS_STATUS_INVALID_EUI64
Definition: error.h:124
@ LDNS_STATUS_INVALID_B32_EXT
Definition: error.h:42
@ LDNS_STATUS_LABEL_OVERFLOW
Definition: error.h:28
@ LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED
Definition: error.h:142
@ LDNS_STATUS_NULL
Definition: error.h:51
@ LDNS_STATUS_INVALID_IP6
Definition: error.h:40
@ LDNS_STATUS_ERR
Definition: error.h:37
@ LDNS_STATUS_MEM_ERR
Definition: error.h:34
@ LDNS_STATUS_INVALID_ILNP64
Definition: error.h:122
@ LDNS_STATUS_INVALID_HEX
Definition: error.h:44
@ LDNS_STATUS_SYNTAX_BAD_ESCAPE
Definition: error.h:95
@ LDNS_STATUS_SYNTAX_SVCPARAM_VALUE_ERR
Definition: error.h:140
@ LDNS_STATUS_INVALID_INT
Definition: error.h:38
@ LDNS_STATUS_OK
Definition: error.h:26
@ LDNS_STATUS_EMPTY_LABEL
Definition: error.h:27
@ LDNS_STATUS_DOMAINNAME_OVERFLOW
Definition: error.h:29
@ LDNS_STATUS_INVALID_B64
Definition: error.h:43
@ LDNS_STATUS_INVALID_TAG
Definition: error.h:126
@ LDNS_STATUS_RDATA_OVERFLOW
Definition: error.h:129
@ LDNS_STATUS_CERT_BAD_ALGORITHM
Definition: error.h:78
@ LDNS_STATUS_NOT_IMPL
Definition: error.h:50
enum ldns_enum_status ldns_status
Definition: error.h:152
#define INET6_ADDRSTRLEN
Definition: host2str.c:43
int ldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
Including this file will include all ldns files, and define some lookup tables.
ldns_lookup_table ldns_algorithms[]
Taken from RFC 2535, section 7.
Definition: host2str.c:53
#define LDNS_IP6ADDRLEN
Definition: ldns.h:133
ldns_lookup_table ldns_cert_algorithms[]
Taken from RFC 2538.
Definition: host2str.c:84
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
returns a token/char from the buffer b.
Definition: parse.c:301
uint32_t ldns_str2period(const char *nptr, const char **endptr)
converts a ttl value (like 5d2h) to a long.
Definition: rdata.c:697
ldns_rdf * ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
returns the rdf containing the native uint8_t repr.
Definition: rdata.c:126
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_rdf * ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
allocates a new rdf structure and fills it.
Definition: rdata.c:179
#define LDNS_MAX_RDFLEN
Definition: rdata.h:31
uint16_t ldns_rdf2native_int16(const ldns_rdf *rd)
returns the native uint16_t representation from the rdf.
Definition: rdata.c:84
enum ldns_enum_svcparam_key ldns_svcparam_key
Definition: rdata.h:193
@ LDNS_RDF_TYPE_INT32
32 bits
Definition: rdata.h:56
@ LDNS_RDF_TYPE_TAG
A non-zero sequence of US-ASCII letters and numbers in lower case.
Definition: rdata.h:132
@ LDNS_RDF_TYPE_HIP
Represents the Public Key Algorithm, HIT and Public Key fields for the HIP RR types.
Definition: rdata.h:95
@ LDNS_RDF_TYPE_IPN
draft-johnson-dns-ipn-cla-07
Definition: rdata.h:155
@ LDNS_RDF_TYPE_B32_EXT
b32 string
Definition: rdata.h:68
@ LDNS_RDF_TYPE_EUI48
6 * 8 bit hex numbers separated by dashes.
Definition: rdata.h:122
@ LDNS_RDF_TYPE_EUI64
8 * 8 bit hex numbers separated by dashes.
Definition: rdata.h:124
@ LDNS_RDF_TYPE_PERIOD
period
Definition: rdata.h:89
@ LDNS_RDF_TYPE_B64
b64 string
Definition: rdata.h:70
@ LDNS_RDF_TYPE_AAAA
AAAA record.
Definition: rdata.h:62
@ LDNS_RDF_TYPE_WKS
well known services
Definition: rdata.h:104
@ LDNS_RDF_TYPE_DNAME
domain name
Definition: rdata.h:50
@ LDNS_RDF_TYPE_TIME
time (32 bits)
Definition: rdata.h:87
@ LDNS_RDF_TYPE_SVCPARAMS
draft-ietf-dnsop-svcb-https
Definition: rdata.h:152
@ LDNS_RDF_TYPE_NSEC3_SALT
nsec3 hash salt
Definition: rdata.h:112
@ LDNS_RDF_TYPE_APL
apl data
Definition: rdata.h:66
@ LDNS_RDF_TYPE_A
A record.
Definition: rdata.h:60
@ LDNS_RDF_TYPE_LONG_STR
A <character-string> encoding of the value field as specified [RFC1035], Section 5....
Definition: rdata.h:138
@ LDNS_RDF_TYPE_LOC
location data
Definition: rdata.h:102
@ LDNS_RDF_TYPE_ILNP64
4 shorts represented as 4 * 16 bit hex numbers separated by colons.
Definition: rdata.h:119
@ LDNS_RDF_TYPE_HEX
hex string
Definition: rdata.h:72
@ LDNS_RDF_TYPE_CLASS
a class
Definition: rdata.h:79
@ LDNS_RDF_TYPE_INT8
8 bits
Definition: rdata.h:52
@ LDNS_RDF_TYPE_IPSECKEY
IPSECKEY.
Definition: rdata.h:110
@ LDNS_RDF_TYPE_STR
txt string
Definition: rdata.h:64
@ LDNS_RDF_TYPE_INT16
16 bits
Definition: rdata.h:54
@ LDNS_RDF_TYPE_AMTRELAY
draft-ietf-mboned-driad-amt-discovery
Definition: rdata.h:149
@ LDNS_RDF_TYPE_TYPE
a RR type
Definition: rdata.h:77
size_t ldns_rdf_size(const ldns_rdf *rd)
returns the size of the rdf.
Definition: rdata.c:24
uint8_t * ldns_rdf_data(const ldns_rdf *rd)
returns the data of the rdf.
Definition: rdata.c:38
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
Definition: rdata.c:241
@ LDNS_SVCPARAM_KEY_PORT
Definition: rdata.h:185
@ LDNS_SVCPARAM_KEY_ALPN
Definition: rdata.h:183
@ LDNS_SVCPARAM_KEY_ECH
Definition: rdata.h:187
@ LDNS_SVCPARAM_KEY_MANDATORY
Definition: rdata.h:182
@ LDNS_SVCPARAM_KEY_IPV4HINT
Definition: rdata.h:186
@ LDNS_SVCPARAM_KEY_IPV6HINT
Definition: rdata.h:188
@ LDNS_SVCPARAM_KEY_LAST_KEY
Definition: rdata.h:190
@ LDNS_SVCPARAM_KEY_NO_DEFAULT_ALPN
Definition: rdata.h:184
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.
Definition: rdata.c:193
ldns_rr_class ldns_get_rr_class_by_name(const char *name)
retrieves a class by looking up its name.
Definition: rr.c:2835
#define LDNS_MAX_LABELLEN
Maximum length of a dname label.
Definition: rr.h:31
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:260
@ LDNS_RR_TYPE_NSEC
Definition: rr.h:171
#define LDNS_MAX_DOMAINLEN
Maximum length of a complete dname.
Definition: rr.h:33
ldns_rr_type ldns_get_rr_type_by_name(const char *name)
retrieves a rrtype by looking up its name.
Definition: rr.c:2795
ldns_status ldns_str2rdf_hex(ldns_rdf **rd, const char *str)
convert a hex value into wireformat
Definition: str2host.c:707
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...
Definition: str2host.c:1735
ldns_status ldns_str2rdf_int8(ldns_rdf **rd, const char *bytestr)
convert a byte into wireformat
Definition: str2host.c:291
ldns_status ldns_str2rdf_certificate_usage(ldns_rdf **rd, const char *str)
convert a tlsa certificate usage value into wireformat
Definition: str2host.c:902
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.
Definition: str2host.c:1639
ldns_status ldns_str2rdf_atma(ldns_rdf **rd, const char *str)
convert a str with a ATMA RR into wireformat
Definition: str2host.c:1318
ldns_status ldns_str2rdf_type(ldns_rdf **rd, const char *str)
convert a rrtype into wireformat
Definition: str2host.c:801
ldns_status ldns_str2rdf_nsec3_salt(ldns_rdf **rd, const char *salt_str)
Definition: str2host.c:126
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...
Definition: str2host.c:2395
ldns_status ldns_str2rdf_aaaa(ldns_rdf **rd, const char *str)
convert the str with an AAAA record into wireformat
Definition: str2host.c:477
ldns_status ldns_str2rdf_b32_ext(ldns_rdf **rd, const char *str)
convert the string with the b32 ext hex data into wireformat
Definition: str2host.c:676
ldns_status ldns_str2rdf_period(ldns_rdf **rd, const char *period)
Definition: str2host.c:178
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....
Definition: str2host.c:1592
ldns_status ldns_str2rdf_class(ldns_rdf **rd, const char *str)
convert string with a classname into wireformat
Definition: str2host.c:812
ldns_status svcparam_key2buffer_str(ldns_buffer *output, uint16_t key)
Definition: str2host.c:2265
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
Definition: str2host.c:374
ldns_status ldns_str2rdf_alg(ldns_rdf **rd, const char *str)
convert an algorithm value into wireformat
Definition: str2host.c:896
ldns_status ldns_str2rdf_nsec(ldns_rdf **rd, const char *str)
convert string with nsec into wireformat
Definition: str2host.c:753
ldns_status ldns_str2rdf_a(ldns_rdf **rd, const char *str)
convert str with an A record into wireformat
Definition: str2host.c:464
ldns_status ldns_str2rdf_matching_type(ldns_rdf **rd, const char *str)
convert a tlsa matching type value into wireformat
Definition: str2host.c:915
ldns_status ldns_str2rdf_wks(ldns_rdf **rd, const char *str)
convert string with a WKS RR into wireformat
Definition: str2host.c:1154
#define htonll(x)
Definition: str2host.c:236
ldns_status ldns_str2rdf_ilnp64(ldns_rdf **rd, const char *str)
convert 4 * 16bit hex separated by colons into wireformat
Definition: str2host.c:1492
ldns_status ldns_str2rdf_unknown(ldns_rdf **rd __attribute__((unused)), const char *str __attribute__((unused)))
Definition: str2host.c:921
ldns_status ldns_str2rdf_service(ldns_rdf **rd __attribute__((unused)), const char *str __attribute__((unused)))
Definition: str2host.c:931
ldns_status ldns_str2rdf_time(ldns_rdf **rd, const char *time)
convert a time string to a time value in wireformat
Definition: str2host.c:57
ldns_status ldns_str2rdf_nsap(ldns_rdf **rd, const char *str)
convert a str with a NSAP RR into wireformat
Definition: str2host.c:1299
ldns_status ldns_str2rdf_eui64(ldns_rdf **rd, const char *str)
convert 8 hex bytes separated by dashes into wireformat
Definition: str2host.c:1538
ldns_status ldns_str2rdf_loc(ldns_rdf **rd, const char *str)
convert a string with a LOC RR into wireformat
Definition: str2host.c:979
ldns_status ldns_str2rdf_str(ldns_rdf **rd, const char *str)
convert a string into wireformat (think txt record)
Definition: str2host.c:491
ldns_status ldns_str2rdf_ipseckey(ldns_rdf **rd, const char *str)
convert a str with a IPSECKEY RR into wireformat
Definition: str2host.c:1338
ldns_status ldns_str2rdf_selector(ldns_rdf **rd, const char *str)
convert a tlsa selector value into wireformat
Definition: str2host.c:909
ldns_status ldns_str2rdf_tag(ldns_rdf **rd, const char *str)
Convert a non-zero sequence of US-ASCII letters and numbers into wireformat.
Definition: str2host.c:1563
ldns_status ldns_str2rdf_apl(ldns_rdf **rd, const char *str)
convert str with the apl record into wireformat
Definition: str2host.c:535
ldns_status ldns_str2rdf_b64(ldns_rdf **rd, const char *str)
convert the string with the b64 data into wireformat
Definition: str2host.c:646
ldns_status ldns_str2rdf_ipn(ldns_rdf **rd, const char *ipnstr)
Convert either two unsigned 32 bit decimal numbers seperated by a '.
Definition: str2host.c:241
ldns_status ldns_str2rdf_eui48(ldns_rdf **rd, const char *str)
convert 6 hex bytes separated by dashes into wireformat
Definition: str2host.c:1515
ldns_status ldns_str2rdf_int32(ldns_rdf **rd, const char *longstr)
convert a strings into a 4 byte int in wireformat
Definition: str2host.c:197
ldns_status ldns_str2rdf_int16(ldns_rdf **rd, const char *shortstr)
convert a string to a int16 in wireformat
Definition: str2host.c:36
ldns_status ldns_str2rdf_cert_alg(ldns_rdf **rd, const char *str)
convert an certificate algorithm value into wireformat
Definition: str2host.c:826
implementation of buffers to ease operations
Definition: buffer.h:51
A general purpose lookup table.
Definition: util.h:178
Resource record data field.
Definition: rdata.h:203
int ldns_hexdigit_to_int(char ch)
Returns the int value of the given (hex) digit.
Definition: util.c:88
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)
Definition: util.c:777
time_t ldns_mktime_from_utc(const struct tm *tm)
Convert TM to seconds since epoch (midnight, January 1st, 1970).
Definition: util.c:194
#define INLINE
splint static inline workaround
Definition: util.h:42
#define LDNS_FREE(ptr)
Definition: util.h:60
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 LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
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...
Definition: util.c:72
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
#define LDNS_XREALLOC(ptr, type, count)
Definition: util.h:57