BPF cheatsheet

Introduction

This article collects a number of BPF filters. The filters are grouped by the OSI layer.

These BPF filters are used throughout the ByteBlower API. Both for counting traffic, as for selecting the traffic to save in the PCAP capture

IP, IPv6, ARP
ExampleDescription
ipCaptures all TCP traffic regardless of lower transport layers
ip6Selects all IP6 traffic. This is not a default filter but has been added to ByteBlower.
arpCaptures only messages from the address resolution protocol.
icmpAll ICMP traffic of which ping is the most known application.
igmpIPv4 Multicast traffic

TCP and UDP

This is the transport layer, ByteBlower supports the two major families: TCP and UDP. Both protocols can be used over IPv4 or IPv6. When the network layer isn't explicitly mentioned in the filter all traffic from both is captured.

In the examples below we'll use tcp by default, but the last 3 example filters can also be used with udp.

ExampleDescription
tcpCaptures all TCP traffic regardless of lower layers transport layers.
udpSame as above, but for UDP.
ip and tcpCapture only traffic over IP.
ip6 and tcpSelects for ip6 and TCP. This not a default BPF filter.
(ip or ip6) and tcpSame behavior as the first filter. This line is only included as an example, prefer to use the first one
Filter on ports
Both TCP and UDP use ports. In the examples below, the filters are shown for both protocols

TCPUDPDescription
tcp port 80udp port 80Captures all traffic from or to port 80. Both directions are collected.
This is mainly useful for TCP.
tcp src port 80udp src port 80Capture only traffic transmitted from port 80.
tcp dst port 80udp dst port 80Unlike the one above, captures all traffic with port 80 as the destination.
TCP flags

The filters below are TCP specific. They filter on specific flags. This makes the following filters very useful to capture only the start of traffic, the end, or any abnormal behavior.

This type of filters uses the array operators of BPF. The filter tcp[13:1] fetches a single byte at offset 13; i.e. the fourteenth byte of the TCP header. This can be written even easier using the tcpflags shorthand. That is used most heavily in the filters below.

Other shorthands are those for those to select the individual bits of the tcp-flags: tcp-fin (= 0x01),

  • tcp-fin, with value 0x01
  • tcp-syn, 0x02
  • tcp-rst, 0x04
  • tcp-push, 0x08
  • tcp-ack, 0x10
  • tcp-urg, 0x20

The BPF syntax has no such definitions for the slightly newer TCP flags: ECE (0x40), CWR (0x80), and NS (0x100). These flags are related to Congestion Notification (rfc3168rfc3540). Especially this last one poses a challenge, it's the final example in the list below.

TCPDescription
tcp[tcpflags] == tcp-synSelecSelect the initial  SYN packet. This is the initiation of the session by the TCP client.
tcp[tcpflags] == (tcp-syn + tcp-ack)This SYN+ACK response is from the TCP server.
(tcp[tcpflags] & tcp-syn) > 0All packets with the SYN flag enabled. This filter matches the traffic of the above two.
This filter uses the bitwise and operator ('&') to select the Syn bit out of the TCP flags.
(tcp[tcpflags] & tcp-fin) > 0All packets with a Fin flag. Similar to the filter directly above, this also selects packets with Fin + Ack.
tcp[tcpflags] == tcp-rstSelect all TCP Resets
(tcp[tcpflags] & tcp-fin) > 0All packets with a Fin flag.
(tcp[tcpflags] & 0x40)  > 0This filter captures all packets with the ECE flag enabled. Both the initial negation is thus captured, as well as a TCP session echoing congestion on the network.
(tcp[tcpflags] & (0x40 + tcp-syn))  == (0x40 + tcp-syn)Like the above, this filter selects packets with the ECE flag enabled. Extra in this filter is to only select the initial handshake. This is done by adding the tcp-syn value.
In other words, this filters all sessions that are capable of reacting to Explicit Congestion Notifications.
(tcp[tcpflags] & (0x40 + tcp-syn))  == 0x40The filter is the inverse of the above. It also packets with the ECE flags but also requires these packets to have the tcp-syn flag disabled.
This filters thus on actual cases where the session reacts to an explicit congestion notification.
(tcp[12:2] & 0x100) > 0As promised, in the last filter the NS flag, or ECN-nonce is used.
This flag is experimental and makes the filter much more complex.

The NS flag has a value of 0x100, this is larger than the usual single byte for the TCP flags.

As a result, 12:2 is used instead of tcpflags. This expression selects 2 bytes at an offset of 12 bytes in the TCP header.

The remainder of this BPF filter is similar to the above.