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