gpt4 book ai didi

linux - 通过 sk_buff 将以太网数据包重定向到本地主机

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:27:20 27 4
gpt4 key购买 nike

我正在编写一个 Linux 内核模块,它将数据包重定向到本地主机网络服务器,该数据包最初是通过这台机器使用网桥转发的。它还重定向以回复客户端。客户端忘记了重定向。所以有2个部分 1. 所有通过网桥转发到外部网络服务器的数据包都被重定向到本地网络服务器。

  1. 本地网络服务器的输出被传送到原始客户端

我可以通过 nf_hook NF_INET_LOCAL_OUT 完成第二部分

unsigned int snoop_hook_reply( unsigned int hooknum, struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
int(*okfn)( struct sk_buff * ) )
{
int offset, len;
struct ethhdr *ethh;
struct iphdr *iph;
struct tcphdr *tcph;
bool flag = false;
struct net_device *eth1_dev , *lo_dev;

if (!skb) return NF_ACCEPT;
iph = ip_hdr(skb);
if (!iph) return NF_ACCEPT;
skb_set_transport_header(skb, iph->ihl * 4);
tcph = tcp_hdr(skb);
/* skip lo packets */
if (iph->saddr == iph->daddr) return NF_ACCEPT;
if (tcph->dest == htons(80))
flag=true;
if(flag != true)
return NF_ACCEPT;

// correct the IP checksum
iph->check = 0;
ip_send_check (iph);

//correct the TCP checksum
offset = skb_transport_offset(skb);
len = skb->len - offset;
tcph->check = 0;
if(skb->len > 60){
tcph->check = csum_tcpudp_magic((iph->saddr), (iph->daddr), len, IPPROTO_TCP, csum_partial((unsigned char *)tcph,len,0));
}
else{
tcph->check = ~csum_tcpudp_magic((iph->saddr), (iph->daddr), len, IPPROTO_TCP, 0);
}

//send to dev
eth1_dev = dev_get_by_name(&init_net,"eth1");
lo_dev = dev_get_by_name(&init_net,"lo");
skb->dev = eth1_dev;
ethh = (struct ethhdr *) skb_push(skb, ETH_HLEN);
skb_reset_mac_header(skb);
skb->protocol = ethh->h_proto = htons(ETH_P_IP);
memcpy (ethh->h_source,eth1_dev->dev_addr , ETH_ALEN);
memcpy (ethh->h_dest, d_mac, ETH_ALEN); // d_mac is mac of the gateway
dev_queue_xmit(skb);

return NF_STOLEN;
}

上面的代码非常适合我。一个问题是稍后我会破坏数据包,因此可能需要创建一个新的 sk_buff。

我无法通过 NF_INET_PRE_ROUTING 完成第一部分,我无法通过 TCP/IP 堆栈将数据包/sk_buff 推送到网络服务器进程。我尝试将 dev_queue_xmit() 函数与 skb->dev 一起用作 eth1 和 lo 。我看到数据包通过 tcpdump 命中 lo 或 eth1。但是数据包没有到达本地主机网络服务器。任何人都可以帮助我解决这个问题或指出一些类似的已回答问题。我相信我需要调用一些接收函数而不是 dev_queue_xmit()。此外,当数据包到达 NF_INET_PREROUTING 时,我的以太网 header 已经存在,所以我没有形成它。我已经通过多种方式完成了上述任务,首先使用原始套接字,然后使用 nf_queue,现在我想通过这种方法查看性能。谢谢

最佳答案

如果你想在本地接收数据包,你不能在 eth1 上调用 dev_queue_xmit(),因为它会被发送出去。在将 skb->dev 指向 eth1/lo 之后,您可能需要调用 netif_rx()。

还有一点,如果dest-ip不是你本地的host ip,那么你需要再次避免路由,否则你的拦截就没有用了。为此,您需要将数据包的目标 ip 修改为 eth1/lo IP 或通过使用 skb_dst_set() 设置“rth->dst.input= ip_local_deliver”来欺骗 IP 层,使数据包被接受为本地数据包。

关于linux - 通过 sk_buff 将以太网数据包重定向到本地主机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32759533/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com