Add EXTRACT_IPV4_TO_HOST_ORDER() and EXTRACT_IPV4_TO_NETWORK_ORDER();
the former extracts a possibly-unaligned IPv4 address, in network byte
order, returning a uint32_t in host byte order, and the latter extracts
a possibly-unaligned IPv4 address, in network byte order, returning a
uint32_t in *network* byte order. Some APIs take an address in network
byte order, and some operations are more easily done in host byte order,
so both are useful.
Remove the structure wrappers around nd_ipv4 and nd_ipv6; that makes it
easier to pass variables of those types to functions/macros that take a
byte pointer as an argument (because they might be used either with
pointers to structure members or raw buffer pointers), and the structure
probably wouldn't do much to prevent people from using EXTRACT_BE_U_4()
when they really want to extract the value in *network* byte order;
using the above EXTRACT_IPV4_ calls should do more to encourage that.
Have separate cpack_ routines for signed and unsigned numbers, with the
signed ones using _S_ extract macros. That way, we can do more type
checking.
Add EXTRACT_LE_S_ macros.
Use signed variables for IEEE80211_RADIOTAP_TX_ATTENUATION and
IEEE80211_RADIOTAP_DB_TX_ATTENUATION, rather than using unsigned
variables that we cast to int.
Also, use EXTRACT_U_1() in cpack_uint8.
Now all the macros have a name meaning a count in bytes.
With _S_: signed, _U_: unsigned
e.g.:
EXTRACT_BE_32BITS -> EXTRACT_BE_U_4
EXTRACT_LE_32BITS -> EXTRACT_LE_U_4
...
EXTRACT_BE_INT32 -> EXTRACT_BE_S_4
and have:
EXTRACT_8BITS -> EXTRACT_U_1
EXTRACT_INT8 -> EXTRACT_S_1
This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.
Add a test using the capture file supplied by the reporter(s), modified
so the capture file won't cause 'tcpdump: pcap_loop: truncated dump file'
Do a lot more bounds and length checks.
Add a EXTRACT_8BITS() macro, for completeness, and so as not to confuse
people into thinking that, to fetch a 1-byte value from a packet, they
need to use EXTRACT_16BITS() to fetch a 2-byte value and then use
shifting and masking to extract the desired byte. Use that rather than
using EXTRACT_16BITS() to fetch a 2-byte value and then shifting and
masking to extract the desired byte.
Don't treat IPv4 addresses and unnumbered interface IDs the same; the
first should be printed as an IPv4 address but the latter should just be
printed as numbers. Handle IPv6 addresses in more object types while
we're at it.
This fixes a buffer over-read discovered by Forcepoint's security
researchers Otto Airamo & Antti Levomäki.
Add a test using the capture file supplied by the reporter(s).
Yes, the behavior of an access with an improperly-aligned pointer is
undefined according to the C standard, but if we're doing that in an
EXTRACT_ function/macro, we're doing it because we know it's safe and
because it's faster than picking the bytes out one by one and assembling
them, so suppress those warnings.
Pull over libpcap's funcattrs.h and use it to do a bunch of checks for
various function attributes; that defines __has_attribute(), so we can
use it to check for the "suppress sanitizer warnings" attribute.
While we're at it, use other things it defines to specify "this function
never returns", "this function is printf-like", and "this function
argument is a printf-style format argument", rather than using various
configure-script checks. That should let us declare some function
attributes with Microsoft Visual Studio's compilers.
The bounds checks fix some heap overflows found with American Fuzzy Lop
by Hanno Böck.
Add some ND_TTEST_/ND_TCHECK_ macros to extract.h to simplify writing
bounds checks for code that uses the other macros in that file.
Fix the printing of the SPB BPDU agreement digest - I don't think the
intent was to print the value of the first 4 bytes, that value + 4, that
value + 8, etc., I suspect it was to print the first 4 bytes, the next 4
bytes, etc..
Define them in netdissect.h.
Use them in ip.h, and *don't* mark the structures as UNALIGNED; that
should no longer be necessary.
Add a new nd_ipv4 type to use as an IPv4 address; it represents the 4
bytes of IPv4 address as an array of unsigned chars, so that its natural
alignment is only on a byte boundary.
Those changes found some places where we weren't using
UNALIGNED_MEMCPY() to extract IPv4 addresses from packets; use it.
They are defined as arrays of bytes, so
1) no padding is inserted before them to put them on natural
boundaries, so they can be used if the values *aren't* so
aligned;
2) you have to use EXTRACT_ macros with them - which you should
be doing *anyway*, to avoid explicitly or implicitly making
assumptions about byte order or alignment safety on the
platform for which your code is being built (it'd better work
when built for little-endian x86 or for big-endian *and*
strict-alignment-requiring SPARC).
Use them in the LISP (no, not the programming language!) dissector;
UNALIGNED means "this structure is not guaranteed to be aligned as a
whole, so don't generate code that assumes it is", not "this structure's
individual members shouldn't have padding to put them on natural
boundaries", so it's not sufficient to do that. (Using these types
*might* suffice to ensure that code that assumes alignment not be
generated, but never underestimate SPARC compilers' eagerness to use
single load and store instructions to fetch big-endian 16-bit, 32-bit,
and 64-bit values from packets that really aren't guaranteed to be
aligned.)
I'm not sure whether
Performing a byte swapping operation on "p" implies that it came
from an external source, and is therefore tainted.
from Coverity means that it thinks we're byte-swapping the pointer
*itself*, or that we're byte-swapping what it points to, but, just in
case it's the former, let's try throwing some more parentheses in.
(If it's the latter, well, yes, it's packet data, so it comes from an
external source, but Coverity didn't seem to point out any place where
we were using the data it points to without checking its value in cases
where we have to.)
Add macros to, given an octet pointer, extract 40-bit, 48-bit, and
56-bit big-endian numbers from the location pointed to by that pointer,
and use them when extracting ACK numbers from DCCP packets. This fixes
problems on big-endian(!) machines.
It won't necessarily work with non-GCC-compatible compilers, so use it
only on GCC-compatible compilers.
Even with some GCC-compatible compilers (such as, err, umm, GCC), it
doesn't do the right thing on some platforms, e.g. 64-bit SPARC, where
the compiler generates code that assumes alignment even when using it.
The only platforms I know of where an unaligned big-endian load can be
done better than by loading bytes and shifting-and-ORing them together
are MIPS and possibly Alpha, so only do it there.
Remove lots of $Header's and a few $Id's that all belong to the former
CVS repository of tcpdump itself. These keywords have been frozen since
the migration to git in late 2008.
convince GCC to generate alignment-safe loads by using
__attribute((packed))" version of EXTRACT_64BITS().
Fix one of the byte offsets in the "alignment required and we don't know
how to trick the compiler into generating alignment-safe loads" version
of EXTRACT_64BITS().
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.
From Neil T. Spring: fixes for many of those warnings:
addrtoname.c, configure.in: Linux needs netinet/ether.h for
ether_ntohost
print-*.c: change char *foo = "bar" to const char *foo = "bar"
to appease -Wwrite-strings; should affect no run-time behavior.
print-*.c: make some variables unsigned.
print-bgp.c: plen ('prefix len') is unsigned, no reason to
validate by comparing to zero.
print-cnfp.c, print-rx.c: use intoa, provided by addrtoname,
instead of inet_ntoa.
print-domain.c: unsigned int l; (l=foo()) < 0 is guaranteed to
be false, so check for (u_int)-1, which represents failure,
explicitly.
print-isakmp.c: complete initialization of attrmap objects.
print-lwres.c: "if(x); print foo;" seemed much more likely to be
intended to be "if(x) { print foo; }".
print-smb.c: complete initialization of some structures.
In addition, add some fixes for the signed vs. unsigned comparison
warnings:
extract.h: cast the result of the byte-extraction-and-combining,
as, at least for the 16-bit version, C's integral promotions
will turn "u_int16_t" into "int" if there are other "int"s
nearby.
print-*.c: make some more variables unsigned, or add casts to an
unsigned type of signed values known not to be negative, or add
casts to "int" of unsigned values known to fit in an "int", and
make other changes needed to handle the aforementioned variables
now being unsigned.
print-isakmp.c: clean up the handling of error/status indicators
in notify messages.
print-ppp.c: get rid of a check that an unsigned quantity is >=
0.
print-radius.c: clean up some of the bounds checking.
print-smb.c: extract the word count into a "u_int" to avoid the
aforementioned problems with C's integral promotions.
print-snmp.c: change a check that an unsigned variable is >= 0
to a check that it's != 0.
Also, fix some formats to use "%u" rather than "%d" for unsigned
quantities.
Use const more.
Use EXTRACT_* macros more.
Use TCHECK* more.
Use tok2str() to replace some home-grown workalikes.
smb:
- Get rid of private types, use tcpdump-defined types
- Rename fdata and fdata1 to smb_fdata and smb_fdata1 to avoid conflict
with IRIX library function.