tc-dump 是一个基于 eBPF 的 tc 抓包工具,支持抓取 tc 的 ingress 和 egress 方向的包。
最近,tc-dump
支持了 pcap-filter,即支持了 pcap 的过滤语法。
与此同时,tc-dump
还支持跟踪 tc-bpf 程序;即如果 tc 上已挂载了 tc-bpf
程序,那么 tc-dump
会自动跟踪该 tc-bpf
程序。
所以,一个有趣的玩法:先在一个终端窗口跑 ./tc-dump -d XXX
,然后在另一个终端窗口跑 ./tc-dump -d XXX
,即可在后一个 tc-dump
中跟踪前一个 tc-dump
的 tc-bpf
程序。
tc-dump 支持 pcap-filter
有位大佬开源了 pcap-filter
注入的库:elibpcap,tc-dump
就是基于该库实现的。
在 tc-dump
中,pcap-filter
的使用方式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
# ./tc-dump -h
Usage: ./tc-dump [options] [pcap-filter]
Available pcap-filter: see "man 7 pcap-filter"
Available options:
-d, --device strings network devices to run tc-dump
-m, --filter-mark uint32 filter mark for tc-dump
-k, --keep-tc-qdisc keep tc-qdisc when exit
pflag: help requested
# ./tc-dump -d enp0s1 tcp port 8888
2023/11/26 10:54:14 Listening events for if@2:enp0s1 INGRESS by TC...
2023/11/26 10:54:14 Listening events for if@2:enp0s1 EGRESS by TC...
ifindex: 2(enp0s1) dir=INGRESS mark=0x0(0)
ETH: 3e:22:fb:b9:64:64 -> de:97:0a:be:b0:2d, protocol IPv4
IPv4: 192.168.64.1 -> 192.168.64.2, header length 20, dscp 0x10, total length 64, id 0x0000, TTL 64, protocol TCP
TCP: 61307 -> 8888, seq 87516102, ack 0, flags SYN,ECE,CWR, win 65535
ifindex: 2(enp0s1) dir=EGRESS mark=0x0(0)
ETH: de:97:0a:be:b0:2d -> 3e:22:fb:b9:64:64, protocol IPv4
IPv4: 192.168.64.2 -> 192.168.64.1, header length 20, dscp 0x
|
elibpcap
elibpcap
是一个注入 pcap-filter
的库,它的使用方式如下:
1
2
3
4
5
6
7
|
progSpec := specTc.Programs["on_ingress"]
progSpec.Instructions, err = elibpcap.Inject(flags.PcapFilterExpr,
progSpec.Instructions, elibpcap.Options{
AtBpf2Bpf: "filter_pcap_ebpf_l2",
DirectRead: true,
L2Skb: true,
})
|
不过,elibpcap
使用 libpcap.a
去编译 pcap-filter
表达式,所以在编译 tc-dump
前需要先编译 libpcap.a
:
1
2
3
4
5
6
|
# Get latest libpcap from https://www.tcpdump.org/
wget https://www.tcpdump.org/release/libpcap-1.10.4.tar.gz
cd libpcap-1.10.4
./configure --disable-rdma --disable-shared --disable-usb --disable-netmap --disable-bluetooth --disable-dbus --without-libnl
make
sudo make install
|
而后,elibpcap
会使用 github.com/cloudflare/cbpfc 去将 libpcap.a
编译得到的 cBPF 汇编转换成 eBPF 汇编。
最后,将得到的 eBPF 汇编注入到指定的 bpf2bpf 函数中。
tc-dump 支持跟踪 tc-bpf
tc-dump
支持跟踪 tc-bpf
的实现方式参考 eBPF Talk: 给 pwru 添砖加瓦 中的 Support tracing tc-bpf 小节。
跟 pwru 不同的是,tc-dump
是根据网络设备去查找 tc-bpf
程序的,而不是 pwru
中直接跟踪所有 tc-bpf
程序。
小结
tc-dump
是一个基于 eBPF 的 tc 抓包工具,支持抓取 tc 的 ingress 和 egress 方向的包。
tc-dump
支持了 pcap-filter
,即支持 pcap 的过滤语法;抛弃了复杂的选项,增加了灵活的包过滤语法。
tc-dump
支持跟踪 tc-bpf
,即如果网络设备的 tc 上已挂载了 tc-bpf
程序,那么 tc-dump
会自动跟踪该 tc-bpf
程序。