1258945Sroberto/*
2280849Scy * Portions Copyright (C) 2004, 2005, 2007, 2008  Internet Systems Consortium, Inc. ("ISC")
3258945Sroberto * Portions Copyright (C) 1996-2001  Internet Software Consortium.
4258945Sroberto *
5258945Sroberto * Permission to use, copy, modify, and/or distribute this software for any
6258945Sroberto * purpose with or without fee is hereby granted, provided that the above
7258945Sroberto * copyright notice and this permission notice appear in all copies.
8258945Sroberto *
9258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10258945Sroberto * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11258945Sroberto * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12258945Sroberto * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13258945Sroberto * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14258945Sroberto * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15258945Sroberto * PERFORMANCE OF THIS SOFTWARE.
16258945Sroberto */
17258945Sroberto
18258945Sroberto/*
19258945Sroberto * Copyright (c) 1983, 1990, 1993
20258945Sroberto *    The Regents of the University of California.  All rights reserved.
21258945Sroberto *
22258945Sroberto * Redistribution and use in source and binary forms, with or without
23258945Sroberto * modification, are permitted provided that the following conditions
24258945Sroberto * are met:
25258945Sroberto * 1. Redistributions of source code must retain the above copyright
26258945Sroberto *    notice, this list of conditions and the following disclaimer.
27258945Sroberto * 2. Redistributions in binary form must reproduce the above copyright
28258945Sroberto *    notice, this list of conditions and the following disclaimer in the
29258945Sroberto *    documentation and/or other materials provided with the distribution.
30258945Sroberto * 3. All advertising materials mentioning features or use of this software
31258945Sroberto *    must display the following acknowledgement:
32258945Sroberto * 	This product includes software developed by the University of
33258945Sroberto * 	California, Berkeley and its contributors.
34258945Sroberto * 4. Neither the name of the University nor the names of its contributors
35258945Sroberto *    may be used to endorse or promote products derived from this software
36258945Sroberto *    without specific prior written permission.
37258945Sroberto *
38258945Sroberto * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39258945Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40258945Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41258945Sroberto * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42258945Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43258945Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44258945Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45258945Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46258945Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47258945Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48258945Sroberto * SUCH DAMAGE.
49258945Sroberto */
50258945Sroberto
51258945Sroberto/*
52258945Sroberto * Portions Copyright (c) 1993 by Digital Equipment Corporation.
53258945Sroberto *
54258945Sroberto * Permission to use, copy, modify, and distribute this software for any
55258945Sroberto * purpose with or without fee is hereby granted, provided that the above
56258945Sroberto * copyright notice and this permission notice appear in all copies, and that
57258945Sroberto * the name of Digital Equipment Corporation not be used in advertising or
58258945Sroberto * publicity pertaining to distribution of the document or software without
59258945Sroberto * specific, written prior permission.
60258945Sroberto *
61258945Sroberto * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
62258945Sroberto * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
63258945Sroberto * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
64258945Sroberto * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
65258945Sroberto * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
66258945Sroberto * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
67258945Sroberto * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
68258945Sroberto * SOFTWARE.
69258945Sroberto */
70258945Sroberto/*! \file */
71258945Sroberto
72258945Sroberto#if defined(LIBC_SCCS) && !defined(lint)
73258945Srobertostatic char sccsid[] = "@(#)inet_addr.c	8.1 (Berkeley) 6/17/93";
74280849Scystatic char rcsid[] = "$Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp $";
75258945Sroberto#endif /* LIBC_SCCS and not lint */
76258945Sroberto
77258945Sroberto#include <config.h>
78258945Sroberto
79258945Sroberto#include <ctype.h>
80258945Sroberto#include <stddef.h>		/* Required for NULL. */
81258945Sroberto
82258945Sroberto#include <isc/types.h>
83258945Sroberto#include <isc/net.h>
84258945Sroberto
85258945Sroberto/*%
86258945Sroberto * Check whether "cp" is a valid ascii representation
87258945Sroberto * of an Internet address and convert to a binary address.
88258945Sroberto * Returns 1 if the address is valid, 0 if not.
89258945Sroberto * This replaces inet_addr, the return value from which
90258945Sroberto * cannot distinguish between failure and a local broadcast address.
91258945Sroberto */
92258945Srobertoint
93258945Srobertoisc_net_aton(const char *cp, struct in_addr *addr) {
94258945Sroberto	unsigned long val;
95293650Sglebius	int base;
96258945Sroberto	unsigned char c;
97258945Sroberto	isc_uint8_t parts[4];
98258945Sroberto	isc_uint8_t *pp = parts;
99258945Sroberto	int digit;
100258945Sroberto
101258945Sroberto	c = *cp;
102258945Sroberto	for (;;) {
103258945Sroberto		/*
104258945Sroberto		 * Collect number up to ``.''.
105258945Sroberto		 * Values are specified as for C:
106258945Sroberto		 * 0x=hex, 0=octal, isdigit=decimal.
107258945Sroberto		 */
108258945Sroberto		if (!isdigit(c & 0xff))
109258945Sroberto			return (0);
110258945Sroberto		val = 0; base = 10; digit = 0;
111258945Sroberto		if (c == '0') {
112258945Sroberto			c = *++cp;
113258945Sroberto			if (c == 'x' || c == 'X')
114258945Sroberto				base = 16, c = *++cp;
115258945Sroberto			else {
116258945Sroberto				base = 8;
117258945Sroberto				digit = 1;
118258945Sroberto			}
119258945Sroberto		}
120258945Sroberto		for (;;) {
121258945Sroberto			/*
122258945Sroberto			 * isascii() is valid for all integer values, and
123258945Sroberto			 * when it is true, c is known to be in scope
124258945Sroberto			 * for isdigit().  No cast necessary.  Similar
125258945Sroberto			 * comment applies for later ctype uses.
126258945Sroberto			 */
127258945Sroberto			if (isascii(c) && isdigit(c)) {
128258945Sroberto				if (base == 8 && (c == '8' || c == '9'))
129258945Sroberto					return (0);
130258945Sroberto				val = (val * base) + (c - '0');
131258945Sroberto				c = *++cp;
132258945Sroberto				digit = 1;
133258945Sroberto			} else if (base == 16 && isascii(c) && isxdigit(c)) {
134258945Sroberto				val = (val << 4) |
135258945Sroberto					(c + 10 - (islower(c) ? 'a' : 'A'));
136258945Sroberto				c = *++cp;
137258945Sroberto				digit = 1;
138258945Sroberto			} else
139258945Sroberto				break;
140258945Sroberto		}
141258945Sroberto		if (c == '.') {
142258945Sroberto			/*
143258945Sroberto			 * Internet format:
144258945Sroberto			 *	a.b.c.d
145258945Sroberto			 *	a.b.c	(with c treated as 16 bits)
146258945Sroberto			 *	a.b	(with b treated as 24 bits)
147258945Sroberto			 */
148258945Sroberto			if (pp >= parts + 3 || val > 0xffU)
149258945Sroberto				return (0);
150258945Sroberto			*pp++ = (isc_uint8_t)val;
151258945Sroberto			c = *++cp;
152258945Sroberto		} else
153258945Sroberto			break;
154258945Sroberto	}
155258945Sroberto	/*
156258945Sroberto	 * Check for trailing characters.
157258945Sroberto	 */
158258945Sroberto	if (c != '\0' && (!isascii(c) || !isspace(c)))
159258945Sroberto		return (0);
160258945Sroberto	/*
161258945Sroberto	 * Did we get a valid digit?
162258945Sroberto	 */
163258945Sroberto	if (!digit)
164258945Sroberto		return (0);
165258945Sroberto	/*
166258945Sroberto	 * Concoct the address according to
167258945Sroberto	 * the number of parts specified.
168258945Sroberto	 */
169293650Sglebius	switch (pp - parts + 1) {
170258945Sroberto	case 1:				/* a -- 32 bits */
171258945Sroberto		break;
172258945Sroberto
173258945Sroberto	case 2:				/* a.b -- 8.24 bits */
174258945Sroberto		if (val > 0xffffffU)
175258945Sroberto			return (0);
176258945Sroberto		val |= parts[0] << 24;
177258945Sroberto		break;
178258945Sroberto
179258945Sroberto	case 3:				/* a.b.c -- 8.8.16 bits */
180258945Sroberto		if (val > 0xffffU)
181258945Sroberto			return (0);
182258945Sroberto		val |= (parts[0] << 24) | (parts[1] << 16);
183258945Sroberto		break;
184258945Sroberto
185258945Sroberto	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
186258945Sroberto		if (val > 0xffU)
187258945Sroberto			return (0);
188258945Sroberto		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
189258945Sroberto		break;
190258945Sroberto	}
191258945Sroberto	if (addr != NULL)
192258945Sroberto		addr->s_addr = htonl(val);
193258945Sroberto
194258945Sroberto	return (1);
195258945Sroberto}
196