Ethereal-dev: Re: [Ethereal-dev] New capture filters

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

From: Guy Harris <guy@xxxxxxxxxx>
Date: Wed, 17 Oct 2001 21:29:04 -0700 (PDT)
> I need to add new capture filters in ethereal-0.8.18 to support two
> propietory protocols.
> 
> One protocol is over PPP and the other is over UDP.
> 
> Each of the propietory protocol in turn has other propietory or internet
> protocols over it....just like encapsulation / tunneling.
> 
> 1) How do I go about it ??
>     Do I need to
>     a) change the BPF filters in side the kernel
>     b) or the LibPcap source code
>     c) or just use the LibPcap interfaces ??

The libpcap source code, assuming that the filter you need can be
compiled into a BPF program.

Note, however, that many of the filters that can be compiled into a BPF
program can be expressed in the standard libpcap language; from the
tcpdump man page:

      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. ...

		...

	  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.

and those can be combined, using "and" and "or", with other expressions,
including, for example, "udp", so you could just use the standard
libpcap interfaces (i.e., just type the expression in question into
tcpdump, or Tethereal, or Ethereal).

> 2) This is required in both Linux and Windows version of Ethereal. So
> code modifications needs to be portable.

WinPcap uses the same code generation code as libpcap, so modifications
to one should work in the other (although WinPcap is currently based on
an older version of libpcap than the current one from tcpdump.org).

> 3) The capture filter needs to be stateful. Is it possible to create a
> stateful capture filter?

That's really the first question you should have asked, because the
answer is "no", which means the answers to the other questions may be
completely irrelevant.  BPF maintains *NO* state between packets
whatsoever - the pass/fail decision it makes must be based solely on the
contents of the packet it's testing.