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:
- How to use specific protocol filters in pcap programming Javier Gálvez Guerrero (Apr 28)
- Re: How to use specific protocol filters in pcap programming Guy Harris (Apr 28)
- Re: How to use specific protocol filters in pcap Javier Gálvez Guerrero (Apr 29)
- Re: How to use specific protocol filters in pcap programming Guy Harris (Apr 28)