忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 569 | 回复: 11

[内核模块] netfilter修改TCP数据包遇到的问题,请各位不吝赐教! [复制链接]

论坛徽章:
0
发表于 2017-11-08 15:49 |显示全部楼层
本帖最后由 flash78910 于 2017-11-08 15:52 编辑

我在LOCAL_OUT点处对TCP数据包的数据段进行扩展,使用skb_put函数扩展16个字节,并插入16字节的数据,同时更新了包的校验和。我在函数里只有一次memcpy动作。为什么抓包显示有多次重复的插入数据出现?以下是这个钩子函数,插入的内容为insert,插入位置为TCP数据开头部分。谢谢各位,请不吝赐教!


  1. unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn) (struct sk_buff *))
  2. {
  3.         struct iphdr *iph = NULL;
  4.         unsigned char *tcp_ins = NULL;         //tcp插入指针
  5.         struct tcphdr *tcph = NULL; //tcp头
  6.         unsigned int tcp_len = 0; //tcp报文长度
  7.         unsigned int data_len = 0; //tcp数据部分长度
  8.         unsigned char insert[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; //插入数据
  9.         if(skb == NULL)
  10.                 return NF_ACCEPT;
  11.         if(is_ign_pkt(skb)==1) //过滤需要修改的数据包,此后都是要修改的数据包
  12.                 return NF_ACCEPT;
  13.         if(skb_is_nonlinear(skb)) //线性化skb
  14.         {                        
  15.                 if(skb_linearize(skb) != 0)
  16.                         return NF_ACCEPT;
  17.         }
  18.         iph = ip_hdr(skb); //skb的ip头
  19.         if(iph == NULL)
  20.                 return NF_ACCEPT;
  21.         if(iph->protocol==TCP)
  22.         {
  23.                 if(skb_tailroom(skb)<=16) //判断tailroom空间
  24.                 {
  25.                         printk("TCP NOT Enough\n");
  26.                 }
  27.                 else
  28.                 {
  29.                         printk("TCP tail: 0x%u\n",skb->tail);               
  30.                         skb_put(skb,16); //数据段空间扩展
  31.                         printk("TCP new_tail: 0x%u\n",skb->tail);
  32.                         printk("TCP------tailroom: %u------\n",skb_tailroom(skb));
  33.                         tcph = tcp_hdr(skb);
  34.                         tcp_ins = (unsigned char *)tcph + (tcph->doff*4); //指向数据起始处
  35.                         iph->tot_len = htons(ntohs(iph->tot_len)+16);
  36.                         tcp_len = ntohs(iph->tot_len) - iph->ihl*4;
  37.                         data_len = tcp_len - (tcph->doff*4);
  38.                         memmove(tcp_ins+16, tcp_ins, data_len); //原始数据后移留出插入空间
  39.                         memcpy(tcp_ins, insert, 16); //拷贝插入数据
  40.                         tcph->check = 0;
  41.                         skb->csum = 0;
  42.                         iph->check = 0;
  43.                         skb->csum = skb_checksum(skb, iph->ihl*4,ntohs(iph->tot_len)-iph->ihl*4,0);
  44.                         tcph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, tcp_len, iph->protocol, skb->csum);
  45.                         iph->check = ip_fast_csum(iph, iph->ihl);
  46.                 }
  47.                 return NF_ACCEPT;
  48.         }
  49.         return NF_ACCEPT;
  50. }

复制代码


Tcp分组截图

Tcp分组截图

论坛徽章:
0
发表于 2017-11-09 09:17 |显示全部楼层
UDP改动发包没有这个情况,这个是不是由于TCP重传的原因造成的?因为我暂时只改了发端,收端还没做处理。抓包看到好多改动的包都不断在重传。

论坛徽章:
5
处女座
日期:2014-10-15 11:57:302015年亚洲杯之中国
日期:2015-03-04 17:05:552015亚冠之西悉尼流浪者
日期:2015-07-31 12:14:2915-16赛季CBA联赛之同曦
日期:2015-12-10 18:14:0615-16赛季CBA联赛之北京
日期:2016-07-07 17:01:53
发表于 2017-11-09 10:08 |显示全部楼层
改了tcp负载长度,后面的数据流要做序列号调整

论坛徽章:
0
发表于 2017-11-09 19:42 |显示全部楼层
回复 3# zhanglin496

但是我打算在下一跳的路由上,再次去掉增加的负载,然后由路由转发。所以就没有改序号,路由器上也有一个内核模块是去掉我这块负载功能的,相当于检测我这个负载标记然后去掉(或者叫还原),再转发。

论坛徽章:
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
发表于 2017-11-09 23:31 |显示全部楼层
回复 4# flash78910

你可以直接在 kernel 里把你的 tcp payload 整个打印出来,和你的抓包对比。
我感觉你调用 memmove 有可能导致内存出现了一些问题。

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
发表于 2017-11-10 10:36 |显示全部楼层
能不能把这个数据包的相关信息打印出来? ip port, seq id 等等,看看到底进入你这个hook几次

论坛徽章:
0
发表于 2017-11-10 20:07 |显示全部楼层
回复 5# Godbach

确实,我打印出未插入16字节前的payload,和抓包后的对比。在第一次发送时修改的分组正常,之后重传的时候尾部有16字节被挤出去没有了,而且每次重传都会经过一遍钩子,又会插入一次数据,后面又会被挤出去16字节。。。重传的长度始终保持和第一次发送时的长度一样,难道重传经过钩子时并没有改变长度吗?skb_put()的定义中不是已经把skb->tail后移了吗,同时更新了skb->len?而且其中也有这么一句SKB_LINEAR_ASSERT(skb),难道最后的空间还不是线性的吗?

论坛徽章:
18
程序设计版块每日发帖之星
日期:2015-08-17 06:20:0015-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:56黑曼巴
日期:2016-12-26 16:00:32每日论坛发贴之星
日期:2016-07-18 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:51程序设计版块每日发帖之星
日期:2016-06-03 06:20:00程序设计版块每日发帖之星
日期:2016-06-02 06:20:00程序设计版块每日发帖之星
日期:2016-05-30 06:20:00
发表于 2017-11-15 17:35 |显示全部楼层
看起来协议栈在tcp control block里记录了skb的有关信息。
重传逻辑假定报文在重传过程中是不变的?

论坛徽章:
7
IT运维版块每日发帖之星
日期:2016-05-27 06:20:00IT运维版块每日发帖之星
日期:2016-06-09 06:20:00操作系统版块每日发帖之星
日期:2016-06-12 06:20:00程序设计版块每日发帖之星
日期:2016-06-12 06:20:00操作系统版块每日发帖之星
日期:2016-06-13 06:20:00IT运维版块每日发帖之星
日期:2016-06-17 06:20:002015-2016NBA季后赛纪念章
日期:2016-06-28 17:42:27
发表于 2017-11-18 19:47 |显示全部楼层
假定? 难道需要netfilter做判断?

论坛徽章:
18
程序设计版块每日发帖之星
日期:2015-08-17 06:20:0015-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:56黑曼巴
日期:2016-12-26 16:00:32每日论坛发贴之星
日期:2016-07-18 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:51程序设计版块每日发帖之星
日期:2016-06-03 06:20:00程序设计版块每日发帖之星
日期:2016-06-02 06:20:00程序设计版块每日发帖之星
日期:2016-05-30 06:20:00
发表于 2017-11-22 18:48 |显示全部楼层
好像tcp层的确在skb->cb(通过TCP_SKB_CB)记录了一些信息。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP