xref: /dragonfly/contrib/ldns/rdata.c (revision 7733acb50455a11cc2ee36edd926ff0fa3361e9a)
1 /*
2  * rdata.c
3  *
4  * rdata implementation
5  *
6  * a Net::DNS like library for C
7  *
8  * (c) NLnet Labs, 2004-2006
9  *
10  * See the file LICENSE for the license
11  */
12 
13 #include <ldns/config.h>
14 
15 #include <ldns/ldns.h>
16 
17 /*
18  * Access functions
19  * do this as functions to get type checking
20  */
21 
22 /* read */
23 size_t
ldns_rdf_size(const ldns_rdf * rd)24 ldns_rdf_size(const ldns_rdf *rd)
25 {
26           assert(rd != NULL);
27           return rd->_size;
28 }
29 
30 ldns_rdf_type
ldns_rdf_get_type(const ldns_rdf * rd)31 ldns_rdf_get_type(const ldns_rdf *rd)
32 {
33           assert(rd != NULL);
34           return rd->_type;
35 }
36 
37 uint8_t *
ldns_rdf_data(const ldns_rdf * rd)38 ldns_rdf_data(const ldns_rdf *rd)
39 {
40           assert(rd != NULL);
41           return rd->_data;
42 }
43 
44 /* write */
45 void
ldns_rdf_set_size(ldns_rdf * rd,size_t size)46 ldns_rdf_set_size(ldns_rdf *rd, size_t size)
47 {
48           assert(rd != NULL);
49           rd->_size = size;
50 }
51 
52 void
ldns_rdf_set_type(ldns_rdf * rd,ldns_rdf_type type)53 ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type)
54 {
55           assert(rd != NULL);
56           rd->_type = type;
57 }
58 
59 void
ldns_rdf_set_data(ldns_rdf * rd,void * data)60 ldns_rdf_set_data(ldns_rdf *rd, void *data)
61 {
62           /* only copy the pointer */
63           assert(rd != NULL);
64           rd->_data = data;
65 }
66 
67 /* for types that allow it, return
68  * the native/host order type */
69 uint8_t
ldns_rdf2native_int8(const ldns_rdf * rd)70 ldns_rdf2native_int8(const ldns_rdf *rd)
71 {
72           uint8_t data;
73 
74           /* only allow 8 bit rdfs */
75           if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) {
76                     return 0;
77           }
78 
79           memcpy(&data, ldns_rdf_data(rd), sizeof(data));
80           return data;
81 }
82 
83 uint16_t
ldns_rdf2native_int16(const ldns_rdf * rd)84 ldns_rdf2native_int16(const ldns_rdf *rd)
85 {
86           uint16_t data;
87 
88           /* only allow 16 bit rdfs */
89           if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) {
90                     return 0;
91           }
92 
93           memcpy(&data, ldns_rdf_data(rd), sizeof(data));
94           return ntohs(data);
95 }
96 
97 uint32_t
ldns_rdf2native_int32(const ldns_rdf * rd)98 ldns_rdf2native_int32(const ldns_rdf *rd)
99 {
100           uint32_t data;
101 
102           /* only allow 32 bit rdfs */
103           if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) {
104                     return 0;
105           }
106 
107           memcpy(&data, ldns_rdf_data(rd), sizeof(data));
108           return ntohl(data);
109 }
110 
111 time_t
ldns_rdf2native_time_t(const ldns_rdf * rd)112 ldns_rdf2native_time_t(const ldns_rdf *rd)
113 {
114           uint32_t data;
115 
116           /* only allow 32 bit rdfs */
117           if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD ||
118                               ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_TIME) {
119                     return 0;
120           }
121           memcpy(&data, ldns_rdf_data(rd), sizeof(data));
122           return (time_t)ntohl(data);
123 }
124 
125 ldns_rdf *
ldns_native2rdf_int8(ldns_rdf_type type,uint8_t value)126 ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value)
127 {
128           return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value);
129 }
130 
131 ldns_rdf *
ldns_native2rdf_int16(ldns_rdf_type type,uint16_t value)132 ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value)
133 {
134           uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1);
135         ldns_rdf* rdf;
136           if (!rdf_data) {
137                     return NULL;
138           }
139           ldns_write_uint16(rdf_data, value);
140           rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data);
141         if(!rdf)
142                 LDNS_FREE(rdf_data);
143         return rdf;
144 }
145 
146 ldns_rdf *
ldns_native2rdf_int32(ldns_rdf_type type,uint32_t value)147 ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
148 {
149           uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1);
150         ldns_rdf* rdf;
151           if (!rdf_data) {
152                     return NULL;
153           }
154           ldns_write_uint32(rdf_data, value);
155           rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data);
156         if(!rdf)
157                 LDNS_FREE(rdf_data);
158         return rdf;
159 }
160 
161 ldns_rdf *
ldns_native2rdf_int16_data(size_t size,uint8_t * data)162 ldns_native2rdf_int16_data(size_t size, uint8_t *data)
163 {
164           uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2);
165         ldns_rdf* rdf;
166           if (!rdf_data) {
167                     return NULL;
168           }
169           ldns_write_uint16(rdf_data, size);
170           memcpy(rdf_data + 2, data, size);
171           rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data);
172         if(!rdf)
173                 LDNS_FREE(rdf_data);
174         return rdf;
175 }
176 
177 /* note: data must be allocated memory */
178 ldns_rdf *
ldns_rdf_new(ldns_rdf_type type,size_t size,void * data)179 ldns_rdf_new(ldns_rdf_type type, size_t size, void *data)
180 {
181           ldns_rdf *rd;
182           rd = LDNS_MALLOC(ldns_rdf);
183           if (!rd) {
184                     return NULL;
185           }
186           ldns_rdf_set_size(rd, size);
187           ldns_rdf_set_type(rd, type);
188           ldns_rdf_set_data(rd, data);
189           return rd;
190 }
191 
192 ldns_rdf *
ldns_rdf_new_frm_data(ldns_rdf_type type,size_t size,const void * data)193 ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data)
194 {
195           ldns_rdf *rdf;
196 
197           /* if the size is too big, fail */
198           if (size > LDNS_MAX_RDFLEN) {
199                     return NULL;
200           }
201 
202           /* allocate space */
203           rdf = LDNS_MALLOC(ldns_rdf);
204           if (!rdf) {
205                     return NULL;
206           }
207           rdf->_data = LDNS_XMALLOC(uint8_t, size);
208           if (!rdf->_data) {
209                     LDNS_FREE(rdf);
210                     return NULL;
211           }
212 
213           /* set the values */
214           ldns_rdf_set_type(rdf, type);
215           ldns_rdf_set_size(rdf, size);
216           memcpy(rdf->_data, data, size);
217 
218           return rdf;
219 }
220 
221 ldns_rdf *
ldns_rdf_clone(const ldns_rdf * rd)222 ldns_rdf_clone(const ldns_rdf *rd)
223 {
224           assert(rd != NULL);
225           return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd),
226                     ldns_rdf_size(rd), ldns_rdf_data(rd)));
227 }
228 
229 void
ldns_rdf_deep_free(ldns_rdf * rd)230 ldns_rdf_deep_free(ldns_rdf *rd)
231 {
232           if (rd) {
233                     if (rd->_data) {
234                               LDNS_FREE(rd->_data);
235                     }
236                     LDNS_FREE(rd);
237           }
238 }
239 
240 void
ldns_rdf_free(ldns_rdf * rd)241 ldns_rdf_free(ldns_rdf *rd)
242 {
243           if (rd) {
244                     LDNS_FREE(rd);
245           }
246 }
247 
248 ldns_rdf *
ldns_rdf_new_frm_str(ldns_rdf_type type,const char * str)249 ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
250 {
251           ldns_rdf *rdf = NULL;
252           ldns_status status;
253 
254           switch (type) {
255           case LDNS_RDF_TYPE_DNAME:
256                     status = ldns_str2rdf_dname(&rdf, str);
257                     break;
258           case LDNS_RDF_TYPE_INT8:
259                     status = ldns_str2rdf_int8(&rdf, str);
260                     break;
261           case LDNS_RDF_TYPE_INT16:
262                     status = ldns_str2rdf_int16(&rdf, str);
263                     break;
264           case LDNS_RDF_TYPE_INT32:
265                     status = ldns_str2rdf_int32(&rdf, str);
266                     break;
267           case LDNS_RDF_TYPE_A:
268                     status = ldns_str2rdf_a(&rdf, str);
269                     break;
270           case LDNS_RDF_TYPE_AAAA:
271                     status = ldns_str2rdf_aaaa(&rdf, str);
272                     break;
273           case LDNS_RDF_TYPE_STR:
274                     status = ldns_str2rdf_str(&rdf, str);
275                     break;
276           case LDNS_RDF_TYPE_APL:
277                     status = ldns_str2rdf_apl(&rdf, str);
278                     break;
279           case LDNS_RDF_TYPE_B64:
280                     status = ldns_str2rdf_b64(&rdf, str);
281                     break;
282           case LDNS_RDF_TYPE_B32_EXT:
283                     status = ldns_str2rdf_b32_ext(&rdf, str);
284                     break;
285           case LDNS_RDF_TYPE_HEX:
286                     status = ldns_str2rdf_hex(&rdf, str);
287                     break;
288           case LDNS_RDF_TYPE_NSEC:
289                     status = ldns_str2rdf_nsec(&rdf, str);
290                     break;
291           case LDNS_RDF_TYPE_TYPE:
292                     status = ldns_str2rdf_type(&rdf, str);
293                     break;
294           case LDNS_RDF_TYPE_CLASS:
295                     status = ldns_str2rdf_class(&rdf, str);
296                     break;
297           case LDNS_RDF_TYPE_CERT_ALG:
298                     status = ldns_str2rdf_cert_alg(&rdf, str);
299                     break;
300           case LDNS_RDF_TYPE_ALG:
301                     status = ldns_str2rdf_alg(&rdf, str);
302                     break;
303           case LDNS_RDF_TYPE_UNKNOWN:
304                     status = ldns_str2rdf_unknown(&rdf, str);
305                     break;
306           case LDNS_RDF_TYPE_TIME:
307                     status = ldns_str2rdf_time(&rdf, str);
308                     break;
309           case LDNS_RDF_TYPE_PERIOD:
310                     status = ldns_str2rdf_period(&rdf, str);
311                     break;
312           case LDNS_RDF_TYPE_HIP:
313                     status = ldns_str2rdf_hip(&rdf, str);
314                     break;
315           case LDNS_RDF_TYPE_SERVICE:
316                     status = ldns_str2rdf_service(&rdf, str);
317                     break;
318           case LDNS_RDF_TYPE_LOC:
319                     status = ldns_str2rdf_loc(&rdf, str);
320                     break;
321           case LDNS_RDF_TYPE_WKS:
322                     status = ldns_str2rdf_wks(&rdf, str);
323                     break;
324           case LDNS_RDF_TYPE_NSAP:
325                     status = ldns_str2rdf_nsap(&rdf, str);
326                     break;
327           case LDNS_RDF_TYPE_ATMA:
328                     status = ldns_str2rdf_atma(&rdf, str);
329                     break;
330           case LDNS_RDF_TYPE_IPSECKEY:
331                     status = ldns_str2rdf_ipseckey(&rdf, str);
332                     break;
333           case LDNS_RDF_TYPE_NSEC3_SALT:
334                     status = ldns_str2rdf_nsec3_salt(&rdf, str);
335                     break;
336           case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER:
337                     status = ldns_str2rdf_b32_ext(&rdf, str);
338                     break;
339           case LDNS_RDF_TYPE_ILNP64:
340                     status = ldns_str2rdf_ilnp64(&rdf, str);
341                     break;
342           case LDNS_RDF_TYPE_EUI48:
343                     status = ldns_str2rdf_eui48(&rdf, str);
344                     break;
345           case LDNS_RDF_TYPE_EUI64:
346                     status = ldns_str2rdf_eui64(&rdf, str);
347                     break;
348           case LDNS_RDF_TYPE_TAG:
349                     status = ldns_str2rdf_tag(&rdf, str);
350                     break;
351           case LDNS_RDF_TYPE_LONG_STR:
352                     status = ldns_str2rdf_long_str(&rdf, str);
353                     break;
354           case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
355                     status = ldns_str2rdf_certificate_usage(&rdf, str);
356                     break;
357           case LDNS_RDF_TYPE_SELECTOR:
358                     status = ldns_str2rdf_selector(&rdf, str);
359                     break;
360           case LDNS_RDF_TYPE_MATCHING_TYPE:
361                     status = ldns_str2rdf_matching_type(&rdf, str);
362                     break;
363           case LDNS_RDF_TYPE_AMTRELAY:
364                     status = ldns_str2rdf_amtrelay(&rdf, str);
365                     break;
366           case LDNS_RDF_TYPE_SVCPARAMS:
367                     status = ldns_str2rdf_svcparams(&rdf, str);
368                     break;
369           case LDNS_RDF_TYPE_NONE:
370           default:
371                     /* default default ??? */
372                     status = LDNS_STATUS_ERR;
373                     break;
374           }
375           if (LDNS_STATUS_OK == status) {
376                     ldns_rdf_set_type(rdf, type);
377                     return rdf;
378           }
379           if (rdf) {
380                     LDNS_FREE(rdf);
381           }
382           return NULL;
383 }
384 
385 ldns_status
ldns_rdf_new_frm_fp(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp)386 ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp)
387 {
388           return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL);
389 }
390 
391 ldns_status
ldns_rdf_new_frm_fp_l(ldns_rdf ** rdf,ldns_rdf_type type,FILE * fp,int * line_nr)392 ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr)
393 {
394           char *line;
395           ldns_rdf *r;
396           ssize_t t;
397 
398           line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
399           if (!line) {
400                     return LDNS_STATUS_MEM_ERR;
401           }
402 
403           /* read an entire line in from the file */
404           if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) {
405                     LDNS_FREE(line);
406                     return LDNS_STATUS_SYNTAX_RDATA_ERR;
407           }
408           r =  ldns_rdf_new_frm_str(type, (const char*) line);
409           LDNS_FREE(line);
410           if (rdf) {
411                     *rdf = r;
412                     return LDNS_STATUS_OK;
413           } else {
414                     return LDNS_STATUS_NULL;
415           }
416 }
417 
418 ldns_rdf *
ldns_rdf_address_reverse(const ldns_rdf * rd)419 ldns_rdf_address_reverse(const ldns_rdf *rd)
420 {
421           uint8_t buf_4[LDNS_IP4ADDRLEN];
422           uint8_t buf_6[LDNS_IP6ADDRLEN * 2];
423           ldns_rdf *rev;
424           ldns_rdf *in_addr;
425           ldns_rdf *ret_dname;
426           uint8_t octet;
427           uint8_t nnibble;
428           uint8_t nibble;
429           uint8_t i, j;
430 
431           char *char_dname;
432           int nbit;
433 
434           if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A &&
435                               ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) {
436                     return NULL;
437           }
438 
439           in_addr = NULL;
440           ret_dname = NULL;
441 
442           switch(ldns_rdf_get_type(rd)) {
443                     case LDNS_RDF_TYPE_A:
444                               /* the length of the buffer is 4 */
445                               buf_4[3] = ldns_rdf_data(rd)[0];
446                               buf_4[2] = ldns_rdf_data(rd)[1];
447                               buf_4[1] = ldns_rdf_data(rd)[2];
448                               buf_4[0] = ldns_rdf_data(rd)[3];
449                               in_addr = ldns_dname_new_frm_str("in-addr.arpa.");
450                               if (!in_addr) {
451                                         return NULL;
452                               }
453                               /* make a new rdf and convert that back  */
454                               rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A,
455                                         LDNS_IP4ADDRLEN, (void*)&buf_4);
456                               if (!rev) {
457                                         LDNS_FREE(in_addr);
458                                         return NULL;
459                               }
460 
461                               /* convert rev to a string */
462                               char_dname = ldns_rdf2str(rev);
463                               if (!char_dname) {
464                                         LDNS_FREE(in_addr);
465                                         ldns_rdf_deep_free(rev);
466                                         return NULL;
467                               }
468                               /* transform back to rdf with type dname */
469                               ret_dname = ldns_dname_new_frm_str(char_dname);
470                               if (!ret_dname) {
471                                         LDNS_FREE(in_addr);
472                                         ldns_rdf_deep_free(rev);
473                                         LDNS_FREE(char_dname);
474                                         return NULL;
475                               }
476                               /* not needed anymore */
477                               ldns_rdf_deep_free(rev);
478                               LDNS_FREE(char_dname);
479                               break;
480                     case LDNS_RDF_TYPE_AAAA:
481                               /* some foo magic to reverse the nibbles ... */
482 
483                               for (nbit = 127; nbit >= 0; nbit = nbit - 4) {
484                                         /* calculate octet (8 bit) */
485                                         octet = ( ((unsigned int) nbit) & 0x78) >> 3;
486                                         /* calculate nibble */
487                                         nnibble = ( ((unsigned int) nbit) & 0x04) >> 2;
488                                         /* extract nibble */
489                                         nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 -
490                                                              nnibble)) ) ) >> ( 4 * (1 -
491                                                             nnibble));
492 
493                                         buf_6[(LDNS_IP6ADDRLEN * 2 - 1) -
494                                                   (octet * 2 + nnibble)] =
495                                                             (uint8_t)ldns_int_to_hexdigit((int)nibble);
496                               }
497 
498                               char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4));
499                               if (!char_dname) {
500                                         return NULL;
501                               }
502                               char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */
503 
504                               /* walk the string and add . 's */
505                               for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) {
506                                         char_dname[j] = (char)buf_6[i];
507                                         if (i != LDNS_IP6ADDRLEN * 2 - 1) {
508                                                   char_dname[j + 1] = '.';
509                                         }
510                               }
511                               in_addr = ldns_dname_new_frm_str("ip6.arpa.");
512                               if (!in_addr) {
513                                         LDNS_FREE(char_dname);
514                                         return NULL;
515                               }
516 
517                               /* convert rev to a string */
518                               ret_dname = ldns_dname_new_frm_str(char_dname);
519                               LDNS_FREE(char_dname);
520                               if (!ret_dname) {
521                                         ldns_rdf_deep_free(in_addr);
522                                         return NULL;
523                               }
524                               break;
525                     default:
526                               break;
527           }
528           /* add the suffix */
529           rev = ldns_dname_cat_clone(ret_dname, in_addr);
530 
531           ldns_rdf_deep_free(ret_dname);
532           ldns_rdf_deep_free(in_addr);
533           return rev;
534 }
535 
536 ldns_status
ldns_rdf_hip_get_alg_hit_pk(ldns_rdf * rdf,uint8_t * alg,uint8_t * hit_size,uint8_t ** hit,uint16_t * pk_size,uint8_t ** pk)537 ldns_rdf_hip_get_alg_hit_pk(ldns_rdf *rdf, uint8_t* alg,
538                             uint8_t *hit_size, uint8_t** hit,
539                             uint16_t *pk_size, uint8_t** pk)
540 {
541           uint8_t *data;
542           size_t rdf_size;
543 
544           if (! rdf || ! alg || ! hit || ! hit_size || ! pk || ! pk_size) {
545                     return LDNS_STATUS_INVALID_POINTER;
546           } else if (ldns_rdf_get_type(rdf) != LDNS_RDF_TYPE_HIP) {
547                     return LDNS_STATUS_INVALID_RDF_TYPE;
548           } else if ((rdf_size = ldns_rdf_size(rdf)) < 6) {
549                     return LDNS_STATUS_WIRE_RDATA_ERR;
550           }
551           data = ldns_rdf_data(rdf);
552           *hit_size = data[0];
553           *alg      = data[1];
554           *pk_size  = ldns_read_uint16(data + 2);
555           *hit      = data + 4;
556           *pk       = data + 4 + *hit_size;
557           if (*hit_size == 0 || *pk_size == 0 ||
558                               rdf_size < (size_t) *hit_size + *pk_size + 4) {
559                     return LDNS_STATUS_WIRE_RDATA_ERR;
560           }
561           return LDNS_STATUS_OK;
562 }
563 
564 ldns_status
ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf ** rdf,uint8_t alg,uint8_t hit_size,uint8_t * hit,uint16_t pk_size,uint8_t * pk)565 ldns_rdf_hip_new_frm_alg_hit_pk(ldns_rdf** rdf, uint8_t alg,
566                                 uint8_t hit_size, uint8_t *hit,
567                                         uint16_t pk_size, uint8_t *pk)
568 {
569           uint8_t *data;
570 
571           if (! rdf) {
572                     return LDNS_STATUS_INVALID_POINTER;
573           }
574           if (4 + hit_size + pk_size > LDNS_MAX_RDFLEN) {
575                     return LDNS_STATUS_RDATA_OVERFLOW;
576           }
577           data = LDNS_XMALLOC(uint8_t, 4 + hit_size + pk_size);
578           if (data == NULL) {
579                     return LDNS_STATUS_MEM_ERR;
580           }
581           data[0] = hit_size;
582           data[1] = alg;
583           ldns_write_uint16(data + 2, pk_size);
584           memcpy(data + 4, hit, hit_size);
585           memcpy(data + 4 + hit_size, pk, pk_size);
586           *rdf = ldns_rdf_new(LDNS_RDF_TYPE_HIP, 4 + hit_size + pk_size, data);
587           if (! *rdf) {
588                     LDNS_FREE(data);
589                     return LDNS_STATUS_MEM_ERR;
590           }
591           return LDNS_STATUS_OK;
592 }
593 
594 ldns_status
ldns_octet(char * word,size_t * length)595 ldns_octet(char *word, size_t *length)
596 {
597     char *s;
598     char *p;
599     *length = 0;
600 
601     for (s = p = word; *s != '\0'; s++,p++) {
602         switch (*s) {
603             case '.':
604                 if (s[1] == '.') {
605                         return LDNS_STATUS_EMPTY_LABEL;
606                 }
607                 *p = *s;
608                 (*length)++;
609                 break;
610             case '\\':
611                 if ('0' <= s[1] && s[1] <= '9' &&
612                     '0' <= s[2] && s[2] <= '9' &&
613                     '0' <= s[3] && s[3] <= '9') {
614                     /* \DDD seen */
615                     int val = ((s[1] - '0') * 100 +
616                            (s[2] - '0') * 10 + (s[3] - '0'));
617 
618                     if (0 <= val && val <= 255) {
619                         /* this also handles \0 */
620                         s += 3;
621                         *p = val;
622                         (*length)++;
623                     } else {
624                         return LDNS_STATUS_DDD_OVERFLOW;
625                     }
626                 } else {
627                     /* an escaped character, like \<space> ?
628                     * remove the '\' keep the rest */
629                     *p = *++s;
630                     (*length)++;
631                 }
632                 break;
633             case '\"':
634                 /* non quoted " Is either first or the last character in
635                  * the string */
636 
637                 *p = *++s; /* skip it */
638                 (*length)++;
639                     /* I'm not sure if this is needed in libdns... MG */
640                 if ( *s == '\0' ) {
641                     /* ok, it was the last one */
642                     *p  = '\0';
643                         return LDNS_STATUS_OK;
644                 }
645                 break;
646             default:
647                 *p = *s;
648                 (*length)++;
649                 break;
650         }
651     }
652     *p = '\0';
653     return LDNS_STATUS_OK;
654 }
655 
656 int
ldns_rdf_compare(const ldns_rdf * rd1,const ldns_rdf * rd2)657 ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2)
658 {
659           uint16_t i1, i2, i;
660           uint8_t *d1, *d2;
661 
662           /* only when both are not NULL we can say anything about them */
663           if (!rd1 && !rd2) {
664                     return 0;
665           }
666           if (!rd1 || !rd2) {
667                     return -1;
668           }
669           i1 = ldns_rdf_size(rd1);
670           i2 = ldns_rdf_size(rd2);
671 
672           if (i1 < i2) {
673                     return -1;
674           } else if (i1 > i2) {
675                     return +1;
676           } else {
677                     d1 = (uint8_t*)ldns_rdf_data(rd1);
678                     d2 = (uint8_t*)ldns_rdf_data(rd2);
679                     for(i = 0; i < i1; i++) {
680                               if (d1[i] < d2[i]) {
681                                         return -1;
682                               } else if (d1[i] > d2[i]) {
683                                         return +1;
684                               }
685                     }
686           }
687           return 0;
688 }
689 
690 uint32_t
ldns_str2period(const char * nptr,const char ** endptr)691 ldns_str2period(const char *nptr, const char **endptr)
692 {
693           int sign = 0;
694           uint32_t i = 0;
695           uint32_t seconds = 0;
696 
697           for(*endptr = nptr; **endptr; (*endptr)++) {
698                     switch (**endptr) {
699                               case ' ':
700                               case '\t':
701                                         break;
702                               case '-':
703                                         if(sign == 0) {
704                                                   sign = -1;
705                                         } else {
706                                                   return seconds;
707                                         }
708                                         break;
709                               case '+':
710                                         if(sign == 0) {
711                                                   sign = 1;
712                                         } else {
713                                                   return seconds;
714                                         }
715                                         break;
716                               case 's':
717                               case 'S':
718                                         seconds += i;
719                                         i = 0;
720                                         break;
721                               case 'm':
722                               case 'M':
723                                         seconds += i * 60;
724                                         i = 0;
725                                         break;
726                               case 'h':
727                               case 'H':
728                                         seconds += i * 60 * 60;
729                                         i = 0;
730                                         break;
731                               case 'd':
732                               case 'D':
733                                         seconds += i * 60 * 60 * 24;
734                                         i = 0;
735                                         break;
736                               case 'w':
737                               case 'W':
738                                         seconds += i * 60 * 60 * 24 * 7;
739                                         i = 0;
740                                         break;
741                               case '0':
742                               case '1':
743                               case '2':
744                               case '3':
745                               case '4':
746                               case '5':
747                               case '6':
748                               case '7':
749                               case '8':
750                               case '9':
751                                         i *= 10;
752                                         i += (**endptr - '0');
753                                         break;
754                               default:
755                                         seconds += i;
756                                         /* disregard signedness */
757                                         return seconds;
758                     }
759           }
760           seconds += i;
761           /* disregard signedness */
762           return seconds;
763 }
764