xref: /csrg-svn/lib/libc/net/inet_addr.c (revision 33676)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12 
13 #if defined(LIBC_SCCS) && !defined(lint)
14 static char sccsid[] = "@(#)inet_addr.c	5.5 (Berkeley) 03/07/88";
15 #endif /* LIBC_SCCS and not lint */
16 
17 #include <sys/types.h>
18 #include <ctype.h>
19 #include <netinet/in.h>
20 
21 /*
22  * Internet address interpretation routine.
23  * All the network library routines call this
24  * routine to interpret entries in the data bases
25  * which are expected to be an address.
26  * The value returned is in network order.
27  */
28 u_long
29 inet_addr(cp)
30 	register char *cp;
31 {
32 	register u_long val, base, n;
33 	register char c;
34 	u_long parts[4], *pp = parts;
35 
36 again:
37 	/*
38 	 * Collect number up to ``.''.
39 	 * Values are specified as for C:
40 	 * 0x=hex, 0=octal, other=decimal.
41 	 */
42 	val = 0; base = 10;
43 	if (*cp == '0') {
44 		if (*++cp == 'x' || *cp == 'X')
45 			base = 16, cp++;
46 		else
47 			base = 8;
48 	}
49 	while (c = *cp) {
50 		if (isdigit(c)) {
51 			val = (val * base) + (c - '0');
52 			cp++;
53 			continue;
54 		}
55 		if (base == 16 && isxdigit(c)) {
56 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
57 			cp++;
58 			continue;
59 		}
60 		break;
61 	}
62 	if (*cp == '.') {
63 		/*
64 		 * Internet format:
65 		 *	a.b.c.d
66 		 *	a.b.c	(with c treated as 16-bits)
67 		 *	a.b	(with b treated as 24 bits)
68 		 */
69 		if (pp >= parts + 4)
70 			return (INADDR_NONE);
71 		*pp++ = val, cp++;
72 		goto again;
73 	}
74 	/*
75 	 * Check for trailing characters.
76 	 */
77 	if (*cp && !isspace(*cp))
78 		return (INADDR_NONE);
79 	*pp++ = val;
80 	/*
81 	 * Concoct the address according to
82 	 * the number of parts specified.
83 	 */
84 	n = pp - parts;
85 	switch (n) {
86 
87 	case 1:				/* a -- 32 bits */
88 		val = parts[0];
89 		break;
90 
91 	case 2:				/* a.b -- 8.24 bits */
92 		val = (parts[0] << 24) | (parts[1] & 0xffffff);
93 		break;
94 
95 	case 3:				/* a.b.c -- 8.8.16 bits */
96 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
97 			(parts[2] & 0xffff);
98 		break;
99 
100 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
101 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
102 		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
103 		break;
104 
105 	default:
106 		return (INADDR_NONE);
107 	}
108 	val = htonl(val);
109 	return (val);
110 }
111