阅读:5565回复:21
请教胡版主:关于NdisIMCopySendCompletePerPacketInfo与分段的问题
请教胡版主:
在passthru中,偶对一个原始的IP包进行处理后,包变大了,现在一个包要变成两个才能发出去。用MPSend来说吧。 (当然,这个IP包是指一个完整的IP包,如果上面给的包就是分段的,得先重组) upper layer给的包是Packet,偶再分配一个MyPacket,对这个MyPacket偶进行处理后,这个包长度增加,要将其分为MyPacket1与MyPacket2才能发送。 代码这里偶应该如何处理 NdisSend(&Status, pAdapt->BindingHandle, MyPacket1); if (Status != NDIS_STATUS_PENDING) { //这个函数现在偶该怎么办??? NdisIMCopySendCompletePerPacketInfo ( Packet, MyPacket); NdisFreePacket(MyPacket); } 是不是象这样就没办法用这个函数处理,如果不用,程序其它地方要注意什么问题。 当然类似的在ptreceivepacket中,偶收到两个包,还原处理完了就只有一个包,也就是说MyPacket1与MyPacket2(收到的包)在处理过后就只有MyPacket了,MiniportReserved中保留的东东怎么办。 只是分段好办,象上述如信息如何处理,还请版主多多指教 |
|
|
沙发#
发布于:2008-04-22 20:56
对于将packet分为packet1和packet2的过程,有没有可参考的代码?有高人可以提供吗?
|
|
|
板凳#
发布于:2002-05-20 16:40
偶以为,当1分2段后,偶最多只能通知上面一次sendcomplete,少通知大不了没释放掉,多说了会不会上面打算释放不存在的资源? 给你一个实用的办法: 当你分片后,将第一个包的OriginalPkt设为NULL,然后在发送完成的例程中判断,若某包的OriginalPkt!=NULL,才NdisIMCopySendCompletePerPacketInfo及NdisMSendComplete,但这样作可能会有这样的问题:当第一个包发送不成功时,由于它的OriginalPkt=NULL,所以可能造成系统不能重发原包; 在接收时更简单,你只需将Packet传上去即可,不要管它是不是分片的,上层的协议会组合的。 但劝你,还是改MTU吧,作分片,会出许许多多莫名其妙的问题。 |
|
地板#
发布于:2002-05-09 22:49
偶以为,当1分2段后,偶最多只能通知上面一次sendcomplete,少通知大不了没释放掉,多说了会不会上面打算释放不存在的资源?
|
|
|
地下室#
发布于:2002-05-09 22:43
偶的关于分段的问题的最新处理修订版:
当上层发包给中间层,中间层copy上层包的数据,并将Packet句柄保留,如果本次(上层分段)不能发送,返回成功; 又收到一个包,这个包的句柄也保留起来,并与上次要发的包重组,得到完整的包,发送处理后的包,如果有必要,再通过保留的句柄通知上层说发送完成。 |
|
|
5楼#
发布于:2002-05-09 18:05
to hu
因此,最好的方法是能够避免分片。避免分片的方法最 直接的方法当然是pmtu,这里我同样不具体描述pmtu的工作 过程和原理。我只是简单的描述一下应用方法。伪造一个 pmtu的数据包传递给ip协议层,告诉它对方发来一个pmtu 数据包,ip层自己会避免分片。同时会传递一个较小的 数据包给imd。例外情况是发送ping的时候,如果指定 -s 2000,那么ip协议会发送一个分片的icmp。(linux下 一定是这样的,win下是不是这样我忘了,你可以做一个 试验)这里面的实施,我的经验是,linux下的实施要 比win下的实施简单得多,linux内核就有一个函数叫做 icmp_send(具体我也忘了),win下还必须做一些工作, 你得对icmp和ndis的工作流程非常清楚才行。 这一段从描述来看应该是最好的解决办法了吧?还请版主给一些具体详细一点的指导,咱们可以少走一些弯路嘛。(程序中偶已经决定还是进行分段处理了,不过有了这个就算偶的分段处理工作不正常也没关系,这就叫双保险。hehe)。 |
|
|
6楼#
发布于:2002-05-09 17:38
解决任何问题不能“等,靠,要”
先说说偶自已的思路,大家来参考一下。 1.关于发送时分段的问题: 当上层来的包要处理后要分段发送时,偶把上层的包保留到MyPacket链表中,这个包分成两段,偶也不管那么多了,第一个包发送成功,偶就copy sendpacket info到MyPacket链中对应包保留位存贮的上层的包,然后调用NdisMSendComplete把通知上层:“老兄,你给我的那个包我已经搞定了,你要怎么的就怎么的了。” 如果上层的包也分段,偶就看MyPacket链中谁是最后一个包,然后把下层返回包的信息copy到MyPacket链中取出的包保留的打算返回给上层的包中,再对上层说:\"Send Complete\" 偶们这里对上层说send complete,他们就会忙碌地开始ptReceiveComplete,做他们发包的后处理工作,该怎么,就怎么。 偶决定就这样先对付着。 2. ptunload: to be continued(这个问题很可恶) 3. PtRegisterDevice to be continued to top 对了,你安装imd时怎么用程序搞定的数字签名。我用注册表工具追查了某些屏弊数据签名的程序,发现好象应该对付两个注册表键值 (1)HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Driver Signing\\Policy(这个应该是固定的,不过好象不怎么起作用:( (2) HKEY_USERS\\S-1-5-21-839522115-920026266-842925246-1000\\Software\\Microsoft\\Driver Signing\\Policy(这个类似的东东每人的机器都会不一样,这个好象起作用,但:(这个可变的东东偶怎么操作? 谁搞定了说一下哈。这个也很讨厌 |
|
|
7楼#
发布于:2002-05-08 23:47
胖胖的问题好长啊~~看的眼睛都花了!我有个想法正好说出来如果不对也有人纠正:是不是把存放分片包的内存在BIND的时候多分配一个PACKETPOOL叫SegPacketPool的来专们放PACKET,一个网卡一个,在UNBIND的时候释放,这样就不会频繁的分配释放,效率应该是会高点,就是占了点内存,但是我觉得多分配几个PACKETPOOL也占不了多少内存吧?
MyPacket1->Private.Flags=Mypacket->Private.Flags; MyPacket2->Private.Flags=Mypacket->Private.Flags; 其它的信息如OOB_DATA,NdisIMCopySendPerPacketInfo打算copy的信息, DDL里面对PRIVATE是这样定义的! Private This is reserved for use exclusively by NDIS. Drivers must call the appropriate NdisXxx functions or NDIS-supplied macros to affect the contents of this area. 看到最后这句说的特定宏没有?NDIS_OOB_DATA_FROM_PACKET这个宏就是获得OOB的啊!我想应该是NDIS_OOB_DATA_FROM_PACKET(MYPACKET2)=NDIS_OOB_DATA_FROM_PACKET(MYPACKET1);//这样就解决了! 下面的问题还是等咱们的灵魂人物回答~~呵呵~~好经典的问题,等这个讨论完了我要保存这个帖子做参考了! |
|
|
8楼#
发布于:2002-05-08 23:12
[quote]哈哈~~~师父您老人家好久没出山了!!!我还是有一点不明白,您说把MTU改成1300,网卡的MTU好象缺省的是1500,这样的话,就会导致更多的分片啊~~我在这里想不通了!还有就是整天听人说改MTU,是不是只要改注册表里面的键值就真的可以实现修改MTU?另外我想问SIRROOM一个问题,如果可以的话,为什么不用点压缩算法??只是个建议,我也不知道你的环境是怎么样的,可能是废话~~对了老大说的TCP/IP详解的卷2好象有IP分片的实现代码~~第10章~~我觉得写的还可以吧~~不知道胡老师这么看~~~总之我觉得如果真的是老师说的那样[CLIENT--》NAT--》SERVER]这样的环境的话,如果SERVER端CLIENT端的代码都可以改还好说,如果只能改一边真的好牵强啊~~我也挺关注这个问题,我想过不了两个星期我的爆头问题就是这个了~~不过现在我还得考虑我的模式匹配的问题,真的很伤脑筋,想可以无限的添加模式规则[假想实现功能!],又不能保证算法的效率,只能用个递归或循环来实现字段匹配,想效率高呢,简单的办法只有实现有限的模式添加数量[但是多少才够用?不够了怎么办?客户可是很挑剔的!]烦恼烦恼啊~~~有谁有什么好的意见也教教小弟啊~~ 如何分片只要找一本详细描述ip数据包头的书就可以开始写, 这个比较简单,并不一定非得参考什么书。我也没有仔细看过 第2卷,我只是简单翻了一遍第一卷(我学习tcp/ip的时候这本 书还没有,我只是拿了一本清华出的小薄书入了一下们而已, 结果基础薄弱:-()。 修改mtu之后tcp/ip协议栈就会避免分片。 你要得模式匹配很简单,你可以去找一本编译原理的书,任何 一本编译原理的书里面都会提到正则表达式,也会提到一些 下载地址,找到source之后就可以开始学习。如果你有unix 得工作经验,那么更不需要我多说废话。 你没有真正想清楚nat环境中的数据包流程。 [/quote] 师父的回答真是高效,竟然猜出了我的所想,我也想到了从其他也用到模式匹配的地方取经,可就是忘记了编译原理,听人家说最近你对这个特别感兴趣??在研究LCC的那个C的编译器吧?我看来我也要在这里面取点经了!!说真的改天您来海南我一定要大请特请才过意的去了!! |
|
|
9楼#
发布于:2002-05-08 22:31
ft,附件怎么总弄不上去:(
白云也有个相关的讨论,不过没说到那个具体的处理 发信人: huyuguang (还是谈谈技术吧), 信区: SysInternals WWW-POST 标 题: Re: hu大侠请看 发信站: 武汉白云黄鹤站 (Thu Feb 15 18:10:49 2001) , 站内信件 【 在 fist (星仔迷) 的大作中提到: 】 : 【 在 huyuguang (还是谈谈技术吧) 的大作中提到: 】 : : 【 在 boring (你快回来) 的大作中提到: 】 : : 你的上一篇文章我早就看到了,一直没有回是因为一方面 : : 这段时间我没有干nt driver了,另一方面要回答很不容易。 : : ------能不能介绍一下大致的方向呢? : : 我门是用分片解决的,不过肯定有修改mtu的方法,不过 : : 我们一直没有找到而已。 : : -----有一个问题想请教的是怎样处理:如果上层(比如ipfilter) : 也发出AH,ESP加密包,怎样区分它呢?当然如果不考虑上层的 : 这些包,Win2k的VPN就不能使用了。如果处理呢,怎样区分 : 是上层的包和收到伪造加密包呢?好像不能自己正确处理的 : 加密包交给上层自己处理也是可行的。 : 还向请教的一个问题是上层(在上层没有其它中间驱动程序的 : 情况下)会发送分片包吗? 一般是不会,nt我没有发现这种情况,不过linux倒是有这种情况。 不过这个问题要考虑,就是2次分片。 : : : ndiswan未必是用irp的方法得到mtu的,但是肯定有方法 : : 得到,如果是irp,ioattachdevice当然可以解决,如果 : : 不是,也同样可以是用别的什么方法,例如读register什么 : : 的,总之我想是可以解决的。 : : 你要是找到了,请告诉我,如果你找不到,建议你就用分片 : : 的方法算了。 : : -----boring说向上层发送ICMP包,告诉上层数据包被分片了, : 上层协议就会调整mtu,正在测试。如果有什么好办法,他一定会 : 通知各位的,I am sure !:-). 这个方法是可以,实际上就是模拟协商pmtu的过程,所以 icmp是不能加密的。 : : : : -- ※ 来源: 武汉白云黄鹤站 bbs.whnet.edu.cn. [FROM: 202.106.97.19] |
|
|
10楼#
发布于:2002-05-08 22:27
to top:压缩当然要做,但做了压缩数据并不是一定就会变小啊,分段的情况还是可能出现哦
to huyg:分片的怎么分,这个到处都有,偶关心的真正问题应该是如monkeyy所言是关于资源的释放 吧。 上层发包时,如果偶的imd发现包是分段的,偶就将其加入队列中,下次等这个包的其它兄弟们来 了一起,先做处理,再发送。假如本来有一个包,处理后偶发现是两个,这两个包 (MyPacket1,MyPacket2)中的某些包的相关信息是不是可以直接将原来的包(未做处理的从上层来的 包,或是自己分配的包,该包已将上层包所有信息copy)的相关信息直接copy过来。 (偶对NDIS_PACKET的理解不是太深刻,不过偶认为以下一些field应该是与Packet中的数据无关的, 而是一些包的特定的信息,这些信息如何处理,还请版主指教) MyPacket1->Private.Flags=Mypacket->Private.Flags; MyPacket2->Private.Flags=Mypacket->Private.Flags; 其它的信息如OOB_DATA,NdisIMCopySendPerPacketInfo打算copy的信息, ,NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO,这些信息可以直接从Mypacket copy到 MyPacket1,MyPacket2吗。 偶不知道可不可以,好,接下来发包 NdisSend(&Status, pAdapt->BindingHandle, MyPacket1); if (Status != NDIS_STATUS_PENDING) { //偶下面不知道该怎么用了:( NdisIMCopySendCompletePerPacketInfo ( Packet,//这个应该是上层发来的包 MyPacket1);//???? NdisFreePacket(MyPacket1); } 问题1:那么,当发MyPacket2的时候,当没有PENDING时,也来调用一次 NdisIMCopySendCompletePerPacketInfo,把MyPacket2的东东告诉Packet吗?偶觉得当然不对,但这 里怎么处理呢? 问题2:如果本次调用MPSend时,我有一个新分配的包,这个包copy了原始包的相关信息,偶现在 的处理只是将其入队了(原因比如说上层给偶的包是分了段的包,要和下次上层来的某个包一起组成 一个完整的IP包后偶处理后再发),这种情况下,我怎么处理这次打算发而又没有真正发出的包?当 偶在MPSend中处理重组后的两个包,发现要分成三个包才能发出去时又怎么办?(感觉好象有点在钻 牛角尖,不过有了问题总应该想清楚吧:))。在下次处理时,本次MPSend中传进来的参数Packet在 下次发送时偶怎么处理?? 这样的情况下调用 NdisIMCopySendCompletePerPacketInfo( 第一个参数是什么? 第二个是本次调用NdisSend发送的包); 说了这么大一堆,不知道把问题描述清楚没有。 下面偶再来一个简单一点的描述吧: 在我的理解中,passthru调用NdisIMCopySendCompletePerPacketInfo是将下层返回的原中间层新 分配的发给下层的包的相关信息copy给一个打算要返回给上层的包;而这个要返回给上层的包就是我 们在本次MPSend中打算发的包。本次如果发送挂起了,那么,因为本次发给下层的包中有保留位用以 保存上层包的句柄,所以我们可以在PtSendComplete时下层返回给中间层的Packet中的保留位中得到 本次要发的上层包的handle,并把下层返回的包的信息copy给中间层打算返回给上层的包中,当包的 处理是一对一,对这样的处理偶没有什么疑问。 然而: 1.当一个完整的IP包要分成两个发出,偶是不是就这样做简单的处理:在这两个包中的保留位中存放 上层要发送的包的相关信息,这两个包发完后,调NdisIMCopySendCompletePerPacketInfo把自身的 发送信息copy给打算返回给上层的那个包(打算用NdisMSendComplete通知上层的)。如果是这样当 发送MyPacket1时pending,发MyPacket2时success,我们应该把谁的SendInfo告诉打算返回给上层的包 ? 2. 当一个完整的IP包分成两个给个中间层,而中间层要把它变成三个发出去(偶不知道实际上会不 会有这样的情况,但从理论上应该存在这样的情况吧)InPacket1中的东东分到了Outpacket1与 OutPacket2中,InPacket2中的东东分到了OutPacket2与OutPacket3中。这时,我们会在下次重组完 的时候发,那么,我们的OutPacket2中包含有InPacket1,InPacket2的处理后的数据,是否我们该在 这个包中同时保留InPacket1与InPacket2的handle,发送完时再分别调 NdisIMCopySendCompletePerPacketInfo把自已的发送信息拷到InPacket1与InPacket2中? (偶真的觉得自已好象在钻牛角,不过代码写到这里,这部分怎么处理真的很迷惑) 再来一点题外的东东,反正也是Passthru的相关话题 1.关于PtUnload的问题 版主多次说过是MS的bug,也说过Ms的xp passthru中已经把这个bug给修正了(可偶就是用的 Xp_passthru啊,ptunload没有被正确调用啊?,这个修正是指的什么?偶当时有很长的一段时间没 注意到这个问题,被害惨了,偶总是想当然的以为偶的ptunload被调用了(偶用的就是xp passthru),所以偶以为偶卸载了原来的再安装新的东东就应该是新的驱动,结果:(,代码都面目全 非了,你看到的source也是新source,连你用softice追的时候也看到新source,但事实上跑的是老驱 动,我常常奇怪我新加的DbgPrint为什么就是没反应,而且在softice中你可以看到这句,但似乎没 有被执行 版主能不能找一个现成的,ptunload被调用的例子(偶用的xp passthru,在2k下build的,发现过 Ptunload被调用的时候,但在更多的时候没有发现被调用,就这个问题我问过lam,他说他用的2k passthru,但ptunload一直都会被正常调用,偶真是ft,偶就没发现过几次ptunload被调用,偶真的 怀疑手上的2k是不是有问题,不过偶的2K来源多半和大家是一样是D版的的,keke,(。 2.关于PtRegisterDevice的问题 我们可以在应用层中 用这样的方式打开 HANDLE m_hPassthru = CreateFile(\"\\\\\\\\.\\\\Passthru\", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 应用层可以利用这个handle通过deviceIoctl来与下层通信(这堆都是肥话),上层deviceIoctl 最后到了驱动的ptdispatch中的 case IRP_MJ_DEVICE_CONTROL: // // Add code here to handle ioctl commands sent to passthru. // //这里偶想加一个类似这样的处理代码 deviceIoctl_test( adapter,//偶有疑问的地方 InBuffer, OutBuffer, OutBufferLength, &ByteReturned); DbgPrint(\"xp_passthru::IRP_MJ_DEVICE_CONTROL\\n\"); break; 这里的这个adapter偶怎么传进来? 通常情况ptbindadapter会被调用两次,一次binding到网卡上,另一次与中间层驱动 ndisWan bind。这样就会有两个adapter,通过lan连出去时,用的adapter应该是与网卡相关的那个 bind关系,比如发包用的pAdapt(假网卡)->BindingHandle,如果拨号,走的是pAdapt(假 NdisWan)->BindingHandle这条线,那么,pAdaptList中有这两个adadpter,偶怎么保证偶用到了现在 要用的adapter。 附件中是偶的xp passthru,但ptunload总不对,版主看看是怎么回事 chat* bow |
|
|
11楼#
发布于:2002-05-08 19:19
哈哈~~~师父您老人家好久没出山了!!!我还是有一点不明白,您说把MTU改成1300,网卡的MTU好象缺省的是1500,这样的话,就会导致更多的分片啊~~我在这里想不通了!还有就是整天听人说改MTU,是不是只要改注册表里面的键值就真的可以实现修改MTU?另外我想问SIRROOM一个问题,如果可以的话,为什么不用点压缩算法??只是个建议,我也不知道你的环境是怎么样的,可能是废话~~对了老大说的TCP/IP详解的卷2好象有IP分片的实现代码~~第10章~~我觉得写的还可以吧~~不知道胡老师这么看~~~总之我觉得如果真的是老师说的那样[CLIENT--》NAT--》SERVER]这样的环境的话,如果SERVER端CLIENT端的代码都可以改还好说,如果只能改一边真的好牵强啊~~我也挺关注这个问题,我想过不了两个星期我的爆头问题就是这个了~~不过现在我还得考虑我的模式匹配的问题,真的很伤脑筋,想可以无限的添加模式规则[假想实现功能!],又不能保证算法的效率,只能用个递归或循环来实现字段匹配,想效率高呢,简单的办法只有实现有限的模式添加数量[但是多少才够用?不够了怎么办?客户可是很挑剔的!]烦恼烦恼啊~~~有谁有什么好的意见也教教小弟啊~~ 如何分片只要找一本详细描述ip数据包头的书就可以开始写, 这个比较简单,并不一定非得参考什么书。我也没有仔细看过 第2卷,我只是简单翻了一遍第一卷(我学习tcp/ip的时候这本 书还没有,我只是拿了一本清华出的小薄书入了一下们而已, 结果基础薄弱:-()。 修改mtu之后tcp/ip协议栈就会避免分片。 你要得模式匹配很简单,你可以去找一本编译原理的书,任何 一本编译原理的书里面都会提到正则表达式,也会提到一些 下载地址,找到source之后就可以开始学习。如果你有unix 得工作经验,那么更不需要我多说废话。 你没有真正想清楚nat环境中的数据包流程。 |
|
|
12楼#
发布于:2002-05-08 13:19
对了,你是先得到数据在分片!
|
|
|
13楼#
发布于:2002-05-08 13:18
我觉得你好说的是,怎么取包的问题和如何将分配的内存释放的问题
斑竹他说的是如何解决分片问题,top说的是怎么分片。而我觉得你问的是怎么得包和分片然后释放内存的问题。不知道我的理解对不对? 你使用NdisIMCopySendCompletePerPacketInfo()时就已经将数据包的数据全部传入你自己分配的内存中了,那么怎么处理应该知道吧! 至于内存释放问题,你自己在SendComplete()中处理就行了!! 祝你好运!! |
|
|
14楼#
发布于:2002-05-07 23:41
哈哈~~~师父您老人家好久没出山了!!!我还是有一点不明白,您说把MTU改成1300,网卡的MTU好象缺省的是1500,这样的话,就会导致更多的分片啊~~我在这里想不通了!还有就是整天听人说改MTU,是不是只要改注册表里面的键值就真的可以实现修改MTU?另外我想问SIRROOM一个问题,如果可以的话,为什么不用点压缩算法??只是个建议,我也不知道你的环境是怎么样的,可能是废话~~对了老大说的TCP/IP详解的卷2好象有IP分片的实现代码~~第10章~~我觉得写的还可以吧~~不知道胡老师这么看~~~总之我觉得如果真的是老师说的那样[CLIENT--》NAT--》SERVER]这样的环境的话,如果SERVER端CLIENT端的代码都可以改还好说,如果只能改一边真的好牵强啊~~我也挺关注这个问题,我想过不了两个星期我的爆头问题就是这个了~~不过现在我还得考虑我的模式匹配的问题,真的很伤脑筋,想可以无限的添加模式规则[假想实现功能!],又不能保证算法的效率,只能用个递归或循环来实现字段匹配,想效率高呢,简单的办法只有实现有限的模式添加数量[但是多少才够用?不够了怎么办?客户可是很挑剔的!]烦恼烦恼啊~~~有谁有什么好的意见也教教小弟啊~~
|
|
|
15楼#
发布于:2002-05-07 13:13
请教胡版主: 这种情况需要从实际情况出发,我很难给出一个超爽的通用 方法。我把我这些年来遇到的问题简单的做一个归纳,更 详细的总结也许需要花一个晚上的时间。在这里,我只能 给你一点线索和思路, 你可以根据你自己的具体情况做出 自己的判断,具体的处理和代码还需要你自己去完成。 另外还有一点要说明的是,这里讨论的只限于ip协议,对于 ipx这种不分片的协议,需要使用另外的方法解决,这涉及 到ipx的工作原理,超出了本文的讨论范围。 ===================================================== 最早的时候,我只需要处理802.3,因此,我做了最简单的 处理,修改了eth interface的mtu。这样从本机发出的数据 包不会超过1300(当我把mtu修改成1300)。 很快我就遇到了新问题,这个方法对于拨号设备不起作用, 为什么不起作用,我这里不打算详细说明,大体原因是无法 截获ndiswan到wan miniport的ndisrequest。nt resource kit 中描述了几个注册表健值,似乎可以修改wan 的mtu,但是 在9x下不能工作,因此也不是好的通用方法。 然后处于各个方面兼容性的考虑,我最终是分片了,把一个数据 包分成两个数据包,在mpsend里面调用两次ndissend,在 reserveprotocol里面保留内存分配的信息。在sendcomplete里面判 断,然后正确的释放内存。 该方法在9x和nt,以及linux环境中工作的都不错,但是接着我 又发现了新问题。分片的结果是,如果路由的过程中有一个nat 网关,那么一切都发生了变化,nat的工作原理是需要用端口 来做映射,而分片的第2个数据包是没有tcp header的,这种 情况下,nat就必须组包,而nat组的是经过加密的数据包, 一般情况下,nat只好无奈的丢弃这个数据包,就算nat组包 成功,nat再次分片发出的时候,也未必能够让接收端正确 解密,这个过程极大的取决于nat的实施,一般情况下,这是 不能正确通讯的。而你又绝对不可能修改nat的实施,因为 那多半是第3方的代码,或者设备。 当然你可以说,nat在处理ftp这种数据包内容里面包含 端口信息的协议的时候,几乎任何vpn实施都不可能正确 工作,除非是对ftp做特别处理,的确如此,这种情况 让人非常困惑,唯一的可能似乎是用隧道封装,目前为止, 我还没有看到ipsec协议组的人能够解决这个nat兼容的问题, (我大约有半年没有去看新的RFC Draft了,GOOGLE上能够 找到几篇cisco和ms以及其他的一些变通解决方案,但是非常 不完美。) 看起来只有修改ipsec协议或者是nat协议规范,但是ipsec 协议的修改会降低安全性,因此ipsec不愿意修改,nat 有很多其它的算法可以实现,可是目前已经有了无数的 实现和设备,这是不太可能立即消失的。现在看起来ftp这种协议 制定的非常dirty,为什么非要用两个端口?但是ftp太广泛了, 根本不可能做任何修改。 因此,最好的方法是能够避免分片。避免分片的方法最 直接的方法当然是pmtu,这里我同样不具体描述pmtu的工作 过程和原理。我只是简单的描述一下应用方法。伪造一个 pmtu的数据包传递给ip协议层,告诉它对方发来一个pmtu 数据包,ip层自己会避免分片。同时会传递一个较小的 数据包给imd。例外情况是发送ping的时候,如果指定 -s 2000,那么ip协议会发送一个分片的icmp。(linux下 一定是这样的,win下是不是这样我忘了,你可以做一个 试验)这里面的实施,我的经验是,linux下的实施要 比win下的实施简单得多,linux内核就有一个函数叫做 icmp_send(具体我也忘了),win下还必须做一些工作, 你得对icmp和ndis的工作流程非常清楚才行。 如果只是想处理tcp数据包,那么有一个更为简单的方法 可以选择,tcp连接需要建链,3个消息。在第2个消息 中tcp header中包含一个option,MSS,就是MAX segment size, 你可以修改这个值,这样tcp自己就会自觉的发送小于mss 的数据包给ip层,因为分片是低效率的,因此tcp会尽量 避免分片。MSS是标准,但是不是tcp header里面的常用 段,协议可以不支持,但是目前我所用到的所有操作系统 的协议栈都支持这个选项。 以上就是我对这个问题的回答,里面并不包含具体的解决 方案,我说过,这需要一整个晚上时间,我必须去我的硬盘 中搜寻那些过时的老代码,这很乏味。我只是就我的一些 个人经验提供一些思路。 关于MSS的方法,我也是去年在看pppoe的实现的时候才知道的, (这说明我看steven的tcp/ip 3卷本的时候还是不细) 如果哪位朋友有更好的解决方案能够加以补充,我不胜感激。 如有错误,也请指正。 |
|
|
16楼#
发布于:2002-05-07 10:45
纠正一下Identification是发送端发送的IP数据包标识字段都是一个唯一值,该值在分片时被复制到每个片中。
分片的标志在flag summary里面,高位为1表示前面有分片包,为0表示前面没分片了,低位为1表示后面还有分片,0表示没有! 刚刚的边QQ边回,结果写错了~~见笑!! |
|
|
17楼#
发布于:2002-05-07 10:13
漏了说了!就算对方的代码你改不了,那对方的TCPIP。SYS也会自动帮你组包的!还有别用IP分片攻击别人哦~~好可怕啊~~~
|
|
|
18楼#
发布于:2002-05-07 10:10
这家伙~~我认为你在专牛角尖了,这么想吧~~要么做两个包处理,要么当一个包处理,就看你的意思咯!我想这个问题一定是你的VPN和GATEWAY之间的包的问题吧?其实就是当IP分片处理,或你自己处理而已!
1、如果你两端的代码都是你维护的[C/S],那么你可以自己维护包的重组和分片,怎么做?当两个包咯~~不过也太不专业了! 2、重要的来了!当IP分片处理,网卡的MTU是1500,也就是说当IP包的大小超过1480[因为IP头固定为20个byte,1480是TCP。UDP头加上DATA后的MAX!!明白了?]就得分片,这个时候一个IP包变成了两个,当然有两个脑袋咯!要不怎么路由??重要的是[马上去截获一个IP包来看看!!]IP包的头部记载了这个包是不是分片包,还有这个包在原IP包的OFFSET[偏移量,或说位置!]的值,这样就保证了IP包可以重组,也就是把你的MYPACKET1的IP脑袋那改改Identification字段=MF,然后设置OFFSET为0,MYPACKET2呢?你得给他加个脑袋!然后Identification也为MF,OFFSET=?你说该是多少??然后就可以冠冕堂皇的当两个包发出去了!你说SENDCOMPLETE该什么时候调用??还有NdisIMCopySendCompletePerPacketInfo该怎么处理??这个不用说了吧?当然现在是两个包啦,两个IP包,要变成一个IP包是那边机子的TCP/IP的事情,关你这边的IMD鸟事,我们就用土方法,数脑袋,几个脑袋就算几个人[后来加上去的!!后来加上去的脑袋也是脑袋!也算!],呵呵~~明白了?所有的处理又恢复正常咯~~~加分!!!!!! |
|
|
19楼#
发布于:2002-05-06 23:35
关注
|
|
|
上一页
下一页