121367Sdist /* 2*43506Skarels * Copyright (c) 1983, 1990 Regents of the University of California. 333676Sbostic * All rights reserved. 433676Sbostic * 542626Sbostic * %sccs.include.redist.c% 621367Sdist */ 78324Ssam 826612Sdonn #if defined(LIBC_SCCS) && !defined(lint) 9*43506Skarels static char sccsid[] = "@(#)inet_addr.c 5.8 (Berkeley) 06/23/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 /* 17*43506Skarels * Ascii internet address interpretation routine. 188357Ssam * The value returned is in network order. 198309Ssam */ 208361Ssam u_long 218309Ssam inet_addr(cp) 228309Ssam register char *cp; 238309Ssam { 24*43506Skarels struct in_addr val; 25*43506Skarels 26*43506Skarels if (inet_aton(cp, &val)) 27*43506Skarels return (val.s_addr); 28*43506Skarels return (INADDR_NONE); 29*43506Skarels } 30*43506Skarels 31*43506Skarels /* 32*43506Skarels * Check whether "cp" is a valid ascii representation 33*43506Skarels * of an Internet address and convert to a binary address. 34*43506Skarels * Returns 1 if the address is valid, 0 if not. 35*43506Skarels * This replaces inet_addr, the return value from which 36*43506Skarels * cannot distinguish between failure and a local broadcast address. 37*43506Skarels */ 38*43506Skarels 39*43506Skarels inet_aton(cp, addr) 40*43506Skarels register char *cp; 41*43506Skarels struct in_addr *addr; 42*43506Skarels { 438357Ssam register u_long val, base, n; 448309Ssam register char c; 458357Ssam u_long parts[4], *pp = parts; 468309Ssam 47*43506Skarels for (;;) { 48*43506Skarels /* 49*43506Skarels * Collect number up to ``.''. 50*43506Skarels * Values are specified as for C: 51*43506Skarels * 0x=hex, 0=octal, other=decimal. 52*43506Skarels */ 53*43506Skarels val = 0; base = 10; 54*43506Skarels if (*cp == '0') { 55*43506Skarels if (*++cp == 'x' || *cp == 'X') 56*43506Skarels base = 16, cp++; 57*43506Skarels else 58*43506Skarels base = 8; 598309Ssam } 60*43506Skarels while ((c = *cp) != '\0') { 61*43506Skarels if (isascii(c) && isdigit(c)) { 62*43506Skarels val = (val * base) + (c - '0'); 63*43506Skarels cp++; 64*43506Skarels continue; 65*43506Skarels } 66*43506Skarels if (base == 16 && isascii(c) && isxdigit(c)) { 67*43506Skarels val = (val << 4) + 68*43506Skarels (c + 10 - (islower(c) ? 'a' : 'A')); 69*43506Skarels cp++; 70*43506Skarels continue; 71*43506Skarels } 72*43506Skarels break; 738309Ssam } 74*43506Skarels if (*cp == '.') { 75*43506Skarels /* 76*43506Skarels * Internet format: 77*43506Skarels * a.b.c.d 78*43506Skarels * a.b.c (with c treated as 16-bits) 79*43506Skarels * a.b (with b treated as 24 bits) 80*43506Skarels */ 81*43506Skarels if (pp >= parts + 3 || val > 0xff) 82*43506Skarels return (0); 83*43506Skarels *pp++ = val, cp++; 84*43506Skarels } else 85*43506Skarels break; 868309Ssam } 878357Ssam /* 888357Ssam * Check for trailing characters. 898357Ssam */ 90*43506Skarels if (*cp && (!isascii(*cp) || !isspace(*cp))) 91*43506Skarels return (0); 928357Ssam /* 938357Ssam * Concoct the address according to 948357Ssam * the number of parts specified. 958357Ssam */ 96*43506Skarels n = pp - parts + 1; 978357Ssam switch (n) { 988357Ssam 998357Ssam case 1: /* a -- 32 bits */ 1008357Ssam break; 1018357Ssam 1028357Ssam case 2: /* a.b -- 8.24 bits */ 103*43506Skarels if (val > 0xffffff) 104*43506Skarels return (0); 105*43506Skarels val |= parts[0] << 24; 1068357Ssam break; 1078357Ssam 1088357Ssam case 3: /* a.b.c -- 8.8.16 bits */ 109*43506Skarels if (val > 0xffff) 110*43506Skarels return (0); 111*43506Skarels val |= (parts[0] << 24) | (parts[1] << 16); 1128357Ssam break; 1138357Ssam 1148357Ssam case 4: /* a.b.c.d -- 8.8.8.8 bits */ 115*43506Skarels if (val > 0xff) 116*43506Skarels return (0); 117*43506Skarels val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 1188357Ssam break; 1198309Ssam } 120*43506Skarels if (addr) 121*43506Skarels addr->s_addr = htonl(val); 122*43506Skarels return (1); 1238309Ssam } 124