Actually, you can calculate the offset of the tcp payload by examining
tcp[12] and adjusting accordingly. The following filter will match on the
string "QUIT" regardless of tcp options length:
tcp[((tcp[12] & 0xf0) / 4):4] = 0x51554954
You need to first mask off the low-order nibble and then bit-shift the
result (divide by 16), then multiply that by 4 (bytes per word) to arrive
at the actual data offset.
Cheers!
On Mon, 16 Dec 2002 22:39:11 -0800
Guy Harris <[EMAIL PROTECTED]> wrote:
> On Mon, Dec 16, 2002 at 08:45:46PM -0500, Sam Carleton wrote:
> > My first exposure to pcap was through the program snort. Being a C/C++
> > Windows programmer, I would like to have a bit more control over the info
> > I would like to capture. Thus I am now looking into pcap as the engine
> > for my packet capture program.
> >
> > The only thing I am scratching my head about is the filtering. I need to
> > filter based on content, the first two bites of the packet, not the addr
> > or even port. Can I create a rule for pcap that will filter based on
> > content?
>
> Yes:
>
> hostname$ man tcpdump
>
> TCPDUMP(1) User Commands TCPDUMP(1)
>
> NAME
> tcpdump - dump traffic on a network
>
> ...
>
> expression
> selects which packets will be dumped. If no expression
> is given, all packets on the net will be dumped. Oth-
> erwise, only packets for which expression is `true'
> will be dumped.
>
> The expression consists of one or more primitives.
>
> ...
>
> In addition to the above, there are some special `prim-
> itive' keywords that don't follow the pattern: gate-
> way, broadcast, less, greater and arithmetic expres-
> sions. All of these are described below.
>
> More complex filter expressions are built up by using
> the words and, or and not to combine primitives. E.g.,
> `host foo and not port ftp and not port ftp-data'. To
> save typing, identical qualifier lists can be omitted.
> E.g., `tcp dst port ftp or ftp-data or domain' is
> exactly the same as `tcp dst port ftp or tcp dst port
> ftp-data or tcp dst port domain'.
>
> Allowable primitives are:
>
> ...
>
> 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 protocol 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 mul-
> ticast traffic. The expression `ip[0] & 0xf != 5'
> catches all IP packets with options. The expres-
> sion `ip[6:2] & 0x1fff = 0' catches only unfrag-
> mented 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.
>
> so as long as you're testing bytes at *fixed offset* from the beginning
> of the link-layer (e.g., Ethernet), network layer (e.g., IP), or
> transport layer (e.g., TCP) header, the libpcap filter syntax can handle
> it.
>
> Note, however, that the length of the TCP header is not necessarily
> fixed length, as it might have options, so if you want to, for example,
> filter based on the content of the TCP payload *and* you want it to
> handle TCP packets with options, you'd have to construct the BPF filter
> code yourself.
>
> > The other thing I need a bit of help with is the flags. I understand the
> > basics, but I have never done any heavy dude IP programming. The snort
> > rule I have contains "flags:AP+". From looking at the snort docs, that
> > means ACK, PSH, and "ALL flag, match on all specified flags plus any
> > others". Would not simply have a + get the same thing done?
>
> That is not a valid libpcap filter expression.
>
> With older versions of libpcap, you would have to test the appropriate
> byte of the TCP header by hand; see RFC 793 to see what byte, and what
> bits, that is.
>
> With newer versions of libpcap, you can test some bits by name:
>
> Some offsets and field values may be expressed as
> names rather than as numeric values. The follow-
> ing protocol header field offsets are available:
> icmptype (ICMP type field), icmpcode (ICMP code
> field), and tcpflags (TCP flags field).
>
> ...
>
> The following TCP flags field values are avail-
> able: tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-
> push, tcp-ack, tcp-urg.
>
> ...
>
> EXAMPLES
>
> To print the start and end packets (the SYN and FIN packets)
> of each TCP conversation that involves a non-local host.
> tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net
>localnet'
>
> If you want that on Windows, you'd need, I think, WinPcap 3.0 alpha - I
> think 2.3 was based on a version of libpcap that didn't have those
> symbolic names.
> -
> This is the TCPDUMP workers list. It is archived at
> http://www.tcpdump.org/lists/workers/index.html
> To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe
--
George Bakos
Institute for Security Technology Studies
Dartmouth College
[EMAIL PROTECTED]
voice 603-646-0665
fax 603-646-0666
Key fingerprint = D646 8F91 F795 27EC FF8B 8C95 B102 9EB2 081E CB85
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe