/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2001 Charles Mott <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/param.h>29#include <sys/ctype.h>30#include <sys/limits.h>31#include <sys/systm.h>3233#include <netinet/in.h>3435int36inet_aton(const char *cp, struct in_addr *addr)37{38u_long parts[4];39in_addr_t val;40const char *c;41char *endptr;42int gotend, n;4344c = (const char *)cp;45n = 0;4647/*48* Run through the string, grabbing numbers until49* the end of the string, or some error50*/51gotend = 0;52while (!gotend) {53unsigned long l;5455l = strtoul(c, &endptr, 0);5657if (l == ULONG_MAX || (l == 0 && endptr == c))58return (0);5960val = (in_addr_t)l;6162/*63* If the whole string is invalid, endptr will equal64* c.. this way we can make sure someone hasn't65* gone '.12' or something which would get past66* the next check.67*/68if (endptr == c)69return (0);70parts[n] = val;71c = endptr;7273/* Check the next character past the previous number's end */74switch (*c) {75case '.' :7677/* Make sure we only do 3 dots .. */78if (n == 3) /* Whoops. Quit. */79return (0);80n++;81c++;82break;8384case '\0':85gotend = 1;86break;8788default:89if (isspace((unsigned char)*c)) {90gotend = 1;91break;92} else {93/* Invalid character, then fail. */94return (0);95}96}97}9899/* Concoct the address according to the number of parts specified. */100switch (n) {101case 0: /* a -- 32 bits */102103/*104* Nothing is necessary here. Overflow checking was105* already done in strtoul().106*/107break;108case 1: /* a.b -- 8.24 bits */109if (val > 0xffffff || parts[0] > 0xff)110return (0);111val |= parts[0] << 24;112break;113114case 2: /* a.b.c -- 8.8.16 bits */115if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)116return (0);117val |= (parts[0] << 24) | (parts[1] << 16);118break;119120case 3: /* a.b.c.d -- 8.8.8.8 bits */121if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||122parts[2] > 0xff)123return (0);124val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);125break;126}127128if (addr != NULL)129addr->s_addr = htonl(val);130return (1);131}132133134