在 BPF 内核模块 (C) 中计算校验和

问题描述

我正在尝试修改在 BPF 内核模块中接收到的数据包(UDP 有效负载)以将其发送回客户端,但我对它为什么不出去感到困惑。我怀疑这是因为我没有重新计算校验和,我不确定如何做到这一点。

我收到的数据包的IP总长度为32,UPD长度为12,payload为0x08 0x1e 0x77 0xda(4字节)。我想向客户端发送一个负载为 0x1a 0xb4 0x3e(3 个字节)的数据包,因此我必须将长度缩小 1(IP = 31,UDP = 11)。这是我的代码

// 1. Swap the MACs
__u8 tmp_mac[ETH_ALEN];
memcpy(tmp_mac,eth->h_dest,ETH_ALEN);
memcpy(eth->h_dest,eth->h_source,ETH_ALEN);
memcpy(eth->h_source,tmp_mac,ETH_ALEN);

// 2. Swap the IPs
if (eth->h_proto == htons(ETH_P_IP)) {
    __u32 tmp_ip = ip->saddr;
    ip->saddr = ip->daddr;
    ip->daddr = tmp_ip;
}

// 3. Swap the ports
udpdata->source = port;
udpdata->dest = srcport;

// 4. Change the content
udpdata->len = htons(8 + 3);
ip->tot_len = htons(31);

// 5. Change the data                   
bpf_skb_adjust_room(skb,-1,BPF_ADJ_ROOM_NET,0);
payload_offset = sizeof(*eth) + sizeof(*ip) + sizeof(*udpdata); // Update pointer as we adjusted.
uint8_t byte1 = 0x1a;
uint8_t byte2 = 0xb4;
uint8_t byte3 = 0x3e;
int ret = bpf_skb_store_bytes(skb,payload_offset,&byte1,sizeof(byte1),0);
ret = bpf_skb_store_bytes(skb,payload_offset+1,&byte2,sizeof(byte2),payload_offset+2,&byte3,sizeof(byte3),0);

// 6. Send
bpf_clone_redirect(skb,skb->ifindex,0);

我对 BPF 有点陌生,所以我不确定客户端收到的数据包缺少什么?也许我应该创建一个新数据包,丢弃当前数据包并发送新数据包?无论如何,我不确定如何进行这项工作。

谢谢。

注意:如果我查看 tcpdump,我可以看到以下错误错误长度): 18:55:46.622339 IP THE.SERVER.IP.25058 > THE.CLIENT.IP.31744:UDP,错误长度3033 > 3

20:01:31.050939 IP THE.SERVER.IP.7777 > THE.CLIENT.IP.54200:UDP,长度3 0x0000:4500 001f 27d9 0000 6e11 0000 c632 fca7 0x0010:559b 852d 1e61 d3b8 000b f020 1ab4 3e00 0x0020:0000 0000 0000 0000 0000 0000 0000

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)