xref: /freebsd/crypto/openssh/openbsd-compat/inet_aton.c (revision 1323ec571215a77ddd21294f0871979d5ad6b992)
1021d409fSDag-Erling Smørgrav /*	$OpenBSD: inet_addr.c,v 1.9 2005/08/06 20:30:03 espie Exp $	*/
283d2307dSDag-Erling Smørgrav 
383d2307dSDag-Erling Smørgrav /*
483d2307dSDag-Erling Smørgrav  * Copyright (c) 1983, 1990, 1993
583d2307dSDag-Erling Smørgrav  *    The Regents of the University of California.  All rights reserved.
683d2307dSDag-Erling Smørgrav  *
783d2307dSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
883d2307dSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
983d2307dSDag-Erling Smørgrav  * are met:
1083d2307dSDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
1183d2307dSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
1283d2307dSDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
1383d2307dSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
1483d2307dSDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
15d95e11bfSDag-Erling Smørgrav  * 3. Neither the name of the University nor the names of its contributors
1683d2307dSDag-Erling Smørgrav  *    may be used to endorse or promote products derived from this software
1783d2307dSDag-Erling Smørgrav  *    without specific prior written permission.
1883d2307dSDag-Erling Smørgrav  *
1983d2307dSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2083d2307dSDag-Erling Smørgrav  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2183d2307dSDag-Erling Smørgrav  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2283d2307dSDag-Erling Smørgrav  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2383d2307dSDag-Erling Smørgrav  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2483d2307dSDag-Erling Smørgrav  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2583d2307dSDag-Erling Smørgrav  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2683d2307dSDag-Erling Smørgrav  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2783d2307dSDag-Erling Smørgrav  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2883d2307dSDag-Erling Smørgrav  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2983d2307dSDag-Erling Smørgrav  * SUCH DAMAGE.
3083d2307dSDag-Erling Smørgrav  * -
3183d2307dSDag-Erling Smørgrav  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
3283d2307dSDag-Erling Smørgrav  *
3383d2307dSDag-Erling Smørgrav  * Permission to use, copy, modify, and distribute this software for any
3483d2307dSDag-Erling Smørgrav  * purpose with or without fee is hereby granted, provided that the above
3583d2307dSDag-Erling Smørgrav  * copyright notice and this permission notice appear in all copies, and that
3683d2307dSDag-Erling Smørgrav  * the name of Digital Equipment Corporation not be used in advertising or
3783d2307dSDag-Erling Smørgrav  * publicity pertaining to distribution of the document or software without
3883d2307dSDag-Erling Smørgrav  * specific, written prior permission.
3983d2307dSDag-Erling Smørgrav  *
4083d2307dSDag-Erling Smørgrav  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
4183d2307dSDag-Erling Smørgrav  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
4283d2307dSDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
4383d2307dSDag-Erling Smørgrav  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
4483d2307dSDag-Erling Smørgrav  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
4583d2307dSDag-Erling Smørgrav  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
4683d2307dSDag-Erling Smørgrav  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4783d2307dSDag-Erling Smørgrav  * SOFTWARE.
4883d2307dSDag-Erling Smørgrav  * -
4983d2307dSDag-Erling Smørgrav  * --Copyright--
5083d2307dSDag-Erling Smørgrav  */
5183d2307dSDag-Erling Smørgrav 
52021d409fSDag-Erling Smørgrav /* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */
53021d409fSDag-Erling Smørgrav 
5483d2307dSDag-Erling Smørgrav #include "includes.h"
5583d2307dSDag-Erling Smørgrav 
5683d2307dSDag-Erling Smørgrav #if !defined(HAVE_INET_ATON)
5783d2307dSDag-Erling Smørgrav 
5883d2307dSDag-Erling Smørgrav #include <sys/types.h>
5983d2307dSDag-Erling Smørgrav #include <netinet/in.h>
6083d2307dSDag-Erling Smørgrav #include <arpa/inet.h>
6183d2307dSDag-Erling Smørgrav #include <ctype.h>
6283d2307dSDag-Erling Smørgrav 
6383d2307dSDag-Erling Smørgrav #if 0
6483d2307dSDag-Erling Smørgrav /*
6583d2307dSDag-Erling Smørgrav  * Ascii internet address interpretation routine.
6683d2307dSDag-Erling Smørgrav  * The value returned is in network order.
6783d2307dSDag-Erling Smørgrav  */
6883d2307dSDag-Erling Smørgrav in_addr_t
69021d409fSDag-Erling Smørgrav inet_addr(const char *cp)
7083d2307dSDag-Erling Smørgrav {
7183d2307dSDag-Erling Smørgrav 	struct in_addr val;
7283d2307dSDag-Erling Smørgrav 
7383d2307dSDag-Erling Smørgrav 	if (inet_aton(cp, &val))
7483d2307dSDag-Erling Smørgrav 		return (val.s_addr);
7583d2307dSDag-Erling Smørgrav 	return (INADDR_NONE);
7683d2307dSDag-Erling Smørgrav }
7783d2307dSDag-Erling Smørgrav #endif
7883d2307dSDag-Erling Smørgrav 
7983d2307dSDag-Erling Smørgrav /*
8083d2307dSDag-Erling Smørgrav  * Check whether "cp" is a valid ascii representation
8183d2307dSDag-Erling Smørgrav  * of an Internet address and convert to a binary address.
8283d2307dSDag-Erling Smørgrav  * Returns 1 if the address is valid, 0 if not.
8383d2307dSDag-Erling Smørgrav  * This replaces inet_addr, the return value from which
8483d2307dSDag-Erling Smørgrav  * cannot distinguish between failure and a local broadcast address.
8583d2307dSDag-Erling Smørgrav  */
8683d2307dSDag-Erling Smørgrav int
inet_aton(const char * cp,struct in_addr * addr)8783d2307dSDag-Erling Smørgrav inet_aton(const char *cp, struct in_addr *addr)
8883d2307dSDag-Erling Smørgrav {
89021d409fSDag-Erling Smørgrav 	u_int32_t val;
90021d409fSDag-Erling Smørgrav 	int base, n;
91021d409fSDag-Erling Smørgrav 	char c;
92021d409fSDag-Erling Smørgrav 	u_int parts[4];
93021d409fSDag-Erling Smørgrav 	u_int *pp = parts;
9483d2307dSDag-Erling Smørgrav 
9583d2307dSDag-Erling Smørgrav 	c = *cp;
9683d2307dSDag-Erling Smørgrav 	for (;;) {
9783d2307dSDag-Erling Smørgrav 		/*
9883d2307dSDag-Erling Smørgrav 		 * Collect number up to ``.''.
9983d2307dSDag-Erling Smørgrav 		 * Values are specified as for C:
10083d2307dSDag-Erling Smørgrav 		 * 0x=hex, 0=octal, isdigit=decimal.
10183d2307dSDag-Erling Smørgrav 		 */
10283d2307dSDag-Erling Smørgrav 		if (!isdigit(c))
10383d2307dSDag-Erling Smørgrav 			return (0);
10483d2307dSDag-Erling Smørgrav 		val = 0; base = 10;
10583d2307dSDag-Erling Smørgrav 		if (c == '0') {
10683d2307dSDag-Erling Smørgrav 			c = *++cp;
10783d2307dSDag-Erling Smørgrav 			if (c == 'x' || c == 'X')
10883d2307dSDag-Erling Smørgrav 				base = 16, c = *++cp;
10983d2307dSDag-Erling Smørgrav 			else
11083d2307dSDag-Erling Smørgrav 				base = 8;
11183d2307dSDag-Erling Smørgrav 		}
11283d2307dSDag-Erling Smørgrav 		for (;;) {
11383d2307dSDag-Erling Smørgrav 			if (isascii(c) && isdigit(c)) {
11483d2307dSDag-Erling Smørgrav 				val = (val * base) + (c - '0');
11583d2307dSDag-Erling Smørgrav 				c = *++cp;
11683d2307dSDag-Erling Smørgrav 			} else if (base == 16 && isascii(c) && isxdigit(c)) {
11783d2307dSDag-Erling Smørgrav 				val = (val << 4) |
11883d2307dSDag-Erling Smørgrav 					(c + 10 - (islower(c) ? 'a' : 'A'));
11983d2307dSDag-Erling Smørgrav 				c = *++cp;
12083d2307dSDag-Erling Smørgrav 			} else
12183d2307dSDag-Erling Smørgrav 				break;
12283d2307dSDag-Erling Smørgrav 		}
12383d2307dSDag-Erling Smørgrav 		if (c == '.') {
12483d2307dSDag-Erling Smørgrav 			/*
12583d2307dSDag-Erling Smørgrav 			 * Internet format:
12683d2307dSDag-Erling Smørgrav 			 *	a.b.c.d
12783d2307dSDag-Erling Smørgrav 			 *	a.b.c	(with c treated as 16 bits)
12883d2307dSDag-Erling Smørgrav 			 *	a.b	(with b treated as 24 bits)
12983d2307dSDag-Erling Smørgrav 			 */
13083d2307dSDag-Erling Smørgrav 			if (pp >= parts + 3)
13183d2307dSDag-Erling Smørgrav 				return (0);
13283d2307dSDag-Erling Smørgrav 			*pp++ = val;
13383d2307dSDag-Erling Smørgrav 			c = *++cp;
13483d2307dSDag-Erling Smørgrav 		} else
13583d2307dSDag-Erling Smørgrav 			break;
13683d2307dSDag-Erling Smørgrav 	}
13783d2307dSDag-Erling Smørgrav 	/*
13883d2307dSDag-Erling Smørgrav 	 * Check for trailing characters.
13983d2307dSDag-Erling Smørgrav 	 */
14083d2307dSDag-Erling Smørgrav 	if (c != '\0' && (!isascii(c) || !isspace(c)))
14183d2307dSDag-Erling Smørgrav 		return (0);
14283d2307dSDag-Erling Smørgrav 	/*
14383d2307dSDag-Erling Smørgrav 	 * Concoct the address according to
14483d2307dSDag-Erling Smørgrav 	 * the number of parts specified.
14583d2307dSDag-Erling Smørgrav 	 */
14683d2307dSDag-Erling Smørgrav 	n = pp - parts + 1;
14783d2307dSDag-Erling Smørgrav 	switch (n) {
14883d2307dSDag-Erling Smørgrav 
14983d2307dSDag-Erling Smørgrav 	case 0:
15083d2307dSDag-Erling Smørgrav 		return (0);		/* initial nondigit */
15183d2307dSDag-Erling Smørgrav 
15283d2307dSDag-Erling Smørgrav 	case 1:				/* a -- 32 bits */
15383d2307dSDag-Erling Smørgrav 		break;
15483d2307dSDag-Erling Smørgrav 
15583d2307dSDag-Erling Smørgrav 	case 2:				/* a.b -- 8.24 bits */
15683d2307dSDag-Erling Smørgrav 		if ((val > 0xffffff) || (parts[0] > 0xff))
15783d2307dSDag-Erling Smørgrav 			return (0);
15883d2307dSDag-Erling Smørgrav 		val |= parts[0] << 24;
15983d2307dSDag-Erling Smørgrav 		break;
16083d2307dSDag-Erling Smørgrav 
16183d2307dSDag-Erling Smørgrav 	case 3:				/* a.b.c -- 8.8.16 bits */
16283d2307dSDag-Erling Smørgrav 		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
16383d2307dSDag-Erling Smørgrav 			return (0);
16483d2307dSDag-Erling Smørgrav 		val |= (parts[0] << 24) | (parts[1] << 16);
16583d2307dSDag-Erling Smørgrav 		break;
16683d2307dSDag-Erling Smørgrav 
16783d2307dSDag-Erling Smørgrav 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
16883d2307dSDag-Erling Smørgrav 		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
16983d2307dSDag-Erling Smørgrav 			return (0);
17083d2307dSDag-Erling Smørgrav 		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
17183d2307dSDag-Erling Smørgrav 		break;
17283d2307dSDag-Erling Smørgrav 	}
17383d2307dSDag-Erling Smørgrav 	if (addr)
17483d2307dSDag-Erling Smørgrav 		addr->s_addr = htonl(val);
17583d2307dSDag-Erling Smørgrav 	return (1);
17683d2307dSDag-Erling Smørgrav }
17783d2307dSDag-Erling Smørgrav 
17883d2307dSDag-Erling Smørgrav #endif /* !defined(HAVE_INET_ATON) */
179