diff options
Diffstat (limited to 'src/lib/libc/net/inet_ntop.c')
-rw-r--r-- | src/lib/libc/net/inet_ntop.c | 35 |
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 |
21 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; | 21 | static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; |
22 | #else | 22 | #else |
23 | static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.3 2002/05/24 21:22:37 deraadt Exp $"; | 23 | static 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 | /* |