nexmon – Blame information for rev 1

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