You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于用eBPF分析802.11x WiFi头添加及追踪mac80211x内核函数的咨询

用eBPF查找802.11x WiFi头添加实现及追踪puts_wifi_header函数的方法

一、查找系统添加802.11x WiFi头的实现

要定位内核中添加802.11x WiFi帧头的逻辑,可通过以下步骤用eBPF追踪:

  • 锁定核心追踪范围:802.11帧头的添加逻辑主要集中在mac80211子系统的发送路径中,重点关注这类函数:

    • 帧构建类:ieee80211_build_tx_frame、ieee80211_prepare_tx
    • 缓冲区操作类:skb_push、skb_put(内核通用的缓冲区头/尾添加函数,mac80211会调用它们添加帧头)
    • 提交发送类:ieee80211_submit_frame
  • 用BCC工具快速追踪验证:
    比如用trace.py追踪skb_push并过滤mac80211相关调用栈,命令如下:

    trace.py -k skb_push -T
    

    执行后触发WiFi发送操作(比如ping同一WiFi下的设备),观察输出的调用栈,找到mac80211子系统中调用skb_push添加帧头的上层函数,顺着调用栈就能定位到具体的头添加实现。

    也可以直接追踪mac80211的特定函数,比如:

    trace.py -k ieee80211_build_tx_frame -A
    

    查看函数的参数和返回值,分析帧头构建的过程。

二、追踪mac80211子集中的puts_wifi_header函数

既然已经完成内核配置和环境搭建,完全可以通过eBPF的kprobe机制追踪该函数的执行过程,具体步骤如下:

1. 确认函数可追踪

先通过内核符号表确认函数存在:

grep puts_wifi_header /proc/kallsyms

如果能输出函数地址,说明该函数是导出的(或内核未开启符号混淆),可以被kprobe追踪。

2. 用BCC编写追踪脚本(快速验证)

创建一个Python脚本trace_puts_wifi_header.py,内容如下:

from bcc import BPF

BPF_PROGRAM = """
#include <linux/skbuff.h>

// 定义kprobe追踪puts_wifi_header
int trace_puts_wifi_header(struct pt_regs *ctx, struct sk_buff *skb) {
    // 打印函数被调用的PID、进程名,以及skb的地址
    bpf_trace_printk("puts_wifi_header called! PID: %d, Comm: %s, SKB addr: %p\\n",
                     bpf_get_current_pid_tgid() >> 32,
                     bpf_get_current_comm(),
                     skb);
    return 0;
}
"""

b = BPF(text=BPF_PROGRAM)
# 挂载kprobe到目标函数
b.attach_kprobe(event="puts_wifi_header", fn_name="trace_puts_wifi_header")

# 打印输出
print("Tracing puts_wifi_header... Hit Ctrl+C to stop.")
b.trace_print()

执行脚本:

sudo python3 trace_puts_wifi_header.py

触发WiFi发送操作,就能看到函数被调用的日志。如果需要更详细的信息(比如帧头内容、参数细节),可以在BPF程序中通过skb指针读取相关数据(注意内核版本的结构体兼容性)。

3. 用libbpf-bootstrap编写C语言BPF程序(生产级)

如果需要更高效、稳定的追踪,可使用libbpf-bootstrap框架:

  • 创建puts_wifi_header_trace.bpf.c:
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

char LICENSE[] SEC("license") = "GPL";

SEC("kprobe/puts_wifi_header")
int BPF_KPROBE(puts_wifi_header, struct sk_buff *skb) {
    u32 pid = bpf_get_current_pid_tgid() >> 32;
    char comm[16];
    bpf_get_current_comm(comm, sizeof(comm));

    bpf_printk("puts_wifi_header invoked by PID %d (%s), SKB: %p", pid, comm, skb);
    return 0;
}
  • 编写用户态加载程序(参考libbpf-bootstrap的模板),编译后执行,即可追踪函数执行。

注意事项

  • 如果函数未导出,需要使用偏移量方式追踪,但需要先获取函数在内存中的偏移地址,这种方式兼容性较差,建议优先使用导出的函数。
  • 不同内核版本的struct sk_buff结构体可能有差异,读取内部字段时要对应目标内核的定义。

内容的提问来源于stack exchange,提问作者Shriyam Khatiwada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:07:08