tcpdump mailing list archives

Re: How to use specific protocol filters in pcap


From: Javier Gálvez Guerrero <javier.galvez.guerrero () gmail com>
Date: Wed, 29 Apr 2009 14:58:17 +0200

Thanks for your thoughtful answer, Guy. I will review all your
suggestions in order to achieve what I'm trying to do.

At the moment I'm trying to install libpcap 1.0.0 and tcpdump 4.0.0 as
they are tagged as the latest releases. However, I'm experiencing a
(probably) simple problem but, as I'm not such an experienced user in
these issues, I would like to ask for some help. I installed correctly
libpcap 1.0.0 but when building (make) tcpdump I get this error:

---------------------------------------------------------------------------------------------------------------------------------------------------------------
...
gcc -O2 -DHAVE_CONFIG_H  -I./missing  -D_U_="__attribute__((unused))"
-I. -I./../libpcap-1.0.0  -I./missing  -o tcpdump addrtoname.o af.o
checksum.o cpack.o gmpls.o oui.o gmt2local.o ipproto.o nlpid.o l2vpn.o
machdep.o parsenfsfh.o print-802_11.o print-ap1394.o print-ah.o
print-arcnet.o print-aodv.o print-arp.o print-ascii.o print-atalk.o
print-atm.o print-beep.o print-bfd.o print-bgp.o print-bootp.o
print-bt.o print-cdp.o print-cfm.o print-chdlc.o print-cip.o
print-cnfp.o print-dccp.o print-decnet.o print-domain.o print-dtp.o
print-dvmrp.o print-enc.o print-egp.o print-eap.o print-eigrp.o
print-esp.o print-ether.o print-fddi.o print-fr.o print-gre.o
print-hsrp.o print-icmp.o print-igmp.o print-igrp.o print-ip.o
print-ipcomp.o print-ipfc.o print-ipx.o print-isoclns.o
print-juniper.o print-krb.o print-l2tp.o print-lane.o print-ldp.o
print-lldp.o print-llc.o print-lmp.o print-lspping.o print-lwapp.o
print-lwres.o print-mobile.o print-mpcp.o print-mpls.o print-msdp.o
print-nfs.o print-ntp.o print-null.o print-olsr.o print-ospf.o
print-pgm.o print-pim.o print-ppp.o print-pppoe.o print-pptp.o
print-radius.o print-raw.o print-rip.o print-rrcp.o print-rsvp.o
print-rx.o print-sctp.o print-sflow.o print-sip.o print-sl.o
print-sll.o print-slow.o print-snmp.o print-stp.o print-sunatm.o
print-sunrpc.o print-symantec.o print-syslog.o print-tcp.o
print-telnet.o print-tftp.o print-timed.o print-token.o print-udld.o
print-udp.o print-vjc.o print-vqp.o print-vrrp.o print-vtp.o
print-wb.o print-zephyr.o setsignal.o tcpdump.o util.o version.o
print-ip6.o print-ip6opts.o print-mobility.o print-ripng.o
print-icmp6.o print-frag6.o print-rt6.o print-ospf6.o print-dhcp6.o
print-smb.o smbutil.o strlcat.o strlcpy.o datalinks.o dlnames.o
pcap_dump_ftell.o print-isakmp.o ./../libpcap-1.0.0/libpcap.a
./../libpcap-1.0.0/libpcap.a(pcap.o): In function `pcap_datalink_name_to_val':
pcap.c:(.text+0x210): multiple definition of `pcap_datalink_name_to_val'
dlnames.o:dlnames.c:(.text+0x90): first defined here
./../libpcap-1.0.0/libpcap.a(pcap.o): In function `pcap_datalink_val_to_name':
pcap.c:(.text+0x280): multiple definition of `pcap_datalink_val_to_name'
dlnames.o:dlnames.c:(.text+0x0): first defined here
./../libpcap-1.0.0/libpcap.a(pcap.o): In function
`pcap_datalink_val_to_description':
pcap.c:(.text+0x2d0): multiple definition of `pcap_datalink_val_to_description'
dlnames.o:dlnames.c:(.text+0x40): first defined here
./../libpcap-1.0.0/libpcap.a(pcap.o): In function `pcap_list_datalinks':
pcap.c:(.text+0xe20): multiple definition of `pcap_list_datalinks'
datalinks.o:datalinks.c:(.text+0x0): first defined here
./../libpcap-1.0.0/libpcap.a(savefile.o): In function `pcap_dump_ftell':
savefile.c:(.text+0x90): multiple definition of `pcap_dump_ftell'
pcap_dump_ftell.o:pcap_dump_ftell.c:(.text+0x0): first defined here
./../libpcap-1.0.0/libpcap.a(grammar.o): In function `.L29':
grammar.c:(.text+0x409): undefined reference to `pcap_lex'
collect2: ld returned 1 exit status
make: *** [tcpdump] Error 1
---------------------------------------------------------------------------------------------------------------------------------------------------------------------

I just followed the INSTALL.txt instructions, which are really simple
(the classic 1. configure; 2. make; 3. make install). I don't know if
I need to install any additional package (I previously installed bison
and flex, which were necessary for building libpcap 1.0.0).

Any help would be much appreciated, so I can get the latest tcpdump
release working.


Thank you so much for your help and time and sorry for the inconvenience,
Javi

2009/4/28 Guy Harris <guy () alum mit edu>:

On Apr 28, 2009, at 2:26 AM, Javier Gálvez Guerrero wrote:

I'm trying to catch DHCP Requests/ACK and IEEE 802.11Probe Requests and
Association ACK packets in a custom C program using libpcap but I'm facing
some problems when applying filter chains different than simple ones like
'ether dst X' or 'port Y'. I would like to know what should I do in order
to
properly get packets with libpcap that Wireshark show me when issuing
filter
chains like:

bootp.option.value == 03
wlan.fc.type_subtype == 0x04

If I use a filter like the previous ones I get a filter compiling error in
'pcap_compile(descr, &fp, filter, 0, netp)', so I would like to know how
to
get the same information with a pcap/tcpdump-compliant filter. Any idea
about how I could do it?

Whether you can, and how you'd do it, depends on the filter.

Libpcap translates the filter into a program in a pseudo-machine language,
and the program is, on many platforms (*BSD, Mac OS X, Tru64 UNIX, Linux if
you have "socket filter" support in the kernel, Windows) loaded into the
kernel, so that packets that don't match the filter are discarded rather
than being (potentially expensively) copied from the kernel to userland or
copied into a buffer shared between the kernel and userland.  That means
that the capabilities of the pseudo-machine are deliberately limited, so the
kernel can check whether the program is "safe"; one such limitation is that
it does not support backward branches, so no loops (as a way of preventing
infinite loops).

Libpcap supports testing somewhat arbitrary bytes in the packet with
expressions; from the tcpdump man page - or, with libpcap 1.x/tcpdump 4.x,
the pcap-filter man page:

             expr relop expr
                    True if the relation holds, where relop is one of  >,
 <,
                    >=,  <=, =, !=, and expr is an arithmetic expression
com-
                    posed of integer constants (expressed in standard C
 syn-
                    tax),  the normal binary operators [+, -, *, /, &, |,
<<,
                    >>], a length operator, and special  packet  data
 acces-
                    sors.   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
 indi-
                    cates   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  protocol  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,
 indi-
                    cated 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
inter-
                    vening fragment.

                    Some offsets and field values may be expressed  as
 names
                    rather  than  as  numeric values.  The following
protocol
                    header field offsets are available: icmptype  (ICMP
 type
                    field),  icmpcode  (ICMP  code  field), and tcpflags
(TCP
                    flags field).

                    The following ICMP type field values are available:
icmp-
                    echoreply,  icmp-unreach,  icmp-sourcequench,
 icmp-redi-
                    rect, icmp-echo,  icmp-routeradvert,
 icmp-routersolicit,
                    icmp-timxceed,  icmp-paramprob,  icmp-tstamp,
icmp-tstam-
                    preply, icmp-ireq,  icmp-ireqreply,  icmp-maskreq,
 icmp-
                    maskreply.

                    The  following TCP flags field values are available:
tcp-
                    fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg.

             Primitives may be combined using:

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

                    Negation (`!' or `not').

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

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

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

For the Wireshark filter "wlan.fc.type_subtype == 0x04", you're testing for
a probe request.  One way to do that is to explicitly check the first byte
of the link-layer header:

       (wlan[0:1] & 0xfc) == 0x40

With newer versions of libpcap - 1.0 and later - and at least some versions
of libpcap on, I think, OpenBSD, you could also have a filter of

       subtype probe�\req

or

       type mgt subtype probe-req

(either would work in libpcap 1.0; I don't remember which ones work on
OpenBSD).

Unfortunately, the reason why "bootp.option.value == 03" works in Wireshark
is that Wireshark dissects bootp/DHCP packets by looping through the options
and adding entries for each of them; the filter "bootp.option.value == 03"
matches any packet that has a bootp option with the value 3.  I used the
word "looping" very deliberately; as noted above, libpcap filters don't
support loops, so they don't support testing for packets that have a bootp
option *anywhere* in it with the value 3; there *is* no pcap filter
equivalent to "bootp.option.value == 03".

The good news is that, if the bootp option that says "this is a DHCP message
of a particular type" is always the *first* DHCP option, you could test for
*that* with a pcap filter expression.  I don't have time to determine what
that expression would be, however.

BTW, in order to get packets with an interface in monitor mode, should I
enter any special configuration in my libpcap application?

That depends on what version of libpcap you're using, and on what OS you're
running.

With libpcap 1.0, you could use pcap_create() to create a pcap_t handle, use
pcap_set_rfmon() on that pcap_t to specify that it should use monitor mode,
and then use pcap_activate() to start capturing.  With earlier versions of
libpcap, you'd have to put the interface into monitor mode using some
complicated OS-dependent and possibly interface-dependent operations.

What about pcap_lookupnet(...)?

What about it?  It has nothing to do with monitor mode; it's primarily
useful for getting some parameters to pass to pcap_compile(), used to make
some filter expressions (those that test the network number in IPv4
addresses, for example) work.-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: