aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-02-22 09:01:23 +0000
committerRon Yorston <rmy@pobox.com>2018-02-22 09:01:23 +0000
commitb407c7256674c12c3d81fa11b01b5739eccd43dd (patch)
treedf0b079f535f9bfcf42af793cb26afeb1384f384 /win32
parent5b5cb69bf3e16e4170d4206621682a12d441c87f (diff)
downloadbusybox-w32-b407c7256674c12c3d81fa11b01b5739eccd43dd.tar.gz
busybox-w32-b407c7256674c12c3d81fa11b01b5739eccd43dd.tar.bz2
busybox-w32-b407c7256674c12c3d81fa11b01b5739eccd43dd.zip
win32: import inet_pton.c from ISC BIND
The copy of inet_pton.c imported from gnulib was licensed under GPL3 which is incompatible with the GPL2-only licence of BusyBox. Import an MPL2-licensed version of this file from ISC BIND git master as of this date.
Diffstat (limited to 'win32')
-rw-r--r--win32/inet_pton.c413
1 files changed, 182 insertions, 231 deletions
diff --git a/win32/inet_pton.c b/win32/inet_pton.c
index ec87abec5..ba8770d2c 100644
--- a/win32/inet_pton.c
+++ b/win32/inet_pton.c
@@ -1,255 +1,206 @@
1/* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
2
3 Copyright (C) 2006, 2008-2015 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* 1/*
19 * Copyright (c) 1996,1999 by Internet Software Consortium. 2 * Copyright (C) 1996-2005, 2007, 2013, 2014, 2016, 2017 Internet Systems Consortium, Inc. ("ISC")
20 * 3 *
21 * Permission to use, copy, modify, and distribute this software for any 4 * This Source Code Form is subject to the terms of the Mozilla Public
22 * purpose with or without fee is hereby granted, provided that the above 5 * License, v. 2.0. If a copy of the MPL was not distributed with this
23 * copyright notice and this permission notice appear in all copies. 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
26 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
28 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
29 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
30 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
31 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
32 * SOFTWARE.
33 */ 7 */
34 8
35#include "libbb.h" 9/*! \file */
10
11#if defined(LIBC_SCCS) && !defined(lint)
12static char rcsid[] =
13 "$Id: inet_pton.c,v 1.19 2007/06/19 23:47:17 tbox Exp $";
14#endif /* LIBC_SCCS and not lint */
36 15
37/* Specification. */ 16#include <config.h>
38#include <arpa/inet.h>
39 17
40# include <ctype.h> 18#include <errno.h>
41# include <string.h> 19#include <string.h>
42# include <errno.h>
43 20
44# define NS_INADDRSZ 4 21#include <isc/net.h>
45# define NS_IN6ADDRSZ 16 22
46# define NS_INT16SZ 2 23/*% INT16 Size */
47# define HAVE_IPV6 1 24#define NS_INT16SZ 2
25/*% IPv4 Address Size */
26#define NS_INADDRSZ 4
27/*% IPv6 Address Size */
28#define NS_IN6ADDRSZ 16
48 29
49/* 30/*
50 * WARNING: Don't even consider trying to compile this on a system where 31 * WARNING: Don't even consider trying to compile this on a system where
51 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. 32 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
52 */ 33 */
53 34
54static int inet_pton4 (const char *src, unsigned char *dst); 35static int inet_pton4(const char *src, unsigned char *dst);
55# if HAVE_IPV6 36static int inet_pton6(const char *src, unsigned char *dst);
56static int inet_pton6 (const char *src, unsigned char *dst); 37
57# endif 38/*%
58 39 * convert from presentation format (which usually means ASCII printable)
59/* int 40 * to network format (which is usually some kind of binary format).
60 * inet_pton(af, src, dst) 41 * \return
61 * convert from presentation format (which usually means ASCII printable) 42 * 1 if the address was valid for the specified address family
62 * to network format (which is usually some kind of binary format). 43 * 0 if the address wasn't valid (`dst' is untouched in this case)
63 * return: 44 * -1 if some other error occurred (`dst' is untouched in this case, too)
64 * 1 if the address was valid for the specified address family 45 * \author
65 * 0 if the address wasn't valid ('dst' is untouched in this case) 46 * Paul Vixie, 1996.
66 * -1 if some other error occurred ('dst' is untouched in this case, too)
67 * author:
68 * Paul Vixie, 1996.
69 */ 47 */
70int 48int
71inet_pton (int af, const char *restrict src, void *restrict dst) 49isc_net_pton(int af, const char *src, void *dst) {
72{ 50 switch (af) {
73 switch (af) 51 case AF_INET:
74 { 52 return (inet_pton4(src, dst));
75 case AF_INET: 53 case AF_INET6:
76 return (inet_pton4 (src, dst)); 54 return (inet_pton6(src, dst));
77 55 default:
78# if HAVE_IPV6 56 errno = EAFNOSUPPORT;
79 case AF_INET6: 57 return (-1);
80 return (inet_pton6 (src, dst)); 58 }
81# endif 59 /* NOTREACHED */
82
83 default:
84 errno = EAFNOSUPPORT;
85 return (-1);
86 }
87 /* NOTREACHED */
88} 60}
89 61
90/* int 62/*!\fn static int inet_pton4(const char *src, unsigned char *dst)
91 * inet_pton4(src, dst) 63 * \brief
92 * like inet_aton() but without all the hexadecimal, octal (with the 64 * like inet_aton() but without all the hexadecimal and shorthand.
93 * exception of 0) and shorthand. 65 * \return
94 * return: 66 * 1 if `src' is a valid dotted quad, else 0.
95 * 1 if 'src' is a valid dotted quad, else 0. 67 * \note
96 * notice: 68 * does not touch `dst' unless it's returning 1.
97 * does not touch 'dst' unless it's returning 1. 69 * \author
98 * author: 70 * Paul Vixie, 1996.
99 * Paul Vixie, 1996.
100 */ 71 */
101static int 72static int
102inet_pton4 (const char *restrict src, unsigned char *restrict dst) 73inet_pton4(const char *src, unsigned char *dst) {
103{ 74 static const char digits[] = "0123456789";
104 int saw_digit, octets, ch; 75 int saw_digit, octets, ch;
105 unsigned char tmp[NS_INADDRSZ], *tp; 76 unsigned char tmp[NS_INADDRSZ], *tp;
106 77
107 saw_digit = 0; 78 saw_digit = 0;
108 octets = 0; 79 octets = 0;
109 *(tp = tmp) = 0; 80 *(tp = tmp) = 0;
110 while ((ch = *src++) != '\0') 81 while ((ch = *src++) != '\0') {
111 { 82 const char *pch;
112 83
113 if (ch >= '0' && ch <= '9') 84 if ((pch = strchr(digits, ch)) != NULL) {
114 { 85 unsigned int byte = *tp * 10;
115 unsigned new = *tp * 10 + (ch - '0'); 86
116 87 byte += (int)(pch - digits);
117 if (saw_digit && *tp == 0) 88 if (saw_digit && *tp == 0)
118 return (0); 89 return (0);
119 if (new > 255) 90 if (byte > 255)
120 return (0); 91 return (0);
121 *tp = new; 92 *tp = byte;
122 if (!saw_digit) 93 if (!saw_digit) {
123 { 94 if (++octets > 4)
124 if (++octets > 4) 95 return (0);
125 return (0); 96 saw_digit = 1;
126 saw_digit = 1; 97 }
127 } 98 } else if (ch == '.' && saw_digit) {
128 } 99 if (octets == 4)
129 else if (ch == '.' && saw_digit) 100 return (0);
130 { 101 *++tp = 0;
131 if (octets == 4) 102 saw_digit = 0;
132 return (0); 103 } else
133 *++tp = 0; 104 return (0);
134 saw_digit = 0; 105 }
135 } 106 if (octets < 4)
136 else 107 return (0);
137 return (0); 108 memmove(dst, tmp, NS_INADDRSZ);
138 } 109 return (1);
139 if (octets < 4)
140 return (0);
141 memcpy (dst, tmp, NS_INADDRSZ);
142 return (1);
143} 110}
144 111
145# if HAVE_IPV6 112/*%
146 113 * convert presentation level address to network order binary form.
147/* int 114 * \return
148 * inet_pton6(src, dst) 115 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
149 * convert presentation level address to network order binary form. 116 * \note
150 * return: 117 * (1) does not touch `dst' unless it's returning 1.
151 * 1 if 'src' is a valid [RFC1884 2.2] address, else 0. 118 * \note
152 * notice: 119 * (2) :: in a full address is silently ignored.
153 * (1) does not touch 'dst' unless it's returning 1. 120 * \author
154 * (2) :: in a full address is silently ignored. 121 * inspired by Mark Andrews.
155 * credit: 122 * \author
156 * inspired by Mark Andrews. 123 * Paul Vixie, 1996.
157 * author:
158 * Paul Vixie, 1996.
159 */ 124 */
160static int 125static int
161inet_pton6 (const char *restrict src, unsigned char *restrict dst) 126inet_pton6(const char *src, unsigned char *dst) {
162{ 127 static const char xdigits_l[] = "0123456789abcdef",
163 static const char xdigits[] = "0123456789abcdef"; 128 xdigits_u[] = "0123456789ABCDEF";
164 unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; 129 unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
165 const char *curtok; 130 const char *xdigits, *curtok;
166 int ch, saw_xdigit; 131 int ch, seen_xdigits;
167 unsigned val; 132 unsigned int val;
168 133
169 tp = memset (tmp, '\0', NS_IN6ADDRSZ); 134 memset((tp = tmp), '\0', NS_IN6ADDRSZ);
170 endp = tp + NS_IN6ADDRSZ; 135 endp = tp + NS_IN6ADDRSZ;
171 colonp = NULL; 136 colonp = NULL;
172 /* Leading :: requires some special handling. */ 137 /* Leading :: requires some special handling. */
173 if (*src == ':') 138 if (*src == ':')
174 if (*++src != ':') 139 if (*++src != ':')
175 return (0); 140 return (0);
176 curtok = src; 141 curtok = src;
177 saw_xdigit = 0; 142 seen_xdigits = 0;
178 val = 0; 143 val = 0;
179 while ((ch = tolower (*src++)) != '\0') 144 while ((ch = *src++) != '\0') {
180 { 145 const char *pch;
181 const char *pch; 146
182 147 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
183 pch = strchr (xdigits, ch); 148 pch = strchr((xdigits = xdigits_u), ch);
184 if (pch != NULL) 149 if (pch != NULL) {
185 { 150 val <<= 4;
186 val <<= 4; 151 val |= (pch - xdigits);
187 val |= (pch - xdigits); 152 if (++seen_xdigits > 4)
188 if (val > 0xffff) 153 return (0);
189 return (0); 154 continue;
190 saw_xdigit = 1; 155 }
191 continue; 156 if (ch == ':') {
192 } 157 curtok = src;
193 if (ch == ':') 158 if (!seen_xdigits) {
194 { 159 if (colonp)
195 curtok = src; 160 return (0);
196 if (!saw_xdigit) 161 colonp = tp;
197 { 162 continue;
198 if (colonp) 163 }
199 return (0); 164 if (tp + NS_INT16SZ > endp)
200 colonp = tp; 165 return (0);
201 continue; 166 *tp++ = (unsigned char) (val >> 8) & 0xff;
202 } 167 *tp++ = (unsigned char) val & 0xff;
203 else if (*src == '\0') 168 seen_xdigits = 0;
204 { 169 val = 0;
205 return (0); 170 continue;
206 } 171 }
207 if (tp + NS_INT16SZ > endp) 172 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
208 return (0); 173 inet_pton4(curtok, tp) > 0) {
209 *tp++ = (u_char) (val >> 8) & 0xff; 174 tp += NS_INADDRSZ;
210 *tp++ = (u_char) val & 0xff; 175 seen_xdigits = 0;
211 saw_xdigit = 0; 176 break; /* '\0' was seen by inet_pton4(). */
212 val = 0; 177 }
213 continue; 178 return (0);
214 } 179 }
215 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && 180 if (seen_xdigits) {
216 inet_pton4 (curtok, tp) > 0) 181 if (tp + NS_INT16SZ > endp)
217 { 182 return (0);
218 tp += NS_INADDRSZ; 183 *tp++ = (unsigned char) (val >> 8) & 0xff;
219 saw_xdigit = 0; 184 *tp++ = (unsigned char) val & 0xff;
220 break; /* '\0' was seen by inet_pton4(). */ 185 }
221 } 186 if (colonp != NULL) {
222 return (0); 187 /*
223 } 188 * Since some memmove()'s erroneously fail to handle
224 if (saw_xdigit) 189 * overlapping regions, we'll do the shift by hand.
225 { 190 */
226 if (tp + NS_INT16SZ > endp) 191 const int n = (int)(tp - colonp);
227 return (0); 192 int i;
228 *tp++ = (u_char) (val >> 8) & 0xff; 193
229 *tp++ = (u_char) val & 0xff; 194 if (tp == endp)
230 } 195 return (0);
231 if (colonp != NULL) 196 for (i = 1; i <= n; i++) {
232 { 197 endp[- i] = colonp[n - i];
233 /* 198 colonp[n - i] = 0;
234 * Since some memmove()'s erroneously fail to handle 199 }
235 * overlapping regions, we'll do the shift by hand. 200 tp = endp;
236 */ 201 }
237 const int n = tp - colonp; 202 if (tp != endp)
238 int i; 203 return (0);
239 204 memmove(dst, tmp, NS_IN6ADDRSZ);
240 if (tp == endp) 205 return (1);
241 return (0);
242 for (i = 1; i <= n; i++)
243 {
244 endp[-i] = colonp[n - i];
245 colonp[n - i] = 0;
246 }
247 tp = endp;
248 }
249 if (tp != endp)
250 return (0);
251 memcpy (dst, tmp, NS_IN6ADDRSZ);
252 return (1);
253} 206}
254
255# endif