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