免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3232 | 回复: 13

netfilter与用户空间通信二法 [复制链接]

论坛徽章:
0
发表于 2009-06-24 19:06 |显示全部楼层
最近在看netfilter的相关文章了,发现大家都是研究的很是深入。而我只是菜鸟一个,先从netfilter与用户空间通信方法入手吧。
法一:netlink
关于内核与用户空间的通信方法,在IBM的developer work上,有两篇很不错的文章。
http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs/
http://www.ibm.com/developerworks/cn/linux/l-netlink/index.html
这两篇文章都提到了netlink,我也认为netfilter+netlink就可以在内核和用户空间实现零距离接触了。
netlink通信流图.jpg
自己也调试了上面的程序,还是蛮又感觉的。
不过还是有个问题,请教大侠们!
我的想法是这样的,一一分拆IP分组,(感觉和WireShark差不多),就是不仅得到skb的ip头和tcp/udp头,还可以同时得到里面的载荷,就是数据内容。但就是得不到数据内容,我先尝试用char类型的指针,不行;给它kmalloc分配空间,不行;使用char数组,也还是不行。但我分别实现就可以:比如说,我使用 netlink传输的结构体,要么只有IP地址、端口等纯数值类型的,或者要么只有传递字符串(就是内容),就可以。不知道是为什么。
法二:使用sockopt与内核交换数据
http://blog.chinaunix.net/u/12313/showart_245767.html
这篇文章写得不错。
nf_sockopt通信.jpg
这个方法是我在看一个开源项目的时候,看到的,主要还是使用的copy_from_user、copy_to_user。
最后:
法一使用的是大量的数据传输,比较常规,容易理解。
法二基本使用在控制方面的,少而精。
上面只是我粗浅的解释,希望能抛砖引玉,多谈谈这方面的自己应用的体会。

论坛徽章:
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
发表于 2009-06-24 19:16 |显示全部楼层
还可以同时得到里面的载荷,就是数据内容。但就是得不到数据内容,我先尝试用char类型的指针,

应该可以得到完整的IP报文的,那就有数据内容啊。你的程序是怎么设置的。

之间记得分析IP Queue的时候,可以设定copy报文的模式,有只拷贝元数据,就是报文的一些摘要信息,也可以完全把整个报文拷贝出来的。

论坛徽章:
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
发表于 2009-06-24 19:17 |显示全部楼层
这两篇文章确实写的很好,对于netlink和sockopt的学习有很大帮助。

论坛徽章:
0
发表于 2009-06-24 20:06 |显示全部楼层

回复 #2 Godbach 的帖子

>应该可以得到完整的IP报文的,那就有数据内容啊。你的程序是怎么设置的
我先设置了一个结构体:
struct packet_info
{
  __u32 srcIP;
  __u32 destIP;
  __u16 destPort;
  __u32 seq;
  __u32 ack_seq;
  __u16 doff;
  __u8 fin;
  __u8 syn;
  __u8 ack;
  char *data;
};
其中data就是载荷数据,不包括包头的。
然后在钩子函数里处理skb,赋值给packet_info结构体。
info.data = (char *)((*pskb)->data+(iph->ihl*4)+(thead->doff*4));
然后,使用netlink_unicast发送,用户区程序接受,但收到的要么没有东西,要么是乱码

论坛徽章:
0
发表于 2009-06-24 20:09 |显示全部楼层
补充一下:
pskb是指向skb的指针的指针,iph是ip头(struct iphdr *iph = (*pskb)->nh.iph;),thead是TCP头(thead = (struct tcphdr *)((*pskb)->data+(iph->ihl*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
发表于 2009-06-24 20:13 |显示全部楼层
struct packet_info
{
  __u32 srcIP;
  __u32 destIP;
  __u16 destPort;
  __u32 seq;
  __u32 ack_seq;
  __u16 doff;
  __u8 fin;
  __u8 syn;
  __u8 ack;
  char *data;
};
其中data就是载荷数据,不包括包头的。
然后在钩子函数里处理skb,赋值给packet_info结构体。
info.data = (char *)((*pskb)->data+(iph->ihl*4)+(thead->doff*4));
然后,使用netlink_unicast发送,用户区程序接受,但收到的要么没有东西,要么是乱码


看一下你这个结构体,我觉得再传给用户态的时候,内存的处理上有问题,整个结构体是一块内存,而data指向的是另外一块内存,这两个应该不是连续的。

建议你这样测试一下,先让data是一个足够大的静态数组,然后报文的内容拷贝进去,然后再传给用户态测试一下数据是否正确。

论坛徽章:
0
发表于 2009-06-24 20:22 |显示全部楼层

回复 #6 Godbach 的帖子

我也觉得是内存地址的指向问题,于是:
1给它kmalloc分配空间,不行;
2使用char数组,也还是不行,空间分的比较大2048,结果直接死机了

论坛徽章:
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
发表于 2009-06-24 20:23 |显示全部楼层
原帖由 GoldenSoldier 于 2009-6-24 20:22 发表
我也觉得是内存地址的指向问题,于是:
1给它kmalloc分配空间,不行;
2使用char数组,也还是不行,空间分的比较大2048,结果直接死机了


你就简单的抓一个ping包上来,char data[256]应该就可以了。

论坛徽章:
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
发表于 2009-06-24 20:24 |显示全部楼层
空间分的比较大2048,结果直接死机了

char data[2048]就有问题吗,你怎么操作的,怎么会导致死机呢。是不是出现oops了?

论坛徽章:
0
发表于 2009-06-24 21:29 |显示全部楼层

回复 #9 Godbach 的帖子

在测试。。。。
初步结果出来了。我先用了ethereal做了比对,把data[1450],做出来的结果已经和ethereal一致了。
上面提到的死机,可能是我记错了,应该是|给它kmalloc分配空间|导致的。

多谢,多谢!!

技术牛人就是不一样!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP