服务器教程 · 2025年3月3日

字节跳动开源 Linux 内核网络抓包工具 netcap,支持美国服务器数据捕获

在 Linux 内核网络开发中,网络丢包一直是一个令人头疼的问题。传统的网络抓包工具(如 tcpdump)虽能协助排查问题,但效率不高,且在深入分析网络丢包时存在诸多限制。如今,随着 eBPF 技术的崛起,字节跳动 STE 团队基于该技术开发了一款强大的内核网络抓包工具—— netcap(全称 net capture,内部原名 xcap),并已正式 开源

📌 GitHub 地址https://github.com/bytedance/netcap

该工具可以用于 美国服务器,在海外部署 Linux 服务器的开发者也可以高效排查网络问题!


🌟 1. netcap 亮点概览

🔍 全内核追踪能力:相比 tcpdump 仅能捕获内核协议栈特定位置的数据包,netcap 可以跟踪整个内核网络协议栈(所有 skb 相关函数)。

💡 兼容 tcpdump 语法:可使用熟悉的 tcpdump 语法作为过滤条件,轻松掌握整个网络报文在内核中的完整路径。

高效定位丢包:基于 eBPF 技术,大幅提升 Linux 服务器 的网络丢包问题排查效率,支持 美国服务器 及全球数据中心环境。


🛠️ 2. 使用示例

🔹 示例 1:追踪特定 IP 地址的 ICMP 报文

📌 目标:查看 10.227.0.45icmp 包是否到达 内核预期的函数调用点

netcap skb -f icmp_rcv@1 -i eth0 -e "host 10.227.0.45" -t "-nnv"

🔹 参数解析

  • -f icmp_rcv@1:跟踪 icmp_rcv 函数的 第 1 个参数(即 skb)。
  • -i eth0:指定网卡接口。
  • -e "host 10.227.0.45"tcpdump 语法过滤规则,仅关注 10.227.0.45 的数据包。
  • -t "-nnv"tcpdump 格式化输出。

🔹 示例 2:定位 TCP 端口 9000 的丢包点

📌 目标:查看 TCP 端口 9000 的报文丢包位置,并打印调用栈。

netcap skb -f tracepoint:skb:kfree_skb -e "tcp port 9000" -S

🔹 参数解析

  • -f tracepoint:skb:kfree_skb:监控 kfree_skb 事件,查找丢包发生位置。
  • -e "tcp port 9000":仅关注 9000 端口的数据包。
  • -S:打印 调用栈,快速定位丢包源头。

🔬 3. netcap 设计与实现

📌 核心架构

  • 基于 eBPF:采用 kprobe / tracepoint 动态 hook 关键函数,提取 skbsock 结构体。
  • 高效数据传输:通过 bpf map 传递数据至 用户态,减少内核干扰,提高抓包效率。
  • tcpdump 深度结合:利用 tcpdump 解析网络数据包,支持 pcap 格式存储。

🏗 技术实现

1️⃣ 基于 tcpdump 语法的 eBPF 过滤

  • netcap 使用 cbpfc 库将 tcpdump 语法 转换为 C 语言函数,嵌入 eBPF 代码。
  • 过滤逻辑tcpdump 语法 → cBPF 指令码 → C 语言函数eBPF 程序

2️⃣ 如何解析并显示数据包

  • netcap 启动后,会 自动运行 tcpdump,以 标准输入流 解析 pcap 数据,并以用户指定的格式输出。

3️⃣ 如何获取完整的 skb 数据

  • 发送方向,有些 skb 结构未完整填充(如 __ip_finish_output)。
  • netcap 通过 sock 结构 推导补全 关键信息,确保数据包完整。

🔄 4. 高级功能与扩展

🔹 多 Trace 点时间分析

📌 目标:跟踪数据包经过 多个 trace 点 的时间,计算网络延迟。

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

📌 输出示例:不同 trace 点的 时间戳,可用于分析 数据包的网络时延


🔹 自定义过滤与输出

📌 目标:用户可以 自定义过滤规则和输出格式,增强调试能力。

1️⃣ 自定义过滤

static inline int xcap_user_filter(void *ctx, void *pkt, u16 trace_index) {
    return 1;  // 返回 1 代表不过滤
}

2️⃣ 自定义输出

struct xcap_user_extend {
    int a;  // format: 0x%x
    uint32_t b;
    int64_t c;     
    uint8_t x1; // format: %c
};

📌 支持的数据类型int8_t, uint8_t, char, int16_t, uint16_t, int, uint32_t, int64_t, uint64_t(不支持指针和数组)。


🚀 5. 未来展望

netcap 已经成为 Linux 服务器 上强大的网络抓包工具,特别适用于 美国服务器 和全球云计算环境。未来,团队将继续优化以下功能:

增强 DPDK 支持,提升高性能网络数据包抓取能力。
支持多种 Linux 内核版本,提升兼容性。
优化自定义输出,解决高并发场景下的日志错乱问题。

欢迎开发者们 Star & PR,一起共建开源项目!
GitHub 地址https://github.com/bytedance/netcap