udhcpc: fix 6rd option formatting (was using 4 more bytes than there is)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
42816c204d
commit
1dff672335
@ -161,8 +161,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
|
||||
int len, type, optlen;
|
||||
char *dest, *ret;
|
||||
|
||||
/* option points to OPT_DATA, need to go back and get OPT_LEN */
|
||||
len = option[OPT_LEN - OPT_DATA];
|
||||
/* option points to OPT_DATA, need to go back to get OPT_LEN */
|
||||
len = option[-OPT_DATA + OPT_LEN];
|
||||
|
||||
type = optflag->flags & OPTION_TYPE_MASK;
|
||||
optlen = dhcp_option_lengths[type];
|
||||
@ -252,39 +252,29 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
|
||||
|
||||
return ret;
|
||||
}
|
||||
case OPTION_6RD: {
|
||||
case OPTION_6RD:
|
||||
/* Option binary format (see RFC 5969):
|
||||
* 0 1 2 3
|
||||
* 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
|
||||
* 0 1 2 3
|
||||
* 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
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | |
|
||||
* | 6rdPrefix |
|
||||
* | (16 octets) |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* ... (16 octets) ...
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | 6rdBRIPv4Address(es) |
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* ... 6rdBRIPv4Address(es) ...
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
* We convert it to a string
|
||||
* "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..."
|
||||
*/
|
||||
|
||||
/* Sanity check: ensure that our length is at least 22 bytes, that
|
||||
*
|
||||
* Sanity check: ensure that our length is at least 22 bytes, that
|
||||
* IPv4MaskLen <= 32,
|
||||
* 6rdPrefixLen <= 128,
|
||||
* 6rdPrefixLen + (32 - IPv4MaskLen) <= 128
|
||||
* (2nd condition need no check - it follows from 1st and 3rd).
|
||||
* If any of these requirements is not fulfilled, return with empty
|
||||
* value.
|
||||
* Else, return envvar with empty value ("optname=")
|
||||
*/
|
||||
if (len >= 22
|
||||
if (len >= (1 + 1 + 16 + 4)
|
||||
&& option[0] <= 32
|
||||
&& (option[1] + 32 - option[0]) <= 128
|
||||
) {
|
||||
@ -295,19 +285,20 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_
|
||||
/* 6rdPrefix */
|
||||
dest += sprint_nip6(dest, /* "", */ option);
|
||||
option += 16;
|
||||
len -= 1 + 1 + 16;
|
||||
/* 6rdBRIPv4Address(es) */
|
||||
len -= 1 + 1 + 16 + 4;
|
||||
/* "+ 4" above corresponds to the length of IPv4 addr
|
||||
* we consume in the loop below */
|
||||
while (1) {
|
||||
/* 6rdBRIPv4Address(es) */
|
||||
dest += sprint_nip(dest, " ", option);
|
||||
option += 4;
|
||||
len -= 4;
|
||||
len -= 4; /* do we have yet another 4+ bytes? */
|
||||
if (len < 0)
|
||||
break;
|
||||
break; /* no */
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if ENABLE_FEATURE_UDHCP_RFC3397
|
||||
case OPTION_DNS_STRING:
|
||||
/* 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_
|
||||
return ret;
|
||||
#endif
|
||||
} /* switch */
|
||||
|
||||
/* If we are here, try to format any remaining data
|
||||
* in the option as another, similarly-formatted option
|
||||
*/
|
||||
option += optlen;
|
||||
len -= optlen;
|
||||
// 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_
|
||||
break;
|
||||
*dest++ = ' ';
|
||||
*dest = '\0';
|
||||
}
|
||||
} /* while */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user