source: trunk/libs/newlib/src/newlib/libc/sys/linux/net/inet_pton.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.2 KB
Line 
1/*      $KAME: inet_pton.c,v 1.5 2001/08/20 02:32:40 itojun Exp $       */
2
3/* Copyright (c) 1996 by Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
10 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
11 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
12 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
15 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16 * SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
20#include <sys/types.h>
21
22#include <sys/param.h>
23#include <sys/types.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#include <arpa/nameser.h>
28#include <string.h>
29#include <errno.h>
30
31/*
32 * WARNING: Don't even consider trying to compile this on a system where
33 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
34 */
35
36static int      inet_pton4(const char *src, u_char *dst);
37static int      inet_pton6(const char *src, u_char *dst);
38
39/* int
40 * inet_pton(af, src, dst)
41 *      convert from presentation format (which usually means ASCII printable)
42 *      to network format (which is usually some kind of binary format).
43 * return:
44 *      1 if the address was valid for the specified address family
45 *      0 if the address wasn't valid (`dst' is untouched in this case)
46 *      -1 if some other error occurred (`dst' is untouched in this case, too)
47 * author:
48 *      Paul Vixie, 1996.
49 */
50int
51inet_pton(af, src, dst)
52        int af;
53        const char *src;
54        void *dst;
55{
56        switch (af) {
57        case AF_INET:
58                return (inet_pton4(src, dst));
59        case AF_INET6:
60                return (inet_pton6(src, dst));
61        default:
62                errno = EAFNOSUPPORT;
63                return (-1);
64        }
65        /* NOTREACHED */
66}
67
68/* int
69 * inet_pton4(src, dst)
70 *      like inet_aton() but without all the hexadecimal and shorthand.
71 * return:
72 *      1 if `src' is a valid dotted quad, else 0.
73 * notice:
74 *      does not touch `dst' unless it's returning 1.
75 * author:
76 *      Paul Vixie, 1996.
77 */
78static int
79inet_pton4(src, dst)
80        const char *src;
81        u_char *dst;
82{
83        static const char digits[] = "0123456789";
84        int saw_digit, octets, ch;
85        u_char tmp[NS_INADDRSZ], *tp;
86
87        saw_digit = 0;
88        octets = 0;
89        *(tp = tmp) = 0;
90        while ((ch = *src++) != '\0') {
91                const char *pch;
92
93                if ((pch = strchr(digits, ch)) != NULL) {
94                        u_int new = *tp * 10 + (pch - digits);
95
96                        if (new > 255)
97                                return (0);
98                        *tp = new;
99                        if (! saw_digit) {
100                                if (++octets > 4)
101                                        return (0);
102                                saw_digit = 1;
103                        }
104                } else if (ch == '.' && saw_digit) {
105                        if (octets == 4)
106                                return (0);
107                        *++tp = 0;
108                        saw_digit = 0;
109                } else
110                        return (0);
111        }
112        if (octets < 4)
113                return (0);
114
115        memcpy(dst, tmp, NS_INADDRSZ);
116        return (1);
117}
118
119/* int
120 * inet_pton6(src, dst)
121 *      convert presentation level address to network order binary form.
122 * return:
123 *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
124 * notice:
125 *      (1) does not touch `dst' unless it's returning 1.
126 *      (2) :: in a full address is silently ignored.
127 * credit:
128 *      inspired by Mark Andrews.
129 * author:
130 *      Paul Vixie, 1996.
131 */
132static int
133inet_pton6(src, dst)
134        const char *src;
135        u_char *dst;
136{
137        static const char xdigits_l[] = "0123456789abcdef",
138                          xdigits_u[] = "0123456789ABCDEF";
139        u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
140        const char *xdigits, *curtok;
141        int ch, saw_xdigit;
142        u_int val;
143
144        memset((tp = tmp), '\0', NS_IN6ADDRSZ);
145        endp = tp + NS_IN6ADDRSZ;
146        colonp = NULL;
147        /* Leading :: requires some special handling. */
148        if (*src == ':')
149                if (*++src != ':')
150                        return (0);
151        curtok = src;
152        saw_xdigit = 0;
153        val = 0;
154        while ((ch = *src++) != '\0') {
155                const char *pch;
156
157                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
158                        pch = strchr((xdigits = xdigits_u), ch);
159                if (pch != NULL) {
160                        val <<= 4;
161                        val |= (pch - xdigits);
162                        if (val > 0xffff)
163                                return (0);
164                        saw_xdigit = 1;
165                        continue;
166                }
167                if (ch == ':') {
168                        curtok = src;
169                        if (!saw_xdigit) {
170                                if (colonp)
171                                        return (0);
172                                colonp = tp;
173                                continue;
174                        }
175                        if (tp + NS_INT16SZ > endp)
176                                return (0);
177                        *tp++ = (u_char) (val >> 8) & 0xff;
178                        *tp++ = (u_char) val & 0xff;
179                        saw_xdigit = 0;
180                        val = 0;
181                        continue;
182                }
183                if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
184                    inet_pton4(curtok, tp) > 0) {
185                        tp += NS_INADDRSZ;
186                        saw_xdigit = 0;
187                        break;  /* '\0' was seen by inet_pton4(). */
188                }
189                return (0);
190        }
191        if (saw_xdigit) {
192                if (tp + NS_INT16SZ > endp)
193                        return (0);
194                *tp++ = (u_char) (val >> 8) & 0xff;
195                *tp++ = (u_char) val & 0xff;
196        }
197        if (colonp != NULL) {
198                /*
199                 * Since some memmove()'s erroneously fail to handle
200                 * overlapping regions, we'll do the shift by hand.
201                 */
202                const int n = tp - colonp;
203                int i;
204
205                for (i = 1; i <= n; i++) {
206                        endp[- i] = colonp[n - i];
207                        colonp[n - i] = 0;
208                }
209                tp = endp;
210        }
211        if (tp != endp)
212                return (0);
213        memcpy(dst, tmp, NS_IN6ADDRSZ);
214        return (1);
215}
216
217/*
218 * Weak aliases for applications that use certain private entry points,
219 * and fail to include <arpa/inet.h>.
220 */
221#undef inet_pton
222__weak_reference(__inet_pton, inet_pton);
Note: See TracBrowser for help on using the repository browser.