aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpc.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-10-20 12:29:18 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-10-20 12:29:18 +0200
commit1dff672335ce227c0875864e3819c8464f978c08 (patch)
treeb66d7fcbaa345ffbadccee19d7af0809bc96d5a5 /networking/udhcp/dhcpc.c
parent42816c204d2c592a86498c3d3b215c9b4d80e9e1 (diff)
downloadbusybox-w32-1dff672335ce227c0875864e3819c8464f978c08.tar.gz
busybox-w32-1dff672335ce227c0875864e3819c8464f978c08.tar.bz2
busybox-w32-1dff672335ce227c0875864e3819c8464f978c08.zip
udhcpc: fix 6rd option formatting (was using 4 more bytes than there is)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp/dhcpc.c')
-rw-r--r--networking/udhcp/dhcpc.c50
1 files changed, 23 insertions, 27 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index d1e40ee65..d9269f277 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -161,8 +161,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
161 int len, type, optlen; 161 int len, type, optlen;
162 char *dest, *ret; 162 char *dest, *ret;
163 163
164 /* option points to OPT_DATA, need to go back and get OPT_LEN */ 164 /* option points to OPT_DATA, need to go back to get OPT_LEN */
165 len = option[OPT_LEN - OPT_DATA]; 165 len = option[-OPT_DATA + OPT_LEN];
166 166
167 type = optflag->flags & OPTION_TYPE_MASK; 167 type = optflag->flags & OPTION_TYPE_MASK;
168 optlen = dhcp_option_lengths[type]; 168 optlen = dhcp_option_lengths[type];
@@ -252,39 +252,29 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
252 252
253 return ret; 253 return ret;
254 } 254 }
255 case OPTION_6RD: { 255 case OPTION_6RD:
256 /* Option binary format (see RFC 5969): 256 /* Option binary format (see RFC 5969):
257 * 0 1 2 3 257 * 0 1 2 3
258 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 258 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
259 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 259 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
260 * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | 260 * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen |
261 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 261 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
262 * | |
263 * | 6rdPrefix | 262 * | 6rdPrefix |
264 * | (16 octets) | 263 * ... (16 octets) ...
265 * | |
266 * | |
267 * | |
268 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 264 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269 * | 6rdBRIPv4Address(es) | 265 * ... 6rdBRIPv4Address(es) ...
270 * . .
271 * . .
272 * . .
273 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 266 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
274 *
275 * We convert it to a string 267 * We convert it to a string
276 * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." 268 * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..."
277 */ 269 *
278 270 * Sanity check: ensure that our length is at least 22 bytes, that
279 /* Sanity check: ensure that our length is at least 22 bytes, that
280 * IPv4MaskLen <= 32, 271 * IPv4MaskLen <= 32,
281 * 6rdPrefixLen <= 128, 272 * 6rdPrefixLen <= 128,
282 * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 273 * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128
283 * (2nd condition need no check - it follows from 1st and 3rd). 274 * (2nd condition need no check - it follows from 1st and 3rd).
284 * If any of these requirements is not fulfilled, return with empty 275 * Else, return envvar with empty value ("optname=")
285 * value.
286 */ 276 */
287 if (len >= 22 277 if (len >= (1 + 1 + 16 + 4)
288 && option[0] <= 32 278 && option[0] <= 32
289 && (option[1] + 32 - option[0]) <= 128 279 && (option[1] + 32 - option[0]) <= 128
290 ) { 280 ) {
@@ -295,19 +285,20 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
295 /* 6rdPrefix */ 285 /* 6rdPrefix */
296 dest += sprint_nip6(dest, /* "", */ option); 286 dest += sprint_nip6(dest, /* "", */ option);
297 option += 16; 287 option += 16;
298 len -= 1 + 1 + 16; 288 len -= 1 + 1 + 16 + 4;
299 /* 6rdBRIPv4Address(es) */ 289 /* "+ 4" above corresponds to the length of IPv4 addr
290 * we consume in the loop below */
300 while (1) { 291 while (1) {
292 /* 6rdBRIPv4Address(es) */
301 dest += sprint_nip(dest, " ", option); 293 dest += sprint_nip(dest, " ", option);
302 option += 4; 294 option += 4;
303 len -= 4; 295 len -= 4; /* do we have yet another 4+ bytes? */
304 if (len < 0) 296 if (len < 0)
305 break; 297 break; /* no */
306 } 298 }
307 } 299 }
308 300
309 return ret; 301 return ret;
310 }
311#if ENABLE_FEATURE_UDHCP_RFC3397 302#if ENABLE_FEATURE_UDHCP_RFC3397
312 case OPTION_DNS_STRING: 303 case OPTION_DNS_STRING:
313 /* unpack option into dest; use ret for prefix (i.e., "optname=") */ 304 /* unpack option into dest; use ret for prefix (i.e., "optname=") */
@@ -347,6 +338,10 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
347 return ret; 338 return ret;
348#endif 339#endif
349 } /* switch */ 340 } /* switch */
341
342 /* If we are here, try to format any remaining data
343 * in the option as another, similarly-formatted option
344 */
350 option += optlen; 345 option += optlen;
351 len -= optlen; 346 len -= optlen;
352// TODO: it can be a list only if (optflag->flags & OPTION_LIST). 347// TODO: it can be a list only if (optflag->flags & OPTION_LIST).
@@ -356,7 +351,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
356 break; 351 break;
357 *dest++ = ' '; 352 *dest++ = ' ';
358 *dest = '\0'; 353 *dest = '\0';
359 } 354 } /* while */
355
360 return ret; 356 return ret;
361} 357}
362 358