7

Linux için ethernet ağ sürücüsünü yazıyorum. Paketleri almak, düzenlemek ve yeniden göndermek istiyorum. Paketin packet_interceptor işlevinde nasıl düzenleneceğini biliyorum, ancak bu işlevdeki gelen paketleri nasıl bırakabilirim ??Linux paketlerini net_dev_add() API kullanarak nasıl filtreleyebilirsiniz?

#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); 
+0

Çözümümle test ettiniz mi? – Atle

+0

Merhaba @Atle, bugünlerde bilgisayarımda bir sorunum var. Cevabınız için teşekkürler, bilgisayarımı başlattığım anda test edeceğim: D. Ama ben sana soruyorum, bu çözümü denedim, ama işe yaramadı. Onu tekrar toplayacağım. –

cevap

6

Modülünüzün tüm ethernet paketlerini ele almasını sağlayın. Linux, eşleşen tüm protokol işleyicilerine paketleri gönderecektir. IP, çekirdeğinizde zaten kayıtlı olduğundan, hem modülünüz hem de ip_rcv IP başlıklarına sahip tüm SKB'leri alacaktır.

Bu davranışı, çekirdek kodunu değiştirmeden değiştiremezsiniz. Bir olasılık yerine bir netfilter modülü oluşturmaktır. Bu şekilde, paketi ip_rcv işlevinden sonra engelleyebilir ve isterseniz (Netfiltre PREROUTING kancasında) kullanabilirsiniz.

Burada yazdığım bazı kodlardan çıkardığım küçük bir Netfilter modülü var. Bu modül bitmemiş, ancak ana şeyler yerinde.

#include <linux/netfilter.h> 
#include <linux/netfilter_ipv4.h> 

// Handler function 
static unsigned int my_handler (
    unsigned int hook, 
    struct sk_buff *skb, 
    const struct net_device *in, 
    const struct net_device *out, 
    int (*okfn)(struct sk_buff *)) 
{ 
    return NF_ACCEPT; 
// or 
    return NF_DROP; 
} 

// Handler registering struct 
static struct nf_hook_ops my_hook __read_mostly = { 
    .hook = my_handler, 
    .pf = NFPROTO_IPV4, 
    .hooknum = (1 << NF_INET_PRE_ROUTING), 
    .priority = NF_IP_PRI_FIRST // My hook will be run before any other netfilter hook 
}; 

int my_init() { 
    int err = nf_register_hook (&my_hook); 
    if (err) { 
      printk (KERN_ERR "Could not register hook\n"); 
    } 
    return err; 
} 
+0

Netfilter'i test ettim, çok iyi çalışıyor, ama 'dev_add_pack() 'kancalarıyla düşmem gerekiyor.Benim sorum, sistemim iki işleyiciye sahipse (ip_rcv, my_packet_interceptor), işleyicimden birinde skb'yi değiştirdiğimde, hangileri geçerli? (my_packet_interceptor'daki skb'yi değiştirdiğimi farzedeyim, yani iki skb var, "orijinal" ve "değişti", hangileri daha fazla işleniyor?) –

+1

İşleyiciler birbiri ardına koşuyorlar. IP'nin, muhtemelen modülünüzden önce kaydedildiği için ilk çalıştırıldığını tahmin ediyorum. SKB'nin bu aşamada kopyalandığını sanmıyorum, bu yüzden IP değiştirmeden önce muhtemelen onunla yapılacaktır. – Atle

+0

Dolayısıyla, eğer işleyiciler birbirlerinden sonra çalışıyorlarsa, Neden paketleri bırakamıyorum? –

6

I (Ben orada içeride bir şey yaptığını beri yılda) kodu ağ Kernel geçti ve ben bir şey sızıntı olmadan bunu yapabilmek do gerektiğini düşünüyorum:

kfree_skb(skb); 
return NET_RX_DROP; 

Edit

Bu, ip_rcv ve arp_rcv gibi diğer protokol işleyicilerinde yapılır (son olarak NET_RX_DROP yerine 0 döndürür, ancak dönüş değeri çok önemli değil). Eğer skropu düşürürseniz başka işleyicileri aramayı unutmayın. (Altta) ip.c içinde ip_rcv için koda

Görünüş: Her şey yolunda giderse http://lxr.free-electrons.com/source/net/ipv4/ip_input.c#L375

(It is bırakın yoksa) o zaman ip_rcv_finish çağırır NetFilter için SKB geçirir. Bir şey ters giderse, skb'yi serbest bırakır ve geri döner. Birden fazla protokol işleyici bir SKB eşleşirse

Düzenleme

, çekirdek hepsine gönderir. Modüllerden birinde kfree_skb()'u kullandığınızda, SKB hala diğer işleyicilerinde yaşayacaktır.

+0

Bugün test ettim, ama işe yaramadı. Onunla sorun nedir? –

+0

"Çalışmıyor" ile ne demek istiyorsun? Paket, sistem tarafından düşürülmek yerine alındı ​​mı? Paketler modülünüzü bile giriyor mu? – Atle

+1

Tüm paketleri 'packet_interceptor 'işleyicisinde alıyorum, ancak sistem tarafından alınan tüm paketler. http://paste.ubuntu.com/6324987/ –

İlgili konular