xref: /illumos-gate/usr/src/lib/libc/port/inet/inet_ntoa.c (revision 7257d1b4)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 /*
30  * Portions of this source code were derived from Berkeley
31  * 4.3 BSD under license from the Regents of the University of
32  * California.
33  */
34 
35 /*
36  * Copyright (c) 1983, 1990, 1993
37  *    The Regents of the University of California.  All rights reserved.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. All advertising materials mentioning features or use of this software
48  *    must display the following acknowledgement:
49  * 	This product includes software developed by the University of
50  * 	California, Berkeley and its contributors.
51  * 4. Neither the name of the University nor the names of its contributors
52  *    may be used to endorse or promote products derived from this software
53  *    without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  */
67 
68 /*
69  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
70  *
71  * Permission to use, copy, modify, and distribute this software for any
72  * purpose with or without fee is hereby granted, provided that the above
73  * copyright notice and this permission notice appear in all copies, and that
74  * the name of Digital Equipment Corporation not be used in advertising or
75  * publicity pertaining to distribution of the document or software without
76  * specific, written prior permission.
77  *
78  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
79  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
80  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
81  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
82  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
83  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
84  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
85  * SOFTWARE.
86  */
87 
88 /*
89  * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
90  *
91  * Permission to use, copy, modify, and distribute this software for any
92  * purpose with or without fee is hereby granted, provided that the above
93  * copyright notice and this permission notice appear in all copies.
94  *
95  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
96  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
97  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
98  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
99  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
100  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
101  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
102  * SOFTWARE.
103  */
104 
105 #pragma ident	"%Z%%M%	%I%	%E% SMI"
106 
107 /*
108  * Convert network-format internet address
109  * to base 256 d.d.d.d representation.
110  *
111  * Reentrant interface
112  */
113 
114 #include "mt.h"
115 #include "rpc_mt.h"
116 #include <errno.h>
117 #include <sys/types.h>
118 #include <ctype.h>
119 #include <netinet/in.h>
120 #include <stdio.h>
121 #include <stdlib.h>
122 
123 
124 char *
125 inet_ntoa_r(in, b)
126 	struct in_addr in;
127 	char	b[];	/* Assumed >= 18 bytes */
128 {
129 	char	*p;
130 
131 	p = (char *)&in;
132 #define	UC(b)	(((int)b)&0xff)
133 	(void) sprintf(b, "%d.%d.%d.%d",
134 				UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
135 	return (b);
136 }
137 
138 char *
139 inet_ntoa(in)
140 	struct in_addr in;
141 {
142 	char *b;
143 	static char b_main[18];
144 	static pthread_key_t ntoa_key = PTHREAD_ONCE_KEY_NP;
145 
146 	if (thr_main())
147 		b = b_main;
148 	else if ((b = thr_get_storage(&ntoa_key, 18, free)) == NULL)
149 		b = b_main;
150 
151 	return (inet_ntoa_r(in, b));
152 }
153 
154 /*
155  * Check whether "cp" is a valid ascii representation
156  * of an Internet address and convert to a binary address.
157  * Returns 1 if the address is valid, 0 if not.
158  * This replaces inet_addr, the return value from which
159  * cannot distinguish between failure and a local broadcast address.
160  */
161 int
162 inet_aton(const char *cp, struct in_addr *addr)
163 {
164 	uint32_t val;
165 	int base, n;
166 	char c;
167 	unsigned int parts[4];
168 	unsigned int *pp = parts;
169 
170 
171 	c = *cp;
172 	for (;;) {
173 		/*
174 		 * Collect number up to ``.''.
175 		 * Values are specified as for C:
176 		 * 0x=hex, 0=octal, isdigit=decimal.
177 		 */
178 		if (!isdigit(c))
179 			return (0);
180 		val = 0; base = 10;
181 		if (c == '0') {
182 			c = *++cp;
183 			if (c == 'x' || c == 'X')
184 				base = 16, c = *++cp;
185 			else
186 				base = 8;
187 		}
188 		for (;;) {
189 			if (isascii(c) && isdigit(c)) {
190 				val = (val * base) + (c - '0');
191 				c = *++cp;
192 			} else if (base == 16 && isascii(c) && isxdigit(c)) {
193 				val = (val << 4) |
194 				    (c + 10 - (islower(c) ? 'a' : 'A'));
195 				c = *++cp;
196 			} else
197 				break;
198 		}
199 		if (c == '.') {
200 			/*
201 			 * Internet format:
202 			 *	a.b.c.d
203 			 *	a.b.c	(with c treated as 16 bits)
204 			 *	a.b	(with b treated as 24 bits)
205 			 */
206 			if (pp >= parts + 3)
207 				return (0);
208 			*pp++ = val;
209 			c = *++cp;
210 		} else
211 			break;
212 	}
213 	/*
214 	 * Check for trailing characters.
215 	 */
216 	if (c != '\0' && (!isascii(c) || !isspace(c)))
217 		return (0);
218 	/*
219 	 * Concoct the address according to
220 	 * the number of parts specified.
221 	 */
222 	n = pp - parts + 1;
223 	switch (n) {
224 
225 	case 0:
226 		return (0);		/* initial nondigit */
227 
228 	case 1:				/* a -- 32 bits */
229 		break;
230 
231 	case 2:				/* a.b -- 8.24 bits */
232 		if ((val > 0xffffff) || (parts[0] > 0xff))
233 			return (0);
234 		val |= parts[0] << 24;
235 		break;
236 
237 	case 3:				/* a.b.c -- 8.8.16 bits */
238 		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
239 			return (0);
240 		val |= (parts[0] << 24) | (parts[1] << 16);
241 		break;
242 
243 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
244 		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) ||
245 		    (parts[2] > 0xff))
246 			return (0);
247 		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
248 		break;
249 	}
250 	if (addr)
251 		addr->s_addr = htonl(val);
252 	return (1);
253 }
254 
255 /*
256  * Internet address interpretation routine.
257  * All the network library routines call this
258  * routine to interpret entries in the data bases
259  * which are expected to be an address.
260  * The value returned is in network order.
261  */
262 in_addr_t
263 inet_addr(const char *cp)
264 {
265 	struct in_addr val;
266 
267 	if (inet_aton(cp, &val))
268 		return (val.s_addr);
269 	return (INADDR_NONE);
270 }
271 
272 /*
273  * Return the network number from an internet
274  * address; handles class a/b/c network #'s.
275  */
276 uint_t
277 inet_netof(struct in_addr in)
278 {
279 	uint32_t i = ntohl(in.s_addr);
280 
281 	if (IN_CLASSA(i))
282 		return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
283 	if (IN_CLASSB(i))
284 		return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
285 	return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
286 }
287