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

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

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


Revision 1.3 - (show annotations) (download) (as text)
Wed Oct 6 19:07:47 2010 UTC (8 years, 10 months ago) by pseudo
Branch: MAIN
CVS Tags: HEAD
Branch point for: gettext
Changes since 1.2: +4 -2 lines
File MIME type: text/x-chdr
Fixed some problems with IPv6 autodetection and system headers.

1 /*
2 * inet_ntop.c -- provides inet_ntop() if necessary
3 *
4 * $Id: inet_ntop.c,v 1.2 2010/08/23 21:27:40 pseudo Exp $
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_ntop.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 <arpa/inet.h>
47
48 #include <stdio.h>
49 #include <string.h>
50
51 #ifdef SPRINTF_CHAR
52 # define SPRINTF(x) strlen(sprintf/**/x)
53 #else
54 # define SPRINTF(x) ((size_t)sprintf x)
55 #endif
56
57 #define NS_INADDRSZ 4 /* IPv4 T_A */
58 #define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
59 #define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
60
61 /*
62 * WARNING: Don't even consider trying to compile this on a system where
63 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
64 */
65
66 static const char *inet_ntop4 (const u_char *src, char *dst, socklen_t size);
67 #ifdef IPV6
68 static const char *inet_ntop6 (const u_char *src, char *dst, socklen_t size);
69 #endif
70
71 /* char *
72 * inet_ntop(af, src, dst, size)
73 * convert a network format address to presentation format.
74 * return:
75 * pointer to presentation format address (`dst'), or NULL (see errno).
76 * author:
77 * Paul Vixie, 1996.
78 */
79 const char *
80 inet_ntop(af, src, dst, size)
81 int af;
82 const void *src;
83 char *dst;
84 socklen_t size;
85 {
86 switch (af) {
87 case AF_INET:
88 return (inet_ntop4(src, dst, size));
89 #ifdef IPV6
90 case AF_INET6:
91 return (inet_ntop6(src, dst, size));
92 #endif
93 default:
94 return NULL;
95 }
96 /* NOTREACHED */
97 }
98
99 /* const char *
100 * inet_ntop4(src, dst, size)
101 * format an IPv4 address
102 * return:
103 * `dst' (as a const)
104 * notes:
105 * (1) uses no statics
106 * (2) takes a u_char* not an in_addr as input
107 * author:
108 * Paul Vixie, 1996.
109 */
110 static const char *inet_ntop4(src, dst, size)
111 const u_char *src;
112 char *dst;
113 socklen_t size;
114 {
115 static const char fmt[] = "%u.%u.%u.%u";
116 char tmp[sizeof "255.255.255.255"];
117
118 if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
119 /* __set_errno (ENOSPC); */
120 return (NULL);
121 }
122 return strcpy(dst, tmp);
123 }
124
125 /* const char *
126 * inet_ntop6(src, dst, size)
127 * convert IPv6 binary address into presentation (printable) format
128 * author:
129 * Paul Vixie, 1996.
130 */
131 #ifdef IPV6
132 static const char *
133 inet_ntop6(src, dst, size)
134 const u_char *src;
135 char *dst;
136 socklen_t size;
137 {
138 /*
139 * Note that int32_t and int16_t need only be "at least" large enough
140 * to contain a value of the specified size. On some systems, like
141 * Crays, there is no such thing as an integer variable with 16 bits.
142 * Keep this in mind if you think this function should have been coded
143 * to use pointer overlays. All the world's not a VAX.
144 */
145 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
146 struct { int base, len; } best, cur;
147 u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
148 int i;
149
150 /*
151 * Preprocess:
152 * Copy the input (bytewise) array into a wordwise array.
153 * Find the longest run of 0x00's in src[] for :: shorthanding.
154 */
155 memset(words, '\0', sizeof words);
156 best.len = cur.len = 0;
157 for (i = 0; i < NS_IN6ADDRSZ; i += 2)
158 words[i / 2] = (src[i] << 8) | src[i + 1];
159 best.base = -1;
160 cur.base = -1;
161 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
162 if (words[i] == 0) {
163 if (cur.base == -1)
164 cur.base = i, cur.len = 1;
165 else
166 cur.len++;
167 } else {
168 if (cur.base != -1) {
169 if (best.base == -1 || cur.len > best.len)
170 best = cur;
171 cur.base = -1;
172 }
173 }
174 }
175 if (cur.base != -1) {
176 if (best.base == -1 || cur.len > best.len)
177 best = cur;
178 }
179 if (best.base != -1 && best.len < 2)
180 best.base = -1;
181
182 /*
183 * Format the result.
184 */
185 tp = tmp;
186 for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
187 /* Are we inside the best run of 0x00's? */
188 if (best.base != -1 && i >= best.base &&
189 i < (best.base + best.len)) {
190 if (i == best.base)
191 *tp++ = ':';
192 continue;
193 }
194 /* Are we following an initial run of 0x00s or any real hex? */
195 if (i != 0)
196 *tp++ = ':';
197 /* Is this address an encapsulated IPv4? */
198 if (i == 6 && best.base == 0 &&
199 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
200 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
201 return (NULL);
202 tp += strlen(tp);
203 break;
204 }
205 tp += SPRINTF((tp, "%x", words[i]));
206 }
207 /* Was it a trailing run of 0x00's? */
208 if (best.base != -1 && (best.base + best.len) ==
209 (NS_IN6ADDRSZ / NS_INT16SZ))
210 *tp++ = ':';
211 *tp++ = '\0';
212
213 /*
214 * Check for overflow, copy, and we're done.
215 */
216 if ((socklen_t)(tp - tmp) > size) {
217 /* __set_errno (ENOSPC); */
218 return (NULL);
219 }
220 return strcpy(dst, tmp);
221 }
222 #endif /* IPV6 */
223
224 #endif /* HAVE_INET_NTOP */

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23