1 /* $NetBSD: inet_addr.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $ */ 2 /* NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp */ 3 4 /* 5 * Copyright (c) 1983, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __RCSID("$NetBSD: inet_addr.c,v 1.1.1.3 2014/07/12 11:57:58 spz Exp $"); 35 36 #if defined(LIBC_SCCS) && !defined(lint) 37 #if 0 38 static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; 39 #else 40 static char rcsid[] = "NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp "; 41 #endif 42 #endif /* LIBC_SCCS and not lint */ 43 44 #include "dhcpd.h" 45 46 #include "omapip/omapip_p.h" 47 48 #ifdef NEED_INET_ATON 49 /* 50 * Check whether "cp" is a valid ascii representation 51 * of an Internet address and convert to a binary address. 52 * Returns 1 if the address is valid, 0 if not. 53 * This replaces inet_addr, the return value from which 54 * cannot distinguish between failure and a local broadcast address. 55 */ 56 int 57 inet_aton(cp, addr) 58 const char *cp; 59 struct in_addr *addr; 60 { 61 register u_long val; 62 register int base, n; 63 register char c; 64 u_int parts[4]; 65 register u_int *pp = parts; 66 67 for (;;) { 68 /* 69 * Collect number up to ``.''. 70 * Values are specified as for C: 71 * 0x=hex, 0=octal, other=decimal. 72 */ 73 val = 0; base = 10; 74 if (*cp == '0') { 75 if (*++cp == 'x' || *cp == 'X') 76 base = 16, cp++; 77 else 78 base = 8; 79 } 80 while ((c = *cp) != '\0') { 81 if (isascii(c) && isdigit((int)c)) { 82 val = (val * base) + (c - '0'); 83 cp++; 84 continue; 85 } 86 if (base == 16 && isascii(c) && isxdigit((int)c)) { 87 val = (val << 4) + 88 (c + 10 - (islower((int)c) ? 'a' : 'A')); 89 cp++; 90 continue; 91 } 92 break; 93 } 94 if (*cp == '.') { 95 /* 96 * Internet format: 97 * a.b.c.d 98 * a.b.c (with c treated as 16-bits) 99 * a.b (with b treated as 24 bits) 100 */ 101 if (pp >= parts + 3 || val > 0xff) 102 return (0); 103 *pp++ = val, cp++; 104 } else 105 break; 106 } 107 /* 108 * Check for trailing characters. 109 */ 110 if (*cp && (!isascii(*cp) || !isspace((int)*cp))) 111 return (0); 112 /* 113 * Concoct the address according to 114 * the number of parts specified. 115 */ 116 n = pp - parts + 1; 117 switch (n) { 118 119 case 0: 120 return (0); /* initial nondigit */ 121 122 case 1: /* a -- 32 bits */ 123 break; 124 125 case 2: /* a.b -- 8.24 bits */ 126 if (val > 0xffffff) 127 return (0); 128 val |= parts[0] << 24; 129 break; 130 131 case 3: /* a.b.c -- 8.8.16 bits */ 132 if (val > 0xffff) 133 return (0); 134 val |= (parts[0] << 24) | (parts[1] << 16); 135 break; 136 137 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 138 if (val > 0xff) 139 return (0); 140 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 141 break; 142 } 143 if (addr) 144 addr->s_addr = htonl(val); 145 return (1); 146 } 147 #endif 148