diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-10-20 12:29:18 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-10-20 12:29:18 +0200 |
commit | 1dff672335ce227c0875864e3819c8464f978c08 (patch) | |
tree | b66d7fcbaa345ffbadccee19d7af0809bc96d5a5 /networking/udhcp/dhcpc.c | |
parent | 42816c204d2c592a86498c3d3b215c9b4d80e9e1 (diff) | |
download | busybox-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.c | 50 |
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 | ||