xref: /csrg-svn/lib/libc/net/inet_addr.c (revision 42626)
1 /*
2  * Copyright (c) 1983 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.7 (Berkeley) 06/01/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  * Internet address interpretation routine.
18  * All the network library routines call this
19  * routine to interpret entries in the data bases
20  * which are expected to be an address.
21  * The value returned is in network order.
22  */
23 u_long
24 inet_addr(cp)
25 	register char *cp;
26 {
27 	register u_long val, base, n;
28 	register char c;
29 	u_long parts[4], *pp = parts;
30 
31 again:
32 	/*
33 	 * Collect number up to ``.''.
34 	 * Values are specified as for C:
35 	 * 0x=hex, 0=octal, other=decimal.
36 	 */
37 	val = 0; base = 10;
38 	if (*cp == '0') {
39 		if (*++cp == 'x' || *cp == 'X')
40 			base = 16, cp++;
41 		else
42 			base = 8;
43 	}
44 	while (c = *cp) {
45 		if (isdigit(c)) {
46 			val = (val * base) + (c - '0');
47 			cp++;
48 			continue;
49 		}
50 		if (base == 16 && isxdigit(c)) {
51 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
52 			cp++;
53 			continue;
54 		}
55 		break;
56 	}
57 	if (*cp == '.') {
58 		/*
59 		 * Internet format:
60 		 *	a.b.c.d
61 		 *	a.b.c	(with c treated as 16-bits)
62 		 *	a.b	(with b treated as 24 bits)
63 		 */
64 		if (pp >= parts + 4)
65 			return (INADDR_NONE);
66 		*pp++ = val, cp++;
67 		goto again;
68 	}
69 	/*
70 	 * Check for trailing characters.
71 	 */
72 	if (*cp && !isspace(*cp))
73 		return (INADDR_NONE);
74 	*pp++ = val;
75 	/*
76 	 * Concoct the address according to
77 	 * the number of parts specified.
78 	 */
79 	n = pp - parts;
80 	switch (n) {
81 
82 	case 1:				/* a -- 32 bits */
83 		val = parts[0];
84 		break;
85 
86 	case 2:				/* a.b -- 8.24 bits */
87 		val = (parts[0] << 24) | (parts[1] & 0xffffff);
88 		break;
89 
90 	case 3:				/* a.b.c -- 8.8.16 bits */
91 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
92 			(parts[2] & 0xffff);
93 		break;
94 
95 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
96 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
97 		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
98 		break;
99 
100 	default:
101 		return (INADDR_NONE);
102 	}
103 	val = htonl(val);
104 	return (val);
105 }
106