xref: /csrg-svn/lib/libc/net/inet_addr.c (revision 33676)
121367Sdist /*
221367Sdist  * Copyright (c) 1983 Regents of the University of California.
3*33676Sbostic  * All rights reserved.
4*33676Sbostic  *
5*33676Sbostic  * Redistribution and use in source and binary forms are permitted
6*33676Sbostic  * provided that this notice is preserved and that due credit is given
7*33676Sbostic  * to the University of California at Berkeley. The name of the University
8*33676Sbostic  * may not be used to endorse or promote products derived from this
9*33676Sbostic  * software without specific prior written permission. This software
10*33676Sbostic  * is provided ``as is'' without express or implied warranty.
1121367Sdist  */
128324Ssam 
1326612Sdonn #if defined(LIBC_SCCS) && !defined(lint)
14*33676Sbostic static char sccsid[] = "@(#)inet_addr.c	5.5 (Berkeley) 03/07/88";
15*33676Sbostic #endif /* LIBC_SCCS and not lint */
1621367Sdist 
178324Ssam #include <sys/types.h>
188324Ssam #include <ctype.h>
199192Ssam #include <netinet/in.h>
208324Ssam 
218309Ssam /*
228309Ssam  * Internet address interpretation routine.
238309Ssam  * All the network library routines call this
248309Ssam  * routine to interpret entries in the data bases
258309Ssam  * which are expected to be an address.
268357Ssam  * The value returned is in network order.
278309Ssam  */
288361Ssam u_long
298309Ssam inet_addr(cp)
308309Ssam 	register char *cp;
318309Ssam {
328357Ssam 	register u_long val, base, n;
338309Ssam 	register char c;
348357Ssam 	u_long parts[4], *pp = parts;
358309Ssam 
368309Ssam again:
378357Ssam 	/*
388357Ssam 	 * Collect number up to ``.''.
398357Ssam 	 * Values are specified as for C:
408357Ssam 	 * 0x=hex, 0=octal, other=decimal.
418357Ssam 	 */
428309Ssam 	val = 0; base = 10;
4331352Sbostic 	if (*cp == '0') {
4431352Sbostic 		if (*++cp == 'x' || *cp == 'X')
4531352Sbostic 			base = 16, cp++;
4631352Sbostic 		else
4731352Sbostic 			base = 8;
4831352Sbostic 	}
498309Ssam 	while (c = *cp) {
508309Ssam 		if (isdigit(c)) {
518309Ssam 			val = (val * base) + (c - '0');
528309Ssam 			cp++;
538309Ssam 			continue;
548309Ssam 		}
558309Ssam 		if (base == 16 && isxdigit(c)) {
568309Ssam 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
578309Ssam 			cp++;
588309Ssam 			continue;
598309Ssam 		}
608309Ssam 		break;
618309Ssam 	}
628309Ssam 	if (*cp == '.') {
638309Ssam 		/*
648309Ssam 		 * Internet format:
658309Ssam 		 *	a.b.c.d
668309Ssam 		 *	a.b.c	(with c treated as 16-bits)
678309Ssam 		 *	a.b	(with b treated as 24 bits)
688309Ssam 		 */
698309Ssam 		if (pp >= parts + 4)
7032314Sbostic 			return (INADDR_NONE);
718309Ssam 		*pp++ = val, cp++;
728309Ssam 		goto again;
738309Ssam 	}
748357Ssam 	/*
758357Ssam 	 * Check for trailing characters.
768357Ssam 	 */
778309Ssam 	if (*cp && !isspace(*cp))
7832314Sbostic 		return (INADDR_NONE);
798357Ssam 	*pp++ = val;
808357Ssam 	/*
818357Ssam 	 * Concoct the address according to
828357Ssam 	 * the number of parts specified.
838357Ssam 	 */
848309Ssam 	n = pp - parts;
858357Ssam 	switch (n) {
868357Ssam 
878357Ssam 	case 1:				/* a -- 32 bits */
888309Ssam 		val = parts[0];
898357Ssam 		break;
908357Ssam 
918357Ssam 	case 2:				/* a.b -- 8.24 bits */
928357Ssam 		val = (parts[0] << 24) | (parts[1] & 0xffffff);
938357Ssam 		break;
948357Ssam 
958357Ssam 	case 3:				/* a.b.c -- 8.8.16 bits */
968357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
978357Ssam 			(parts[2] & 0xffff);
988357Ssam 		break;
998357Ssam 
1008357Ssam 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
1018357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
1028357Ssam 		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
1038357Ssam 		break;
1048357Ssam 
1058357Ssam 	default:
10632314Sbostic 		return (INADDR_NONE);
1078309Ssam 	}
1088357Ssam 	val = htonl(val);
1098309Ssam 	return (val);
1108309Ssam }
111