netcap
简介
netcap是一个基于bcc的工具,可以对包含skb作为参数的系统函数,或基于DPDK的mbuf进行抓包分析。简单使用示例如下:
netcap skb -f icmp_rcv@1 -e "host 10.227.0.72" -i eth0
安装依赖
netcap工具依赖于bcc
包的安装。
命令行参数说明
可以通过netcap的help获取使用说明和示例,如下:
# 查看 skb 模式支持的参数
netcap help skb
# 查看 mbuf 模式支持的参数
netcap help mbuf
本质上,命令行参数分为以下3类:
- skb模式和mbuf模式通用的
- 仅适用于skb模式的
- 仅适用于mbuf/raw模式的
通用命令行参数
-
-f function_name<@param1><@param2>
设置需要跟踪的函数格式,function_name表示要跟踪的函数名称,支持多点抓包,用逗号分隔,例如
ip_local_deliver@1,icmp_rcv@1
。对于skb模式,支持:
- -f tracepoint:net:netif_receive_skb 是tracepoint方式,此时不需要param1和param2。
- -f icmp_rcv@1 是kprobe方式,需要param1,表示skb是被跟踪函数的第几个参数(从1开始),不需要param2。
对于mbuf模式,由于DPDK会使用mbuf数组,因此使用param2时表示是mbuf数组,仅使用param1时是单个mbuf:
- -f usdt:rx_one@1 是usdt方式,rx_one的usdt第一个参数param1是mbuf指针。
- -f usdt:rx_array@1@2 是usdt方式,rx_array的usdt第一个参数param1是mbuf指针数组,第二个参数param2是前面提到的数组大小。
- -f func@1 是uprobe跟踪,此处表示单个mbuf。
- -f func_array@1@2 是uprobe跟踪,此处表示mbuf数组。
注意:-f 参数较为复杂,可以结合后面的示例理解。
-
-e expression
设置需要过滤数据包的表达式,此表达式基于tcpdump的语法。
-
-t tcpdump-flags
设置tcpdump的flags,例如想以 -nnve 的tcpdump方式查看数据包,可输入 -t "-nnve"。
-
-w file
--write-file-rotate rotate-num
抓包写入文件,类似tcpdump,通过 --write-file-rotate 指定的 rotate-num 表示循环抓包,即抓取最后的rotate-num个包,写入pcap文件。
-
-c capture-count
抓取指定数量的包后退出,设置为0或不设置表示不限制次数,类似tcpdump。
-
--capture-max-size max
这个size指抓取的包保存到缓冲区的大小,如果包长超过这个值,则包会被截断。
-
--gather
汇总输出用法,此参数为开关参数,打开此开关会忽略 -w 参数。
gather功能仅在多点跟踪下使用,以第一个被跟踪的点为基准值,跟踪数据包到达后续跟踪点的延迟信息。
gather功能包含以下子参数:
- --gather-buffer-size size : 设置缓冲区大小。
- --gather-timeout timeout : 超时时间。
- --gather-distinguish-by-pointer : 以指针(skb或mbuf)来标识同一个数据包,否则以包内容标识。
- --gather-output-color : 设置打印gather结果的颜色: red|green|yellow|blue|purple|cyan。
此功能较为复杂,可参照示例理解。
-
--user-filter filename.c
用户自定义过滤器,过滤器脚本模板
-
--user-action filename.c
用户自定义的匹配后的动作,在动作中netcap会将用户填充的自定义结构体信息与数据包一起输出到控制台。动作脚本模板
- --user-output-color:设置打印用户输出的颜色:红色|绿色|黄色|蓝色|紫色|青色。
-
--dry-run
不实际执行,仅打印生成的eBPF代码。
skb模式的参数
-
-i 接口
例如 -i eth0,与tcpdump相同
-
--fake-hdr
在某些发送方向的函数(如__ip_finish_output)中,内核尚未填充以太网、IP等头信息,使用此选项可以让netcap根据skb的套接字信息伪造出头部来适配tcpdump过滤语法。
-
--skb-data
不设置此参数表示使用netcap的默认策略来寻找数据包起始地址,若设置此标志,则使用skb->data + offset作为数据包的起始位置。其中的offset由--skb-data-offset设置。需要设置此参数的场景:某些特殊函数行为导致默认策略找到的地址错误。
-
-S
开关参数,设置后,会随pcap打印此包对应的内核堆栈,并忽略--gather和-w参数。
- --stack-dump-color:设置打印内核堆栈的颜色:红色|绿色|黄色|蓝色|紫色|青色。
mbuf/raw模式的参数
-
-p pid
设置要跟踪的DPDK程序的进程ID。
示例
skb的常规用法
# 在icmp_rcv捕获数据包,指定eth0为接收网卡,并按tcpdump语法过滤
netcap skb -f icmp_rcv@1 -e "host 10.227.0.72" -i eth0 -t "-nnv"
# 将捕获的数据包写入文件icmp.pcap
netcap skb -f icmp_rcv@1 -e "host 10.227.0.72" -i eth0 -w icmp.pcap
# 打印内核堆栈
netcap skb -f icmp_rcv@1 -e "host 10.227.0.72" -i eth0 -S
# 在tracepoint捕获数据包,注意:tracepoint不需要使用@传递skb是第几个参数
netcap skb -f tracepoint:net:netif_receive_skb@1 -i eth0 -e "host 10.227.0.72"
mbuf的常规用法
# 在进程ID为1111的DPDK进程中,对you_func函数(uprobe)捕获数据包,其中mbuf指针作为此函数的第一个参数
netcap mbuf -f you_func@1 -e "tcp and port 80" -t "-nnve" --pid 1111
# 在进程ID为1111的DPDK进程中,对vec_func函数(uprobe)捕获数据包,其中vec_func传递的是mbuf指针数组,因此需要2个参数
netcap mbuf -f vec_func@1@2 -e "tcp and port 80" -t "-nnve" --pid 1111
# 同时在多个函数捕获数据包
netcap mbuf -f func_rcv@1,func_send@1 -e "tcp" --pid 111
gather用法
gather只能针对跟踪多个函数(即-f后面要使用多个函数),并将第一个作为基准。示例如下:
# 使用gather统计以下函数,并用青色输出信息
netcap skb -f tracepoint:net:netif_receive_skb,ip_local_deliver@1,ip_local_deliver_finish@3,icmp_rcv@1 -e "host 10.227.0.72 and icmp" -i eth0 --gather --gather-output-color cyan