How to capture network frames in a kernel module

2019-02-03 19:11发布

I want to capture frames when they're received by a certain NIC; extract some information from them(currently I need to capture the source MAC and source IP addresses); save these information in some public data structure; and let the frame go up in its way to the TCP/IP stack.

I've used Netfilter before, but apparently it doesn't provide Link layer hooks.
Is there any way I can do this?

I am writing this as a Kernel Module; running Linux kernel 2.6.32

1条回答
劫难
2楼-- · 2019-02-03 19:29

Actually Netfilter should work fine because it receives the entire packet (internally stored as an sk_buff which includes the Link layer information). Here's some sample code that should get you started. This code intercepts all incoming packets for a given device and prints the src MAC and 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);
查看更多
登录 后发表回答