xref: /illumos-gate/usr/src/lib/libc/port/inet/inet_ntoa.c (revision 8a2b682e57a046b828f37bcde1776f131ef4629f)
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 /*
106  * Convert network-format internet address
107  * to base 256 d.d.d.d representation.
108  *
109  * Reentrant interface
110  */
111 
112 #include "lint.h"
113 #include "thr_uberdata.h"
114 
115 #include <sys/types.h>
116 
117 #include <netinet/in.h>
118 
119 #include <ctype.h>
120 #include <errno.h>
121 #include <stdio.h>
122 #include <stdlib.h>
123 
124 char *
125 inet_ntoa_r(struct in_addr in, char b[])
126 {
127 	char	*p;
128 
129 	p = (char *)&in;
130 #define	UC(b)	(((int)b)&0xff)
131 	(void) sprintf(b, "%d.%d.%d.%d",
132 	    UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
133 	return (b);
134 }
135 
136 char *
137 inet_ntoa(struct in_addr in)
138 {
139 	return (inet_ntoa_r(in, curthread->ul_ntoabuf));
140 }
141 
142 /*
143  * Check whether "cp" is a valid ascii representation
144  * of an Internet address and convert to a binary address.
145  * Returns 1 if the address is valid, 0 if not.
146  * This replaces inet_addr, the return value from which
147  * cannot distinguish between failure and a local broadcast address.
148  */
149 int
150 inet_aton(const char *cp, struct in_addr *addr)
151 {
152 	uint32_t val;
153 	int base, n;
154 	char c;
155 	unsigned int parts[4];
156 	unsigned int *pp = parts;
157 
158 	c = *cp;
159 	for (;;) {
160 		/*
161 		 * Collect number up to ``.''.
162 		 * Values are specified as for C:
163 		 * 0x=hex, 0=octal, isdigit=decimal.
164 		 */
165 		if (!isdigit(c))
166 			return (0);
167 		val = 0; base = 10;
168 		if (c == '0') {
169 			c = *++cp;
170 			if (c == 'x' || c == 'X')
171 				base = 16, c = *++cp;
172 			else
173 				base = 8;
174 		}
175 		for (;;) {
176 			if (isascii(c) && isdigit(c)) {
177 				val = (val * base) + (c - '0');
178 				c = *++cp;
179 			} else if (base == 16 && isascii(c) && isxdigit(c)) {
180 				val = (val << 4) |
181 				    (c + 10 - (islower(c) ? 'a' : 'A'));
182 				c = *++cp;
183 			} else
184 				break;
185 		}
186 		if (c == '.') {
187 			/*
188 			 * Internet format:
189 			 *	a.b.c.d
190 			 *	a.b.c	(with c treated as 16 bits)
191 			 *	a.b	(with b treated as 24 bits)
192 			 */
193 			if (pp >= parts + 3)
194 				return (0);
195 			*pp++ = val;
196 			c = *++cp;
197 		} else
198 			break;
199 	}
200 	/*
201 	 * Check for trailing characters.
202 	 */
203 	if (c != '\0' && (!isascii(c) || !isspace(c)))
204 		return (0);
205 	/*
206 	 * Concoct the address according to
207 	 * the number of parts specified.
208 	 */
209 	n = pp - parts + 1;
210 	switch (n) {
211 
212 	case 0:
213 		return (0);		/* initial nondigit */
214 
215 	case 1:				/* a -- 32 bits */
216 		break;
217 
218 	case 2:				/* a.b -- 8.24 bits */
219 		if ((val > 0xffffff) || (parts[0] > 0xff))
220 			return (0);
221 		val |= parts[0] << 24;
222 		break;
223 
224 	case 3:				/* a.b.c -- 8.8.16 bits */
225 		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
226 			return (0);
227 		val |= (parts[0] << 24) | (parts[1] << 16);
228 		break;
229 
230 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
231 		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) ||
232 		    (parts[2] > 0xff))
233 			return (0);
234 		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
235 		break;
236 	}
237 	if (addr)
238 		addr->s_addr = htonl(val);
239 	return (1);
240 }
241 
242 /*
243  * Internet address interpretation routine.
244  * All the network library routines call this
245  * routine to interpret entries in the data bases
246  * which are expected to be an address.
247  * The value returned is in network order.
248  */
249 in_addr_t
250 inet_addr(const char *cp)
251 {
252 	struct in_addr val;
253 
254 	if (inet_aton(cp, &val))
255 		return (val.s_addr);
256 	return (INADDR_NONE);
257 }
258 
259 /*
260  * Return the network number from an internet
261  * address; handles class a/b/c network #'s.
262  */
263 in_addr_t
264 inet_netof(struct in_addr in)
265 {
266 	uint32_t i = ntohl(in.s_addr);
267 
268 	if (IN_CLASSA(i))
269 		return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
270 	if (IN_CLASSB(i))
271 		return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
272 	return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
273 }
274