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