]> git.ipfire.org Git - thirdparty/squid.git/blame - compat/inet_pton.cc
SourceFormat Enforcement
[thirdparty/squid.git] / compat / inet_pton.cc
CommitLineData
37be9888 1/*
bde978a6 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
37be9888
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
0e076fb1 9/*
10 * Shamelessly duplicated from the bind9 public sources
11 * for use by the Squid Project under ISC written permission
12 * included "as found" below.
13 *
14 * Update/Maintenance History:
15 *
16 * 24-Sep-2007 : Copied from bind 9.3.3
17 * - Added protection around libray headers
18 * - Altered configure checks to import
19 *
20 * 06-Oct-2007 : Various fixes to allow the build on MinGW
21 *
22 * 28-Oct-2007: drop some dead code. now tested working without.
23 *
0e076fb1 24 * Original License and code follows.
25 */
26
f7f3304a 27#include "squid.h"
0e076fb1 28
55d7d5e9 29#if !HAVE_DECL_INET_PTON
0e076fb1 30
31/*
32 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
33 * Copyright (c) 1996,1999 by Internet Software Consortium.
34 *
35 * Permission to use, copy, modify, and distribute this software for any
36 * purpose with or without fee is hereby granted, provided that the above
37 * copyright notice and this permission notice appear in all copies.
38 *
39 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
40 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
41 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
42 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
43 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
44 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
45 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
46 */
47
48#if defined(LIBC_SCCS) && !defined(lint)
49static const char rcsid[] = "inet_pton.c,v 1.2.206.2 2005/07/28 07:43:18 marka Exp";
50#endif /* LIBC_SCCS and not lint */
51
52#if HAVE_SYS_PARAM_H
53#include <sys/param.h>
54#endif
55#if HAVE_SYS_TYPES_H
56#include <sys/types.h>
57#endif
58#if HAVE_SYS_SOCKET_H
59#include <sys/socket.h>
60#endif
61#if HAVE_NETINET_IN_H
62#include <netinet/in.h>
63#endif
64#if ARPA_INET_H
65#include <arpa/inet.h>
66#endif
67#if HAVE_ARPA_NAMESER_H
68#include <arpa/nameser.h>
69#endif
70#if HAVE_STRING_H
71#include <string.h>
72#endif
73#if HAVE_ERRNO_H
74#include <errno.h>
75#endif
76
77#if ! defined(NS_INADDRSZ)
78#define NS_INADDRSZ 4
79#endif
80#if ! defined(NS_IN6ADDRSZ)
81#define NS_IN6ADDRSZ 16
82#endif
83#if ! defined(NS_INT16SZ)
84#define NS_INT16SZ 2
85#endif
86
87/*
88 * WARNING: Don't even consider trying to compile this on a system where
89 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
90 */
91
f53969cc
SM
92static int inet_pton4 (const char *src, u_char *dst);
93static int inet_pton6 (const char *src, u_char *dst);
0e076fb1 94
95/* int
96 * inet_pton(af, src, dst)
f53969cc
SM
97 * convert from presentation format (which usually means ASCII printable)
98 * to network format (which is usually some kind of binary format).
0e076fb1 99 * return:
f53969cc
SM
100 * 1 if the address was valid for the specified address family
101 * 0 if the address wasn't valid (`dst' is untouched in this case)
102 * -1 if some other error occurred (`dst' is untouched in this case, too)
0e076fb1 103 * author:
f53969cc 104 * Paul Vixie, 1996.
0e076fb1 105 */
106int
107xinet_pton(af, src, dst)
26ac0430
AJ
108int af;
109const char *src;
110void *dst;
0e076fb1 111{
26ac0430
AJ
112 switch (af) {
113 case AF_INET:
114 return (inet_pton4(src, dst));
115 case AF_INET6:
116 return (inet_pton6(src, dst));
117 default:
118 errno = EAFNOSUPPORT;
119 return (-1);
120 }
121 /* NOTREACHED */
0e076fb1 122}
123
124/* int
125 * inet_pton4(src, dst)
f53969cc 126 * like inet_aton() but without all the hexadecimal and shorthand.
0e076fb1 127 * return:
f53969cc 128 * 1 if `src' is a valid dotted quad, else 0.
0e076fb1 129 * notice:
f53969cc 130 * does not touch `dst' unless it's returning 1.
0e076fb1 131 * author:
f53969cc 132 * Paul Vixie, 1996.
0e076fb1 133 */
134static int
135inet_pton4(src, dst)
26ac0430
AJ
136const char *src;
137u_char *dst;
0e076fb1 138{
26ac0430
AJ
139 static const char digits[] = "0123456789";
140 int saw_digit, octets, ch;
141 u_char tmp[NS_INADDRSZ], *tp;
0e076fb1 142
26ac0430
AJ
143 saw_digit = 0;
144 octets = 0;
145 *(tp = tmp) = 0;
146 while ((ch = *src++) != '\0') {
147 const char *pch;
0e076fb1 148
26ac0430
AJ
149 if ((pch = strchr(digits, ch)) != NULL) {
150 u_int new = *tp * 10 + (pch - digits);
0e076fb1 151
26ac0430
AJ
152 if (saw_digit && *tp == 0)
153 return (0);
154 if (new > 255)
155 return (0);
156 *tp = new;
157 if (!saw_digit) {
158 if (++octets > 4)
159 return (0);
160 saw_digit = 1;
161 }
162 } else if (ch == '.' && saw_digit) {
163 if (octets == 4)
164 return (0);
165 *++tp = 0;
166 saw_digit = 0;
167 } else
168 return (0);
169 }
170 if (octets < 4)
171 return (0);
172 memcpy(dst, tmp, NS_INADDRSZ);
173 return (1);
0e076fb1 174}
175
176/* int
177 * inet_pton6(src, dst)
f53969cc 178 * convert presentation level address to network order binary form.
0e076fb1 179 * return:
f53969cc 180 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
0e076fb1 181 * notice:
f53969cc
SM
182 * (1) does not touch `dst' unless it's returning 1.
183 * (2) :: in a full address is silently ignored.
0e076fb1 184 * credit:
f53969cc 185 * inspired by Mark Andrews.
0e076fb1 186 * author:
f53969cc 187 * Paul Vixie, 1996.
0e076fb1 188 */
189static int
190inet_pton6(src, dst)
26ac0430
AJ
191const char *src;
192u_char *dst;
0e076fb1 193{
26ac0430
AJ
194 static const char xdigits_l[] = "0123456789abcdef",
195 xdigits_u[] = "0123456789ABCDEF";
196 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
197 const char *xdigits, *curtok;
198 int ch, seen_xdigits;
199 u_int val;
0e076fb1 200
26ac0430
AJ
201 memset((tp = tmp), '\0', NS_IN6ADDRSZ);
202 endp = tp + NS_IN6ADDRSZ;
203 colonp = NULL;
204 /* Leading :: requires some special handling. */
205 if (*src == ':')
206 if (*++src != ':')
207 return (0);
208 curtok = src;
209 seen_xdigits = 0;
210 val = 0;
211 while ((ch = *src++) != '\0') {
212 const char *pch;
0e076fb1 213
26ac0430
AJ
214 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
215 pch = strchr((xdigits = xdigits_u), ch);
216 if (pch != NULL) {
217 val <<= 4;
218 val |= (pch - xdigits);
219 if (++seen_xdigits > 4)
220 return (0);
221 continue;
222 }
223 if (ch == ':') {
224 curtok = src;
225 if (!seen_xdigits) {
226 if (colonp)
227 return (0);
228 colonp = tp;
229 continue;
230 } else if (*src == '\0') {
231 return (0);
232 }
233 if (tp + NS_INT16SZ > endp)
234 return (0);
235 *tp++ = (u_char) (val >> 8) & 0xff;
236 *tp++ = (u_char) val & 0xff;
237 seen_xdigits = 0;
238 val = 0;
239 continue;
240 }
241 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
242 inet_pton4(curtok, tp) > 0) {
243 tp += NS_INADDRSZ;
244 seen_xdigits = 0;
f53969cc 245 break; /* '\0' was seen by inet_pton4(). */
26ac0430
AJ
246 }
247 return (0);
248 }
249 if (seen_xdigits) {
250 if (tp + NS_INT16SZ > endp)
251 return (0);
252 *tp++ = (u_char) (val >> 8) & 0xff;
253 *tp++ = (u_char) val & 0xff;
254 }
255 if (colonp != NULL) {
256 /*
257 * Since some memmove()'s erroneously fail to handle
258 * overlapping regions, we'll do the shift by hand.
259 */
260 const int n = tp - colonp;
261 int i;
0e076fb1 262
26ac0430
AJ
263 if (tp == endp)
264 return (0);
265 for (i = 1; i <= n; i++) {
266 endp[- i] = colonp[n - i];
267 colonp[n - i] = 0;
268 }
269 tp = endp;
270 }
271 if (tp != endp)
272 return (0);
273 memcpy(dst, tmp, NS_IN6ADDRSZ);
274 return (1);
0e076fb1 275}
276
55d7d5e9 277#endif /* HAVE_DECL_INET_PTON */
f53969cc 278