skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:5428回复:28

关于TCPIP堆栈的问题

楼主#
更多 发布于:2003-01-15 18:40
我在开发的过程中遇到了一个非常棘手的问题,希望各位高手来看看。我在98下开发VPN客户端,现在,一般的情况下都可以成功了,但是,在进行一些特殊的通讯模式的时候会出现问题,比如,我在FTP的前几个协商包里面需要改掉其协商地址,在驱动里面对包进行过滤并重新填入新的地址,但是,我发现虽然FTP的协商是成功的,但是,TCP的序列号却发生了改变,导致TCP栈不停的重发包,通信也没有办法进行,想了想问题,应该是这样的,因为长度发生了变化,序列号的确是应该改变的,而其差值正好是我改包导致的差值,这个序列号是来自TCPIP协议栈,我们改不了的,我想请教大家,该怎么办?

最新喜欢:

WY.lslrtWY.lsl... ljmmaryljmmar...
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-01-15 18:50
很好办啊,在内部为你改过的这个 TCP 连接建一个表项,里面记录改后的差值,以后收到属于这个连接的数据包的时候进行 TCP 序号修正就可以了。

这也是 RFC1631 和 RFC3022 里推荐的标准方法!
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-15 18:51
edust对这个应该熟悉,你要修改序列号的。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-15 19:15
你的这个方法是想在驱动里面为每个包都改序列号吗?这个,TCP上层似乎不会忍这种改变,你试过没?你想,比如,我发个A,想得到的是B,而你传回来的是C,你想我能认识吗?
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-01-15 20:08
你的这个方法是想在驱动里面为每个包都改序列号吗?这个,TCP上层似乎不会忍这种改变,你试过没?


当然试过了,没试过的话我只会说“关注”,就不会参与讨论了!
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-01-15 20:23
 
你想,比如,我发个A,想得到的是B,而你传回来的是C,你想我能认识吗?


主机 A 要发给 B 之前,你截到了包,改完之后假设差值为 2,把这个 2 记下来,把改过的包发给 B,B 收到这个包之后回送给你一个包,这时就要进行序号修正了,把这个包的 ACK 序号跟差值运算,当然还要重新计算校验和,然后传给 A。这样怎么能不认识?兄弟,质疑精神是必须要有的,可也得先好好想想吧?!
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-01-16 10:01
首先感谢edust的回答,也谢谢你的提醒,可能是因为最近过与烦乱的缘故,不过,你的回答我的确是考虑过的,其实,说明白一点,你就是自己实现IP协议栈对这个功能的支持,而在其他操作系统中,IP堆栈总是为每个连接保存这几个序列号的值,显然,针对一个连接而言,如果你在其中的一个包该了这个值,那么,你就意味着你必须改掉整个连接的所有报文,这正是edust你的想法吧?但是,在看了Linux的协议堆栈实现后,我发现,如果,我们在windows中同样能够改掉协议堆栈当中的那几个保留值,则对以后的报文就可以不用管了,这也是在Linux实现的标准方式,希望edust能够指点,还有,你能告诉我你的QQ吗?我这边上网不是很方便,只能在这里跟你说一下,再次谢谢你的关注
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-01-16 10:30
linux下面代码都是公开的,你可以修改,windows下面你有不知道TCPIP是在哪里处理的你去哪里修改?只能你自己来处理这个问题。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
fracker
驱动太牛
驱动太牛
  • 注册日期2001-06-28
  • 最后登录2021-03-30
  • 粉丝0
  • 关注0
  • 积分219分
  • 威望81点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分1分
  • 社区居民
8楼#
发布于:2003-01-16 11:05
不明白,改地址,跟序号什么关系?
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-01-16 12:30
 
linux下面代码都是公开的,你可以修改,windows下面你有不知道TCPIP是在哪里处理的你去哪里修改?只能你自己来处理这个问题。


对啊,在 Windows 平台下改什么、改哪里怎么知道呢?只能自己实现一套机制了:(
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-01-16 13:54
再次感谢edust和各位高手的指教,也许正如你们所说的,办法可能只有这样子,我只是想通过其它的方法考虑一下这个问题,是啊,我们没有办法看到TCPIP的实现,这也许就是只能那样做了,好吧,如果我能解决这个问题,我会回来再聊些话题的,怎么感觉上刑场,呵呵,先谢了,大家
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-01-16 13:59
哎呀,不知道怎么放分了,怎么办呢?告诉我一下,我上网不是很方便,希望大家谅解,还有,只有下次给你们分了
mikeluo
驱动老牛
驱动老牛
  • 注册日期2001-09-04
  • 最后登录2007-05-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-01-16 14:19
第一个留言的下面,点给分即可:)

有什么心得来汇报一下。
学而不思则罔,思而不学则殆 学而思之,思而学之,岂非圣人乎?
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-01-16 17:22
哈哈,我发现很多人第一次都找不到“给分”在哪里,我就是:)
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-01-16 19:48
我也是首次给分给你们哦,其实,说实话,我看见很多的实现都是被封装在TCPIP。SYS中了,我其实很想仔细的分析一下这个驱动,可是我将它反汇编出来以后,不太懂,我用的是IDRA,不知道哪里有资料介绍它的使用,反正想要看的东西很多了,你们知道有什么好的静态反汇编的软件吗?
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-01-17 08:59
当然是 WDASM 了
skylgl
驱动小牛
驱动小牛
  • 注册日期2002-05-13
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分71分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-01-17 09:16
是吗?我也去下一个来看一下。edust,虽然你说的有道理,但我还是在想其它的解决办法,显然,将大的内容的报文改成小的时候,是不用那么麻烦的,只要在适当的地方填入一些空的字符就可以搞定,那么将短的改长呢?如果,我们的方法能够影响IP堆栈的序列号参数,也可以达到目的,但是,我们似乎没有办法去改动这些参数,那么我们可以想点其它办法呢?比如,再通过和应用的通信将差的数据传出去,希望前面那个发送的应用程序再发一个比刚才那个大那个差值包(在内容上),这样就可以使IP堆栈改变它的设置,但是又有这样一个问题,如何才能使我们能够在应用层再次使用那个进程去发包呢?比如,开始我用一个FTP,后面又需要在我自己的应用程序里控制让这个FTP进程使用的SOCKET来发个大点的包,这好象不能实现,我只是想使用一个新的想法,见谅了
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-01-17 10:43
以下内容来自 RFC1631:

The arguments to the File Transfer Protocol (FTP) PORT command include an IP address (in ASCII!). If the IP address in the PORT command is local to the stub domain, then NAT must substitute this. Because the address is encoded in ASCII, this may result in a change in the size of the packet (for instance 10.18.177.42 is 12 ASCII characters, while 193.45.228.137 is 14 ASCII characters). If the new size is the same as the previous, only the TCP checksum needs adjustment (again). If the new size is less than the previous, ASCII zeroes may be inserted, but this is not guaranteed to work. If the new size is larger than the previous, TCP sequence numbers must be changed too.
edust
驱动中牛
驱动中牛
  • 注册日期2002-04-02
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-01-17 10:47
你那样做又何必呢?!每个 Application 你都能顾及得过来吗?
看看 RFC1631 推荐的方法:

A special table is used to correct the TCP sequence and acknowledge numbers with source port FTP or destination port FTP. The table entries should have source, destination, source port, destination port, initial sequence number, delta for sequence numbers and a timestamp. New entries are created only when FTP PORT commands are seen. The initial sequence numbers are used to find out if the sequence number of a packet is before or after the last FTP PORT command (delta may be increased for every FTP PORT command). Sequence numbers are incremented and acknowledge numbers are decremented.
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
19楼#
发布于:2003-01-17 11:19
我在开发的过程中遇到了一个非常棘手的问题,希望各位高手来看看。我在98下开发VPN客户端,现在,一般的情况下都可以成功了,但是,在进行一些特殊的通讯模式的时候会出现问题,比如,我在FTP的前几个协商包里面需要改掉其协商地址,在驱动里面对包进行过滤并重新填入新的地址,但是,我发现虽然FTP的协商是成功的,但是,TCP的序列号却发生了改变,导致TCP栈不停的重发包,通信也没有办法进行,想了想问题,应该是这样的,因为长度发生了变化,序列号的确是应该改变的,而其差值正好是我改包导致的差值,这个序列号是来自TCPIP协议栈,我们改不了的,我想请教大家,该怎么办?



修改原ip包的地址不是一个好方法,ftp会出问题,所有nat
实现必须特殊处理的协议都会出问题,看看linux nat实现的
那些用于特殊处理的模块就知道,这不是一个小数目,还有
ldap,voiceip等等。

所以通常你可以封装,如果要remote access,为了穿透firewall,
用虚拟网卡dhcp从对方的dhcp server中得到地址。然后用eth0
或者ppp0封装。你的vpn gateway必须支持dhcp转发。



不再回忆从前,我已经生活在幸福当中。
上一页
游客

返回顶部