2

我在PC上有一个客户端。我在PC上有一台服务器。客户端和服务器通过基于 Linux 操作系统固件的路由器连接。
客户端向服务器发送数据包并接收响应。路由器必须拦截数据包并对其进行修改。像嗅探一样的东西,但它不是嗅探,因为我需要修改数据包。
我必须为此编写一个程序。
我试图在路由器上打开一个原始套接字,但原始套接字上的 reсvfrom 不会拦截数据包而只是复制它。数据包正在进行中。
你能建议我解决这个问题的任何方法吗?
PS对不起我的英语不好。:)

4

3 回答 3

4

我会混合使用iptableslibnetfilter_queue(假设您的内核是相对较新的)

  1. 添加将iptables所有 udp 数据包转发到的规则,NFQUEUE 0以便将数据包从内核获取到用户空间。

    iptables -A INPUT -p udp -m udp --dport xxxxx -j NFQUEUE --queue-num 0

  2. 构建一个进程来监听NFQUEUE number 0、修改有效负载并使用功能将完整的数据包返回给内核空间libnetfilter_queue。按照此链接了解如何操作。

简而言之,您必须打开队列 0 ( nfq_create_queue),设置模式以获取数据包的内容 ( nfq_set_mode),然后无限循环recv以获取被过滤的 udp 数据包iptables

fd = nfq_fd(h);

while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
    printf("pkt received\n");
    nfq_handle_packet(h, buf, rv);
}

每次调用nfq_handle_packet时,都会调用阶段期间定义的回调nfq_create_queue。在该回调中,您必须修改有效负载,更新大小并重新计算校验和,然后设置为“有效”nfq_set_verdict

于 2013-02-19T12:47:10.920 回答
1

我为内核和一些应用程序编写了模块。模块使用 netfilter 并丢弃我需要到 netfilter_queue 的数据包。应用程序处理一个队列,我决定如何处理每个包。

uint hook_main(uint hooknum,
                  struct sk_buff *skb,
                  const struct net_device *in,
                  const struct net_device *out,
                  int (*okfn)(struct sk_buff *)  )
{
     struct iphdr *ip;
     struct udphdr *udp;
     if (skb->protocol == htons(ETH_P_IP)){
        ip = (struct iphdr *)(skb->data);
        if (ip->version == 4 && ip->protocol == IPPROTO_UDP){
            udp = (struct udphdr *)(skb->data + sizeof(struct iphdr));
            if(ntohs(udp->dest) == SOME_PORT){
                return NF_QUEUE;
            }
        }
     }
     return NF_ACCEPT;
}

int init_module ()
{
    printk("[udp-catch] start udp-catch\n");

    catch_hook.hook = hook_main;
    catch_hook.owner = THIS_MODULE;
    catch_hook.pf = PF_INET;
    catch_hook.hooknum = NF_INET_FORWARD;
    catch_hook.priority = NF_IP_PRI_FIRST;
    nf_register_hook(&catch_hook);

    return 0;
}

来自 netfilter.org 的重新设计示例是该应用程序。

于 2013-03-04T09:29:08.147 回答
0

路由器将自动发送它们在其他端口上接收到的任何内容。

例如,对于一个 4 端口路由器,从端口 1 进入的内容将在端口 2,3 和 4 上发送出去。

要执行您需要的操作,您需要另一台带有 2 个网卡的 PC。将您的客户端 PC 连接到一个网卡,将服务器 PC 连接到另一个。

然后你的程序需要从一张网卡上recvfrom ,修改数据包并发送到另一张网卡上。

于 2013-02-19T10:36:39.407 回答