免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1792 | 回复: 5

[网络子系统] 询问:为什么在netfilter的钩子函数中利用skb_copy会不成功? [复制链接]

论坛徽章:
0
发表于 2014-07-03 16:12 |显示全部楼层
  如题,我在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");

论坛徽章:
1
摩羯座
日期:2014-05-07 11:21:33
发表于 2014-07-03 18:06 |显示全部楼层
sk = skb_copy(skb, 1);是不是要用GFP_ATOMIC 分配呢?

论坛徽章:
0
发表于 2014-07-04 15:22 |显示全部楼层
回复 2# wan3610425

谢谢,按照您的提法改正之后变成sk = skb_copy(skb, GFP_ATOMIC );之后就不会出现错误了。是因为内存分配的时候出问题了么?因为崩溃提示oops错误的时候有BUG: scheduling while atomic: swapper/0/0x00000100 .

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-04-30 06:20:00
发表于 2014-07-14 10:07 |显示全部楼层
软中断中不能试用带休眠的操作,atomic是立即返回,其他的有些是要休眠到有空间了才返回

论坛徽章:
0
发表于 2014-07-14 17:36 |显示全部楼层
回复 4# icebluechao
嗯嗯,谢谢,我最近用kmalloc也有gfp_mask这个参数,看来内核的东西还要多学习啊。

   

论坛徽章:
1
IT运维版块每日发帖之星
日期:2016-04-30 06:20:00
发表于 2014-07-16 20:24 |显示全部楼层
我也是刚做这个,还有其他复杂的问题呢,桥转发的时候容易出问题回复 5# zhaoyun0819


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

ITPUB技术栈

ITPUB技术栈:http://z.itpub.net/
ITPUB技术栈是由ITPUB社区打造的垂直于IT领域的知识交流平台,在这里,你既可以是创作者也可以是消费者。如果你的IT生涯丰富多彩,喷薄的个人价值尽可在小栈内体现;如果你渴望找到志同道合的伙伴,拓宽人脉,小栈会是你最好的选择。





点击进入>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP