1157016Sdes/*	$OpenBSD: inet_addr.c,v 1.9 2005/08/06 20:30:03 espie Exp $	*/
2126274Sdes
398937Sdes/*
498937Sdes * Copyright (c) 1983, 1990, 1993
598937Sdes *    The Regents of the University of California.  All rights reserved.
6323124Sdes *
798937Sdes * Redistribution and use in source and binary forms, with or without
898937Sdes * modification, are permitted provided that the following conditions
998937Sdes * are met:
1098937Sdes * 1. Redistributions of source code must retain the above copyright
1198937Sdes *    notice, this list of conditions and the following disclaimer.
1298937Sdes * 2. Redistributions in binary form must reproduce the above copyright
1398937Sdes *    notice, this list of conditions and the following disclaimer in the
1498937Sdes *    documentation and/or other materials provided with the distribution.
15124208Sdes * 3. Neither the name of the University nor the names of its contributors
1698937Sdes *    may be used to endorse or promote products derived from this software
1798937Sdes *    without specific prior written permission.
18323124Sdes *
1998937Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2098937Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2198937Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2298937Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2398937Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2498937Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2598937Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2698937Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2798937Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2898937Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2998937Sdes * SUCH DAMAGE.
3098937Sdes * -
3198937Sdes * Portions Copyright (c) 1993 by Digital Equipment Corporation.
32323124Sdes *
3398937Sdes * Permission to use, copy, modify, and distribute this software for any
3498937Sdes * purpose with or without fee is hereby granted, provided that the above
3598937Sdes * copyright notice and this permission notice appear in all copies, and that
3698937Sdes * the name of Digital Equipment Corporation not be used in advertising or
3798937Sdes * publicity pertaining to distribution of the document or software without
3898937Sdes * specific, written prior permission.
39323124Sdes *
4098937Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
4198937Sdes * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
4298937Sdes * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
4398937Sdes * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
4498937Sdes * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
4598937Sdes * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
4698937Sdes * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4798937Sdes * SOFTWARE.
4898937Sdes * -
4998937Sdes * --Copyright--
5098937Sdes */
5198937Sdes
52157016Sdes/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */
53157016Sdes
5498937Sdes#include "includes.h"
5598937Sdes
5698937Sdes#if !defined(HAVE_INET_ATON)
5798937Sdes
5898937Sdes#include <sys/types.h>
5998937Sdes#include <sys/param.h>
6098937Sdes#include <netinet/in.h>
6198937Sdes#include <arpa/inet.h>
6298937Sdes#include <ctype.h>
6398937Sdes
6498937Sdes#if 0
6598937Sdes/*
6698937Sdes * Ascii internet address interpretation routine.
6798937Sdes * The value returned is in network order.
6898937Sdes */
6998937Sdesin_addr_t
70157016Sdesinet_addr(const char *cp)
7198937Sdes{
7298937Sdes	struct in_addr val;
7398937Sdes
7498937Sdes	if (inet_aton(cp, &val))
7598937Sdes		return (val.s_addr);
7698937Sdes	return (INADDR_NONE);
7798937Sdes}
7898937Sdes#endif
7998937Sdes
80323124Sdes/*
8198937Sdes * Check whether "cp" is a valid ascii representation
8298937Sdes * of an Internet address and convert to a binary address.
8398937Sdes * Returns 1 if the address is valid, 0 if not.
8498937Sdes * This replaces inet_addr, the return value from which
8598937Sdes * cannot distinguish between failure and a local broadcast address.
8698937Sdes */
8798937Sdesint
8898937Sdesinet_aton(const char *cp, struct in_addr *addr)
8998937Sdes{
90157016Sdes	u_int32_t val;
91157016Sdes	int base, n;
92157016Sdes	char c;
93157016Sdes	u_int parts[4];
94157016Sdes	u_int *pp = parts;
9598937Sdes
9698937Sdes	c = *cp;
9798937Sdes	for (;;) {
9898937Sdes		/*
9998937Sdes		 * Collect number up to ``.''.
10098937Sdes		 * Values are specified as for C:
10198937Sdes		 * 0x=hex, 0=octal, isdigit=decimal.
10298937Sdes		 */
10398937Sdes		if (!isdigit(c))
10498937Sdes			return (0);
10598937Sdes		val = 0; base = 10;
10698937Sdes		if (c == '0') {
10798937Sdes			c = *++cp;
10898937Sdes			if (c == 'x' || c == 'X')
10998937Sdes				base = 16, c = *++cp;
11098937Sdes			else
11198937Sdes				base = 8;
11298937Sdes		}
11398937Sdes		for (;;) {
11498937Sdes			if (isascii(c) && isdigit(c)) {
11598937Sdes				val = (val * base) + (c - '0');
11698937Sdes				c = *++cp;
11798937Sdes			} else if (base == 16 && isascii(c) && isxdigit(c)) {
11898937Sdes				val = (val << 4) |
11998937Sdes					(c + 10 - (islower(c) ? 'a' : 'A'));
12098937Sdes				c = *++cp;
12198937Sdes			} else
12298937Sdes				break;
12398937Sdes		}
12498937Sdes		if (c == '.') {
12598937Sdes			/*
12698937Sdes			 * Internet format:
12798937Sdes			 *	a.b.c.d
12898937Sdes			 *	a.b.c	(with c treated as 16 bits)
12998937Sdes			 *	a.b	(with b treated as 24 bits)
13098937Sdes			 */
13198937Sdes			if (pp >= parts + 3)
13298937Sdes				return (0);
13398937Sdes			*pp++ = val;
13498937Sdes			c = *++cp;
13598937Sdes		} else
13698937Sdes			break;
13798937Sdes	}
13898937Sdes	/*
13998937Sdes	 * Check for trailing characters.
14098937Sdes	 */
14198937Sdes	if (c != '\0' && (!isascii(c) || !isspace(c)))
14298937Sdes		return (0);
14398937Sdes	/*
14498937Sdes	 * Concoct the address according to
14598937Sdes	 * the number of parts specified.
14698937Sdes	 */
14798937Sdes	n = pp - parts + 1;
14898937Sdes	switch (n) {
14998937Sdes
15098937Sdes	case 0:
15198937Sdes		return (0);		/* initial nondigit */
15298937Sdes
15398937Sdes	case 1:				/* a -- 32 bits */
15498937Sdes		break;
15598937Sdes
15698937Sdes	case 2:				/* a.b -- 8.24 bits */
15798937Sdes		if ((val > 0xffffff) || (parts[0] > 0xff))
15898937Sdes			return (0);
15998937Sdes		val |= parts[0] << 24;
16098937Sdes		break;
16198937Sdes
16298937Sdes	case 3:				/* a.b.c -- 8.8.16 bits */
16398937Sdes		if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
16498937Sdes			return (0);
16598937Sdes		val |= (parts[0] << 24) | (parts[1] << 16);
16698937Sdes		break;
16798937Sdes
16898937Sdes	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
16998937Sdes		if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff))
17098937Sdes			return (0);
17198937Sdes		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
17298937Sdes		break;
17398937Sdes	}
17498937Sdes	if (addr)
17598937Sdes		addr->s_addr = htonl(val);
17698937Sdes	return (1);
17798937Sdes}
17898937Sdes
17998937Sdes#endif /* !defined(HAVE_INET_ATON) */
180