]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/TlsLib/SysCall/inet_pton.c
CryptoPkg/Library: Cleanup BaseCryptLib and TlsLib
[mirror_edk2.git] / CryptoPkg / Library / TlsLib / SysCall / inet_pton.c
CommitLineData
8d16ef82
LE
1/* Copyright (c) 1996 by Internet Software Consortium.\r
2 *\r
3 * Permission to use, copy, modify, and distribute this software for any\r
4 * purpose with or without fee is hereby granted, provided that the above\r
5 * copyright notice and this permission notice appear in all copies.\r
6 *\r
7 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r
8 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r
9 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r
10 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r
11 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r
12 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r
13 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r
14 * SOFTWARE.\r
15 */\r
16\r
17/*\r
18 * Portions copyright (c) 1999, 2000\r
19 * Intel Corporation.\r
20 * All rights reserved.\r
7c342378 21 *\r
8d16ef82
LE
22 * Redistribution and use in source and binary forms, with or without\r
23 * modification, are permitted provided that the following conditions\r
24 * are met:\r
7c342378 25 *\r
8d16ef82
LE
26 * 1. Redistributions of source code must retain the above copyright\r
27 * notice, this list of conditions and the following disclaimer.\r
7c342378 28 *\r
8d16ef82
LE
29 * 2. Redistributions in binary form must reproduce the above copyright\r
30 * notice, this list of conditions and the following disclaimer in the\r
31 * documentation and/or other materials provided with the distribution.\r
7c342378 32 *\r
8d16ef82
LE
33 * 3. All advertising materials mentioning features or use of this software\r
34 * must display the following acknowledgement:\r
7c342378 35 *\r
8d16ef82
LE
36 * This product includes software developed by Intel Corporation and\r
37 * its contributors.\r
7c342378 38 *\r
8d16ef82
LE
39 * 4. Neither the name of Intel Corporation or its contributors may be\r
40 * used to endorse or promote products derived from this software\r
41 * without specific prior written permission.\r
7c342378 42 *\r
8d16ef82
LE
43 * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS''\r
44 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
46 * ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE\r
47 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
51 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
52 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF\r
53 * THE POSSIBILITY OF SUCH DAMAGE.\r
7c342378 54 *\r
8d16ef82
LE
55 */\r
56\r
7c342378
MK
57#if defined (LIBC_SCCS) && !defined (lint)\r
58static char rcsid[] = "$Id: inet_pton.c,v 1.1.1.1 2003/11/19 01:51:30 kyu3 Exp $";\r
8d16ef82
LE
59#endif /* LIBC_SCCS and not lint */\r
60\r
61#include <sys/param.h>\r
62#include <sys/types.h>\r
63#include <sys/socket.h>\r
64#include <netinet/in.h>\r
65#include <arpa/inet.h>\r
66#include <arpa/nameser.h>\r
67#include <string.h>\r
68#include <errno.h>\r
69\r
70/*\r
71 * WARNING: Don't even consider trying to compile this on a system where\r
72 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.\r
73 */\r
74\r
7c342378
MK
75static int\r
76inet_pton4 (\r
77 const char *src,\r
78 u_char *dst\r
79 );\r
80\r
81static int\r
82inet_pton6 (\r
83 const char *src,\r
84 u_char *dst\r
85 );\r
8d16ef82
LE
86\r
87/* int\r
88 * inet_pton(af, src, dst)\r
7c342378
MK
89 * convert from presentation format (which usually means ASCII printable)\r
90 * to network format (which is usually some kind of binary format).\r
8d16ef82 91 * return:\r
7c342378
MK
92 * 1 if the address was valid for the specified address family\r
93 * 0 if the address wasn't valid (`dst' is untouched in this case)\r
94 * -1 if some other error occurred (`dst' is untouched in this case, too)\r
8d16ef82 95 * author:\r
7c342378 96 * Paul Vixie, 1996.\r
8d16ef82
LE
97 */\r
98int\r
7c342378
MK
99inet_pton (\r
100 int af,\r
101 const char *src,\r
102 void *dst\r
103 )\r
8d16ef82 104{\r
7c342378
MK
105 switch (af) {\r
106 case AF_INET:\r
107 return (inet_pton4 (src, dst));\r
108 case AF_INET6:\r
109 return (inet_pton6 (src, dst));\r
110 default:\r
111 errno = EAFNOSUPPORT;\r
112 return (-1);\r
113 }\r
114\r
115 /* NOTREACHED */\r
8d16ef82
LE
116}\r
117\r
118/* int\r
119 * inet_pton4(src, dst)\r
7c342378 120 * like inet_aton() but without all the hexadecimal and shorthand.\r
8d16ef82 121 * return:\r
7c342378 122 * 1 if `src' is a valid dotted quad, else 0.\r
8d16ef82 123 * notice:\r
7c342378 124 * does not touch `dst' unless it's returning 1.\r
8d16ef82 125 * author:\r
7c342378 126 * Paul Vixie, 1996.\r
8d16ef82
LE
127 */\r
128static int\r
7c342378
MK
129inet_pton4 (\r
130 const char *src,\r
131 u_char *dst\r
132 )\r
8d16ef82 133{\r
7c342378
MK
134 static const char digits[] = "0123456789";\r
135 int saw_digit, octets, ch;\r
136 u_char tmp[NS_INADDRSZ], *tp;\r
137\r
138 saw_digit = 0;\r
139 octets = 0;\r
140 *(tp = tmp) = 0;\r
141 while ((ch = *src++) != '\0') {\r
142 const char *pch;\r
143\r
144 if ((pch = strchr (digits, ch)) != NULL) {\r
145 u_int new = *tp * 10 + (u_int)(pch - digits);\r
146\r
147 if (new > 255) {\r
148 return (0);\r
149 }\r
150\r
151 *tp = (u_char)new;\r
152 if (!saw_digit) {\r
153 if (++octets > 4) {\r
154 return (0);\r
155 }\r
156\r
157 saw_digit = 1;\r
158 }\r
159 } else if ((ch == '.') && saw_digit) {\r
160 if (octets == 4) {\r
161 return (0);\r
162 }\r
163\r
164 *++tp = 0;\r
165 saw_digit = 0;\r
166 } else {\r
167 return (0);\r
168 }\r
169 }\r
170\r
171 if (octets < 4) {\r
172 return (0);\r
173 }\r
174\r
175 memcpy (dst, tmp, NS_INADDRSZ);\r
176 return (1);\r
8d16ef82
LE
177}\r
178\r
179/* int\r
180 * inet_pton6(src, dst)\r
7c342378 181 * convert presentation level address to network order binary form.\r
8d16ef82 182 * return:\r
7c342378 183 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.\r
8d16ef82 184 * notice:\r
7c342378
MK
185 * (1) does not touch `dst' unless it's returning 1.\r
186 * (2) :: in a full address is silently ignored.\r
8d16ef82 187 * credit:\r
7c342378 188 * inspired by Mark Andrews.\r
8d16ef82 189 * author:\r
7c342378 190 * Paul Vixie, 1996.\r
8d16ef82
LE
191 */\r
192static int\r
7c342378
MK
193inet_pton6 (\r
194 const char *src,\r
195 u_char *dst\r
196 )\r
8d16ef82 197{\r
7c342378
MK
198 static const char xdigits_l[] = "0123456789abcdef",\r
199 xdigits_u[] = "0123456789ABCDEF";\r
200 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;\r
201 const char *xdigits, *curtok;\r
202 int ch, saw_xdigit;\r
203 u_int val;\r
204\r
205 memset ((tp = tmp), '\0', NS_IN6ADDRSZ);\r
206 endp = tp + NS_IN6ADDRSZ;\r
207 colonp = NULL;\r
208 /* Leading :: requires some special handling. */\r
209 if (*src == ':') {\r
210 if (*++src != ':') {\r
211 return (0);\r
212 }\r
213 }\r
214\r
215 curtok = src;\r
216 saw_xdigit = 0;\r
217 val = 0;\r
218 while ((ch = *src++) != '\0') {\r
219 const char *pch;\r
220\r
221 if ((pch = strchr ((xdigits = xdigits_l), ch)) == NULL) {\r
222 pch = strchr ((xdigits = xdigits_u), ch);\r
223 }\r
224\r
225 if (pch != NULL) {\r
226 val <<= 4;\r
227 val |= (pch - xdigits);\r
228 if (val > 0xffff) {\r
229 return (0);\r
230 }\r
231\r
232 saw_xdigit = 1;\r
233 continue;\r
234 }\r
235\r
236 if (ch == ':') {\r
237 curtok = src;\r
238 if (!saw_xdigit) {\r
239 if (colonp) {\r
240 return (0);\r
241 }\r
242\r
243 colonp = tp;\r
244 continue;\r
245 }\r
246\r
247 if (tp + NS_INT16SZ > endp) {\r
248 return (0);\r
249 }\r
250\r
251 *tp++ = (u_char)(val >> 8) & 0xff;\r
252 *tp++ = (u_char)val & 0xff;\r
253 saw_xdigit = 0;\r
254 val = 0;\r
255 continue;\r
256 }\r
257\r
258 if ((ch == '.') && ((tp + NS_INADDRSZ) <= endp) &&\r
259 (inet_pton4 (curtok, tp) > 0))\r
260 {\r
261 tp += NS_INADDRSZ;\r
262 saw_xdigit = 0;\r
263 break; /* '\0' was seen by inet_pton4(). */\r
264 }\r
265\r
266 return (0);\r
267 }\r
268\r
269 if (saw_xdigit) {\r
270 if (tp + NS_INT16SZ > endp) {\r
271 return (0);\r
272 }\r
273\r
274 *tp++ = (u_char)(val >> 8) & 0xff;\r
275 *tp++ = (u_char)val & 0xff;\r
276 }\r
277\r
278 if (colonp != NULL) {\r
279 /*\r
280 * Since some memmove()'s erroneously fail to handle\r
281 * overlapping regions, we'll do the shift by hand.\r
282 */\r
283 const int n = (int)(tp - colonp);\r
284 int i;\r
285\r
286 for (i = 1; i <= n; i++) {\r
287 endp[-i] = colonp[n - i];\r
288 colonp[n - i] = 0;\r
289 }\r
290\r
291 tp = endp;\r
292 }\r
293\r
294 if (tp != endp) {\r
295 return (0);\r
296 }\r
297\r
298 memcpy (dst, tmp, NS_IN6ADDRSZ);\r
299 return (1);\r
8d16ef82 300}\r