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 | * Written by Russ Allbery <rra@stanford.edu> |
---|
9 | * This work is hereby placed in the public domain by its author. |
---|
10 | */ |
---|
11 | |
---|
12 | #include <config.h> |
---|
13 | #include <portable/system.h> |
---|
14 | #include <portable/socket.h> |
---|
15 | |
---|
16 | /* |
---|
17 | * If we're running the test suite, rename inet_ntoa to avoid conflicts with |
---|
18 | * the system version. |
---|
19 | */ |
---|
20 | #if TESTING |
---|
21 | # define inet_aton test_inet_aton |
---|
22 | int test_inet_aton(const char *, struct in_addr *); |
---|
23 | #endif |
---|
24 | |
---|
25 | int |
---|
26 | inet_aton(const char *s, struct in_addr *addr) |
---|
27 | { |
---|
28 | unsigned long octet[4], address; |
---|
29 | const char *p; |
---|
30 | int base, i; |
---|
31 | int part = 0; |
---|
32 | |
---|
33 | if (s == NULL) |
---|
34 | return 0; |
---|
35 | |
---|
36 | /* |
---|
37 | * Step through each period-separated part of the address. If we see |
---|
38 | * more than four parts, the address is invalid. |
---|
39 | */ |
---|
40 | for (p = s; *p != 0; part++) { |
---|
41 | if (part > 3) |
---|
42 | return 0; |
---|
43 | |
---|
44 | /* |
---|
45 | * Determine the base of the section we're looking at. Numbers are |
---|
46 | * represented the same as in C; octal starts with 0, hex starts |
---|
47 | * with 0x, and anything else is decimal. |
---|
48 | */ |
---|
49 | if (*p == '0') { |
---|
50 | p++; |
---|
51 | if (*p == 'x') { |
---|
52 | p++; |
---|
53 | base = 16; |
---|
54 | } else { |
---|
55 | base = 8; |
---|
56 | } |
---|
57 | } else { |
---|
58 | base = 10; |
---|
59 | } |
---|
60 | |
---|
61 | /* |
---|
62 | * Make sure there's actually a number. (A section of just "0" |
---|
63 | * would set base to 8 and leave us pointing at a period; allow |
---|
64 | * that.) |
---|
65 | */ |
---|
66 | if (*p == '.' && base != 8) |
---|
67 | return 0; |
---|
68 | octet[part] = 0; |
---|
69 | |
---|
70 | /* |
---|
71 | * Now, parse this segment of the address. For each digit, multiply |
---|
72 | * the result so far by the base and then add the value of the digit. |
---|
73 | * Be careful of arithmetic overflow in cases where an unsigned long |
---|
74 | * is 32 bits; we need to detect it *before* we multiply by the base |
---|
75 | * since otherwise we could overflow and wrap and then not detect the |
---|
76 | * error. |
---|
77 | */ |
---|
78 | for (; *p != 0 && *p != '.'; p++) { |
---|
79 | if (octet[part] > 0xffffffffUL / base) |
---|
80 | return 0; |
---|
81 | |
---|
82 | /* |
---|
83 | * Use a switch statement to parse each digit rather than assuming |
---|
84 | * ASCII. Probably pointless portability. |
---|
85 | */ |
---|
86 | switch (*p) { |
---|
87 | case '0': i = 0; break; |
---|
88 | case '1': i = 1; break; |
---|
89 | case '2': i = 2; break; |
---|
90 | case '3': i = 3; break; |
---|
91 | case '4': i = 4; break; |
---|
92 | case '5': i = 5; break; |
---|
93 | case '6': i = 6; break; |
---|
94 | case '7': i = 7; break; |
---|
95 | case '8': i = 8; break; |
---|
96 | case '9': i = 9; break; |
---|
97 | case 'A': case 'a': i = 10; break; |
---|
98 | case 'B': case 'b': i = 11; break; |
---|
99 | case 'C': case 'c': i = 12; break; |
---|
100 | case 'D': case 'd': i = 13; break; |
---|
101 | case 'E': case 'e': i = 14; break; |
---|
102 | case 'F': case 'f': i = 15; break; |
---|
103 | default: return 0; |
---|
104 | } |
---|
105 | if (i >= base) |
---|
106 | return 0; |
---|
107 | octet[part] = (octet[part] * base) + i; |
---|
108 | } |
---|
109 | |
---|
110 | /* |
---|
111 | * Advance over periods; the top of the loop will increment the count |
---|
112 | * of parts we've seen. We need a check here to detect an illegal |
---|
113 | * trailing period. |
---|
114 | */ |
---|
115 | if (*p == '.') { |
---|
116 | p++; |
---|
117 | if (*p == 0) |
---|
118 | return 0; |
---|
119 | } |
---|
120 | } |
---|
121 | if (part == 0) |
---|
122 | return 0; |
---|
123 | |
---|
124 | /* IPv4 allows three types of address specification: |
---|
125 | * |
---|
126 | * a.b |
---|
127 | * a.b.c |
---|
128 | * a.b.c.d |
---|
129 | * |
---|
130 | * If there are fewer than four segments, the final segment accounts for |
---|
131 | * all of the remaining portion of the address. For example, in the a.b |
---|
132 | * form, b is the final 24 bits of the address. We also allow a simple |
---|
133 | * number, which is interpreted as the 32-bit number corresponding to the |
---|
134 | * full IPv4 address. |
---|
135 | * |
---|
136 | * The first for loop below ensures that any initial segments represent |
---|
137 | * only 8 bits of the address and builds the upper portion of the IPv4 |
---|
138 | * address. Then, the remaining segment is checked to make sure it's no |
---|
139 | * bigger than the remaining space in the address and then is added into |
---|
140 | * the result. |
---|
141 | */ |
---|
142 | address = 0; |
---|
143 | for (i = 0; i < part - 1; i++) { |
---|
144 | if (octet[i] > 0xff) |
---|
145 | return 0; |
---|
146 | address |= octet[i] << (8 * (3 - i)); |
---|
147 | } |
---|
148 | if (octet[i] > (0xffffffffUL >> (i * 8))) |
---|
149 | return 0; |
---|
150 | address |= octet[i]; |
---|
151 | if (addr != NULL) |
---|
152 | addr->s_addr = htonl(address); |
---|
153 | return 1; |
---|
154 | } |
---|