mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-26 10:39:23 +01:00
monitor: Support arbitrarily long bitfields
Support arbitrarily long bitfields by providing field and mask values as arrays with their length measured in bytes. Some of the IE fields easily reach 80 bits or more, thus easily overrunning any integer sizes used by the OS architecture.
This commit is contained in:
parent
1637f3519a
commit
6d652fb743
@ -681,12 +681,16 @@ static const char *rsn_capabilities_bitfield[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void print_ie_bitfield(unsigned int level, const char *label,
|
static void print_ie_bitfield(unsigned int level, const char *label,
|
||||||
uint64_t bits, const char *bitfield_table[])
|
const uint8_t *bytes, const uint8_t *mask, size_t len,
|
||||||
|
const char *bitfield_table[])
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; bitfield_table[i]; i++) {
|
for (i = 0; i < len * 8; i++) {
|
||||||
if (!(bits & 1 << i))
|
uint8_t byte = i / 8;
|
||||||
|
uint8_t bit = i % 8;
|
||||||
|
|
||||||
|
if (!util_is_bit_set(bytes[byte] & mask[byte], bit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
print_attr(level, "%s: bit %2d: %s", label, i,
|
print_attr(level, "%s: bit %2d: %s", label, i,
|
||||||
@ -699,7 +703,8 @@ static void print_ie_rsn(unsigned int level, const char *label,
|
|||||||
{
|
{
|
||||||
const void *end = data + size;
|
const void *end = data + size;
|
||||||
|
|
||||||
uint16_t version, count, rsn_capa;
|
uint16_t version, count;
|
||||||
|
uint8_t bytemask[2];
|
||||||
int i;
|
int i;
|
||||||
const char *rsn_capabilities_replay_counter[] = {
|
const char *rsn_capabilities_replay_counter[] = {
|
||||||
"1 replay counter",
|
"1 replay counter",
|
||||||
@ -760,22 +765,25 @@ static void print_ie_rsn(unsigned int level, const char *label,
|
|||||||
if (end - data < 2)
|
if (end - data < 2)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
rsn_capa = l_get_le16(data);
|
|
||||||
data += 2;
|
data += 2;
|
||||||
|
|
||||||
print_ie_bitfield(level + 1, "RSN capabilities", rsn_capa & 0x0003,
|
bytemask[0] = 0x03;
|
||||||
rsn_capabilities_bitfield);
|
bytemask[1] = 0x00;
|
||||||
|
print_ie_bitfield(level + 1, "RSN capabilities", data, bytemask,
|
||||||
|
sizeof(bytemask), rsn_capabilities_bitfield);
|
||||||
|
|
||||||
count = (rsn_capa & 0x000c) >> 2;
|
count = (*((uint8_t *)data) & 0x0c) >> 2;
|
||||||
print_attr(level + 1, "RSN capabilities: bits 3 - 4: %s per PTKSA",
|
print_attr(level + 1, "RSN capabilities: bits 3 - 4: %s per PTKSA",
|
||||||
rsn_capabilities_replay_counter[count]);
|
rsn_capabilities_replay_counter[count]);
|
||||||
|
|
||||||
count = (rsn_capa & 0x0030) >> 4;
|
count = (*((uint8_t *)data) & 0x30) >> 4;
|
||||||
print_attr(level + 1, "RSN capabilities: bits 5 - 6: %s per GTKSA",
|
print_attr(level + 1, "RSN capabilities: bits 5 - 6: %s per GTKSA",
|
||||||
rsn_capabilities_replay_counter[count]);
|
rsn_capabilities_replay_counter[count]);
|
||||||
|
|
||||||
print_ie_bitfield(level + 1, "RSN capabilities", rsn_capa & 0xffc0,
|
bytemask[0] = 0xc0;
|
||||||
rsn_capabilities_bitfield);
|
bytemask[1] = 0xff;
|
||||||
|
print_ie_bitfield(level + 1, "RSN capabilities", data, bytemask,
|
||||||
|
sizeof(bytemask), rsn_capabilities_bitfield);
|
||||||
|
|
||||||
if (end - data < 2)
|
if (end - data < 2)
|
||||||
goto end;
|
goto end;
|
||||||
|
Loading…
Reference in New Issue
Block a user