aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-09-03 13:48:10 +0100
committerRon Yorston <rmy@pobox.com>2021-09-03 13:48:10 +0100
commitdbde555df62c7a574993424c7162cd5ba2250433 (patch)
tree0f91e8c4f8d5e102464f2db59de7bfbcec8c6106
parent39ae0a5dcb115272eb97417ebb43d12d68d1271a (diff)
downloadbusybox-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.c258
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> 7Copyright © 2005-2020 Rich Felker, et al.
13 8
14/*% INT16 Size */ 9Permission is hereby granted, free of charge, to any person obtaining
15#define NS_INT16SZ 2 10a 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 12without limitation the rights to use, copy, modify, merge, publish,
18/*% IPv6 Address Size */ 13distribute, sublicense, and/or sell copies of the Software, and to
19#define NS_IN6ADDRSZ 16 14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
20 16
21/* 17The above copyright notice and this permission notice shall be
22 * WARNING: Don't even consider trying to compile this on a system where 18included 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
26static int inet_pton4(const char *src, unsigned char *dst); 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27#if ENABLE_FEATURE_IPV6 21EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28static int inet_pton6(const char *src, unsigned char *dst); 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29#endif 23IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27----------------------------------------------------------------------
28*/
29#include "libbb.h"
30 30
31/*% 31static 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 */
41int
42inet_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) 39int 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 */
67static int
68inet_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
121static int
122inet_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