Ethereal-users: Re: [Ethereal-users] Capturing only Cisco Discovery Protocol (CDP) Packets.

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: Mon, 4 Mar 2002 15:55:35 -0800
On Mon, Mar 04, 2002 at 06:00:36PM -0500, Karl Lherisson wrote:
> Unfortunately, I don't know how to setup
> ethereal to only capture CDP packets without having to capture everything
> else.  Does anyone know how to correctly setup the capture filter to only
> receive CDP?  

Well, CDP packets, over Ethernet, are 802.3 packets (rather than
DEC/Intel/Xerox Ethernet packets) with 802.2 LLC SNAP headers with an
OUI of 0x00000C and a protocol ID of 0x2000.

So, that means the capture filter has to check for:

	1) an 802.3 packet;

	2) a SNAP packet;

	3) an OUI of 0x00000C;

	4) a protocol ID of 0x2000.

using the

	  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.

	  Primitives may be combined using:

	       A parenthesized group of	primitives and	operators
	       (parentheses  are special to the	Shell and must be
	       escaped).

	       Negation	(`!' or	`not').

	       Concatenation (`&&' or `and').

	       Alternation (`||' or `or').

	  Negation has highest precedence.  Alternation	and  con-
	  catenation  have equal precedence and	associate left to
	  right.  Note that explicit and tokens,  not  juxtaposi-
	  tion,	are now	required for concatenation.

	  If an	identifier is given without a keyword,	the  most
	  recent keyword is assumed.  For example,
	       not host	vs and ace
	  is short for
	       not host	vs and host ace
	  which	should not be confused with
	       not ( host vs or	ace )

expression syntax (the above comes from the tcpdump man page).

The first test is a test of the type/length field, to see whether it's
<= 1500; <= 1500 means it's a length field, and thus an 802.3 packet,
while > 1500 means it's a type field, and thus a D/I/X packet.

The type/length field is 2 bytes long, at an offset of 12 from the
beginning of the Ethernet header, so that's

	ether[12:2] <= 1500

The second test is a test of the 2 bytes *after* the 14-byte Ethernet
header, comparing them both with 0xAA, and of the third byte, comparing
it with 0x03; that'd be

	ether[14:2] == 0xAAAA && ether[16:1] == 0x03

The third test is a test of the 3 bytes after the 3-byte LLC header,
comparing them with 0x00000C; that'd be

	ether[17:2] == 0x0000 && ether[19:1] == 0x0C

The fourth test is a test of the 2 bytes after those three bytes,
comparing them with 0x2000; that'd be

	ether[20:2] == 0x2000

so an expression testing for CDP packets would be

	ether[12:2] <= 1500 && ether[14:2] == 0xAAAA && ether[16:1] == 0x03 &&
	  ether[17:2] == 0x0000 && ether[19:1] == 0x0C && ether[20:2] == 0x2000

It might be nice to have a keyword in the capture filter expression to
check for SNAP packets with a particular OUI and protocol ID (there's
already an internal routine in the current version of libpcap, used for
various SNAP-based protocols, that will generate BPF code to check for a
SNAP header with a given OUI and PID; we'd add items to the grammar to
let you specify explicit OUI and PID values), and perhaps also an
explicit "cdp" keyword.  That's not available now, and would only be
generally available when a libpcap release comes out with it - and it'd
be available to UNIX users only if their OS comes with that version of
libpcap or they install that version of libpcap, and available to
Windows users only after a WinPcap release comes out based on that
libpcap release, so its availability is not under the control of the
Ethereal developers.