1/* $NetBSD: inet_aton.c,v 1.2.6.1 2012/06/05 21:15:07 bouyer Exp $ */ 2 3/* 4 * Portions Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") 5 * Portions Copyright (C) 1996-2001 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* 21 * Copyright (c) 1983, 1990, 1993 22 * The Regents of the University of California. All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 3. All advertising materials mentioning features or use of this software 33 * must display the following acknowledgement: 34 * This product includes software developed by the University of 35 * California, Berkeley and its contributors. 36 * 4. Neither the name of the University nor the names of its contributors 37 * may be used to endorse or promote products derived from this software 38 * without specific prior written permission. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 */ 52 53/* 54 * Portions Copyright (c) 1993 by Digital Equipment Corporation. 55 * 56 * Permission to use, copy, modify, and distribute this software for any 57 * purpose with or without fee is hereby granted, provided that the above 58 * copyright notice and this permission notice appear in all copies, and that 59 * the name of Digital Equipment Corporation not be used in advertising or 60 * publicity pertaining to distribution of the document or software without 61 * specific, written prior permission. 62 * 63 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 64 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 65 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 66 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 67 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 68 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 69 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 70 * SOFTWARE. 71 */ 72/*! \file */ 73 74#if defined(LIBC_SCCS) && !defined(lint) 75static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; 76static char rcsid[] = "Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp "; 77#endif /* LIBC_SCCS and not lint */ 78 79#include <config.h> 80 81#include <ctype.h> 82#include <stddef.h> /* Required for NULL. */ 83 84#include <isc/types.h> 85#include <isc/net.h> 86 87/*% 88 * Check whether "cp" is a valid ascii representation 89 * of an Internet address and convert to a binary address. 90 * Returns 1 if the address is valid, 0 if not. 91 * This replaces inet_addr, the return value from which 92 * cannot distinguish between failure and a local broadcast address. 93 */ 94int 95isc_net_aton(const char *cp, struct in_addr *addr) { 96 unsigned long val; 97 int base, n; 98 unsigned char c; 99 isc_uint8_t parts[4]; 100 isc_uint8_t *pp = parts; 101 int digit; 102 103 c = *cp; 104 for (;;) { 105 /* 106 * Collect number up to ``.''. 107 * Values are specified as for C: 108 * 0x=hex, 0=octal, isdigit=decimal. 109 */ 110 if (!isdigit(c & 0xff)) 111 return (0); 112 val = 0; base = 10; digit = 0; 113 if (c == '0') { 114 c = *++cp; 115 if (c == 'x' || c == 'X') 116 base = 16, c = *++cp; 117 else { 118 base = 8; 119 digit = 1; 120 } 121 } 122 for (;;) { 123 /* 124 * isascii() is valid for all integer values, and 125 * when it is true, c is known to be in scope 126 * for isdigit(). No cast necessary. Similar 127 * comment applies for later ctype uses. 128 */ 129 if (isascii(c) && isdigit(c)) { 130 if (base == 8 && (c == '8' || c == '9')) 131 return (0); 132 val = (val * base) + (c - '0'); 133 c = *++cp; 134 digit = 1; 135 } else if (base == 16 && isascii(c) && isxdigit(c)) { 136 val = (val << 4) | 137 (c + 10 - (islower(c) ? 'a' : 'A')); 138 c = *++cp; 139 digit = 1; 140 } else 141 break; 142 } 143 if (c == '.') { 144 /* 145 * Internet format: 146 * a.b.c.d 147 * a.b.c (with c treated as 16 bits) 148 * a.b (with b treated as 24 bits) 149 */ 150 if (pp >= parts + 3 || val > 0xffU) 151 return (0); 152 *pp++ = (isc_uint8_t)val; 153 c = *++cp; 154 } else 155 break; 156 } 157 /* 158 * Check for trailing characters. 159 */ 160 if (c != '\0' && (!isascii(c) || !isspace(c))) 161 return (0); 162 /* 163 * Did we get a valid digit? 164 */ 165 if (!digit) 166 return (0); 167 /* 168 * Concoct the address according to 169 * the number of parts specified. 170 */ 171 n = pp - parts + 1; 172 switch (n) { 173 case 1: /* a -- 32 bits */ 174 break; 175 176 case 2: /* a.b -- 8.24 bits */ 177 if (val > 0xffffffU) 178 return (0); 179 val |= parts[0] << 24; 180 break; 181 182 case 3: /* a.b.c -- 8.8.16 bits */ 183 if (val > 0xffffU) 184 return (0); 185 val |= (parts[0] << 24) | (parts[1] << 16); 186 break; 187 188 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 189 if (val > 0xffU) 190 return (0); 191 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 192 break; 193 } 194 if (addr != NULL) 195 addr->s_addr = htonl(val); 196 197 return (1); 198} 199