]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/BsdSocketLib/inet_pton.c
NetworkPkg:Fix the issue Http boot hang when network failed.
[mirror_edk2.git] / StdLib / BsdSocketLib / inet_pton.c
CommitLineData
d7ce7006 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
21 * \r
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
25 * \r
26 * 1. Redistributions of source code must retain the above copyright\r
27 * notice, this list of conditions and the following disclaimer.\r
28 * \r
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
32 * \r
33 * 3. All advertising materials mentioning features or use of this software\r
34 * must display the following acknowledgement:\r
35 * \r
36 * This product includes software developed by Intel Corporation and\r
37 * its contributors.\r
38 * \r
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
42 * \r
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
54 * \r
55 */\r
56\r
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
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
75static int inet_pton4 (const char *src, u_char *dst);\r
76static int inet_pton6 (const char *src, u_char *dst);\r
77\r
78/* int\r
79 * inet_pton(af, src, dst)\r
80 * convert from presentation format (which usually means ASCII printable)\r
81 * to network format (which is usually some kind of binary format).\r
82 * return:\r
83 * 1 if the address was valid for the specified address family\r
84 * 0 if the address wasn't valid (`dst' is untouched in this case)\r
85 * -1 if some other error occurred (`dst' is untouched in this case, too)\r
86 * author:\r
87 * Paul Vixie, 1996.\r
88 */\r
89int\r
90inet_pton(\r
91 int af,\r
92 const char *src,\r
93 void *dst\r
94 )\r
95{\r
96 switch (af) {\r
97 case AF_INET:\r
98 return (inet_pton4(src, dst));\r
99 case AF_INET6:\r
100 return (inet_pton6(src, dst));\r
101 default:\r
102 errno = EAFNOSUPPORT;\r
103 return (-1);\r
104 }\r
105 /* NOTREACHED */\r
106}\r
107\r
108/* int\r
109 * inet_pton4(src, dst)\r
110 * like inet_aton() but without all the hexadecimal and shorthand.\r
111 * return:\r
112 * 1 if `src' is a valid dotted quad, else 0.\r
113 * notice:\r
114 * does not touch `dst' unless it's returning 1.\r
115 * author:\r
116 * Paul Vixie, 1996.\r
117 */\r
118static int\r
119inet_pton4(\r
120 const char *src,\r
121 u_char *dst\r
122 )\r
123{\r
124 static const char digits[] = "0123456789";\r
125 int saw_digit, octets, ch;\r
126 u_char tmp[NS_INADDRSZ], *tp;\r
127\r
128 saw_digit = 0;\r
129 octets = 0;\r
130 *(tp = tmp) = 0;\r
131 while ((ch = *src++) != '\0') {\r
132 const char *pch;\r
133\r
134 if ((pch = strchr(digits, ch)) != NULL) {\r
135 u_int new = *tp * 10 + (u_int)(pch - digits);\r
136\r
137 if (new > 255)\r
138 return (0);\r
139 *tp = (u_char)new;\r
140 if (! saw_digit) {\r
141 if (++octets > 4)\r
142 return (0);\r
143 saw_digit = 1;\r
144 }\r
145 } else if (ch == '.' && saw_digit) {\r
146 if (octets == 4)\r
147 return (0);\r
148 *++tp = 0;\r
149 saw_digit = 0;\r
150 } else\r
151 return (0);\r
152 }\r
153 if (octets < 4)\r
154 return (0);\r
155\r
156 memcpy(dst, tmp, NS_INADDRSZ);\r
157 return (1);\r
158}\r
159\r
160/* int\r
161 * inet_pton6(src, dst)\r
162 * convert presentation level address to network order binary form.\r
163 * return:\r
164 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.\r
165 * notice:\r
166 * (1) does not touch `dst' unless it's returning 1.\r
167 * (2) :: in a full address is silently ignored.\r
168 * credit:\r
169 * inspired by Mark Andrews.\r
170 * author:\r
171 * Paul Vixie, 1996.\r
172 */\r
173static int\r
174inet_pton6(\r
175 const char *src,\r
176 u_char *dst\r
177 )\r
178{\r
179 static const char xdigits_l[] = "0123456789abcdef",\r
180 xdigits_u[] = "0123456789ABCDEF";\r
181 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;\r
182 const char *xdigits, *curtok;\r
183 int ch, saw_xdigit;\r
184 u_int val;\r
185\r
186 memset((tp = tmp), '\0', NS_IN6ADDRSZ);\r
187 endp = tp + NS_IN6ADDRSZ;\r
188 colonp = NULL;\r
189 /* Leading :: requires some special handling. */\r
190 if (*src == ':')\r
191 if (*++src != ':')\r
192 return (0);\r
193 curtok = src;\r
194 saw_xdigit = 0;\r
195 val = 0;\r
196 while ((ch = *src++) != '\0') {\r
197 const char *pch;\r
198\r
199 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)\r
200 pch = strchr((xdigits = xdigits_u), ch);\r
201 if (pch != NULL) {\r
202 val <<= 4;\r
203 val |= (pch - xdigits);\r
204 if (val > 0xffff)\r
205 return (0);\r
206 saw_xdigit = 1;\r
207 continue;\r
208 }\r
209 if (ch == ':') {\r
210 curtok = src;\r
211 if (!saw_xdigit) {\r
212 if (colonp)\r
213 return (0);\r
214 colonp = tp;\r
215 continue;\r
216 }\r
217 if (tp + NS_INT16SZ > endp)\r
218 return (0);\r
219 *tp++ = (u_char) (val >> 8) & 0xff;\r
220 *tp++ = (u_char) val & 0xff;\r
221 saw_xdigit = 0;\r
222 val = 0;\r
223 continue;\r
224 }\r
225 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&\r
226 inet_pton4(curtok, tp) > 0) {\r
227 tp += NS_INADDRSZ;\r
228 saw_xdigit = 0;\r
229 break; /* '\0' was seen by inet_pton4(). */\r
230 }\r
231 return (0);\r
232 }\r
233 if (saw_xdigit) {\r
234 if (tp + NS_INT16SZ > endp)\r
235 return (0);\r
236 *tp++ = (u_char) (val >> 8) & 0xff;\r
237 *tp++ = (u_char) val & 0xff;\r
238 }\r
239 if (colonp != NULL) {\r
240 /*\r
241 * Since some memmove()'s erroneously fail to handle\r
242 * overlapping regions, we'll do the shift by hand.\r
243 */\r
244 const int n = (int)(tp - colonp);\r
245 int i;\r
246\r
247 for (i = 1; i <= n; i++) {\r
248 endp[- i] = colonp[n - i];\r
249 colonp[n - i] = 0;\r
250 }\r
251 tp = endp;\r
252 }\r
253 if (tp != endp)\r
254 return (0);\r
255 memcpy(dst, tmp, NS_IN6ADDRSZ);\r
256 return (1);\r
257}\r