1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup dnscore
36 * @ingroup dnscore
37 * @brief Functions used to manipulate dns formatted names and labels
38 *
39 * DNS names are stored in many ways:
40 * _ C string : ASCII with a '\0' sentinel
41 * _ DNS wire : label_length_byte + label_bytes) ending with a label_length_byte with a value of 0
42 * _ simple array of pointers to labels
43 * _ simple stack of pointers to labels (so the same as above, but with the order reversed)
44 * _ sized array of pointers to labels
45 * _ sized stack of pointers to labels (so the same as above, but with the order reversed)
46 *
47 * @{
48 */
49 #pragma once
50
51 #include <dnscore/sys_types.h>
52 #include <dnscore/rfc.h>
53
54 #if DNSCORE_HAS_FULL_ASCII7
55 #include <ctype.h>
56 #endif
57
58 /**
59 * The maximum number of domains-subdomains handled by the database.
60 * This should not be set to a value greater than 128 (128 covers (\001 'a') * 255 )
61 *
62 * Recommended value: 128
63 *
64 */
65
66 #define SRV_UNDERSCORE_SUPPORT 1
67
68 #define DNSNAME_MAX_SECTIONS ((MAX_DOMAIN_LENGTH + 1) / 2)
69
70 #if !DNSNAME_C_
71 extern const u8 __LOCASE_TABLE__[256];
72 #endif
73
74 // dns equal chars comparison should give 0x00 or 0x20
75 // the '_' breaks this so there is a slightly different (slightly slower) way to handle it
76
77 // IMPORTANT NOTE 1 : MACROS ARE WRITTEN TO USE THEIR PARAMETERS EXACTLY ONCE
78
79 // IMPORTANT NOTE 2 : LOCASEEQUAL only works on the DNS chars AND with the first parameter being a lo-case string (like in the database)
80
81 #if !DNSCORE_HAS_FULL_ASCII7
82
83 #define dnsname_equals_ignorecase dnsname_equals_ignorecase3
84 #define dnslabel_equals_ignorecase_left dnslabel_equals_ignorecase_left1
85
86 #if !SRV_UNDERSCORE_SUPPORT
87 #define LOCASE(c__) ((char)(c__)|(char)0x20)
88
LOCASEEQUALS(char ca__,char cb__)89 static inline bool LOCASEEQUALS(char ca__,char cb__)
90 {
91 return ((((char)(ca__)-(char)(cb__))&0xdf) == 0);
92 }
93
LOCASEEQUALSBY2(const u8 * name_a,const u8 * name_b)94 static inline bool LOCASEEQUALSBY2(const u8* name_a, const u8* name_b)
95 {
96 return (((GET_U16_AT(name_a[0]) - GET_U16_AT(name_b[0])) & ((u16)0xdfdf)) == 0);
97 }
98
LOCASEEQUALSBY3(const u8 * name_a,const u8 * name_b)99 static inline bool LOCASEEQUALSBY3(const u8* name_a, const u8* name_b)
100 {
101 return LOCASEEQUALSBY2(name_a, name_b) && LOCASEEQUALS(name_a[2], name_b[2]);
102 }
103
LOCASEEQUALSBY4(const u8 * name_a,const u8 * name_b)104 static inline bool LOCASEEQUALSBY4(const u8* name_a, const u8* name_b)
105 {
106 return (((GET_U32_AT(name_a[0]) - GET_U32_AT(name_b[0])) & ((u16)0xdfdfdfdf)) == 0);
107 }
108 #else // slightly modified to take '_' into account
109
110 #define LOCASE(c__) (((((char)(c__)+(char)0x01)|(char)0x20))-(char)0x01)
111
LOCASEEQUALS(u8 a,u8 b)112 static inline bool LOCASEEQUALS(u8 a, u8 b)
113 {
114 return ((((u8)(a+0x01)-(u8)(b+0x01))&0xdf) == 0);
115 }
116
LOCASEEQUALSBY2(const u8 * name_a,const u8 * name_b)117 static inline bool LOCASEEQUALSBY2(const u8* name_a, const u8* name_b)
118 {
119 return (( ( (GET_U16_AT(name_a[0]) + 0x0101) - (GET_U16_AT(name_b[0]) + 0x0101)) & ((u16)0xdfdf)) == 0);
120 }
121
LOCASEEQUALSBY3(const u8 * name_a,const u8 * name_b)122 static inline bool LOCASEEQUALSBY3(const u8* name_a, const u8* name_b)
123 {
124 return LOCASEEQUALSBY2(name_a, name_b) && LOCASEEQUALS(name_a[2], name_b[2]);
125 }
126
LOCASEEQUALSBY4(const u8 * name_a,const u8 * name_b)127 static inline bool LOCASEEQUALSBY4(const u8* name_a, const u8* name_b)
128 {
129 return (( ( (GET_U32_AT(name_a[0]) + 0x01010101) - (GET_U32_AT(name_b[0]) + 0x01010101)) & ((u32)0xdfdfdfdf)) == 0);
130 }
131 #endif
132
133 #else // DNSCORE_HAS_FULL_ASCII7
134
135 #define dnsname_equals_ignorecase dnsname_equals_ignorecase3
136 #define dnslabel_equals_ignorecase_left dnslabel_equals_ignorecase_left4
137
138 #define LOCASE(c__) __LOCASE_TABLE__[(c__)]
139
LOCASEEQUALS(u8 a,u8 b)140 static inline bool LOCASEEQUALS(u8 a, u8 b)
141 {
142 return LOCASE(a) == LOCASE(b);
143 }
144
LOCASEEQUALSBY2(const u8 * name_a,const u8 * name_b)145 static inline bool LOCASEEQUALSBY2(const u8* name_a, const u8* name_b)
146 {
147 return LOCASEEQUALS(name_a[0], name_b[0]) && LOCASEEQUALS(name_a[1], name_b[1]);
148 }
149
LOCASEEQUALSBY3(const u8 * name_a,const u8 * name_b)150 static inline bool LOCASEEQUALSBY3(const u8* name_a, const u8* name_b)
151 {
152 return LOCASEEQUALSBY2(name_a, name_b) && LOCASEEQUALS(name_a[2], name_b[2]);
153 }
154
LOCASEEQUALSBY4(const u8 * name_a,const u8 * name_b)155 static inline bool LOCASEEQUALSBY4(const u8* name_a, const u8* name_b)
156 {
157 return LOCASEEQUALSBY3(name_a, name_b) && LOCASEEQUALS(name_a[3], name_b[3]);
158 }
159
160 #endif
161
162 #define ZDB_NAME_TAG 0x454d414e42445a /* "ZDBNAME" */
163 #define ZDB_LABEL_TAG 0x4c424c42445a /* "ZDBLBL" */
164
165 #ifdef __cplusplus
166 extern "C"
167 {
168 #endif
169
170 /*
171 * A dnslabel_array is basically a dnslabel*[]
172 * There are two kind of arrays :
173 *
174 * dnslabel_stack:
175 *
176 * [0000] "." label
177 * [0001] "tdl" label
178 * [0002] "domain" label <- top
179 *
180 * dnslabel_vector:
181 *
182 * [0000] "domain" label
183 * [0001] "tdl" label
184 * [0002] "." label <- top
185 *
186 */
187
188 /*
189 * The plan was to typedef an array into a stack or a vector.
190 * But in order to help the compiler complaining about mixing both,
191 * I have to define them separatly
192 *
193 */
194
195 typedef const u8* dnslabel_stack[DNSNAME_MAX_SECTIONS];
196
197 /* This + 1 is just to make sure both are different to the compiler's eyes */
198
199 typedef const u8* dnslabel_vector[DNSNAME_MAX_SECTIONS + 1];
200
201 typedef const u8** dnslabel_stack_reference;
202 typedef const u8** dnslabel_vector_reference;
203
204 typedef const u8*const* const_dnslabel_stack_reference;
205 typedef const u8*const* const_dnslabel_vector_reference;
206
207 #if DEBUG
208 #define DEBUG_RESET_dnsname(name) memset(&(name),0x5b,sizeof(dnsname_stack))
209 #else
210 #define DEBUG_RESET_dnsname(name)
211 #endif
212
213 typedef struct dnsname_stack dnsname_stack;
214
215
216 struct dnsname_stack
217 {
218 s32 size;
219 dnslabel_stack labels;
220 };
221
222 typedef struct dnsname_vector dnsname_vector;
223
224
225 struct dnsname_vector
226 {
227 s32 size;
228 dnslabel_vector labels;
229 };
230
231 /*****************************************************************************
232 *
233 * BUFFER
234 *
235 *****************************************************************************/
236
237 /** @brief Converts a C string to a dns name.
238 *
239 * Converts a C string to a dns name.
240 *
241 * @param[in] name_parm a pointer to a buffer that will get the full dns name
242 * @param[in] str a pointer to the source c-string
243 *
244 * @return Returns the length of the string up to the last '\0'
245 */
246
247 /* TWO use */
248
249 ya_result cstr_to_dnsname(u8* name_parm, const char* str);
250
251 /** @brief Converts a C string to a lower-case dns name.
252 *
253 * Converts a C string to a lower-case dns name.
254 *
255 * @param[in] name_parm a pointer to a buffer that will get the full dns name
256 * @param[in] str a pointer to the source c-string
257 *
258 * @return Returns the length of the string up to the last '\0'
259 */
260
261 ya_result cstr_to_locase_dnsname(u8* name_parm, const char* str);
262
263 /** @brief Converts a text buffer to a dns name.
264 *
265 * Converts a text buffer to a dns name.
266 *
267 * @param[in] name_parm a pointer to a buffer that will get the full dns name
268 * @param[in] str a pointer to the source buffer
269 * @param[in] str_len the length of the source buffer
270 *
271 * @return Returns the length of the string up to the last '\0'
272 */
273
274 ya_result charp_to_dnsname(u8* name_parm, const char* str, u32 str_len);
275
276 /** @brief Converts a text buffer to a lower-case dns name.
277 *
278 * Converts a text buffer to a lower-case dns name.
279 *
280 * @param[in] name_parm a pointer to a buffer that will get the full dns name
281 * @param[in] str a pointer to the source buffer
282 * @param[in] str_len the length of the source buffer
283 *
284 * @return Returns the length of the string up to the last '\0'
285 */
286
287 ya_result charp_to_locase_dnsname(u8* name_parm, const char* str, u32 str_len);
288
289 /** @brief Converts a text buffer to a lower-case dns name and checks for validity
290 *
291 * Converts a text buffer to a lower-case dns name.
292 *
293 * @param[in] name_parm a pointer to a buffer that will get the full dns name
294 * @param[in] str a pointer to the source buffer
295 * @param[in] str_len the length of the source buffer
296 *
297 * @return Returns the length of the string up to the last '\0'
298 */
299
300 ya_result charp_to_locase_dnsname_with_check(u8* name_parm, const char* str, u32 str_len);
301
302 /**
303 * @brief Converts a C string to a dns name and checks for validity
304 *
305 * Converts a C string to a dns name.
306 *
307 * @param[in] name_parm a pointer to a buffer that will get the full dns name
308 * @param[in] str a pointer to the source c-string
309 *
310 * @return Returns the length of the string up to the last '\0'
311 */
312
313 ya_result cstr_to_dnsname_with_check(u8* name_parm, const char* str);
314
315 /**
316 * @brief Converts a C string to a dns rname and checks for validity
317 *
318 * Converts a C string to a dns rname.
319 *
320 * @param[in] name_parm a pointer to a buffer that will get the full dns name
321 * @param[in] str a pointer to the source c-string
322 *
323 * @return Returns the length of the string up to the last '\0'
324 */
325
326 ya_result cstr_to_dnsrname_with_check(u8* name_parm, const char* str);
327
328 ya_result cstr_to_dnsname_with_check_len(u8* name_parm, const char* text, u32 text_len);
329
330 ya_result cstr_to_locase_dnsname_with_check_len(u8* name_parm, const char* text, u32 text_len);
331
332 ya_result cstr_to_dnsname_with_check_len_with_origin(u8* name_parm, const char* text, u32 text_len, const u8 *origin);
333
334 ya_result cstr_to_locase_dnsname_with_check_len_with_origin(u8* name_parm, const char* text, u32 text_len, const u8 *origin);
335
336 /* ONE use */
337
338 ya_result cstr_get_dnsname_len(const char* str);
339
340 /** @brief Converts a dns name to a C string
341 *
342 * Converts a dns name to a C string
343 *
344 * @param[in] name a pointer to the source dns name
345 * @param[in] str a pointer to a buffer that will get the c-string
346 *
347 * @return Returns the length of the string
348 */
349
350 /* SIX uses */
351
352 u32 dnsname_to_cstr(char* str, const u8* name);
353
354 /** @brief Tests if two DNS labels are equals
355 *
356 * Tests if two DNS labels are equals
357 *
358 * @param[in] name_a a pointer to a dnsname to compare
359 * @param[in] name_b a pointer to a dnsname to compare
360 *
361 * @return Returns TRUE if names are equal, else FALSE.
362 */
363
364 /* ELEVEN uses */
365
366 bool dnslabel_equals(const u8* name_a, const u8* name_b);
367
368 int dnsname_compare(const u8* name_a, const u8* name_b);
369
370 bool dnsname_is_subdomain(const u8* subdomain, const u8* domain);
371
372 /** @brief Tests if two DNS labels are (case-insensitive) equals
373 *
374 * Tests if two DNS labels are (case-insensitive) equals
375 *
376 * @param[in] name_a a pointer to a lo-case dnsname to compare
377 * @param[in] name_b a pointer to a any-case dnsname to compare
378 *
379 * @return Returns TRUE if names are equal, else FALSE.
380 */
381
382 bool dnslabel_equals_ignorecase_left1(const u8* name_a, const u8* name_b);
383
384 bool dnslabel_equals_ignorecase_left2(const u8* name_a, const u8* name_b);
385
386 bool dnslabel_equals_ignorecase_left3(const u8* name_a, const u8* name_b);
387
388 bool dnslabel_equals_ignorecase_left4(const u8* name_a, const u8* name_b);
389
390 bool dnslabel_equals_ignorecase_left5(const u8* name_a, const u8* name_b);
391
392 /** @brief Tests if two DNS names are equals
393 *
394 * Tests if two DNS labels are equals
395 *
396 * @param[in] name_a a pointer to a dnsname to compare
397 * @param[in] name_b a pointer to a dnsname to compare
398 *
399 * @return Returns TRUE if names are equal, else FALSE.
400 */
401
402 /* TWO uses */
403
404 bool dnsname_equals(const u8* name_a, const u8* name_b);
405
406 /** @brief Tests if two DNS names are (ignore case) equals
407 *
408 * Tests if two DNS labels are (ignore case) equals
409 *
410 * @param[in] name_a a pointer to a dnsname to compare
411 * @param[in] name_b a pointer to a dnsname to compare
412 *
413 * @return Returns TRUE if names are equal, else FALSE.
414 */
415
416 /* TWO uses */
417
418 bool dnsname_equals_ignorecase1(const u8* name_a, const u8* name_b);
419
420 bool dnsname_equals_ignorecase2(const u8* name_a, const u8* name_b);
421
422 bool dnsname_equals_ignorecase3(const u8* name_a, const u8* name_b);
423
424 /** @brief Returns the full length of a dns name
425 *
426 * Returns the full length of a dns name
427 *
428 * @param[in] name a pointer to the dnsname
429 *
430 * @return The length of the dnsname, "." ( zero ) included
431 */
432
433 /* SEVENTEEN uses (more or less) */
434
435 u32 dnsname_len(const u8* name);
436
437 ya_result dnsname_len_checked(const u8 *name);
438
439 /* ONE use */
440
441 u32 dnsname_getdepth(const u8* name);
442
443 /* ONE use */
444
445 u32 dnsname_copy(u8* dst, const u8* src);
446
447 ya_result dnsname_copy_checked(u8* dst, const u8* src);
448
449 /* malloc & copies a dnsname */
450
451 u8* dnsname_dup(const u8* src);
452
453 void dnsname_free(u8* ptr);
454
455 /** @brief Canonizes a dns name.
456 *
457 * Canonizes a dns name. (Lo-case)
458 *
459 * @param[in] src a pointer to the dns name
460 * @param[out] dst a pointer to a buffer that will hold the canonized dns name
461 *
462 * @return The length of the dns name
463 */
464
465 /* TWELVE uses */
466
467 u32 dnsname_canonize(const u8* src, u8* dst);
468
469 /**
470 * char DNS charset test
471 *
472 * @param c
473 * @return TRUE iff c in in the DNS charset
474 *
475 */
476
477 bool dnsname_is_charspace(u8 c);
478
479 s32 dnslabel_compare(const u8 *a, const u8 *b);
480
481 /**
482 * label DNS charset test
483 *
484 * @param label
485 * @return TRUE iff each char in the label in in the DNS charset
486 *
487 */
488
489 bool dnslabel_verify_charspace(const u8 *label);
490
491 /**
492 * dns name DNS charset test
493 *
494 * @param name_wire
495 * @return TRUE if each char in the name is in the DNS charset
496 *
497 */
498
499 bool dnsname_verify_charspace(const u8 *name_wire);
500
501 /**
502 * label DNS charset test and set to lower case
503 *
504 * @param label
505 * @return TRUE iff each char in the label in in the DNS charset
506 *
507 */
508
509 bool dnslabel_locase_verify_charspace(u8 *label);
510
511
512 /**
513 * dns name DNS charset test and set to lower case
514 *
515 * LOCASE is done using |32
516 *
517 * @param name_wire
518 * @return TRUE iff each char in the name in in the DNS charset
519 *
520 */
521
522 bool dnsname_locase_verify_charspace(u8 *name_wire);
523
524 /**
525 * dns name DNS charset test and set to lower case
526 *
527 * LOCASE is done using tolower(c)
528 *
529 * @param name_wire
530 * @return TRUE iff each char in the name in in the DNS charset
531 *
532 */
533
534 bool dnsname_locase_verify_extended_charspace(u8 *name_wire);
535
536 /*****************************************************************************
537 *
538 * VECTOR
539 *
540 *****************************************************************************/
541
542 /* ONE use */
543
544 u32 dnslabel_vector_to_cstr(const_dnslabel_vector_reference name, s32 top, char *str);
545
546 /* TWO use */
547
548 u32 dnslabel_vector_to_dnsname(const_dnslabel_vector_reference name, s32 top, u8 *str_start);
549
550 /* ONE use */
551
552 u32 dnslabel_vector_dnslabel_to_dnsname(const u8 *prefix, const dnsname_vector *namestack, s32 bottom, u8 *str);
553
554 static inline u32
dnslabel_copy(u8 * target,const u8 * src)555 dnslabel_copy(u8 *target, const u8 *src)
556 {
557 u32 len = src[0] + 1;
558 memcpy(target, src, len);
559 return len;
560 }
561
562 u32 dnslabel_vector_len(const_dnslabel_vector_reference name, s32 top);
563
564 /* ONE use */
565
566 u32 dnsname_vector_sub_to_dnsname(const dnsname_vector *name, s32 from, u8 *name_start);
567
568 /** @brief Divides a name into sections
569 *
570 * Divides a name into sections.
571 * Writes a pointer to each label of the dnsname into an array
572 * "." is never put in there.
573 *
574 * @param[in] name a pointer to the dnsname
575 * @param[out] sections a pointer to the target array of pointers
576 *
577 * @return The index of the top-level label ("." is never put in there)
578 */
579
580 /* TWO uses */
581
582 s32 dnsname_to_dnslabel_vector(const u8* dns_name, dnslabel_vector_reference labels);
583
584 s32 dnsname_to_dnslabel_stack(const u8* dns_name, dnslabel_stack_reference labels);
585
586 /** @brief Divides a name into sections
587 *
588 * Divides a name into sections.
589 * Writes a pointer to each label of the dnsname into an array
590 * "." is never put in there.
591 *
592 * @param[in] name a pointer to the dnsname
593 * @param[out] sections a pointer to the target array of pointers
594 *
595 * @return The index of the top-level label ("." is never put in there)
596 */
597
598 /* TWENTY-ONE uses */
599
600 s32 dnsname_to_dnsname_vector(const u8* dns_name, dnsname_vector* name);
601
602 u32 dnsname_vector_copy(dnsname_vector *dst, const dnsname_vector* src);
603
604 u32 dnsname_vector_len(dnsname_vector *name_vector);
605
606 /*****************************************************************************
607 *
608 * STACK
609 *
610 *****************************************************************************/
611
612 /** @brief Converts a stack of dns labels to a C string
613 *
614 * Converts a stack of dns labels to a C string
615 *
616 * @param[in] name a pointer to the dnslabel stack
617 * @param[in] top the index of the top of the stack
618 * @param[in] str a pointer to a buffer that will get the c-string
619 *
620 * @return Returns the length of the string
621 */
622
623 /* ONE use */
624
625 u32 dnslabel_stack_to_cstr(const const_dnslabel_stack_reference name, s32 top, char* str);
626
627 /* ONE use */
628
629 u32 dnslabel_stack_to_dnsname(const const_dnslabel_stack_reference name, s32 top, u8* str_start);
630
631 /* ONE use */
632
633 u32 dnsname_stack_to_dnsname(const dnsname_stack* name_stack, u8* name_start);
634
635 /* ONE use, returns the fqdn len */
636
637 u32 dnsname_stack_len(const dnsname_stack* name_stack);
638
639 /* TWO uses (debug) */
640
641 u32 dnsname_stack_to_cstr(const dnsname_stack* name, char* str);
642
643 /* ONE use */
644
645 bool dnsname_equals_dnsname_stack(const u8* str, const dnsname_stack* name);
646
647 bool dnsname_under_dnsname_stack(const u8* str, const dnsname_stack* name);
648
649 /* FOUR uses */
650
651 s32 dnsname_stack_push_label(dnsname_stack* dns_name, const u8* dns_label);
652
653 /* FOUR uses */
654
655 s32 dnsname_stack_pop_label(dnsname_stack* name);
656
657 s32 dnsname_to_dnsname_stack(const u8* dns_name, dnsname_stack* name);
658
659 /** @brief Allocates and duplicates a name with ZALLOC.
660 *
661 * Allocates and duplicates a name ZALLOC.
662 *
663 * @param[in] name a pointer to the dnsname
664 *
665 * @return A new instance of the dnsname.
666 */
667
668
669 u8 *dnsname_zdup(const u8 *name);
670
671 /** @brief Converts a name to a newly allocated dns name with ZALLOC.
672 *
673 * Converts a name to a newly allocated dns name with ZALLOC.
674 *
675 * @param domainname a pointer to the name
676 *
677 * @return a new instance of the name converted to a dnsname
678 */
679
680 u8 *dnsname_zdup_from_name(const char* domainname);
681
682 void dnsname_zfree(u8 *name);
683
684 /** @brief Allocates and duplicates a label with ZALLOC.
685 *
686 * Allocates and duplicates a label with ZALLOC.
687 *
688 * @param[in] name a pointer to the label
689 *
690 * @return A new instance of the label
691 */
692
693 u8 *dnslabel_zdup(const u8 *name);
694
695 void dnslabel_zfree(u8 *name);
696
697 /**
698 *
699 * Expands a compressed FQDN from a wire.
700 *
701 * @param wire_base_ the address of the wire buffer
702 * @param wire_size the size of the wire buffer
703 * @param compressed_fqdn the address, in the wire buffer, of the FQDN to expand
704 * @param output_fqdn the address of the buffer that will get a copy of the expanded FQDN
705 * @param output_fqdn_size the size of the buffer that will get a a copy of the expanded FQDN
706 *
707 * @return a pointer to the next byte after the expanded FQDN (ie: points to a type) or NULL if an error occurred
708 */
709
710 const u8* dnsname_expand_compressed(const void *wire_base_, size_t wire_size, const void *compressed_fqdn, u8 *output_fqdn, u32 output_fqdn_size);
711
712 /**
713 *
714 * Skip a compressed FQDN from a wire.
715 *
716 * @param wire_base_ the address of the wire buffer
717 * @param wire_size the size of the wire buffer
718 * @param compressed_fqdn the address, in the wire buffer, of the FQDN to expand
719 *
720 * @return a pointer to the next byte after the FQDN (ie: points to a type) or NULL if an error occurred
721 */
722
723 const u8* dnsname_skip_compressed(const void *wire_base_, size_t wire_size, const void *compressed_fqdn);
724
725 #ifdef __cplusplus
726 }
727 #endif
728
729 /** @} */
730