6

特定の NIC がフレームを受信したときにフレームをキャプチャしたい。それらからいくつかの情報を抽出します (現在、送信元 MAC アドレスと送信元 IP アドレスを取得する必要があります); これらの情報を公開データ構造に保存します。そして、フレームが TCP/IP スタックに到達するまで待ちます。

以前に Netfilter を使用したことがありますが、どうやらリンク層フックを提供していないようです。
これを行う方法はありますか?

これをカーネルモジュールとして書いています。Linux カーネル 2.6.32 の実行

4

1 に答える 1

6

実際、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);
于 2012-06-16T02:24:03.320 に答える