xref: /csrg-svn/lib/libc/net/inet_addr.c (revision 26612)
121367Sdist /*
221367Sdist  * Copyright (c) 1983 Regents of the University of California.
321367Sdist  * All rights reserved.  The Berkeley software License Agreement
421367Sdist  * specifies the terms and conditions for redistribution.
521367Sdist  */
68324Ssam 
7*26612Sdonn #if defined(LIBC_SCCS) && !defined(lint)
8*26612Sdonn static char sccsid[] = "@(#)inet_addr.c	5.2 (Berkeley) 03/09/86";
9*26612Sdonn #endif LIBC_SCCS and not lint
1021367Sdist 
118324Ssam #include <sys/types.h>
128324Ssam #include <ctype.h>
139192Ssam #include <netinet/in.h>
148324Ssam 
158309Ssam /*
168309Ssam  * Internet address interpretation routine.
178309Ssam  * All the network library routines call this
188309Ssam  * routine to interpret entries in the data bases
198309Ssam  * which are expected to be an address.
208357Ssam  * The value returned is in network order.
218309Ssam  */
228361Ssam u_long
238309Ssam inet_addr(cp)
248309Ssam 	register char *cp;
258309Ssam {
268357Ssam 	register u_long val, base, n;
278309Ssam 	register char c;
288357Ssam 	u_long parts[4], *pp = parts;
298309Ssam 
308309Ssam again:
318357Ssam 	/*
328357Ssam 	 * Collect number up to ``.''.
338357Ssam 	 * Values are specified as for C:
348357Ssam 	 * 0x=hex, 0=octal, other=decimal.
358357Ssam 	 */
368309Ssam 	val = 0; base = 10;
378309Ssam 	if (*cp == '0')
388309Ssam 		base = 8, cp++;
398309Ssam 	if (*cp == 'x' || *cp == 'X')
408309Ssam 		base = 16, cp++;
418309Ssam 	while (c = *cp) {
428309Ssam 		if (isdigit(c)) {
438309Ssam 			val = (val * base) + (c - '0');
448309Ssam 			cp++;
458309Ssam 			continue;
468309Ssam 		}
478309Ssam 		if (base == 16 && isxdigit(c)) {
488309Ssam 			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
498309Ssam 			cp++;
508309Ssam 			continue;
518309Ssam 		}
528309Ssam 		break;
538309Ssam 	}
548309Ssam 	if (*cp == '.') {
558309Ssam 		/*
568309Ssam 		 * Internet format:
578309Ssam 		 *	a.b.c.d
588309Ssam 		 *	a.b.c	(with c treated as 16-bits)
598309Ssam 		 *	a.b	(with b treated as 24 bits)
608309Ssam 		 */
618309Ssam 		if (pp >= parts + 4)
628309Ssam 			return (-1);
638309Ssam 		*pp++ = val, cp++;
648309Ssam 		goto again;
658309Ssam 	}
668357Ssam 	/*
678357Ssam 	 * Check for trailing characters.
688357Ssam 	 */
698309Ssam 	if (*cp && !isspace(*cp))
708309Ssam 		return (-1);
718357Ssam 	*pp++ = val;
728357Ssam 	/*
738357Ssam 	 * Concoct the address according to
748357Ssam 	 * the number of parts specified.
758357Ssam 	 */
768309Ssam 	n = pp - parts;
778357Ssam 	switch (n) {
788357Ssam 
798357Ssam 	case 1:				/* a -- 32 bits */
808309Ssam 		val = parts[0];
818357Ssam 		break;
828357Ssam 
838357Ssam 	case 2:				/* a.b -- 8.24 bits */
848357Ssam 		val = (parts[0] << 24) | (parts[1] & 0xffffff);
858357Ssam 		break;
868357Ssam 
878357Ssam 	case 3:				/* a.b.c -- 8.8.16 bits */
888357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
898357Ssam 			(parts[2] & 0xffff);
908357Ssam 		break;
918357Ssam 
928357Ssam 	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
938357Ssam 		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
948357Ssam 		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
958357Ssam 		break;
968357Ssam 
978357Ssam 	default:
988357Ssam 		return (-1);
998309Ssam 	}
1008357Ssam 	val = htonl(val);
1018309Ssam 	return (val);
1028309Ssam }
103