Ethereal-users: Re: [ethereal-users] filter for payload

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Mon, 14 Aug 2000 01:48:12 -0700
On Mon, Aug 14, 2000 at 09:37:02AM +0200, Sven Bruelisauer wrote:
> among all the nice filtering rules I could not find a way to set up a
> filter which filters the
> payload of an ip- packet (data). how can I look for a specific string in
> the packet-payload for 
> example ?

Look for a specific string at a specific location in the packet, or look
for it anywhere in the packet?

Neither the capture filter mechanism of libpcap nor the display filter
mechanism of Ethereal support filter expressions that match packets with
specific strings anywhere in the packet.

However:

	the libpcap capture filter mechanism (as documented in the
	tcpdump man page) does let you look for specific one-byte,
	2-byte, or 4-byte values at specific offsets from the beginning
	of the MAC-layer (Ethernet/FDDI) header, IP header, ARP/RARP
	header, TCP header, UDP header, or ICMP header:

             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.  To access data  inside  the
                     packet, use the following syntax:
                          proto [ expr : size ]
                     Proto  is one of ether, fddi, ip, arp, rarp,
                     tcp, udp, or icmp, and indicates the  proto-
                     col layer for the index operation.  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  IP  packets  with
                     options.  The expression `ip[6:2] & 0x1fff =
                     0' catches only unfragmented  datagrams  and
                     frag  zero  of  fragmented  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.

	the Ethereal display filter mechanism supports a similar
	mechanism, as documented in the Ethereal man page:

	       A substring operator also exists.  You can check the
	       substring (byte-string) of any protocol or field.  For
	       example, you can filter on the vendor portion of an
	       ethernet address (the first three bytes) like this:

		   eth.src[0:3] == 00:00:83

	       Or more simply, since the number of bytes is inherent in
	       the byte-string you provide, you can provide just the
	       offset.	The previous example can be stated like this:

		   eth.src[0] == 00:00:83

	       In fact, the only time you need to explicitly provide a
	       length is when you don't provide a byte-string, and are
	       comparing fields against fields:

		   fddi.src[0:3] == fddi.dst[0:3]

	       If the length of your byte-string is only one byte, then
	       it must be represented in the same way as an unsigned
	       8-bit integer:

		   llc[3] == 0xaa

	       You can use the substring operator on a protocol name,
	       too.  And remember, the "frame" protocol encompasses the
	       entire packet, allowing you to look at the nth byte of a
	       packet regardless of its frame type (Ethernet, token-ring,
	       etc.).

		   token[0:5] ne 0.0.0.1.1
		   ipx[0:2] == ff:ff
		   llc[3:1] eq 0xaa

	       Offsets for byte-strings can also be negative, in which
	       case the negative number indicates the number of bytes
	       from the end of the field or protocol that you are
	       testing.  Here's how to check the last 4 bytes of a frame:

		   frame[-4] == 0.1.2.3

	       or

		   frame[-4:4] == 0.1.2.3

Unfortunately, the capture filter mechanism doesn't let you specify
strings (and doesn't let you compare anything other than 1-byte, 2-byte,
or 4-byte values), and the display filter mechanism doesn't seem to
support matching strings against substrings (e.g.

	http[0] == "HTTP"

gives a parse error, rather than finding all HTTP packets beginning with
"HTTP").