summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/inet_ntop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/net/inet_ntop.c')
-rw-r--r--src/lib/libc/net/inet_ntop.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/lib/libc/net/inet_ntop.c b/src/lib/libc/net/inet_ntop.c
index 212c0396b2..5293e80fc0 100644
--- a/src/lib/libc/net/inet_ntop.c
+++ b/src/lib/libc/net/inet_ntop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: inet_ntop.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $ */ 1/* $OpenBSD: inet_ntop.c,v 1.4 2002/08/19 03:01:54 itojun Exp $ */
2 2
3/* Copyright (c) 1996 by Internet Software Consortium. 3/* Copyright (c) 1996 by Internet Software Consortium.
4 * 4 *
@@ -20,7 +20,7 @@
20#if 0 20#if 0
21static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; 21static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
22#else 22#else
23static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $"; 23static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.4 2002/08/19 03:01:54 itojun Exp $";
24#endif 24#endif
25#endif /* LIBC_SCCS and not lint */ 25#endif /* LIBC_SCCS and not lint */
26 26
@@ -116,10 +116,12 @@ inet_ntop6(src, dst, size)
116 * Keep this in mind if you think this function should have been coded 116 * Keep this in mind if you think this function should have been coded
117 * to use pointer overlays. All the world's not a VAX. 117 * to use pointer overlays. All the world's not a VAX.
118 */ 118 */
119 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 119 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
120 char *tp, *ep;
120 struct { int base, len; } best, cur; 121 struct { int base, len; } best, cur;
121 u_int words[IN6ADDRSZ / INT16SZ]; 122 u_int words[IN6ADDRSZ / INT16SZ];
122 int i; 123 int i;
124 int advance;
123 125
124 /* 126 /*
125 * Preprocess: 127 * Preprocess:
@@ -156,30 +158,45 @@ inet_ntop6(src, dst, size)
156 * Format the result. 158 * Format the result.
157 */ 159 */
158 tp = tmp; 160 tp = tmp;
159 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { 161 ep = tmp + sizeof(tmp);
162 for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) {
160 /* Are we inside the best run of 0x00's? */ 163 /* Are we inside the best run of 0x00's? */
161 if (best.base != -1 && i >= best.base && 164 if (best.base != -1 && i >= best.base &&
162 i < (best.base + best.len)) { 165 i < (best.base + best.len)) {
163 if (i == best.base) 166 if (i == best.base) {
167 if (tp + 1 >= ep)
168 return (NULL);
164 *tp++ = ':'; 169 *tp++ = ':';
170 }
165 continue; 171 continue;
166 } 172 }
167 /* Are we following an initial run of 0x00s or any real hex? */ 173 /* Are we following an initial run of 0x00s or any real hex? */
168 if (i != 0) 174 if (i != 0) {
175 if (tp + 1 >= ep)
176 return (NULL);
169 *tp++ = ':'; 177 *tp++ = ':';
178 }
170 /* Is this address an encapsulated IPv4? */ 179 /* Is this address an encapsulated IPv4? */
171 if (i == 6 && best.base == 0 && 180 if (i == 6 && best.base == 0 &&
172 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 181 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
173 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) 182 if (!inet_ntop4(src+12, tp, (size_t)(ep - tp)))
174 return (NULL); 183 return (NULL);
175 tp += strlen(tp); 184 tp += strlen(tp);
176 break; 185 break;
177 } 186 }
178 tp += sprintf(tp, "%x", words[i]); 187 advance = snprintf(tp, ep - tp, "%x", words[i]);
188 if (advance <= 0 || advance >= ep - tp)
189 return (NULL);
190 tp += advance;
179 } 191 }
180 /* Was it a trailing run of 0x00's? */ 192 /* Was it a trailing run of 0x00's? */
181 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) 193 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
194 if (tp + 1 >= ep)
195 return (NULL);
182 *tp++ = ':'; 196 *tp++ = ':';
197 }
198 if (tp + 1 >= ep)
199 return (NULL);
183 *tp++ = '\0'; 200 *tp++ = '\0';
184 201
185 /* 202 /*