Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/libkern/inet_aton.c
34820 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2001 Charles Mott <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/param.h>
30
#include <sys/ctype.h>
31
#include <sys/limits.h>
32
#include <sys/systm.h>
33
34
#include <netinet/in.h>
35
36
int
37
inet_aton(const char *cp, struct in_addr *addr)
38
{
39
u_long parts[4];
40
in_addr_t val;
41
const char *c;
42
char *endptr;
43
int gotend, n;
44
45
c = (const char *)cp;
46
n = 0;
47
48
/*
49
* Run through the string, grabbing numbers until
50
* the end of the string, or some error
51
*/
52
gotend = 0;
53
while (!gotend) {
54
unsigned long l;
55
56
l = strtoul(c, &endptr, 0);
57
58
if (l == ULONG_MAX || (l == 0 && endptr == c))
59
return (0);
60
61
val = (in_addr_t)l;
62
63
/*
64
* If the whole string is invalid, endptr will equal
65
* c.. this way we can make sure someone hasn't
66
* gone '.12' or something which would get past
67
* the next check.
68
*/
69
if (endptr == c)
70
return (0);
71
parts[n] = val;
72
c = endptr;
73
74
/* Check the next character past the previous number's end */
75
switch (*c) {
76
case '.' :
77
78
/* Make sure we only do 3 dots .. */
79
if (n == 3) /* Whoops. Quit. */
80
return (0);
81
n++;
82
c++;
83
break;
84
85
case '\0':
86
gotend = 1;
87
break;
88
89
default:
90
if (isspace((unsigned char)*c)) {
91
gotend = 1;
92
break;
93
} else {
94
/* Invalid character, then fail. */
95
return (0);
96
}
97
}
98
}
99
100
/* Concoct the address according to the number of parts specified. */
101
switch (n) {
102
case 0: /* a -- 32 bits */
103
104
/*
105
* Nothing is necessary here. Overflow checking was
106
* already done in strtoul().
107
*/
108
break;
109
case 1: /* a.b -- 8.24 bits */
110
if (val > 0xffffff || parts[0] > 0xff)
111
return (0);
112
val |= parts[0] << 24;
113
break;
114
115
case 2: /* a.b.c -- 8.8.16 bits */
116
if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
117
return (0);
118
val |= (parts[0] << 24) | (parts[1] << 16);
119
break;
120
121
case 3: /* a.b.c.d -- 8.8.8.8 bits */
122
if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
123
parts[2] > 0xff)
124
return (0);
125
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
126
break;
127
}
128
129
if (addr != NULL)
130
addr->s_addr = htonl(val);
131
return (1);
132
}
133
134