1 /*
2 * Replacement for a missing inet_aton.
3 *
4 * Provides the same functionality as the standard library routine
5 * inet_aton for those platforms that don't have it. inet_aton is
6 * thread-safe.
7 *
8 * The canonical version of this file is maintained in the rra-c-util package,
9 * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
10 *
11 * Written by Russ Allbery <eagle@eyrie.org>
12 * Copyright 2000-2001, 2017, 2019-2020 Russ Allbery <eagle@eyrie.org>
13 * Copyright 2008, 2011, 2014
14 * The Board of Trustees of the Leland Stanford Junior University
15 *
16 * Copying and distribution of this file, with or without modification, are
17 * permitted in any medium without royalty provided the copyright notice and
18 * this notice are preserved. This file is offered as-is, without any
19 * warranty.
20 *
21 * SPDX-License-Identifier: FSFAP
22 */
23
24 #include "config.h"
25 #include "portable/socket.h"
26 #include "portable/system.h"
27
28 /*
29 * If we're running the test suite, rename inet_aton to avoid conflicts with
30 * the system version.
31 */
32 #if TESTING
33 # undef inet_aton
34 # define inet_aton test_inet_aton
35 int test_inet_aton(const char *, struct in_addr *);
36 #endif
37
38 int
inet_aton(const char * s,struct in_addr * addr)39 inet_aton(const char *s, struct in_addr *addr)
40 {
41 unsigned octet[4];
42 uint32_t address;
43 const char *p;
44 unsigned int base, i;
45 unsigned int part = 0;
46
47 if (s == NULL)
48 return 0;
49
50 /*
51 * Step through each period-separated part of the address. If we see
52 * more than four parts, the address is invalid.
53 */
54 for (p = s; *p != 0; part++) {
55 if (part > 3)
56 return 0;
57
58 /*
59 * Determine the base of the section we're looking at. Numbers are
60 * represented the same as in C; octal starts with 0, hex starts
61 * with 0x, and anything else is decimal.
62 */
63 if (*p == '0') {
64 p++;
65 if (*p == 'x') {
66 p++;
67 base = 16;
68 } else {
69 base = 8;
70 }
71 } else {
72 base = 10;
73 }
74
75 /*
76 * Make sure there's actually a number. (A section of just "0"
77 * would set base to 8 and leave us pointing at a period; allow
78 * that.)
79 */
80 if (*p == '.' && base != 8)
81 return 0;
82 octet[part] = 0;
83
84 /*
85 * Now, parse this segment of the address. For each digit, multiply
86 * the result so far by the base and then add the value of the digit.
87 * Be careful of arithmetic overflow in cases where an unsigned long
88 * is 32 bits; we need to detect it *before* we multiply by the base
89 * since otherwise we could overflow and wrap and then not detect the
90 * error.
91 */
92 for (; *p != 0 && *p != '.'; p++) {
93 if (octet[part] > 0xffffffffUL / base)
94 return 0;
95
96 /*
97 * Use a switch statement to parse each digit rather than assuming
98 * ASCII. Probably pointless portability.
99 */
100 /* clang-format off */
101 switch (*p) {
102 case '0': i = 0; break;
103 case '1': i = 1; break;
104 case '2': i = 2; break;
105 case '3': i = 3; break;
106 case '4': i = 4; break;
107 case '5': i = 5; break;
108 case '6': i = 6; break;
109 case '7': i = 7; break;
110 case '8': i = 8; break;
111 case '9': i = 9; break;
112 case 'A': case 'a': i = 10; break;
113 case 'B': case 'b': i = 11; break;
114 case 'C': case 'c': i = 12; break;
115 case 'D': case 'd': i = 13; break;
116 case 'E': case 'e': i = 14; break;
117 case 'F': case 'f': i = 15; break;
118 default: return 0;
119 }
120 /* clang-format on */
121 if (i >= base)
122 return 0;
123 octet[part] = (octet[part] * base) + i;
124 }
125
126 /*
127 * Advance over periods; the top of the loop will increment the count
128 * of parts we've seen. We need a check here to detect an illegal
129 * trailing period.
130 */
131 if (*p == '.') {
132 p++;
133 if (*p == 0)
134 return 0;
135 }
136 }
137 if (part == 0)
138 return 0;
139
140 /* IPv4 allows three types of address specification:
141 *
142 * a.b
143 * a.b.c
144 * a.b.c.d
145 *
146 * If there are fewer than four segments, the final segment accounts for
147 * all of the remaining portion of the address. For example, in the a.b
148 * form, b is the final 24 bits of the address. We also allow a simple
149 * number, which is interpreted as the 32-bit number corresponding to the
150 * full IPv4 address.
151 *
152 * The first for loop below ensures that any initial segments represent
153 * only 8 bits of the address and builds the upper portion of the IPv4
154 * address. Then, the remaining segment is checked to make sure it's no
155 * bigger than the remaining space in the address and then is added into
156 * the result.
157 */
158 address = 0;
159 for (i = 0; i < part - 1; i++) {
160 if (octet[i] > 0xff)
161 return 0;
162 address |= octet[i] << (8 * (3 - i));
163 }
164 if (octet[i] > (0xffffffffUL >> (i * 8)))
165 return 0;
166 address |= octet[i];
167 if (addr != NULL)
168 addr->s_addr = htonl(address);
169 return 1;
170 }
171