免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3341 | 回复: 7
打印 上一主题 下一主题

[内核模块] [求助]利用netfilter对sk_buff做更改的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-23 21:56 |只看该作者 |倒序浏览
本帖最后由 newand 于 2012-11-23 21:58 编辑

利用netfilter在NF_IP6_PRE_ROUTING挂载点对经过的指定组播报文报头做更改。
现在的问题是,更改报头之后发送的组播报文接收端却接收不到,除非卸载此模块。
所以我考虑是不是检验的问题,但IPV6报文不需要检验,MAC层的头部也没有校验,只剩UDP的校验。
代码如下:
  1. /*
  2. * this programe is working as plugin of netfilter which will pin a timestamp to
  3. * the destination header of ipv6 packet every x seconds when the packet is
  4. * the object multicast packet.
  5. */

  6. #include <linux/netfilter.h>
  7. #include <linux/netfilter_ipv6.h>
  8. #include <linux/netfilter_ipv6/ip6_tables.h>
  9. #include <linux/module.h>
  10. #include <linux/moduleparam.h>
  11. #include <linux/kernel.h>
  12. #include <linux/inet.h>
  13. #include <linux/ip.h>
  14. #include <linux/udp.h>
  15. #include <net/checksum.h>
  16. #include <net/udp.h>
  17. #include <net/ipv6.h>
  18. #include <linux/time.h>


  19. #define PRINT(fmt,args...) printk("Marker: " fmt, ##args)


  20. /* IP6 Hooks */
  21. /* After promisc drops, checksum checks. */
  22. #define NF_IP6_PRE_ROUTING  0
  23. /* If the packet is destined for this box. */
  24. #define NF_IP6_LOCAL_IN     1
  25. /* If the packet is destined for another interface. */
  26. #define NF_IP6_FORWARD      2
  27. /* Packets coming from a local process. */
  28. #define NF_IP6_LOCAL_OUT        3
  29. /* Packets about to hit the wire. */
  30. #define NF_IP6_POST_ROUTING 4

  31. /*test begin*/
  32. /*原本打算使用skb_copy来拷贝一个sk_buff,然后再修改其中的某一项,最后kfree_skb原来的
  33. 但是不能free的总是出错,于是创新的,直接在原来的sk_buff的ip报头进行修改,结果却是接收端不能收到报文
  34. */
  35. struct sk_buff *
  36. ip6_encapsulate_pkt_t(struct sk_buff *skb)
  37. {
  38.         struct sk_buff *new_skb, *temp_skb;
  39.         struct ipv6hdr * ipv6h;
  40.         struct udphdr *udph;

  41.         //copy from the *skb to new_skb
  42.         /*new_skb = skb_copy(skb, GFP_ATOMIC);
  43.         if(new_skb == NULL)
  44.         {
  45.                 PRINT("Allocate new sk_buffer error!\n");
  46.                 //kfree_skb(skb);
  47.                 return NULL;
  48.         }*/
  49.         udph = udp_hdr(skb);
  50.         ipv6h->nexthdr = 0x60;//set next header as 60 which means next destination header.

  51.         udph->check = csum_ipv6_magic(&ipv6h->saddr,&ipv6h->daddr, udplen,IPPROTO_UDP, csum_partial((char*)udph,udplen,0));
  52.         printk(" skb sum %u,CheckSum  = %u\n",skb->ip_summed,udph->check);
  53.         
  54.         //kfree_skb(skb);
  55.         //        skb = new_skb;//skb pointer to new_skb
  56.    
  57.         return skb;
  58. }
  59. /*test end*/

  60. /*Hook which will call the encapsulate func when condition satisfied
  61. *condition1: IPv6 Multicast packets
  62. *condition2: every 20ms
  63. */
  64. static unsigned int
  65. ip6_multi_modify(unsigned int hooknum,
  66.                                 struct sk_buff *skb,
  67.                                 const struct net_device *in,
  68.                                 const struct net_device *out,
  69.                                 int (*okfn)(struct sk_buff*))
  70. {
  71.     struct sk_buff *sk = skb;
  72.         struct ipv6hdr *ip6_hdr = ipv6_hdr(skb);//header

  73.         if(ip6_hdr->version == 6)
  74.         {
  75.                 struct in6_addr destip = ip6_hdr->daddr;//destination ip
  76.           
  77.                 if(destip.s6_addr[0] == 0xff && destip.s6_addr[1] == 0x15)
  78.                 {
  79.                         if(skb_tailroom(sk) >= 40)
  80.                         {
  81.                                 //expand
  82.                                 PRINT("tailroom is enough\n");
  83.                         }
  84.                         else
  85.                         {
  86.                                 //modify
  87.                                 PRINT("not enough\n");
  88.                         }
  89.                         //print before change
  90.                         PRINT("before change %x", ip6_hdr->nexthdr);
  91.                         skb = ip6_encapsulate_pkt_t(skb);
  92.                         if(skb == NULL)
  93.                         {
  94.                                 PRINT("Allocate new sk_buffer error!\n");
  95.                                 return NF_STOLEN;
  96.                         }
  97.                         ip6_hdr= ipv6_hdr(skb);
  98.                         PRINT("after change %x \n", ip6_hdr->nexthdr);

  99.                 }

  100.         }

  101.         return NF_ACCEPT;
  102. }


  103. /*Initialize the hook*/
  104. static struct nf_hook_ops nf_out_modify =
  105. {
  106.         .hook = ip6_multi_modify,
  107.         .hooknum = NF_IP6_PRE_ROUTING,//Check all the forwarded packets
  108.         .pf = PF_INET6,
  109.         .priority = NF_IP6_PRI_FIRST,
  110. };

  111. /*Initialize the module*/
  112. static int __init ip6_multi_init(void)
  113. {
  114.         int ret;
  115.         ret = nf_register_hook(&nf_out_modify);
  116.         PRINT("IPV6 multicast packet modify module init.\n");
  117.         return 0; //success
  118. }

  119. /*Clear the module*/
  120. static void __exit ip6_multi_exit(void)
  121. {
  122.         nf_unregister_hook(&nf_out_modify);
  123.         PRINT("IPV6 multicast packet modify module exit.\n");
  124. }

  125. module_init(ip6_multi_init);
  126. module_exit(ip6_multi_exit);
复制代码
请各位帮忙看下。

论坛徽章:
0
2 [报告]
发表于 2012-11-23 23:57 |只看该作者
在本机和对端抓一下包吧,ipv6的4层头计算校验和也是需要添加三层的伪头部的,如果真是校验和的问题是可以在网卡抓到包的

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2012-11-24 14:18 |只看该作者
回复 2# luoyan_xy
四层校验和出错不应该导致报文发布出去。


   

论坛徽章:
0
4 [报告]
发表于 2012-11-29 15:08 |只看该作者
本帖最后由 newand 于 2012-11-29 15:22 编辑

回复 3# Godbach


    是的,后来看了,确实不是那个问题。
   谢谢两位。
   现在又遇到个问题,用skb_cpy_expand时会分配不了新的空间。
  1. PRINT("SKB SIZE:%u;",sizeof(*skb));
  2.         //copy from the *skb to new_skb
  3.         new_skb = skb_copy_expand(skb, skb_headroom(skb),
  4.                                 skb_tailroom(skb) + 16
  5.                                 GFP_ATOMIC);
  6. PRINT("NEW SKB SIZE:%u;",sizeof(*new_skb));
复制代码
打印的结果是:
SKB SIZE:192;   NEW SKB SIZE:192
空间没有变大,但是地址确实是不同的。
请问怎么会这样呢?

论坛徽章:
0
5 [报告]
发表于 2012-11-29 15:39 |只看该作者
本帖最后由 newand 于 2012-11-29 15:59 编辑

我打印skb_copy_expand前后skb的内容,结果如下:
SKB SIZE:192,skb->len:60;
head room:24,tailroom:235,add:16.
NEW SKB SIZE:192,newskb->len:60;
head room:24,tailroom:747,add:16.
为什么tailroom也增了,而sizeof(*skb)不增呢?

论坛徽章:
0
6 [报告]
发表于 2012-11-29 17:16 |只看该作者
回复 5# newand
LZ大意了吧,用sizeof()会改变么?

   

论坛徽章:
0
7 [报告]
发表于 2012-11-29 18:29 |只看该作者
本帖最后由 newand 于 2012-11-29 19:36 编辑

回复 6# whaaat


what兄说的对,sizeof是不能查看到动态分配的。   
是我PRINT位置不对,一楼的这段代码没有问题的。

论坛徽章:
0
8 [报告]
发表于 2012-11-30 10:54 |只看该作者
回复 7# newand
如果要free掉skb,hook需要返回NF_STOLEN。
udp_hdr在hook中是不能用的,还没有到4层。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP