Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Wireshark-users: Re: [Wireshark-users] capture short packets in tcpdump/tshark?

Date Prev · Date Next · Thread Prev · Thread Next
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Tue, 27 Jan 2015 00:52:37 -0800
On Jan 26, 2015, at 9:25 PM, Mathias Koerber <mathias@xxxxxxxxxxx> wrote:

> On one system, we see a few
> 
> UDP: short packet: From a.b.c.d:xx 50/44 to
> e.f.g.h:yy
> 
> which then apparently the kernel drops.
> 
> If I capture all traffic on that NIC (using tcpdump or
> tshark) will these show up in the capture, or will the kernel
> drop them before the libpcap lib even sees them?

On most if not of the OSes supported by libpcap, including Linux, as long as the *network adapter itself* doesn't do processing on input that would cause it to drop those packets rather than handing them to the host, the code path to libpcap is different from the code path to a socket that would normally receive UDP input to a particular port, so they should show up in the capture.

> If they are captured, how to I filter for these in wireshark/tshark?

From a quick look at the Linux kernel, that message apparently means that either:

	1) the length field in the UDP header:

		http://tools.ietf.org/html/rfc768

	   is less than 8, which is an error because that length includes the length of the UDP header itself, which is 8 bytes, so it cannot be < 8 in a valid packet

or

	2) some internal "this should not happen" error occurred.

2) isn't some characteristic of the packet, it's a characteristic of the code path, so you can't filter for it, and it shouldn't happen anyway, so that's probably not what you're seeing.

1) can be filtered for.

For a capture filter, so that you can run a capture and only capture the packets in question:

In a UDP packet, the length field is a 2-byte big-endian field at an offset of 4 from the beginning of the UDP header, and:

$ man pcap-filter

	...

       expr relop expr
              True if the relation holds, where relop is one of >, <, >=,
              <=, =, !=, and expr is an arithmetic expression composed of
              integer constants (expressed in  standard  C  syntax),  the
              normal  binary  operators  [+,  -,  *,  /, &, |, <<, >>], a
              length operator, and special packet data  accessors.   Note
              that  all  comparisons  are unsigned, so that, for example,
              0x80000000 and 0xffffffff are > 0.  To access  data  inside
              the packet, use the following syntax:
                   proto [ expr : size ]
              Proto is one of ether, fddi, tr, wlan, ppp, slip, link, ip,
              arp, rarp, tcp, udp, icmp, ip6 or radio, and indicates  the
              protocol  layer  for  the  index  operation.  (ether, fddi,
              wlan, tr, ppp, slip and link all refer to the  link  layer.
              radio  refers  to  the  "radio header" added to some 802.11
              captures.)  Note that tcp, udp and other upper-layer proto-
              col  types only apply to IPv4, not IPv6 (this will be fixed
              in the future).  The byte offset, relative to the indicated
              protocol  layer,  is  given  by expr.  Size is optional and
              indicates the number of bytes in the field of interest;  it
              can  be either one, two, or four, and defaults to one.  The
              length operator, indicated by the keyword  len,  gives  the
              length of the packet.

              For  example,  `ether[0]  &  1  != 0' catches all multicast
              traffic.  The expression `ip[0] & 0xf  !=  5'  catches  all
              IPv4  packets  with  options.   The  expression  `ip[6:2] &
              0x1fff = 0' catches only unfragmented  IPv4  datagrams  and
              frag  zero  of  fragmented  IPv4  datagrams.  This check is
              implicitly applied to the tcp  and  udp  index  operations.
              For instance, tcp[0] always means the first byte of the TCP
              header, and never means the first byte  of  an  intervening
              fragment.

so udp[4:2] should fetch the length field and "udp[4:2] < 8" should cause only packets with a too-short UDP length to be captured.  (That will, as noted, work only for UDP-over-IPv4, not for UDP-over-IPv6; UDP-over-IPv6 isn't supported there - the future hasn't arrived yet.)

For a display filter, so that, if you have a capture and you want to find packets of that sort in it:

The UDP length field is named "udp.length", so "udp.length < 8" will find those packets.  (That will work over IPv4 or over IPv6.)