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