【问题标题】:How to capture network frames in a kernel module如何在内核模块中捕获网络帧
【发布时间】:2012-06-15 13:29:56
【问题描述】:

我想在某个 NIC 接收到帧时对其进行捕获;从中提取一些信息(目前我需要捕获源MAC和源IP地址);将这些信息保存在一些公共数据结构中;并让帧向上到达 TCP/IP 堆栈。

我以前使用过 Netfilter,但显然它不提供链接层挂钩。
有什么办法可以做到吗?

我把它写成一个内核模块;运行 Linux 内核 2.6.32

【问题讨论】:

    标签: linux networking linux-kernel


    【解决方案1】:

    实际上,Netfilter 应该可以正常工作,因为它接收整个数据包(内部存储为包含链路层信息的 sk_buff)。这里有一些示例代码可以帮助您入门。此代码拦截给定设备的所有传入数据包并打印 src MAC 和 src IP。

    static struct nf_hook_ops nfin;
    
    static unsigned int hook_func_in(unsigned int hooknum,
                struct sk_buff *skb,
                                const struct net_device *in,
                                const struct net_device *out,
                                int (*okfn)(struct sk_buff *))
    {
        struct ethhdr *eth;
        struct iphdr *ip_header;
        /* check *in is the correct device */
        if (in is not the correct device)
              return NF_ACCEPT;         
    
        eth = (struct ethhdr*)skb_mac_header(skb);
        ip_header = (struct iphdr *)skb_network_header(skb);
        printk("src mac %pM, dst mac %pM\n", eth->h_source, eth->h_dest);
        printk("src IP addr:=%d.%d.%d.%d:%d\n", NIPQUAD(ip_headr->saddr));
        return NF_ACCEPT;
    }
    
    static int __init init_main(void)
    {
        nfin.hook     = hook_func_in;
        nfin.hooknum  = NF_IP_LOCAL_IN;
        nfin.pf       = PF_INET;
        nfin.priority = NF_IP_PRI_FIRST;
        nf_register_hook(&nfin);
    
        return 0;
    }
    
    
    
    static void __exit cleanup_main(void)
    {
        nf_unregister_hook(&nfin);
    }
    module_init(init_main);
    module_exit(cleanup_main);
    

    【讨论】:

    • 大声笑,我觉得不尝试这个有点愚蠢;非常感谢楼主^^
    • 应该是:printk("src IP addr:=%d.%d.%d.%d:%d\n", NIPQUAD(ip_header->saddr));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-08
    • 2012-10-25
    • 2020-06-06
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多