8

Linux用のイーサネットネットワークドライバーを書いています。パケットを受信し、編集して再送信したい。関数でパケットを編集する方法は知ってpacket_interceptorいますが、この関数で着信パケットをドロップするにはどうすればよいですか??

#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/sock.h>

struct packet_type my_proto;

int packet_interceptor(struct sk_buff *skb,
    struct net_device *dev,
    struct packet_type *pt,
    struct net_device *orig_dev) {

    // I dont want certain packets go to upper in net_devices for further processing.
    // How can I drop sk_buff here?!

  return 0;
}

static int hello_init( void ) {
    printk(KERN_INFO "Hello, world!\n");

    my_proto.type = htons(ETH_P_ALL);
    my_proto.dev = NULL;
    my_proto.func = packet_interceptor;

    dev_add_pack(&my_proto);
    return 0;
}    

static void hello_exit(void) {
  dev_remove_pack(&my_proto);
  printk(KERN_INFO "Bye, world\n");
}

module_init(hello_init);
module_exit(hello_exit);
4

2 に答える 2

6

私はカーネルネットワーキングコードを調べました(そこで何かをしてから1年)、何も漏らさずにこれを行うことができるはずだと思います:

kfree_skb(skb);
return NET_RX_DROP;

編集

これはip_rcvandのような他のプロトコル ハンドラで行われますarp_rcv(最後のものは NET_RX_DROP の代わりに 0 を返しますが、戻り値はあまり重要ではないと思います)。skb を削除する場合は、他のハンドラーを呼び出さないでください。

ip_rcvip.c (下部)のコードを見てください: http://lxr.free-electrons.com/source/net/ipv4/ip_input.c#L375

すべてがうまくいくと、skb を Netfilter に渡し、Netfilter が呼び出しますip_rcv_finish(ドロップしない場合)。何か問題が発生した場合は、skb を解放して戻ります。

編集

複数のプロトコル ハンドラーが SKB に一致する場合、カーネルはそれをすべてのハンドラーに送信します。モジュールの 1 つにいる場合kfree_skb()、SKB は他のハンドラーに残ります。

于 2013-10-15T17:56:24.363 に答える