xref: /original-bsd/lib/libc/net/inet_addr.c (revision fa921481)
1 /*
2  * Copyright (c) 1983, 1990 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)inet_addr.c	5.8 (Berkeley) 06/23/90";
10 #endif /* LIBC_SCCS and not lint */
11 
12 #include <sys/types.h>
13 #include <ctype.h>
14 #include <netinet/in.h>
15 
16 /*
17  * Ascii internet address interpretation routine.
18  * The value returned is in network order.
19  */
20 u_long
21 inet_addr(cp)
22 	register char *cp;
23 {
24 	struct in_addr val;
25 
26 	if (inet_aton(cp, &val))
27 		return (val.s_addr);
28 	return (INADDR_NONE);
29 }
30 
31 /*
32  * Check whether "cp" is a valid ascii representation
33  * of an Internet address and convert to a binary address.
34  * Returns 1 if the address is valid, 0 if not.
35  * This replaces inet_addr, the return value from which
36  * cannot distinguish between failure and a local broadcast address.
37  */
38 
39 inet_aton(cp, addr)
40 	register char *cp;
41 	struct in_addr *addr;
42 {
43 	register u_long val, base, n;
44 	register char c;
45 	u_long parts[4], *pp = parts;
46 
47 	for (;;) {
48 		/*
49 		 * Collect number up to ``.''.
50 		 * Values are specified as for C:
51 		 * 0x=hex, 0=octal, other=decimal.
52 		 */
53 		val = 0; base = 10;
54 		if (*cp == '0') {
55 			if (*++cp == 'x' || *cp == 'X')
56 				base = 16, cp++;
57 			else
58 				base = 8;
59 		}
60 		while ((c = *cp) != '\0') {
61 			if (isascii(c) && isdigit(c)) {
62 				val = (val * base) + (c - '0');
63 				cp++;
64 				continue;
65 			}
66 			if (base == 16 && isascii(c) && isxdigit(c)) {
67 				val = (val << 4) +
68 					(c + 10 - (islower(c) ? 'a' : 'A'));
69 				cp++;
70 				continue;
71 			}
72 			break;
73 		}
74 		if (*cp == '.') {
75 			/*
76 			 * Internet format:
77 			 *	a.b.c.d
78 			 *	a.b.c	(with c treated as 16-bits)
79 			 *	a.b	(with b treated as 24 bits)
80 			 */
81 			if (pp >= parts + 3 || val > 0xff)
82 				return (0);
83 			*pp++ = val, cp++;
84 		} else
85 			break;
86 	}
87 	/*
88 	 * Check for trailing characters.
89 	 */
90 	if (*cp && (!isascii(*cp) || !isspace(*cp)))
91 		return (0);
92 	/*
93 	 * Concoct the address according to
94 	 * the number of parts specified.
95 	 */
96 	n = pp - parts + 1;
97 	switch (n) {
98 
99 	case 1:				/* a -- 32 bits */
100 		break;
101 
102 	case 2:				/* a.b -- 8.24 bits */
103 		if (val > 0xffffff)
104 			return (0);
105 		val |= parts[0] << 24;
106 		break;
107 
108 	case 3:				/* a.b.c -- 8.8.16 bits */
109 		if (val > 0xffff)
110 			return (0);
111 		val |= (parts[0] << 24) | (parts[1] << 16);
112 		break;
113 
114 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
115 		if (val > 0xff)
116 			return (0);
117 		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
118 		break;
119 	}
120 	if (addr)
121 		addr->s_addr = htonl(val);
122 	return (1);
123 }
124