Chinaunix

标题: 请教IPTABLE中如何修改数据包内容 [打印本页]

作者: leigaiting    时间: 2007-03-30 11:50
标题: 请教IPTABLE中如何修改数据包内容
我想将IP数据包封装的TCP包头及内容添加个UDP包头再用IP封装,具体如下:
MAC头|IP头|TCP头及内容  封装成如下内容  MAC头|IP头|UDP头及内容
作者: 独孤九贱    时间: 2007-03-30 13:24
标题: 回复 #1 leigaiting 的帖子
现在的插件好像没有你说的这个功能,不过你自己写个简单的模块,可以很容易地完成这个功能的……
作者: platinum    时间: 2007-03-30 13:35
若添加了 udp 头,多了 8 bytes,总大小超过了 MTU 怎么办?是否要考虑分片?还是 netfilter 自己实现的?
作者: ssffzz1    时间: 2007-03-30 13:40
他说的好象是把TCP头换成UDP头,不过目前没有这个模块,你可以自己写一个的.
作者: 独孤九贱    时间: 2007-03-30 13:49
标题: 回复 #3 platinum 的帖子
较为直接的方式,肯定是在内核处理分片之前来做这个事情……
作者: platinum    时间: 2007-03-30 13:57
原帖由 ssffzz1 于 2007-3-30 13:40 发表于 4楼  
他说的好象是把TCP头换成UDP头,不过目前没有这个模块,你可以自己写一个的.

他说的是“添加个UDP包头再用IP封装”
作者: platinum    时间: 2007-03-30 13:59
原帖由 独孤九贱 于 2007-3-30 13:49 发表于 5楼  
较为直接的方式,肯定是在内核处理分片之前来做这个事情……

九贱兄,我就是这个弄不明白,netfilter 修改过数据包,并重新计算 chksum 后,重分片动作是哪里进行的?
我记得重组的时候是在 netfilter 最开始的时候,那么重新分片是否在最后脱离 netfilter 的地方进行的呢?
功力不够,没能弄懂 netfilter 的工作流程……
作者: ssffzz1    时间: 2007-03-30 14:03
可以他举的哪个例子是把TCP头替换成UDP头的.
但搞不明白他具体要干什么.
作者: platinum    时间: 2007-03-30 14:05
原帖由 ssffzz1 于 2007-3-30 14:03 发表于 8楼  
可以他举的哪个例子是把TCP头替换成UDP头的.
但搞不明白他具体要干什么.


他例子里的“及内容”可能指的是原先 TCP 头往后的所有东西,也就是原先的 4 层上面的
作者: ssffzz1    时间: 2007-03-30 14:08
哦,这肯定要出现大于MTU的情况,但在NETFILTER中是可以处理,进入到NETFILTER中的包是重足好了的.包修改后大于了MTU在离开NETFILTER后会被系统重新分片的,在NETFILTER中看到的是完整的包.
作者: platinum    时间: 2007-03-30 14:11
原帖由 ssffzz1 于 2007-3-30 14:08 发表于 10楼  
哦,这肯定要出现大于MTU的情况,但在NETFILTER中是可以处理,进入到NETFILTER中的包是重足好了的.包修改后大于了MTU在离开NETFILTER后会被系统重新分片的,在NETFILTER中看到的是完整的包.

我就是不清楚重组、分片在 netfilter 里的状况是怎样的,所以想请教一下大家,ssffzz 兄说的和我之前推测的是一样的
若真是这样的话,netfilter 处理起来就很简单了,难点主要就在 chksum 了而已 ^_^
作者: ssffzz1    时间: 2007-03-30 14:22
chksum 也有现成的函数.网上也有很多源代码,不过要改的东西还是很多的,IP头部,TCP都要改的.关键是这样改有什么意义.回流的数据怎么办,是不是应该做相反方向的改动,那么TCP头部的一些参数譬如"窗口"是关系到流控的又应该如何取舍.
作者: platinum    时间: 2007-03-30 14:25
ssffzz 兄对修改数据包很有经验,而我在 chksum 方面是个弱项
ssffzz 可否针对 IP、TCP、UDP、ICMP 的 chksum 单独写个精华讲解一下应如何计算这些 chksum,用到哪些函数啊?
作者: ssffzz1    时间: 2007-03-30 14:30
原帖由 platinum 于 2007-3-30 14:25 发表于 13楼  
ssffzz 兄对修改数据包很有经验,而我在 chksum 方面是个弱项
ssffzz 可否针对 IP、TCP、UDP、ICMP 的 chksum 单独写个精华讲解一下应如何计算这些 chksum,用到哪些函数啊?


对不起,我觉的自己功力不够.IP协议簇中大部分协议使用的都是一个chksum函数,所不同的只是传入的数据包内容及长度的不同而已.网上现有的算法就可以.内核中也有几个算法函数,那是针对不同体系的CPU,用汇编写的,效率很高.
作者: 独孤九贱    时间: 2007-03-30 14:47
原帖由 platinum 于 2007-3-30 14:11 发表于 11楼  

我就是不清楚重组、分片在 netfilter 里的状况是怎样的,所以想请教一下大家,ssffzz 兄说的和我之前推测的是一样的
若真是这样的话,netfilter 处理起来就很简单了,难点主要就在 chksum 了而已 ^_^


1、netfilter为了完成连接跟踪,NAT等功能,需要一个完整的数据包,也就是说它会在进入模块时进行重组,离开的时候,该分片还得分片……
你可以在netfilter中看到很多用于检查是否分片包,如果是分片包,就不处理之类的宏调用……

2、系统的分片,你可以参考ip_output.c中的ip_output函数:
  1. int ip_output(struct sk_buff *skb)
  2. {
  3.         IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);

  4.         if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size)
  5.                 return ip_fragment(skb, ip_finish_output);
  6.         else
  7.                 return ip_finish_output(skb);
  8. }
复制代码

也就是说如果数据包需要分片,就调用ip_fragment进行分片处理;

3、关于计算检验和,标准做法是做一个伪头,自己计算,不过内核有现成的API,你直接调用就是,它们根据硬件平台不同,由不同的汇编指令完成……比如以下调用:

  1.         /* Adjust TCP checksum */
  2.         tcph->check = 0;
  3.         tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
  4.                                    nskb->nh.iph->saddr,
  5.                                    nskb->nh.iph->daddr,
  6.                                    csum_partial((char *)tcph,
  7.                                                 sizeof(struct tcphdr), 0));
复制代码

  1.         /* Adjust IP checksum */
  2.         nskb->nh.iph->check = 0;
  3.         nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph,
  4.                                            nskb->nh.iph->ihl);
复制代码


4、就楼主的要求,其实就是自己写一个netfilter模块,然后重新增加skb容量,把传输层及以后再往后移8个字节,然后写入UDP首部,然后重新计算较验和……

[ 本帖最后由 独孤九贱 于 2007-3-30 14:48 编辑 ]
作者: platinum    时间: 2007-03-30 15:11
原帖由 独孤九贱 于 2007-3-30 14:47 发表于 15楼  


1、netfilter为了完成连接跟踪,NAT等功能,需要一个完整的数据包,也就是说它会在进入模块时进行重组,离开的时候,该分片还得分片……
你可以在netfilter中看到很多用于检查是否分片包,如果是分片包,就 ...

请问九贱兄,分片和重组是否都是 netfilter 之外的工作呢?
换句话说,是否和我与 ssffzz 说的一样,netfilter 只是处理单独数据包就可以了?还是 netfilter 抓到的是重组前的?送出去前还要自己重新分片?
ip_output 这个函数位于什么部分?
功底太差了,还请多指点……
作者: 独孤九贱    时间: 2007-03-30 15:19
原帖由 platinum 于 2007-3-30 15:11 发表于 16楼  

请问九贱兄,分片和重组是否都是 netfilter 之外的工作呢?
换句话说,是否和我与 ssffzz 说的一样,netfilter 只是处理单独数据包就可以了?还是 netfilter 抓到的是重组前的?送出去前还要自己重新分片?
...


1、网络栈本身有分片和重组的东东,分片在ip_output中,它是网络层一个重要的数据包发送函数……代码上面已经列出来了。发往本机的数据包,在交给传输层之前,会被重组:
  1. /*
  2. *         Deliver IP Packets to the higher protocol layers.
  3. */
  4. int ip_local_deliver(struct sk_buff *skb)
  5. {
  6.         /*
  7.          *        Reassemble IP fragments.
  8.          */

  9.         if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
  10.                 skb = ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER);
  11.                 if (!skb)
  12.                         return 0;
  13.         }

  14.         return NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL,
  15.                        ip_local_deliver_finish);
  16. }
复制代码


2、netfilter某些模块,需要一个完整的数据包,所以,它有也重组和分片的动作,两者互不干涉,最多是调用相同的函数……

[ 本帖最后由 独孤九贱 于 2007-3-30 15:27 编辑 ]
作者: funix_zjx    时间: 2007-03-30 16:27
标题: 回复 #1 leigaiting 的帖子
最好的办法是建立一个虚拟设备 类似 ipip,gre隧道。 具体可以看ipip的内核代码
作者: platinum    时间: 2007-03-30 16:36
原帖由 funix_zjx 于 2007-3-30 16:27 发表于 18楼  
最好的办法是建立一个虚拟设备 类似 ipip,gre隧道。 具体可以看ipip的内核代码

完全可以,但似乎这样做的难度远大于编写一个可以直接挂接在 netfilter 上的 module
作者: ssffzz1    时间: 2007-03-31 16:30
关键是我没搞明白LZ是要做什么用途,还是单纯的技术问题.不过感觉在IPTABLES下做一个这样的模块效率也许不会太高,需要加长原缓冲区,加UDP头部,计算校验和,建立状态链表,返回的数据还需要做相反的程序,同时对TCP头一些参数的处理也是大问题.

个人感觉应该是代理服务器类的软件.要做的事情.
作者: platinum    时间: 2007-04-01 13:28
原帖由 ssffzz1 于 2007-3-31 16:30 发表于 20楼  
关键是我没搞明白LZ是要做什么用途,还是单纯的技术问题.不过感觉在IPTABLES下做一个这样的模块效率也许不会太高,需要加长原缓冲区,加UDP头部,计算校验和,建立状态链表,返回的数据还需要做相 ...

从效率来讲,绝对要比 L7 的 proxy 代理软件快的多
具体实现可以参考 netfilter 的 XOR 这个 TARGET
作者: lanfn    时间: 2007-04-01 22:35
关注,TCP头转换成UDP头到底要注意些什么呢?
作者: playmud    时间: 2007-04-10 09:09
原帖由 platinum 于 2007-3-30 16:36 发表于 19楼  

完全可以,但似乎这样做的难度远大于编写一个可以直接挂接在 netfilter 上的 module

你觉得写一个这样的module容易?除了变换协议头以外还需要增加其他协议头,标识哪个数据包分片成了什么样子
还要计算tcp的序列,我觉得难度更大.类似于一个没有加密和hash计算的ipsec协议.
作者: platinum    时间: 2007-04-10 11:10
原帖由 playmud 于 2007-4-10 09:09 发表于 23楼  

你觉得写一个这样的module容易?除了变换协议头以外还需要增加其他协议头,标识哪个数据包分片成了什么样子
还要计算tcp的序列,我觉得难度更大.类似于一个没有加密和hash计算的ipsec协议.

我觉得和 XOR 那个 target 大同小异




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