Как захватить сетевые кадры в модуле ядра

Я хочу захватывать кадры, когда они получены определенным NIC; извлечь некоторую информацию из них (в настоящее время мне нужно захватить исходный MAC-адрес и исходные IP-адреса); сохранить эту информацию в какой-либо общедоступной структуре данных; и позволить фрейму идти вверх по пути к стеку TCP / IP.

Я ранее использовал Netfilter, но, по-видимому, он не предоставляет хуков канального уровня.
Есть ли способ, которым я могу сделать это?

Я пишу это как модуль ядра; работает ядро Linux 2.6.32

Ответы на вопрос(1)

Решение Вопроса

потому что он получает весь пакет (внутренне хранится как 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);
 16 июн. 2012 г., 17:10
@ Адель Рад, что это работает для вас!
 Fingolfin16 июн. 2012 г., 10:52
лол, я чувствую себя глупо, что не попробовал это; Большое спасибо, сэр ^^
 07 февр. 2016 г., 12:52
должно быть: printk ("IP-адрес источника: =% d.% d.% d.% d:% d \ n", NIPQUAD (ip_header- & gt; saddr));

Ваш ответ на вопрос