1238104Sdes/* From openssh4.3p2 compat/inet_aton.c */
2238104Sdes/*
3238104Sdes * Copyright (c) 1983, 1990, 1993
4238104Sdes *    The Regents of the University of California.  All rights reserved.
5238104Sdes *
6238104Sdes * Redistribution and use in source and binary forms, with or without
7238104Sdes * modification, are permitted provided that the following conditions
8238104Sdes * are met:
9238104Sdes * 1. Redistributions of source code must retain the above copyright
10238104Sdes *    notice, this list of conditions and the following disclaimer.
11238104Sdes * 2. Redistributions in binary form must reproduce the above copyright
12238104Sdes *    notice, this list of conditions and the following disclaimer in the
13238104Sdes *    documentation and/or other materials provided with the distribution.
14238104Sdes * 3. Neither the name of the University nor the names of its contributors
15238104Sdes *    may be used to endorse or promote products derived from this software
16238104Sdes *    without specific prior written permission.
17238104Sdes *
18238104Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19238104Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20238104Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21238104Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22238104Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23238104Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24238104Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25238104Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26238104Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27238104Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28238104Sdes * SUCH DAMAGE.
29238104Sdes * -
30238104Sdes * Portions Copyright (c) 1993 by Digital Equipment Corporation.
31238104Sdes *
32238104Sdes * Permission to use, copy, modify, and distribute this software for any
33238104Sdes * purpose with or without fee is hereby granted, provided that the above
34238104Sdes * copyright notice and this permission notice appear in all copies, and that
35238104Sdes * the name of Digital Equipment Corporation not be used in advertising or
36238104Sdes * publicity pertaining to distribution of the document or software without
37238104Sdes * specific, written prior permission.
38238104Sdes *
39238104Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
40238104Sdes * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
41238104Sdes * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
42238104Sdes * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
43238104Sdes * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
44238104Sdes * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
45238104Sdes * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46238104Sdes * SOFTWARE.
47238104Sdes * -
48238104Sdes * --Copyright--
49238104Sdes */
50238104Sdes
51238104Sdes/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */
52238104Sdes
53238104Sdes#include <ldns/config.h>
54238104Sdes
55238104Sdes#if !defined(HAVE_INET_ATON)
56238104Sdes
57238104Sdes#include <sys/types.h>
58238104Sdes#include <sys/param.h>
59238104Sdes#ifdef HAVE_NETINET_IN_H
60238104Sdes#include <netinet/in.h>
61238104Sdes#endif
62238104Sdes#ifdef HAVE_ARPA_INET_H
63238104Sdes#include <arpa/inet.h>
64238104Sdes#endif
65238104Sdes#include <ctype.h>
66238104Sdes
67238104Sdes#if 0
68238104Sdes/*
69238104Sdes * Ascii internet address interpretation routine.
70238104Sdes * The value returned is in network order.
71238104Sdes */
72238104Sdesin_addr_t
73238104Sdesinet_addr(const char *cp)
74238104Sdes{
75238104Sdes	struct in_addr val;
76238104Sdes
77238104Sdes	if (inet_aton(cp, &val))
78238104Sdes		return (val.s_addr);
79238104Sdes	return (INADDR_NONE);
80238104Sdes}
81238104Sdes#endif
82238104Sdes
83238104Sdes/*
84238104Sdes * Check whether "cp" is a valid ascii representation
85238104Sdes * of an Internet address and convert to a binary address.
86238104Sdes * Returns 1 if the address is valid, 0 if not.
87238104Sdes * This replaces inet_addr, the return value from which
88238104Sdes * cannot distinguish between failure and a local broadcast address.
89238104Sdes */
90238104Sdesint
91238104Sdesinet_aton(const char *cp, struct in_addr *addr)
92238104Sdes{
93238104Sdes	uint32_t val;
94238104Sdes	int base, n;
95238104Sdes	char c;
96238104Sdes	unsigned int parts[4];
97238104Sdes	unsigned int *pp = parts;
98238104Sdes
99238104Sdes	c = *cp;
100238104Sdes	for (;;) {
101238104Sdes		/*
102238104Sdes		 * Collect number up to ``.''.
103238104Sdes		 * Values are specified as for C:
104238104Sdes		 * 0x=hex, 0=octal, isdigit=decimal.
105238104Sdes		 */
106238104Sdes		if (!isdigit((int) c))
107238104Sdes			return (0);
108238104Sdes		val = 0; base = 10;
109238104Sdes		if (c == '0') {
110238104Sdes			c = *++cp;
111238104Sdes			if (c == 'x' || c == 'X')
112238104Sdes				base = 16, c = *++cp;
113238104Sdes			else
114238104Sdes				base = 8;
115238104Sdes		}
116238104Sdes		for (;;) {
117238104Sdes			if (isascii((int) c) && isdigit((int) c)) {
118238104Sdes				val = (val * base) + (c - '0');
119238104Sdes				c = *++cp;
120238104Sdes			} else if (base == 16 && isascii((int) c) && isxdigit((int) c)) {
121238104Sdes				val = (val << 4) |
122238104Sdes					(c + 10 - (islower((int) c) ? 'a' : 'A'));
123238104Sdes				c = *++cp;
124238104Sdes			} else
125238104Sdes				break;
126238104Sdes		}
127238104Sdes		if (c == '.') {
128238104Sdes			/*
129238104Sdes			 * Internet format:
130238104Sdes			 *	a.b.c.d
131238104Sdes			 *	a.b.c	(with c treated as 16 bits)
132238104Sdes			 *	a.b	(with b treated as 24 bits)
133238104Sdes			 */
134238104Sdes			if (pp >= parts + 3)
135238104Sdes				return (0);
136238104Sdes			*pp++ = val;
137238104Sdes			c = *++cp;
138238104Sdes		} else
139238104Sdes			break;
140238104Sdes	}
141238104Sdes	/*
142238104Sdes	 * Check for trailing characters.
143238104Sdes	 */
144238104Sdes	if (c != '\0' && (!isascii((int) c) || !isspace((int) c)))
145238104Sdes		return (0);
146238104Sdes	/*
147238104Sdes	 * Concoct the address according to
148238104Sdes	 * the number of parts specified.
149238104Sdes	 */
150238104Sdes	n = pp - parts + 1;
151238104Sdes	switch (n) {
152238104Sdes
153238104Sdes	case 0:
154238104Sdes		return (0);		/* initial nondigit */
155238104Sdes
156238104Sdes	case 1:				/* a -- 32 bits */
157238104Sdes		break;
158238104Sdes
159238104Sdes	case 2:				/* a.b -- 8.24 bits */
160238104Sdes		if ((val > 0xffffff) || (parts[0] > 0xff))
161238104Sdes			return (0);
162238104Sdes		val |= parts[0] << 24;
163238104Sdes		break;
164238104Sdes
165238104Sdes	case 3:				/* a.b.c -- 8.8.16 bits */
166238104Sdes		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
167238104Sdes			return (0);
168238104Sdes		val |= (parts[0] << 24) | (parts[1] << 16);
169238104Sdes		break;
170238104Sdes
171238104Sdes	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
172238104Sdes		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
173238104Sdes			return (0);
174238104Sdes		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
175238104Sdes		break;
176238104Sdes	}
177238104Sdes	if (addr)
178238104Sdes		addr->s_addr = htonl(val);
179238104Sdes	return (1);
180238104Sdes}
181238104Sdes
182238104Sdes#endif /* !defined(HAVE_INET_ATON) */
183