Using pcap-filter syntax for network filtering
Published: 2023-03-18 18:25:55

[libpcap](https://github.com/the-tcpdump-group/libpcap) is a library that provides a high-level interface for capturing network traffic. It was developed as an open source project in the 1990s, and is widely used in a variety of network analysis tools, including Wireshark and tcpdump. One of the key features of `libpcap` is its filtering syntax, which is based on the Berkeley Packet Filter ([BPF](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter)) syntax.
In short, [BPF](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter) is implemented as a virtual machine that executes user-defined byte-code programs within the Linux kernel to filter and process network packets.

`BPF` syntax allows users to create filters that selectively capture only the network traffic they are interested in, based on various criteria such as source and destination IP addresses, protocol type, port number and packet content. Libpcap supports both packet-level and byte-level filtering, which allows users to create filters based on both the contents and the structure of the packets being captured.

Note that in 2014, an extended version of `BPF` called [eBPF](https://en.wikipedia.org/wiki/EBPF) (extended Berkeley Packet Filter) has been developed, which offers even more powerful capabilities - it is not only used for networking, but also for various other purposes, such as tracing system calls, kernel instrumentation, and security monitoring. Its versatility has made it a popular choice among developers and system administrators for a wide range of use cases beyond just network analysis. However, `eBPF` is a topic for a separate article, here we’ll concentrate on `BPF` libpcap syntax.

## Practical Examples
### Showing HTTP traffic
```
tcpdump -i enp0s3 -A src 10.0.2.15 and dst port http
```


<blockquote>
<a href='https://www.tcpdump.org/manpages/tcpdump.1.html'>tcpdump</a> is a powerful command-line packet analyser which can be used to display or record traffic. 
</blockquote>


Here we are using tcpdump on interface enp0s3 (check yours with `ifconfig` command) to show the traffic in ASCII (`-A` flag). We are using BPF syntax to specify that we are interested in packets sourced from IP `10.0.2.15` to any host on port `80` (`port http` part).

Note that we could also use `ngrep` to show only packets with a specific content. 


<blockquote>
<a href='https://linux.die.net/man/8/ngrep'>ngrep</a> (short for network grep) is command-line packet analyser that supports filtering by packet content using grep-like regex syntax. For instance, the following line will capture a request to http://info.cern.ch/
</blockquote>


```
$ ngrep -W byline cern src net 10.0.2.0/24 and dst port http

###
T 10.0.2.15:50660 -> 188.184.21.108:80 [AP] #3
GET / HTTP/1.1.
Host: info.cern.ch.
User-Agent: Wget/1.21.2.
Accept: */*.
Accept-Encoding: identity.
Connection: Keep-Alive.
.
```

### Displaying network stats for a particular host
You can use `iftop` to get network stats for a specific host.


<blockquote>
<a href='https://linux.die.net/man/8/iftop'>iftop</a> is a command-line system monitor that focuses on network stats.
</blockquote>


```
iftop -f "dst host github.com"
```

### Capturing packets with specific headers
You can use the involved syntax to check values in protocol flags and content of the packet. For this you usually use `protocol[offset:size]` or `protocol[offset]` syntax. There are also some predefined values (see example below) which shows only end packets of each TCP conversation:

```
tcpdump -i enp0s3 -X 'tcp[tcpflags] & tcp-fin != 0'
```

Or try this to get all packets longer than 256 bytes – you can see the structure of IPv4 header - e.g. in [wiki](https://en.wikipedia.org/wiki/Internet_Protocol_version_4#Total_Length):

```
tcpdump -i enp0s3 -X 'ip[2:2] > 256'
```

## Links

1. [pcap-filter](https://www.tcpdump.org/manpages/pcap-filter.7.html)
1. [pcap](https://en.wikipedia.org/wiki/Pcap)
1. [libpcap](https://github.com/the-tcpdump-group/libpcap)
1. [BPF](https://en.wikipedia.org/wiki/Berkeley_Packet_Filter)
1. [eBPF](https://en.wikipedia.org/wiki/EBPF)
1. [iftop](https://linux.die.net/man/8/iftop)
1. [ngrep](https://linux.die.net/man/8/ngrep)
1. [tcpdump](https://www.tcpdump.org/manpages/tcpdump.1.html)