xref: /csrg-svn/lib/libc/net/inet_addr.c (revision 42626)
121367Sdist /*
221367Sdist  * Copyright (c) 1983 Regents of the University of California.
333676Sbostic  * All rights reserved.
433676Sbostic  *
5*42626Sbostic  * %sccs.include.redist.c%
621367Sdist  */
78324Ssam 
826612Sdonn #if defined(LIBC_SCCS) && !defined(lint)
9*42626Sbostic static char sccsid[] = "@(#)inet_addr.c	5.7 (Berkeley) 06/01/90";
1033676Sbostic #endif /* LIBC_SCCS and not lint */
1121367Sdist 
128324Ssam #include <sys/types.h>
138324Ssam #include <ctype.h>
149192Ssam #include <netinet/in.h>
158324Ssam 
168309Ssam /*
178309Ssam  * Internet address interpretation routine.
188309Ssam  * All the network library routines call this
198309Ssam  * routine to interpret entries in the data bases
208309Ssam  * which are expected to be an address.
218357Ssam  * The value returned is in network order.
228309Ssam  */
238361Ssam u_long
248309Ssam inet_addr(cp)
258309Ssam 	register char *cp;
268309Ssam {
278357Ssam 	register u_long val, base, n;
288309Ssam 	register char c;
298357Ssam 	u_long parts[4], *pp = parts;
308309Ssam 
318309Ssam again:
328357Ssam 	/*
338357Ssam 	 * Collect number up to ``.''.
348357Ssam 	 * Values are specified as for C:
358357Ssam 	 * 0x=hex, 0=octal, other=decimal.
368357Ssam 	 */
378309Ssam 	val = 0; base = 10;
3831352Sbostic 	if (*cp == '0') {
3931352Sbostic 		if (*++cp == 'x' || *cp == 'X')
4031352Sbostic 			base = 16, cp++;
4131352Sbostic 		else
4231352Sbostic 			base = 8;
4331352Sbostic 	}
448309Ssam 	while (c = *cp) {
458309Ssam 		if (isdigit(c)) {
468309Ssam 			val = (val * base) + (c - '0');
478309Ssam 			cp++;
488309Ssam 			continue;
498309Ssam 		}
508309Ssam 		if (base == 16 && isxdigit(c)) {
518309Ssam 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
528309Ssam 			cp++;
538309Ssam 			continue;
548309Ssam 		}
558309Ssam 		break;
568309Ssam 	}
578309Ssam 	if (*cp == '.') {
588309Ssam 		/*
598309Ssam 		 * Internet format:
608309Ssam 		 *	a.b.c.d
618309Ssam 		 *	a.b.c	(with c treated as 16-bits)
628309Ssam 		 *	a.b	(with b treated as 24 bits)
638309Ssam 		 */
648309Ssam 		if (pp >= parts + 4)
6532314Sbostic 			return (INADDR_NONE);
668309Ssam 		*pp++ = val, cp++;
678309Ssam 		goto again;
688309Ssam 	}
698357Ssam 	/*
708357Ssam 	 * Check for trailing characters.
718357Ssam 	 */
728309Ssam 	if (*cp && !isspace(*cp))
7332314Sbostic 		return (INADDR_NONE);
748357Ssam 	*pp++ = val;
758357Ssam 	/*
768357Ssam 	 * Concoct the address according to
778357Ssam 	 * the number of parts specified.
788357Ssam 	 */
798309Ssam 	n = pp - parts;
808357Ssam 	switch (n) {
818357Ssam 
828357Ssam 	case 1:				/* a -- 32 bits */
838309Ssam 		val = parts[0];
848357Ssam 		break;
858357Ssam 
868357Ssam 	case 2:				/* a.b -- 8.24 bits */
878357Ssam 		val = (parts[0] << 24) | (parts[1] & 0xffffff);
888357Ssam 		break;
898357Ssam 
908357Ssam 	case 3:				/* a.b.c -- 8.8.16 bits */
918357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
928357Ssam 			(parts[2] & 0xffff);
938357Ssam 		break;
948357Ssam 
958357Ssam 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
968357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
978357Ssam 		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
988357Ssam 		break;
998357Ssam 
1008357Ssam 	default:
10132314Sbostic 		return (INADDR_NONE);
1028309Ssam 	}
1038357Ssam 	val = htonl(val);
1048309Ssam 	return (val);
1058309Ssam }
106