/[cvs]/eggdrop1.8/src/compat/inet_pton.c
ViewVC logotype

Contents of /eggdrop1.8/src/compat/inet_pton.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Thu Aug 5 18:12:05 2010 UTC (9 years, 2 months ago) by pseudo
Branch: MAIN
File MIME type: text/x-chdr
Added new, full IPv6 support to eggdrop.

1 /*
2 * inet_pton.c -- provides inet_pton() if necessary
3 *
4 * $Id$
5 */
6 /*
7 * Portions Copyright (C) 2010 Eggheads Development Team
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include "inet_pton.h"
25
26 #ifndef HAVE_INET_NTOP
27 /*
28 * Copyright (c) 1996,1999 by Internet Software Consortium.
29 *
30 * Permission to use, copy, modify, and distribute this software for any
31 * purpose with or without fee is hereby granted, provided that the above
32 * copyright notice and this permission notice appear in all copies.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
35 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
36 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
37 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
38 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
39 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
40 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41 * SOFTWARE.
42 */
43
44 #include <sys/param.h>
45 #include <sys/types.h>
46 #include <ctype.h>
47 #include <string.h>
48
49 #define NS_INADDRSZ 4 /* IPv4 T_A */
50 #define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
51 #define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
52
53 static int inet_pton4 (const char *src, u_char *dst);
54 static int inet_pton6 (const char *src, u_char *dst);
55
56 /* int
57 * inet_pton(af, src, dst)
58 * convert from presentation format (which usually means ASCII printable)
59 * to network format (which is usually some kind of binary format).
60 * return:
61 * 1 if the address was valid for the specified address family
62 * 0 if the address wasn't valid (`dst' is untouched in this case)
63 * -1 if some other error occurred (`dst' is untouched in this case, too)
64 * author:
65 * Paul Vixie, 1996.
66 */
67 int inet_pton(af, src, dst)
68 int af;
69 const char *src;
70 void *dst;
71 {
72 switch (af) {
73 case AF_INET:
74 return (inet_pton4(src, dst));
75 #ifdef IPV6
76 case AF_INET6:
77 return (inet_pton6(src, dst));
78 #endif
79 default:
80 return -1;
81 }
82 /* NOTREACHED */
83 }
84
85 /* int
86 * inet_pton4(src, dst)
87 * like inet_aton() but without all the hexadecimal and shorthand.
88 * return:
89 * 1 if `src' is a valid dotted quad, else 0.
90 * notice:
91 * does not touch `dst' unless it's returning 1.
92 * author:
93 * Paul Vixie, 1996.
94 */
95 static int
96 inet_pton4(src, dst)
97 const char *src;
98 u_char *dst;
99 {
100 int saw_digit, octets, ch;
101 u_char tmp[NS_INADDRSZ], *tp;
102
103 saw_digit = 0;
104 octets = 0;
105 *(tp = tmp) = 0;
106 while ((ch = *src++) != '\0') {
107
108 if (ch >= '0' && ch <= '9') {
109 u_int new = *tp * 10 + (ch - '0');
110
111 if (new > 255)
112 return (0);
113 *tp = new;
114 if (! saw_digit) {
115 if (++octets > 4)
116 return (0);
117 saw_digit = 1;
118 }
119 } else if (ch == '.' && saw_digit) {
120 if (octets == 4)
121 return (0);
122 *++tp = 0;
123 saw_digit = 0;
124 } else
125 return (0);
126 }
127 if (octets < 4)
128 return (0);
129 memcpy(dst, tmp, NS_INADDRSZ);
130 return (1);
131 }
132
133 /* int
134 * inet_pton6(src, dst)
135 * convert presentation level address to network order binary form.
136 * return:
137 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
138 * notice:
139 * (1) does not touch `dst' unless it's returning 1.
140 * (2) :: in a full address is silently ignored.
141 * credit:
142 * inspired by Mark Andrews.
143 * author:
144 * Paul Vixie, 1996.
145 */
146 #ifdef IPV6
147 static int
148 inet_pton6(src, dst)
149 const char *src;
150 u_char *dst;
151 {
152 static const char xdigits[] = "0123456789abcdef";
153 u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
154 const char *curtok;
155 int ch, saw_xdigit;
156 u_int val;
157
158 tp = memset(tmp, '\0', NS_IN6ADDRSZ);
159 endp = tp + NS_IN6ADDRSZ;
160 colonp = NULL;
161 /* Leading :: requires some special handling. */
162 if (*src == ':')
163 if (*++src != ':')
164 return (0);
165 curtok = src;
166 saw_xdigit = 0;
167 val = 0;
168 while ((ch = tolower (*src++)) != '\0') {
169 const char *pch;
170
171 pch = strchr(xdigits, ch);
172 if (pch != NULL) {
173 val <<= 4;
174 val |= (pch - xdigits);
175 if (val > 0xffff)
176 return (0);
177 saw_xdigit = 1;
178 continue;
179 }
180 if (ch == ':') {
181 curtok = src;
182 if (!saw_xdigit) {
183 if (colonp)
184 return (0);
185 colonp = tp;
186 continue;
187 } else if (*src == '\0') {
188 return (0);
189 }
190 if (tp + NS_INT16SZ > endp)
191 return (0);
192 *tp++ = (u_char) (val >> 8) & 0xff;
193 *tp++ = (u_char) val & 0xff;
194 saw_xdigit = 0;
195 val = 0;
196 continue;
197 }
198 if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
199 inet_pton4(curtok, tp) > 0) {
200 tp += NS_INADDRSZ;
201 saw_xdigit = 0;
202 break; /* '\0' was seen by inet_pton4(). */
203 }
204 return (0);
205 }
206 if (saw_xdigit) {
207 if (tp + NS_INT16SZ > endp)
208 return (0);
209 *tp++ = (u_char) (val >> 8) & 0xff;
210 *tp++ = (u_char) val & 0xff;
211 }
212 if (colonp != NULL) {
213 /*
214 * Since some memmove()'s erroneously fail to handle
215 * overlapping regions, we'll do the shift by hand.
216 */
217 const int n = tp - colonp;
218 int i;
219
220 if (tp == endp)
221 return (0);
222 for (i = 1; i <= n; i++) {
223 endp[- i] = colonp[n - i];
224 colonp[n - i] = 0;
225 }
226 tp = endp;
227 }
228 if (tp != endp)
229 return (0);
230 memcpy(dst, tmp, NS_IN6ADDRSZ);
231 return (1);
232 }
233 #endif /* IPV6 */
234
235 #endif /* HAVE_INET_NTOP */

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23