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