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