line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/*
|
2
|
|
|
|
|
|
|
inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
Modifications to inet_pton6 allowing IPv4 addresses to appear
|
5
|
|
|
|
|
|
|
throughout, and miscellaneous modifications to inet_pton4, by Tom
|
6
|
|
|
|
|
|
|
Harrison (Copyright (C) 2010).
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
Copyright (C) 2006 Free Software Foundation, Inc.
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
11
|
|
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
12
|
|
|
|
|
|
|
the Free Software Foundation; either version 2, or (at your option)
|
13
|
|
|
|
|
|
|
any later version.
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
16
|
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
|
|
|
|
|
|
GNU General Public License for more details.
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
21
|
|
|
|
|
|
|
along with this program; if not, write to the Free Software Foundation,
|
22
|
|
|
|
|
|
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Copyright (c) 1996,1999 by Internet Software Consortium.
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
Permission to use, copy, modify, and distribute this software for any
|
27
|
|
|
|
|
|
|
purpose with or without fee is hereby granted, provided that the above
|
28
|
|
|
|
|
|
|
copyright notice and this permission notice appear in all copies.
|
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
31
|
|
|
|
|
|
|
ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
32
|
|
|
|
|
|
|
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
33
|
|
|
|
|
|
|
CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
34
|
|
|
|
|
|
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
35
|
|
|
|
|
|
|
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
36
|
|
|
|
|
|
|
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
37
|
|
|
|
|
|
|
SOFTWARE.
|
38
|
|
|
|
|
|
|
*/
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
#include
|
41
|
|
|
|
|
|
|
#include
|
42
|
|
|
|
|
|
|
#include
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
#define NS_INADDRSZ 4
|
45
|
|
|
|
|
|
|
#define NS_IN6ADDRSZ 16
|
46
|
|
|
|
|
|
|
#define NS_INT16SZ 2
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
int inet_pton4 (const char *src, unsigned char *dst);
|
49
|
|
|
|
|
|
|
int inet_pton6 (const char *src, unsigned char *dst);
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
/* int
|
52
|
|
|
|
|
|
|
* inet_pton4(src, dst)
|
53
|
|
|
|
|
|
|
* like inet_aton() but without all the hexadecimal, octal (with the
|
54
|
|
|
|
|
|
|
* exception of 0) and shorthand.
|
55
|
|
|
|
|
|
|
* return:
|
56
|
|
|
|
|
|
|
* 1 if `src' is a valid dotted quad, else 0.
|
57
|
|
|
|
|
|
|
* notice:
|
58
|
|
|
|
|
|
|
* does not touch `dst' unless it's returning 1.
|
59
|
|
|
|
|
|
|
* author:
|
60
|
|
|
|
|
|
|
* Paul Vixie, 1996.
|
61
|
|
|
|
|
|
|
* (Some modifications by Tom Harrison, 2010.)
|
62
|
|
|
|
|
|
|
*/
|
63
|
|
|
|
|
|
|
int
|
64
|
2205
|
|
|
|
|
|
inet_pton4 (const char *src, unsigned char *dst)
|
65
|
|
|
|
|
|
|
{
|
66
|
|
|
|
|
|
|
int saw_digit, octets, ch;
|
67
|
|
|
|
|
|
|
unsigned char tmp[NS_INADDRSZ], *tp;
|
68
|
|
|
|
|
|
|
|
69
|
2205
|
|
|
|
|
|
memset(tmp, 0, NS_INADDRSZ);
|
70
|
2205
|
|
|
|
|
|
saw_digit = 0;
|
71
|
2205
|
|
|
|
|
|
octets = 0;
|
72
|
2205
|
|
|
|
|
|
*(tp = tmp) = 0;
|
73
|
|
|
|
|
|
|
|
74
|
30236
|
100
|
|
|
|
|
while ((ch = *src++) != '\0') {
|
75
|
49543
|
100
|
|
|
|
|
if (ch >= '0' && ch <= '9') {
|
|
|
100
|
|
|
|
|
|
76
|
21506
|
|
|
|
|
|
unsigned n = *tp * 10 + (ch - '0');
|
77
|
|
|
|
|
|
|
|
78
|
21506
|
100
|
|
|
|
|
if (saw_digit && *tp == 0) {
|
|
|
100
|
|
|
|
|
|
79
|
1
|
|
|
|
|
|
return 0;
|
80
|
|
|
|
|
|
|
}
|
81
|
21505
|
100
|
|
|
|
|
if (n > 255) {
|
82
|
2
|
|
|
|
|
|
return 0;
|
83
|
|
|
|
|
|
|
}
|
84
|
21503
|
|
|
|
|
|
*tp = n;
|
85
|
21503
|
100
|
|
|
|
|
if (!saw_digit) {
|
86
|
8727
|
|
|
|
|
|
++octets;
|
87
|
8727
|
|
|
|
|
|
saw_digit = 1;
|
88
|
|
|
|
|
|
|
}
|
89
|
6534
|
100
|
|
|
|
|
} else if (ch == '.' && saw_digit) {
|
|
|
50
|
|
|
|
|
|
90
|
6530
|
100
|
|
|
|
|
if (octets == 4) {
|
91
|
2
|
|
|
|
|
|
return 0;
|
92
|
|
|
|
|
|
|
}
|
93
|
6528
|
|
|
|
|
|
++tp;
|
94
|
6528
|
|
|
|
|
|
saw_digit = 0;
|
95
|
|
|
|
|
|
|
} else {
|
96
|
4
|
|
|
|
|
|
return 0;
|
97
|
|
|
|
|
|
|
}
|
98
|
|
|
|
|
|
|
}
|
99
|
|
|
|
|
|
|
|
100
|
2196
|
|
|
|
|
|
memcpy(dst, tmp, NS_INADDRSZ);
|
101
|
2205
|
|
|
|
|
|
return 1;
|
102
|
|
|
|
|
|
|
}
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
/* int
|
105
|
|
|
|
|
|
|
* inet_pton6(src, dst)
|
106
|
|
|
|
|
|
|
* convert presentation level address to network order binary form.
|
107
|
|
|
|
|
|
|
* return:
|
108
|
|
|
|
|
|
|
* 1 if `src' is a valid IPv6 address (may contain IPv4 addresses
|
109
|
|
|
|
|
|
|
* in any position), else 0.
|
110
|
|
|
|
|
|
|
* notice:
|
111
|
|
|
|
|
|
|
* (1) does not touch `dst' unless it's returning 1.
|
112
|
|
|
|
|
|
|
* (2) :: in a full address is silently ignored.
|
113
|
|
|
|
|
|
|
* credit:
|
114
|
|
|
|
|
|
|
* inspired by Mark Andrews.
|
115
|
|
|
|
|
|
|
* author:
|
116
|
|
|
|
|
|
|
* Paul Vixie, 1996.
|
117
|
|
|
|
|
|
|
* (Modifications allowing IPv4 addresses to appear throughout
|
118
|
|
|
|
|
|
|
* by Tom Harrison, 2010.)
|
119
|
|
|
|
|
|
|
*/
|
120
|
|
|
|
|
|
|
int
|
121
|
839
|
|
|
|
|
|
inet_pton6 (const char *src, unsigned char *dst)
|
122
|
|
|
|
|
|
|
{
|
123
|
|
|
|
|
|
|
static const char xdigits[] = "0123456789abcdef";
|
124
|
|
|
|
|
|
|
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
125
|
|
|
|
|
|
|
const char *ipv4_endp;
|
126
|
|
|
|
|
|
|
char ipv4[16];
|
127
|
|
|
|
|
|
|
int diff;
|
128
|
|
|
|
|
|
|
const char *curtok;
|
129
|
|
|
|
|
|
|
int ch, saw_xdigit;
|
130
|
|
|
|
|
|
|
unsigned val;
|
131
|
|
|
|
|
|
|
|
132
|
839
|
|
|
|
|
|
tp = (unsigned char *) memset (tmp, '\0', NS_IN6ADDRSZ);
|
133
|
839
|
|
|
|
|
|
endp = tp + NS_IN6ADDRSZ;
|
134
|
839
|
|
|
|
|
|
colonp = NULL;
|
135
|
|
|
|
|
|
|
/* Leading :: requires some special handling. */
|
136
|
839
|
100
|
|
|
|
|
if (*src == ':') {
|
137
|
40
|
100
|
|
|
|
|
if (*++src != ':') {
|
138
|
1
|
|
|
|
|
|
return 0;
|
139
|
|
|
|
|
|
|
}
|
140
|
|
|
|
|
|
|
}
|
141
|
838
|
|
|
|
|
|
curtok = src;
|
142
|
838
|
|
|
|
|
|
saw_xdigit = 0;
|
143
|
838
|
|
|
|
|
|
val = 0;
|
144
|
29352
|
100
|
|
|
|
|
while ((ch = tolower (*src++)) != '\0') {
|
145
|
|
|
|
|
|
|
const char *pch;
|
146
|
|
|
|
|
|
|
|
147
|
28525
|
|
|
|
|
|
pch = strchr (xdigits, ch);
|
148
|
28525
|
100
|
|
|
|
|
if (pch != NULL) {
|
149
|
23205
|
|
|
|
|
|
val <<= 4;
|
150
|
23205
|
|
|
|
|
|
val |= (pch - xdigits);
|
151
|
23205
|
100
|
|
|
|
|
if (val > 0xffff) {
|
152
|
1
|
|
|
|
|
|
return 0;
|
153
|
|
|
|
|
|
|
}
|
154
|
23204
|
|
|
|
|
|
saw_xdigit = 1;
|
155
|
23204
|
|
|
|
|
|
continue;
|
156
|
|
|
|
|
|
|
}
|
157
|
5320
|
100
|
|
|
|
|
if (ch == ':') {
|
158
|
5300
|
|
|
|
|
|
curtok = src;
|
159
|
5300
|
100
|
|
|
|
|
if (!saw_xdigit) {
|
160
|
112
|
100
|
|
|
|
|
if (colonp) {
|
161
|
1
|
|
|
|
|
|
return 0;
|
162
|
|
|
|
|
|
|
}
|
163
|
111
|
|
|
|
|
|
colonp = tp;
|
164
|
111
|
|
|
|
|
|
continue;
|
165
|
5188
|
100
|
|
|
|
|
} else if (*src == '\0') {
|
166
|
1
|
|
|
|
|
|
return 0;
|
167
|
|
|
|
|
|
|
}
|
168
|
5187
|
100
|
|
|
|
|
if (tp + NS_INT16SZ > endp) {
|
169
|
2
|
|
|
|
|
|
return 0;
|
170
|
|
|
|
|
|
|
}
|
171
|
5185
|
|
|
|
|
|
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
172
|
5185
|
|
|
|
|
|
*tp++ = (unsigned char) val & 0xff;
|
173
|
5185
|
|
|
|
|
|
saw_xdigit = 0;
|
174
|
5185
|
|
|
|
|
|
val = 0;
|
175
|
5185
|
|
|
|
|
|
continue;
|
176
|
|
|
|
|
|
|
}
|
177
|
20
|
100
|
|
|
|
|
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp)) {
|
|
|
100
|
|
|
|
|
|
178
|
|
|
|
|
|
|
/* Find the next : from curtok, copy from curtok to that
|
179
|
|
|
|
|
|
|
* point to ipv4, if it's IPv4 all is good. If the : is not found,
|
180
|
|
|
|
|
|
|
* it terminates, so check it directly. */
|
181
|
16
|
|
|
|
|
|
ipv4_endp = strchr(curtok, ':');
|
182
|
16
|
100
|
|
|
|
|
if (ipv4_endp) {
|
183
|
15
|
|
|
|
|
|
diff = ipv4_endp - curtok;
|
184
|
15
|
100
|
|
|
|
|
if (diff > 15) {
|
185
|
1
|
|
|
|
|
|
return 0;
|
186
|
|
|
|
|
|
|
}
|
187
|
14
|
|
|
|
|
|
memcpy(ipv4, curtok, diff);
|
188
|
14
|
|
|
|
|
|
ipv4[diff] = '\0';
|
189
|
14
|
|
|
|
|
|
diff = inet_pton4(ipv4, tp);
|
190
|
|
|
|
|
|
|
} else {
|
191
|
1
|
|
|
|
|
|
diff = inet_pton4(curtok, tp);
|
192
|
|
|
|
|
|
|
}
|
193
|
15
|
50
|
|
|
|
|
if (diff) {
|
194
|
15
|
|
|
|
|
|
val = (tp[2] << 8) | tp[3];
|
195
|
15
|
|
|
|
|
|
tp += 2;
|
196
|
15
|
|
|
|
|
|
saw_xdigit=1;
|
197
|
15
|
100
|
|
|
|
|
if (ipv4_endp) {
|
198
|
14
|
|
|
|
|
|
src = ipv4_endp;
|
199
|
14
|
|
|
|
|
|
continue;
|
200
|
|
|
|
|
|
|
} else {
|
201
|
1
|
|
|
|
|
|
saw_xdigit=0;
|
202
|
1
|
|
|
|
|
|
tp += 2;
|
203
|
1
|
|
|
|
|
|
break;
|
204
|
|
|
|
|
|
|
}
|
205
|
|
|
|
|
|
|
}
|
206
|
|
|
|
|
|
|
}
|
207
|
4
|
|
|
|
|
|
return 0;
|
208
|
|
|
|
|
|
|
}
|
209
|
828
|
100
|
|
|
|
|
if (saw_xdigit) {
|
210
|
734
|
100
|
|
|
|
|
if (tp + NS_INT16SZ > endp) {
|
211
|
1
|
|
|
|
|
|
return 0;
|
212
|
|
|
|
|
|
|
}
|
213
|
733
|
|
|
|
|
|
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
214
|
733
|
|
|
|
|
|
*tp++ = (unsigned char) val & 0xff;
|
215
|
|
|
|
|
|
|
}
|
216
|
827
|
100
|
|
|
|
|
if (colonp != NULL) {
|
217
|
|
|
|
|
|
|
/*
|
218
|
|
|
|
|
|
|
* Since some memmove()'s erroneously fail to handle
|
219
|
|
|
|
|
|
|
* overlapping regions, we'll do the shift by hand.
|
220
|
|
|
|
|
|
|
*/
|
221
|
110
|
|
|
|
|
|
const int n = tp - colonp;
|
222
|
|
|
|
|
|
|
int i;
|
223
|
|
|
|
|
|
|
|
224
|
110
|
100
|
|
|
|
|
if (tp == endp) {
|
225
|
1
|
|
|
|
|
|
return 0;
|
226
|
|
|
|
|
|
|
}
|
227
|
165
|
100
|
|
|
|
|
for (i = 1; i <= n; i++) {
|
228
|
56
|
|
|
|
|
|
endp[-i] = colonp[n - i];
|
229
|
56
|
|
|
|
|
|
colonp[n - i] = 0;
|
230
|
|
|
|
|
|
|
}
|
231
|
109
|
|
|
|
|
|
tp = endp;
|
232
|
|
|
|
|
|
|
}
|
233
|
|
|
|
|
|
|
|
234
|
872
|
100
|
|
|
|
|
while (tp < endp) {
|
235
|
46
|
|
|
|
|
|
*(tp++) = 0;
|
236
|
|
|
|
|
|
|
}
|
237
|
826
|
|
|
|
|
|
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
238
|
839
|
|
|
|
|
|
return 1;
|
239
|
|
|
|
|
|
|
}
|