type we see, not the *last*, so the first one gets printed. If,
however, a rates IE has a zero-length list of rates, don't save that
one; some devices send out frames with two rates IEs, one zero-length
and a later one containing the actual rates.
Have parse_elements() return an indication of whether truncation
occurred - and pass it the frame length, so it doesn't just keep parsing
until an end-of-captured-data test fails, as that would make *every*
frame look truncated.
"present but truncated", and "not present", and don't have it return an
indication of whether we ran past the end of a packet - instead, have
the routines that handle particular management frame types use macros
that check what the status of a particular tagged parameter is and:
print it if present and not truncated;
skip it if not present;
return a "packet truncated" indication if present but truncated.
This means we handle tagged parameters that aren't present, and print
parameters that are present and not truncated even if there's a
present-but-truncated field after them.
Add some additional bounds checks.
Make the table of rates bigger - there can be more than 8 rates in a
rates tagged parameter.
IEEE802_11_AP_LEN as the length of the previous AP in reassociation
frame.
Before copying variable-length fields from a management frame IE, make
sure the length isn't too large.
[This patch] fixes some bugs and adds a new feature. Control
packets were showing as [|802.11] because tcpdump expected for
there to be an FCS on each one (wrong assumption). Also, even
if pieces of a control packet are missing, I have made tcpdump
print its type when it knows it. The new features is that if
you give -v, the 802.11 Duration field (for virtual carrier
sense) is printed. This is useful for detecting
hardware/firmware bugs (!!) and for debugging the new crop of
802.11 drivers.
compile with Sun C, as "interface.h" isn't being included before the
structures are being declared.
Furthermore, in the files that Sun C *can* compile, it doesn't cause Sun
C to generate code that's safe with unaligned accesses, as
"__attribute__" is defined as a do-nothing macro with compilers that
don't support it.
Therefore, we get rid of that tag on the structures to which it was
added, and instead use "EXTRACT_16BIT()" and "EXTRACT_32BIT()" to fetch
16-bit and 32-bit big-endian quantities from packets. We also fix some
other references to multi-byte quantities to get rid of code that tries
to do unaligned loads on platforms that don't support them.
We also throw in a hack that makes those macros use
"__attribute__((packed))" on structures containing only one 16-bit or
32-bit integer to get the compiler to generate unaligned-safe code
rather than doing it by hand. (GCC on SPARC produces the same code that
doing it by hand does; I don't know if GCC on any other big-endian
strict-alignment processor generates better code for that case. On
little-endian processors, as "ntohs()" and "ntohl()" might be functions,
that might actually produce worse code.)
Fix some places to use "%u" rather than "%d" to print unsigned
quantities.
structures for the headers might have padding added by the compiler (I
think at least some versions of GCC for ARM, for example, pad structures
to a multiple of 4 bytes in length), use explicit #define values.
The sequence control field of a management frame header is 16 bits long,
not 8 bits long.
that may force it to be aligned on a 4-byte boundary, and it's not
always aligned on a 4-byte boundary in those structures.
Add a bunch of bounds checking.
"ctrl_body_print()" expects its first argument to point to the beginning
of the link-level frame; pass it a pointer to that, not to the stuff
following the link-level frame.