121367Sdist /* 243506Skarels * 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*46604Sbostic static char sccsid[] = "@(#)inet_addr.c 5.9 (Berkeley) 02/24/91"; 1033676Sbostic #endif /* LIBC_SCCS and not lint */ 1121367Sdist 12*46604Sbostic #include <sys/param.h> 139192Ssam #include <netinet/in.h> 14*46604Sbostic #include <arpa/inet.h> 158324Ssam 168309Ssam /* 1743506Skarels * Ascii internet address interpretation routine. 188357Ssam * The value returned is in network order. 198309Ssam */ 208361Ssam u_long 218309Ssam inet_addr(cp) 22*46604Sbostic register const char *cp; 238309Ssam { 2443506Skarels struct in_addr val; 2543506Skarels 2643506Skarels if (inet_aton(cp, &val)) 2743506Skarels return (val.s_addr); 2843506Skarels return (INADDR_NONE); 2943506Skarels } 3043506Skarels 3143506Skarels /* 3243506Skarels * Check whether "cp" is a valid ascii representation 3343506Skarels * of an Internet address and convert to a binary address. 3443506Skarels * Returns 1 if the address is valid, 0 if not. 3543506Skarels * This replaces inet_addr, the return value from which 3643506Skarels * cannot distinguish between failure and a local broadcast address. 3743506Skarels */ 3843506Skarels 3943506Skarels inet_aton(cp, addr) 4043506Skarels register char *cp; 4143506Skarels struct in_addr *addr; 4243506Skarels { 438357Ssam register u_long val, base, n; 448309Ssam register char c; 458357Ssam u_long parts[4], *pp = parts; 468309Ssam 4743506Skarels for (;;) { 4843506Skarels /* 4943506Skarels * Collect number up to ``.''. 5043506Skarels * Values are specified as for C: 5143506Skarels * 0x=hex, 0=octal, other=decimal. 5243506Skarels */ 5343506Skarels val = 0; base = 10; 5443506Skarels if (*cp == '0') { 5543506Skarels if (*++cp == 'x' || *cp == 'X') 5643506Skarels base = 16, cp++; 5743506Skarels else 5843506Skarels base = 8; 598309Ssam } 6043506Skarels while ((c = *cp) != '\0') { 6143506Skarels if (isascii(c) && isdigit(c)) { 6243506Skarels val = (val * base) + (c - '0'); 6343506Skarels cp++; 6443506Skarels continue; 6543506Skarels } 6643506Skarels if (base == 16 && isascii(c) && isxdigit(c)) { 6743506Skarels val = (val << 4) + 6843506Skarels (c + 10 - (islower(c) ? 'a' : 'A')); 6943506Skarels cp++; 7043506Skarels continue; 7143506Skarels } 7243506Skarels break; 738309Ssam } 7443506Skarels if (*cp == '.') { 7543506Skarels /* 7643506Skarels * Internet format: 7743506Skarels * a.b.c.d 7843506Skarels * a.b.c (with c treated as 16-bits) 7943506Skarels * a.b (with b treated as 24 bits) 8043506Skarels */ 8143506Skarels if (pp >= parts + 3 || val > 0xff) 8243506Skarels return (0); 8343506Skarels *pp++ = val, cp++; 8443506Skarels } else 8543506Skarels break; 868309Ssam } 878357Ssam /* 888357Ssam * Check for trailing characters. 898357Ssam */ 9043506Skarels if (*cp && (!isascii(*cp) || !isspace(*cp))) 9143506Skarels return (0); 928357Ssam /* 938357Ssam * Concoct the address according to 948357Ssam * the number of parts specified. 958357Ssam */ 9643506Skarels 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 */ 10343506Skarels if (val > 0xffffff) 10443506Skarels return (0); 10543506Skarels val |= parts[0] << 24; 1068357Ssam break; 1078357Ssam 1088357Ssam case 3: /* a.b.c -- 8.8.16 bits */ 10943506Skarels if (val > 0xffff) 11043506Skarels return (0); 11143506Skarels val |= (parts[0] << 24) | (parts[1] << 16); 1128357Ssam break; 1138357Ssam 1148357Ssam case 4: /* a.b.c.d -- 8.8.8.8 bits */ 11543506Skarels if (val > 0xff) 11643506Skarels return (0); 11743506Skarels val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 1188357Ssam break; 1198309Ssam } 12043506Skarels if (addr) 12143506Skarels addr->s_addr = htonl(val); 12243506Skarels return (1); 1238309Ssam } 124