我正在为
linux编写以太网网络驱动程序.我想接收数据包,编辑并重新发送它们.
我知道如何在packet_interceptor函数中编辑数据包,但是如何在此函数中丢弃传入的数据包?
我知道如何在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);
解决方法
您正在使您的模块处理所有以太网数据包. Linux将向所有匹配的协议处理程序发送数据包.由于IP已在您的内核中注册,因此您的模块和ip_rcv都将接收所有带有IP头的SKB.
如果不更改内核代码,则无法更改此行为.一种可能性是创建一个netfilter模块.这样,您可以在ip_rcv函数之后拦截数据包,并在需要时删除它(在Netfilters PREROUTING挂钩中).
这是一个小的Netfilter模块,我从我已编写的一些代码中提取.这个模块尚未完成,但主要内容已经到位.
#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; }