00001 /* $NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $ */ 00002 00003 /* 00004 * Copyright (c) 1983, 1990, 1993 00005 * The Regents of the University of California. All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the University nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software 00017 * without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 00020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 00023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00024 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00025 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00027 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00028 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00029 * SUCH DAMAGE. 00030 */ 00031 00032 #if defined(LIBC_SCCS) && !defined(lint) 00033 #if 0 00034 static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; 00035 #else 00036 static char rcsid[] = "$NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $"; 00037 #endif 00038 #endif /* LIBC_SCCS and not lint */ 00039 00040 #include "dhcpd.h" 00041 00042 #include "omapip/omapip_p.h" 00043 00044 #ifdef NEED_INET_ATON 00045 /* 00046 * Check whether "cp" is a valid ascii representation 00047 * of an Internet address and convert to a binary address. 00048 * Returns 1 if the address is valid, 0 if not. 00049 * This replaces inet_addr, the return value from which 00050 * cannot distinguish between failure and a local broadcast address. 00051 */ 00052 int 00053 inet_aton(cp, addr) 00054 const char *cp; 00055 struct in_addr *addr; 00056 { 00057 register u_long val; 00058 register int base, n; 00059 register char c; 00060 u_int parts[4]; 00061 register u_int *pp = parts; 00062 00063 for (;;) { 00064 /* 00065 * Collect number up to ``.''. 00066 * Values are specified as for C: 00067 * 0x=hex, 0=octal, other=decimal. 00068 */ 00069 val = 0; base = 10; 00070 if (*cp == '0') { 00071 if (*++cp == 'x' || *cp == 'X') 00072 base = 16, cp++; 00073 else 00074 base = 8; 00075 } 00076 while ((c = *cp) != '\0') { 00077 if (isascii(c) && isdigit((int)c)) { 00078 val = (val * base) + (c - '0'); 00079 cp++; 00080 continue; 00081 } 00082 if (base == 16 && isascii(c) && isxdigit((int)c)) { 00083 val = (val << 4) + 00084 (c + 10 - (islower((int)c) ? 'a' : 'A')); 00085 cp++; 00086 continue; 00087 } 00088 break; 00089 } 00090 if (*cp == '.') { 00091 /* 00092 * Internet format: 00093 * a.b.c.d 00094 * a.b.c (with c treated as 16-bits) 00095 * a.b (with b treated as 24 bits) 00096 */ 00097 if (pp >= parts + 3 || val > 0xff) 00098 return (0); 00099 *pp++ = val, cp++; 00100 } else 00101 break; 00102 } 00103 /* 00104 * Check for trailing characters. 00105 */ 00106 if (*cp && (!isascii(*cp) || !isspace((int)*cp))) 00107 return (0); 00108 /* 00109 * Concoct the address according to 00110 * the number of parts specified. 00111 */ 00112 n = pp - parts + 1; 00113 switch (n) { 00114 00115 case 0: 00116 return (0); /* initial nondigit */ 00117 00118 case 1: /* a -- 32 bits */ 00119 break; 00120 00121 case 2: /* a.b -- 8.24 bits */ 00122 if (val > 0xffffff) 00123 return (0); 00124 val |= parts[0] << 24; 00125 break; 00126 00127 case 3: /* a.b.c -- 8.8.16 bits */ 00128 if (val > 0xffff) 00129 return (0); 00130 val |= (parts[0] << 24) | (parts[1] << 16); 00131 break; 00132 00133 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 00134 if (val > 0xff) 00135 return (0); 00136 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 00137 break; 00138 } 00139 if (addr) 00140 addr->s_addr = htonl(val); 00141 return (1); 00142 } 00143 #endif