175880123SAttilio Rao /*- 275880123SAttilio Rao * Copyright (c) 2001 Charles Mott <cm@linktel.net> 375880123SAttilio Rao * All rights reserved. 475880123SAttilio Rao * 575880123SAttilio Rao * Redistribution and use in source and binary forms, with or without 675880123SAttilio Rao * modification, are permitted provided that the following conditions 775880123SAttilio Rao * are met: 875880123SAttilio Rao * 1. Redistributions of source code must retain the above copyright 975880123SAttilio Rao * notice, this list of conditions and the following disclaimer. 1075880123SAttilio Rao * 2. Redistributions in binary form must reproduce the above copyright 1175880123SAttilio Rao * notice, this list of conditions and the following disclaimer in the 1275880123SAttilio Rao * documentation and/or other materials provided with the distribution. 1375880123SAttilio Rao * 1475880123SAttilio Rao * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1575880123SAttilio Rao * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1675880123SAttilio Rao * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1775880123SAttilio Rao * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1875880123SAttilio Rao * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1975880123SAttilio Rao * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2075880123SAttilio Rao * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2175880123SAttilio Rao * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2275880123SAttilio Rao * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2375880123SAttilio Rao * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2475880123SAttilio Rao * SUCH DAMAGE. 2575880123SAttilio Rao */ 2675880123SAttilio Rao 2775880123SAttilio Rao #include <sys/cdefs.h> 2875880123SAttilio Rao __FBSDID("$FreeBSD$"); 2975880123SAttilio Rao 3075880123SAttilio Rao #include <sys/param.h> 3175880123SAttilio Rao #include <sys/ctype.h> 3275880123SAttilio Rao #include <sys/limits.h> 3375880123SAttilio Rao #include <sys/systm.h> 3475880123SAttilio Rao 3575880123SAttilio Rao #include <netinet/in.h> 3675880123SAttilio Rao 3775880123SAttilio Rao int 3875880123SAttilio Rao inet_aton(const char *cp, struct in_addr *addr) 3975880123SAttilio Rao { 4075880123SAttilio Rao u_long parts[4]; 4175880123SAttilio Rao in_addr_t val; 4275880123SAttilio Rao const char *c; 4375880123SAttilio Rao char *endptr; 4475880123SAttilio Rao int gotend, n; 4575880123SAttilio Rao 4675880123SAttilio Rao c = (const char *)cp; 4775880123SAttilio Rao n = 0; 4875880123SAttilio Rao 4975880123SAttilio Rao /* 5075880123SAttilio Rao * Run through the string, grabbing numbers until 5175880123SAttilio Rao * the end of the string, or some error 5275880123SAttilio Rao */ 5375880123SAttilio Rao gotend = 0; 5475880123SAttilio Rao while (!gotend) { 5575880123SAttilio Rao unsigned long l; 5675880123SAttilio Rao 5775880123SAttilio Rao l = strtoul(c, &endptr, 0); 5875880123SAttilio Rao 5975880123SAttilio Rao if (l == ULONG_MAX || (l == 0 && endptr == c)) 6075880123SAttilio Rao return (0); 6175880123SAttilio Rao 6275880123SAttilio Rao val = (in_addr_t)l; 6375880123SAttilio Rao 6475880123SAttilio Rao /* 6575880123SAttilio Rao * If the whole string is invalid, endptr will equal 6675880123SAttilio Rao * c.. this way we can make sure someone hasn't 6775880123SAttilio Rao * gone '.12' or something which would get past 6875880123SAttilio Rao * the next check. 6975880123SAttilio Rao */ 7075880123SAttilio Rao if (endptr == c) 7175880123SAttilio Rao return (0); 7275880123SAttilio Rao parts[n] = val; 7375880123SAttilio Rao c = endptr; 7475880123SAttilio Rao 7575880123SAttilio Rao /* Check the next character past the previous number's end */ 7675880123SAttilio Rao switch (*c) { 7775880123SAttilio Rao case '.' : 7875880123SAttilio Rao 7975880123SAttilio Rao /* Make sure we only do 3 dots .. */ 8075880123SAttilio Rao if (n == 3) /* Whoops. Quit. */ 8175880123SAttilio Rao return (0); 8275880123SAttilio Rao n++; 8375880123SAttilio Rao c++; 8475880123SAttilio Rao break; 8575880123SAttilio Rao 8675880123SAttilio Rao case '\0': 8775880123SAttilio Rao gotend = 1; 8875880123SAttilio Rao break; 8975880123SAttilio Rao 9075880123SAttilio Rao default: 9175880123SAttilio Rao if (isspace((unsigned char)*c)) { 9275880123SAttilio Rao gotend = 1; 9375880123SAttilio Rao break; 9475880123SAttilio Rao } else { 9575880123SAttilio Rao 9675880123SAttilio Rao /* Invalid character, then fail. */ 9775880123SAttilio Rao return (0); 9875880123SAttilio Rao } 9975880123SAttilio Rao } 10075880123SAttilio Rao 10175880123SAttilio Rao } 10275880123SAttilio Rao 10375880123SAttilio Rao /* Concoct the address according to the number of parts specified. */ 10475880123SAttilio Rao switch (n) { 10575880123SAttilio Rao case 0: /* a -- 32 bits */ 10675880123SAttilio Rao 10775880123SAttilio Rao /* 10875880123SAttilio Rao * Nothing is necessary here. Overflow checking was 10975880123SAttilio Rao * already done in strtoul(). 11075880123SAttilio Rao */ 11175880123SAttilio Rao break; 11275880123SAttilio Rao case 1: /* a.b -- 8.24 bits */ 11375880123SAttilio Rao if (val > 0xffffff || parts[0] > 0xff) 11475880123SAttilio Rao return (0); 11575880123SAttilio Rao val |= parts[0] << 24; 11675880123SAttilio Rao break; 11775880123SAttilio Rao 11875880123SAttilio Rao case 2: /* a.b.c -- 8.8.16 bits */ 11975880123SAttilio Rao if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff) 12075880123SAttilio Rao return (0); 12175880123SAttilio Rao val |= (parts[0] << 24) | (parts[1] << 16); 12275880123SAttilio Rao break; 12375880123SAttilio Rao 12475880123SAttilio Rao case 3: /* a.b.c.d -- 8.8.8.8 bits */ 12575880123SAttilio Rao if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff || 12675880123SAttilio Rao parts[2] > 0xff) 12775880123SAttilio Rao return (0); 12875880123SAttilio Rao val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 12975880123SAttilio Rao break; 13075880123SAttilio Rao } 13175880123SAttilio Rao 13275880123SAttilio Rao if (addr != NULL) 13375880123SAttilio Rao addr->s_addr = htonl(val); 13475880123SAttilio Rao return (1); 13575880123SAttilio Rao } 13675880123SAttilio Rao 137