Open cheneytianx opened 2 years ago
Hello @cheneytianx,一看便知是高端玩家。几个问题先确认下:
1、你的eBPF代码是怎样的?verifier报什么错?
2、当前获取skb数据,可以直接"direct packet access",即skb->data
和skb->data_end
,这个方式尝试过了吗?
这大概是一个数据包的结构信息。
skb->data -->[ ethhdr | iphdr | tcphdr | payload ] <-- skb->data_end
首先解析各种协议包头,计算 payload 的 offset 和 长度 data_len:
u16 offset = sizeof(*eth) + sizeof(*iph) + (tcph->doff << 2);
u32 data_len = skb->len - offset;
然后想使用 bpf_skb_load_bytes()
一次性把 payload 拷到一个 buffer 中:
// 这里做过一些逻辑判断,确保 data_len < MAX_LEN,offset + data_len < skb->data_end
char buf[MAX_LEN] = {0};
bpf_skb_load_bytes(skb, offset, buf, data_len);
于是验证器报错:
85: (85) call bpf_skb_load_bytes#26
invalid stack type R3 off=-136 access_size=0
在这里找到一些相关资料:link
上面验证器报的是 R3
的错,不过把 data_len(R4
) 换成一个字面值常量程序就正常了。
可能,第四个参数就是没办法传一个变量吧。
感谢大佬,看您的博客学到了不少 >_<
我成功把tcp payload打印到std,tls协议还得解密。
let start = Ipv4Hdr::LEN + TcpHdr::LEN;
let end = ctx.len() as usize;
if end - start <= 0 {
info!(&ctx, "no payload");
return Ok(1);
}
有个地方需要注意:根据我观察,只有XDP程序才需要把offset加上eth的报文长度,其他钩子例如cgroups skb,只需要ipv4 + tcp 就足够了
大佬你好,
不知道你有没有尝试过在 tc 程序中获取网络数据包的 payload。
一般根据 skb 的长度和各个协议包头的长度可以计算出有效的 payload 长度,现在我想利用 bpf_skb_load_bytes() 这个函数将 payload 拷贝到自己定义的 buffer 中,想着后续匹配下关键词什么的。
结果一直绕不过 eBPF verifier 的校验,不知道大佬是否有相关经验可以分享?