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