Chinaunix

标题: 关于在netfilter中使用skb_copy发生的问题 [打印本页]

作者: anhongkui    时间: 2010-11-23 17:22
标题: 关于在netfilter中使用skb_copy发生的问题
本帖最后由 anhongkui 于 2010-11-24 09:23 编辑

在NF_IP_LOCAL_OUT注册了一个hook,   想将一个包变成两个包。



  1. #ifndef __KERNEL__
  2. #define __KERNEL__
  3. #endif

  4. #ifndef MODULE
  5. #define MODULE
  6. #endif

  7. #include <linux/module.h>
  8. #include <linux/skbuff.h>
  9. #include <linux/netdevice.h>
  10. #include <linux/config.h>
  11. #include <linux/ip.h>
  12. #include <linux/tcp.h>
  13. #include <linux/udp.h>
  14. #include <net/ip.h>
  15. #include <linux/netfilter_ipv4.h>



  16. static unsigned int doit(unsigned int hooknum, struct sk_buff **skb,
  17.                          const struct net_device *in,
  18.                          const struct net_device *out,
  19.                          int (*okfn) (struct sk_buff *))
  20. {

  21.     struct sk_buff *newskb = skb_copy(*skb, GFP_ATOMIC);
  22.     if (newskb  != NULL) {
  23.          okfn(newskb);
  24.     }
  25.     return NF_ACCEPT;
  26. }

  27. static struct nf_hook_ops mynetfilter = {
  28.     {NULL, NULL},
  29.     doit,
  30.     PF_INET,
  31.     /* NF_IP_PRE_ROUTING, */
  32.     NF_IP_LOCAL_OUT,
  33. #if 1
  34.     INT_MIN
  35. #else
  36.     NF_IP_PRI_FILTER - 1
  37. #endif
  38. };

  39. int init_module(void)           //注册模块函数
  40. {
  41.     return nf_register_hook(&mynetfilter);
  42. }

  43. void cleanup_module(void)
  44. {
  45.     nf_unregister_hook(&mynetfilter);
  46. }

  47. MODULE_LICENSE("GPL");


复制代码
这样子,只要 insmod test.o(2.4内核),且有数据包,则直接死机


因为设备无法接显示器,所以无法查错误。

希望有人能告诉我怎么回事,谢谢啦。


编译:
  1. gcc -c mynf.c -D__KERNEL__ -DMODULE -I /usr/src/linux-2.4/include -O -Wall
复制代码

作者: Godbach    时间: 2010-11-23 19:30
# static unsigned int doit(unsigned int hooknum, struct sk_buff **skb,
#                          const struct net_device *in,
#                          const struct net_device *out,
#                          int (*okfn) (struct sk_buff *))
# {
#

#     struct sk_buff *newskb = skb_copy(*skb, GFP_ATOMIC);
#     if (newskb  != NULL) {
#          okfn(*skb);
#     }
#     return NF_ACCEPT;
# }

你这个地方的逻辑不对, 既然你都调用 okfn 将 skb 发出去了,为什么还 return NF_ACCEPT 呢。
修改为 return NF_STOLEN 试一下
作者: anhongkui    时间: 2010-11-24 09:22
是这样的,我想将复制出来的包发出去,原始包继续走以前的流程(iptables规则链)

上边是我抄代码抄错了,应该是okfn(newskb);
作者: 瀚海书香    时间: 2010-11-24 10:29
回复 1# anhongkui
如果你把注册点放到NF_IP_PRE_ROUTING上应该没问题吧?
还有对newskb的处理,可以试试用netif_rx(newskb)试试。
作者: anhongkui    时间: 2010-11-24 11:07
谢谢2楼和4楼,是我的代码写错了。

我的代码写成了okfn(*skb);改成okfn(newskb)就ok了。

我太马虎了。~
作者: Godbach    时间: 2010-11-24 11:36
谢谢2楼和4楼,是我的代码写错了。

我的代码写成了okfn(*skb);改成okfn(newskb)就ok了。

我太马虎了 ...
anhongkui 发表于 2010-11-24 11:07


就是嘛。如果你 okfn 里面传递的 skb,传送完毕之后 skb 就释放了,你还要 return NF_ACCEPT,后续处理模块接收到的 skb 是 NULL,是要出问题的




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2