1 /* Convert DNS domain names from network format to textual presentation format.
2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (c) 1996,1999 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <arpa/nameser.h>
19 #include <errno.h>
20 #include <shlib-compat.h>
21 #include <stdbool.h>
22
23 /* Thinking in noninternationalized US-ASCII (per the DNS spec), is
24 this character special ("in need of quoting")? */
25 static inline bool
special(int ch)26 special (int ch)
27 {
28 switch (ch)
29 {
30 case '"':
31 case '.':
32 case ';':
33 case '\\':
34 case '(':
35 case ')':
36 /* Special modifiers in zone files. */
37 case '@':
38 case '$':
39 return true;
40 default:
41 return false;
42 }
43 }
44
45 /* Thinking in noninternationalized US-ASCII (per the DNS spec), is
46 this character visible and not a space when printed? */
47 static inline bool
printable(int ch)48 printable (int ch)
49 {
50 return ch > 0x20 && ch < 0x7f;
51 }
52
53 /* Converts an uncompressed, encoded domain name to printable ASCII as
54 per RFC1035. Returns the number of bytes written to buffer, or -1
55 (with errno set). The root is returned as "." All other domains
56 are returned in non absolute form. */
57 int
___ns_name_ntop(const unsigned char * src,char * dst,size_t dstsiz)58 ___ns_name_ntop (const unsigned char *src, char *dst, size_t dstsiz)
59 {
60 const unsigned char *cp;
61 char *dn, *eom;
62 unsigned char c;
63 int l;
64
65 cp = src;
66 dn = dst;
67 eom = dst + dstsiz;
68
69 while ((l = *cp++) != 0)
70 {
71 if (l >= 64)
72 {
73 /* Some kind of compression pointer. */
74 __set_errno (EMSGSIZE);
75 return -1;
76 }
77 if (dn != dst)
78 {
79 if (dn >= eom)
80 {
81 __set_errno (EMSGSIZE);
82 return -1;
83 }
84 *dn++ = '.';
85 }
86 for (; l > 0; l--)
87 {
88 c = *cp++;
89 if (special (c))
90 {
91 if (eom - dn < 2)
92 {
93 __set_errno (EMSGSIZE);
94 return -1;
95 }
96 *dn++ = '\\';
97 *dn++ = c;
98 }
99 else if (!printable (c))
100 {
101 if (eom - dn < 4)
102 {
103 __set_errno (EMSGSIZE);
104 return -1;
105 }
106 *dn++ = '\\';
107 *dn++ = '0' + (c / 100);
108 *dn++ = '0' + ((c % 100) / 10);
109 *dn++ = '0' + (c % 10);
110 }
111 else
112 {
113 if (eom - dn < 2)
114 {
115 __set_errno (EMSGSIZE);
116 return -1;
117 }
118 *dn++ = c;
119 }
120 }
121 }
122 if (dn == dst)
123 {
124 if (dn >= eom)
125 {
126 __set_errno (EMSGSIZE);
127 return -1;
128 }
129 *dn++ = '.';
130 }
131 if (dn >= eom)
132 {
133 __set_errno (EMSGSIZE);
134 return -1;
135 }
136 *dn++ = '\0';
137 return dn - dst;
138 }
139 versioned_symbol (libc, ___ns_name_ntop, ns_name_ntop, GLIBC_2_34);
140 versioned_symbol (libc, ___ns_name_ntop, __ns_name_ntop, GLIBC_PRIVATE);
141 libc_hidden_ver (___ns_name_ntop, __ns_name_ntop)
142
143 #if OTHER_SHLIB_COMPAT (libresolv, GLIBC_2_9, GLIBC_2_34)
144 compat_symbol (libresolv, ___ns_name_ntop, ns_name_ntop, GLIBC_2_9);
145 #endif
146