diff options
author | Ron Yorston <rmy@pobox.com> | 2021-09-03 13:48:10 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-09-03 13:48:10 +0100 |
commit | dbde555df62c7a574993424c7162cd5ba2250433 (patch) | |
tree | 0f91e8c4f8d5e102464f2db59de7bfbcec8c6106 | |
parent | 39ae0a5dcb115272eb97417ebb43d12d68d1271a (diff) | |
download | busybox-w32-dbde555df62c7a574993424c7162cd5ba2250433.tar.gz busybox-w32-dbde555df62c7a574993424c7162cd5ba2250433.tar.bz2 busybox-w32-dbde555df62c7a574993424c7162cd5ba2250433.zip |
win32: use inet_pton() from musl
Saves 88 bytes.
-rw-r--r-- | win32/inet_pton.c | 258 |
1 files changed, 75 insertions, 183 deletions
diff --git a/win32/inet_pton.c b/win32/inet_pton.c index 310c2ce58..f229a9355 100644 --- a/win32/inet_pton.c +++ b/win32/inet_pton.c | |||
@@ -1,203 +1,95 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 1996-2005, 2007, 2013, 2014, 2016, 2017 Internet Systems Consortium, Inc. ("ISC") | 2 | inet_pton from musl (https://www.musl-libc.org/). |
3 | * | ||
4 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
5 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
7 | */ | ||
8 | 3 | ||
9 | #include "libbb.h" | 4 | MIT licensed: |
10 | 5 | ||
11 | #include <errno.h> | 6 | ---------------------------------------------------------------------- |
12 | #include <string.h> | 7 | Copyright © 2005-2020 Rich Felker, et al. |
13 | 8 | ||
14 | /*% INT16 Size */ | 9 | Permission is hereby granted, free of charge, to any person obtaining |
15 | #define NS_INT16SZ 2 | 10 | a copy of this software and associated documentation files (the |
16 | /*% IPv4 Address Size */ | 11 | "Software"), to deal in the Software without restriction, including |
17 | #define NS_INADDRSZ 4 | 12 | without limitation the rights to use, copy, modify, merge, publish, |
18 | /*% IPv6 Address Size */ | 13 | distribute, sublicense, and/or sell copies of the Software, and to |
19 | #define NS_IN6ADDRSZ 16 | 14 | permit persons to whom the Software is furnished to do so, subject to |
15 | the following conditions: | ||
20 | 16 | ||
21 | /* | 17 | The above copyright notice and this permission notice shall be |
22 | * WARNING: Don't even consider trying to compile this on a system where | 18 | included in all copies or substantial portions of the Software. |
23 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. | ||
24 | */ | ||
25 | 19 | ||
26 | static int inet_pton4(const char *src, unsigned char *dst); | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
27 | #if ENABLE_FEATURE_IPV6 | 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
28 | static int inet_pton6(const char *src, unsigned char *dst); | 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
29 | #endif | 23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 | ---------------------------------------------------------------------- | ||
28 | */ | ||
29 | #include "libbb.h" | ||
30 | 30 | ||
31 | /*% | 31 | static int hexval(unsigned c) |
32 | * convert from presentation format (which usually means ASCII printable) | 32 | { |
33 | * to network format (which is usually some kind of binary format). | 33 | if (c-'0'<10) return c-'0'; |
34 | * \return | 34 | c |= 32; |
35 | * 1 if the address was valid for the specified address family | 35 | if (c-'a'<6) return c-'a'+10; |
36 | * 0 if the address wasn't valid (`dst' is untouched in this case) | 36 | return -1; |
37 | * -1 if some other error occurred (`dst' is untouched in this case, too) | ||
38 | * \author | ||
39 | * Paul Vixie, 1996. | ||
40 | */ | ||
41 | int | ||
42 | inet_pton(int af, const char *src, void *dst) { | ||
43 | switch (af) { | ||
44 | case AF_INET: | ||
45 | return (inet_pton4(src, dst)); | ||
46 | #if ENABLE_FEATURE_IPV6 | ||
47 | case AF_INET6: | ||
48 | return (inet_pton6(src, dst)); | ||
49 | #endif | ||
50 | default: | ||
51 | errno = EAFNOSUPPORT; | ||
52 | return (-1); | ||
53 | } | ||
54 | /* NOTREACHED */ | ||
55 | } | 37 | } |
56 | 38 | ||
57 | /*!\fn static int inet_pton4(const char *src, unsigned char *dst) | 39 | int inet_pton(int af, const char *restrict s, void *restrict a0) |
58 | * \brief | 40 | { |
59 | * like inet_aton() but without all the hexadecimal and shorthand. | 41 | uint16_t ip[8]; |
60 | * \return | 42 | unsigned char *a = a0; |
61 | * 1 if `src' is a valid dotted quad, else 0. | 43 | int i, j, v, d, brk=-1, need_v4=0; |
62 | * \note | ||
63 | * does not touch `dst' unless it's returning 1. | ||
64 | * \author | ||
65 | * Paul Vixie, 1996. | ||
66 | */ | ||
67 | static int | ||
68 | inet_pton4(const char *src, unsigned char *dst) { | ||
69 | static const char digits[] = "0123456789"; | ||
70 | int saw_digit, octets, ch; | ||
71 | unsigned char tmp[NS_INADDRSZ], *tp; | ||
72 | |||
73 | saw_digit = 0; | ||
74 | octets = 0; | ||
75 | *(tp = tmp) = 0; | ||
76 | while ((ch = *src++) != '\0') { | ||
77 | const char *pch; | ||
78 | 44 | ||
79 | if ((pch = strchr(digits, ch)) != NULL) { | 45 | if (af==AF_INET) { |
80 | unsigned int byte = *tp * 10; | 46 | for (i=0; i<4; i++) { |
81 | 47 | for (v=j=0; j<3 && isdigit(s[j]); j++) | |
82 | byte += (int)(pch - digits); | 48 | v = 10*v + s[j]-'0'; |
83 | if (saw_digit && *tp == 0) | 49 | if (j==0 || (j>1 && s[0]=='0') || v>255) return 0; |
84 | return (0); | 50 | a[i] = v; |
85 | if (byte > 255) | 51 | if (s[j]==0 && i==3) return 1; |
86 | return (0); | 52 | if (s[j]!='.') return 0; |
87 | *tp = byte; | 53 | s += j+1; |
88 | if (!saw_digit) { | 54 | } |
89 | if (++octets > 4) | 55 | return 0; |
90 | return (0); | 56 | } else if (af!=AF_INET6) { |
91 | saw_digit = 1; | 57 | errno = EAFNOSUPPORT; |
92 | } | 58 | return -1; |
93 | } else if (ch == '.' && saw_digit) { | ||
94 | if (octets == 4) | ||
95 | return (0); | ||
96 | *++tp = 0; | ||
97 | saw_digit = 0; | ||
98 | } else | ||
99 | return (0); | ||
100 | } | 59 | } |
101 | if (octets < 4) | ||
102 | return (0); | ||
103 | memmove(dst, tmp, NS_INADDRSZ); | ||
104 | return (1); | ||
105 | } | ||
106 | 60 | ||
107 | /*% | 61 | if (*s==':' && *++s!=':') return 0; |
108 | * convert presentation level address to network order binary form. | ||
109 | * \return | ||
110 | * 1 if `src' is a valid [RFC1884 2.2] address, else 0. | ||
111 | * \note | ||
112 | * (1) does not touch `dst' unless it's returning 1. | ||
113 | * \note | ||
114 | * (2) :: in a full address is silently ignored. | ||
115 | * \author | ||
116 | * inspired by Mark Andrews. | ||
117 | * \author | ||
118 | * Paul Vixie, 1996. | ||
119 | */ | ||
120 | #if ENABLE_FEATURE_IPV6 | ||
121 | static int | ||
122 | inet_pton6(const char *src, unsigned char *dst) { | ||
123 | static const char xdigits_l[] = "0123456789abcdef", | ||
124 | xdigits_u[] = "0123456789ABCDEF"; | ||
125 | unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; | ||
126 | const char *xdigits, *curtok; | ||
127 | int ch, seen_xdigits; | ||
128 | unsigned int val; | ||
129 | 62 | ||
130 | memset((tp = tmp), '\0', NS_IN6ADDRSZ); | 63 | for (i=0; ; i++) { |
131 | endp = tp + NS_IN6ADDRSZ; | 64 | if (s[0]==':' && brk<0) { |
132 | colonp = NULL; | 65 | brk=i; |
133 | /* Leading :: requires some special handling. */ | 66 | ip[i&7]=0; |
134 | if (*src == ':') | 67 | if (!*++s) break; |
135 | if (*++src != ':') | 68 | if (i==7) return 0; |
136 | return (0); | ||
137 | curtok = src; | ||
138 | seen_xdigits = 0; | ||
139 | val = 0; | ||
140 | while ((ch = *src++) != '\0') { | ||
141 | const char *pch; | ||
142 | |||
143 | if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) | ||
144 | pch = strchr((xdigits = xdigits_u), ch); | ||
145 | if (pch != NULL) { | ||
146 | val <<= 4; | ||
147 | val |= (pch - xdigits); | ||
148 | if (++seen_xdigits > 4) | ||
149 | return (0); | ||
150 | continue; | 69 | continue; |
151 | } | 70 | } |
152 | if (ch == ':') { | 71 | for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++) |
153 | curtok = src; | 72 | v=16*v+d; |
154 | if (!seen_xdigits) { | 73 | if (j==0) return 0; |
155 | if (colonp) | 74 | ip[i&7] = v; |
156 | return (0); | 75 | if (!s[j] && (brk>=0 || i==7)) break; |
157 | colonp = tp; | 76 | if (i==7) return 0; |
158 | continue; | 77 | if (s[j]!=':') { |
159 | } | 78 | if (s[j]!='.' || (i<6 && brk<0)) return 0; |
160 | if (tp + NS_INT16SZ > endp) | 79 | need_v4=1; |
161 | return (0); | 80 | i++; |
162 | *tp++ = (unsigned char) (val >> 8) & 0xff; | 81 | break; |
163 | *tp++ = (unsigned char) val & 0xff; | ||
164 | seen_xdigits = 0; | ||
165 | val = 0; | ||
166 | continue; | ||
167 | } | 82 | } |
168 | if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && | 83 | s += j+1; |
169 | inet_pton4(curtok, tp) > 0) { | ||
170 | tp += NS_INADDRSZ; | ||
171 | seen_xdigits = 0; | ||
172 | break; /* '\0' was seen by inet_pton4(). */ | ||
173 | } | ||
174 | return (0); | ||
175 | } | 84 | } |
176 | if (seen_xdigits) { | 85 | if (brk>=0) { |
177 | if (tp + NS_INT16SZ > endp) | 86 | memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk)); |
178 | return (0); | 87 | for (j=0; j<7-i; j++) ip[brk+j] = 0; |
179 | *tp++ = (unsigned char) (val >> 8) & 0xff; | ||
180 | *tp++ = (unsigned char) val & 0xff; | ||
181 | } | 88 | } |
182 | if (colonp != NULL) { | 89 | for (j=0; j<8; j++) { |
183 | /* | 90 | *a++ = ip[j]>>8; |
184 | * Since some memmove()'s erroneously fail to handle | 91 | *a++ = ip[j]; |
185 | * overlapping regions, we'll do the shift by hand. | ||
186 | */ | ||
187 | const int n = (int)(tp - colonp); | ||
188 | int i; | ||
189 | |||
190 | if (tp == endp) | ||
191 | return (0); | ||
192 | for (i = 1; i <= n; i++) { | ||
193 | endp[- i] = colonp[n - i]; | ||
194 | colonp[n - i] = 0; | ||
195 | } | ||
196 | tp = endp; | ||
197 | } | 92 | } |
198 | if (tp != endp) | 93 | if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0; |
199 | return (0); | 94 | return 1; |
200 | memmove(dst, tmp, NS_IN6ADDRSZ); | ||
201 | return (1); | ||
202 | } | 95 | } |
203 | #endif | ||