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