- 论坛徽章:
- 0
|
如题,我在POST_ROUTING中注册了一个钩子函数,实现的功能是拦截到HTTP包(目的端口是80或8080)就计数返回NF_ACCEPT。
函数体中声明:
struct sk_buff *sk=NULL;
之后利用拷贝函数:
sk = skb_copy(skb, 1);
结果发现,打开网页时,最开始没有问题,当我不停的点击F5刷新的时候,就会崩溃,提示oops信息。后来根据oops和objdump反汇编调试。发现有可能是指针问题。
所以开始进行容错:
if(sk==NULL)
{printk("<0>""sk pointer is NULL \n");return NF_ACCEPT;}
此后打开网页时,最开始没有问题,当我不停的点击F5刷新的时候,就会打印 sk pointer is NULL,证明skb_copy();拷贝失败。
最后我直接对skb进行操作,没有拷贝的过程,狂按F5刷新就不会有问题,系统不会崩溃了。
搞不懂这是什么原因,特来指教。
以下是源代码:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/string.h>
#include <linux/kmod.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/socket.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <net/sock.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <linux/if_arp.h>
//定义钩子函数结构体
struct nf_hook_ops post_hook;
static int count=0;
//实例化钩子函数
static unsigned int watch_out(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
//复制skbuff结构体,将指针指向ip头和tcp头
struct sk_buff *sk=NULL;
struct iphdr *iph=NULL;
struct tcphdr *tcph=NULL;
sk = skb_copy(skb, 1); //此处利用了skb拷贝,后来我没有拷贝,直接操作skb指针,不会崩溃。
if(sk==NULL)
{printk("<0>""sk pointer is NULL \n");return NF_ACCEPT;}
iph = ip_hdr(sk);
if(iph==NULL)
{printk("<0>""iph pointer is NULL \n");return NF_ACCEPT;}
tcph = (void *) iph + (iph->ihl<<2);
if(tcph==NULL)
{printk("<0>""tcph pointer is NULL \n");return NF_ACCEPT;}
if ( iph->protocol == IPPROTO_TCP)
{
if(tcph->dest == htons(8080) || tcph->dest == htons(80))
{
count++;
int temp=count%100;
if(temp==0)
{
printk("<0>""HTTP FOUND ACCEPT:%d \n",count);
return NF_ACCEPT;
}
else
return NF_ACCEPT;
}
else
return NF_ACCEPT;
}
else
return NF_ACCEPT;
}
int init_module()
{
printk("------HTTP_Kernel Start default------\n");
//将钩子函数注册到POST_RPOTING挂载点上,设置优先级最高。
post_hook.hook = watch_out;
post_hook.pf = PF_INET;
post_hook.priority = NF_IP_PRI_FIRST;
post_hook.hooknum = NF_INET_POST_ROUTING;
nf_register_hook(&post_hook);
return 0;
}
void cleanup_module()
{
printk("------HTTP_Kernel finish default------\n");
//注销钩子函数
nf_unregister_hook(&post_hook);
}
MODULE_INIT(init_module);
MODULE_EXIT(cleanup_module);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhaoyun");
|
|