阅读:2994回复:18
怎样用NdisRequest修改MTU? 40分
在PassThru程序中,对IP包分片,分得我是一肚子火。只好改MTU了,再说改MTU效率高,我这样作了,但不知方法对不对,希望大侠来指点一二:
if(pAdapt->nMaxFrameSize==0) { //设定MTU pAdapt->nMaxFrameSize=1460; NdisMtuRequest.RequestType=NdisRequestSetInformation ; NdisMtuRequest.DATA.SET_INFORMATION.Oid=OID_GEN_MAXIMUM_FRAME_SIZE; NdisMtuRequest.DATA.SET_INFORMATION.InformationBuffer=&pAdapt->nMaxFrameSize ; NdisMtuRequest.DATA.SET_INFORMATION.InformationBufferLength=4; NdisMtuRequest.DATA.SET_INFORMATION.BytesRead=4; NdisMtuRequest.DATA.SET_INFORMATION.BytesNeeded=4; NdisRequest(&Status,pAdapt->BindingHandle,&NdisMtuRequest); DbgPrint(\"\\n MTU: SET MTU:Max=%d, status=0x%x BytesRead=0x%x \",pAdapt->nMaxFrameSize,Status,NdisMtuRequest.DATA.SET_INFORMATION.BytesRead); NdisMtuRequest.RequestType=NdisRequestQueryInformation; NdisMtuRequest.DATA.QUERY_INFORMATION.Oid=OID_GEN_MAXIMUM_FRAME_SIZE; NdisMtuRequest.DATA.QUERY_INFORMATION.InformationBuffer=&pAdapt->nMaxFrameSize ; NdisMtuRequest.DATA.QUERY_INFORMATION.InformationBufferLength=4; NdisMtuRequest.DATA.QUERY_INFORMATION.BytesWritten=0; NdisMtuRequest.DATA.QUERY_INFORMATION.BytesNeeded=0; NdisRequest(&Status,pAdapt->BindingHandle,&NdisMtuRequest); DbgPrint(\"\\n MTU: Queue MTU:Max=%d, status=0x%x ,BytesWritten=0x%x\",pAdapt->nMaxFrameSize,Status,NdisMtuRequest.DATA.QUERY_INFORMATION.BytesWritten); } 打印的结果是: MTU: SET MTU:Max=1460, status=0x103 BytesRead=0x0 MTU: Queue MTU:Max=1500, status=0x103 ,BytesWritten=0x4 为什么查询正确,就不能修改了呢? 修改MTU是上述这样改,还是通过ICMP包来修改? |
|
沙发#
发布于:2002-05-27 18:28
追加40分
|
|
|
板凳#
发布于:2002-05-27 18:49
分段是有点烦
|
|
|
地板#
发布于:2002-05-27 20:58
关注! ;) |
|
|
地下室#
发布于:2002-05-28 09:00
sorry,我一个帖子只能给20分,但我可以另开帖子给分的。
看到这么多回复我真激动,但可惜... |
|
5楼#
发布于:2002-05-28 09:03
我也关注,等hyg吧!
|
|
|
6楼#
发布于:2002-05-28 10:41
更改MTU,我是这样实现的,在passthru中的miniport.c里有一个函数是mpqueryinformation,你可以在NdisRequest调用之后,但在整个函数返回之前,拦截一个oid:OID_GEN_MAXIMUM_FRAME_SIZE
然后把*(ULONG *)pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer =YOUR_MTU; 如果YOUR_MTU=1200,那么MTU就是1200,我在2000上实现了! |
|
7楼#
发布于:2002-05-28 10:53
楼上的方法不错,应该得分
|
|
8楼#
发布于:2002-05-28 11:02
引用:
―――――――――――――――――――――――――――――― 在PassThru程序中,对IP包分片,分得我是一肚子火。只好改MTU了,再说改MTU效率高,我这样作了,但不知方法对不对,希望大侠来指点一二: ――――――――――――――――――――――――――――――上述有两个问题 一、NdisRequest属于异步调用,有可能你的SetInformation还没有被执行,所以查询时还是原来的值。 二、有些网卡驱动可能会忽略你的设置,至少我写的网卡驱动是这样(不要拿臭鸡蛋砸我啊,公司的网卡只做单向收)。 还有就是TCP/IP协议是不是也会发那个SetInformation啊 |
|
9楼#
发布于:2002-05-28 11:15
哈,哈,哈...
给分,给分... 没啥说的了,swift,都到我家喝酒去! |
|
10楼#
发布于:2002-05-28 11:43
好说好说,呵呵 :))
|
|
11楼#
发布于:2002-05-28 13:07
我也关注,等hyg吧! 修改mtu的方法不适用于wan。 具体的代码如下: if (Oid == OID_GEN_MAXIMUM_FRAME_SIZE ) { DBGPRINT((\"Query OID_GEN_MAXIMUM_FRAME_SIZE\\n\")); *(PULONG)InformationBuffer = LoadTimeOption.NEW_MTU - MAC_HEADER_LEN; *BytesWritten = 4; *BytesNeeded = 4; return NDIS_STATUS_SUCCESS; } if (Oid == OID_GEN_MAXIMUM_TOTAL_SIZE) { // to my surprise,it\'s seemed never run the following code ... DBGPRINT((\"Query OID_GEN_MAXIMUM_TOTAL_SIZE\\n\")); *(PULONG)InformationBuffer=LoadTimeOption.NEW_MTU; *BytesWritten = 4; *BytesNeeded = 4; return NDIS_STATUS_SUCCESS; } 今天心情好,中午刚刚吃了顿饱饭,吃得我坐在草地上喘了 半个小时的气还没有缓过劲来,其实也就是双份蛋炒饭,不过 感觉很爽。因此就干脆把碎包代码贴上: INT CrashSendBuf( PUCHAR SendBuffer, PINT BufferLength, PUCHAR CrashSendBuffer, PINT CrashPktLen ) { USHORT packet_len,first_buf_len,crash_buf_len, mac_head_len, ip_len, New_cksum; USHORT crash_frag_off ; PIP_HEADER iphead, ipheadcrash; iphead = (PIP_HEADER)(SendBuffer+MAC_HEADER_LEN); /* if the ip packet is \"Don\'t Fragment\", reset flag */ if( iphead->FragmentOffset & 0x0040 ) iphead->FragmentOffset &= ~(0x0040); /* Caculate first packet len , it must mod 8 and must have full space for encrypt */ mac_head_len = sizeof(MAC_HEADER); packet_len = ( *BufferLength - mac_head_len - sizeof(IP_HEADER)) / 2; packet_len -= ( packet_len % 8 ); first_buf_len = mac_head_len + sizeof(IP_HEADER) + packet_len; crash_buf_len = *BufferLength - first_buf_len; /* copy data from first buffer to second buffer */ NdisMoveMemory( CrashSendBuffer, SendBuffer, mac_head_len+sizeof(IP_HEADER) ); NdisMoveMemory( CrashSendBuffer+mac_head_len+sizeof(IP_HEADER), SendBuffer+first_buf_len, crash_buf_len ); /* Caculate fragment flag and fragment off */ // if( htons(iphead->FragmentOffset) & IP_MF ) { if( iphead->FragmentOffset & 0x0020 ) { /* for the MF_MED or MF_FST packet */ // crash_frag_off = htons(((ntohs(iphead->FragmentOffset) & IP_OFFSET) + packet_len/8) | IP_MF); crash_frag_off = ((iphead->FragmentOffset&0xff00)>>8) + ((iphead->FragmentOffset&0x00ff)<<8); crash_frag_off = (((crash_frag_off & IP_OFFSET) + packet_len/8) | IP_MF); crash_frag_off = ((crash_frag_off&0xff00)>>8) + ((crash_frag_off&0x00ff)<<8); // crash_frag_off = (((iphead->FragmentOffset & 0xff1f) + packet_len/8) | 0x0020 ); }else{ /* for the MF_END or MF_NON packet */ iphead->FragmentOffset = iphead->FragmentOffset | 0x0020 ; crash_frag_off = ((iphead->FragmentOffset&0xff00)>>8) + ((iphead->FragmentOffset&0x00ff)<<8); crash_frag_off = ((crash_frag_off & IP_OFFSET) + packet_len/8); crash_frag_off = ((crash_frag_off&0xff00)>>8) + ((crash_frag_off&0x00ff)<<8); // crash_frag_off = (( iphead->FragmentOffset & 0xff1f )+ packet_len/8 ); } /* do with the first buffer */ ip_len = first_buf_len - mac_head_len; iphead->HeaderCRC = 0; iphead->LengthL = (USHORT)(ip_len)&0x00ff; iphead->LengthU = ((USHORT)(ip_len)&0xff00)>>8; New_cksum = In_cksum((PUCHAR)iphead,IP_HEADER_LEN); iphead->HeaderCRC = New_cksum; *BufferLength = first_buf_len; /* do with the second buffer */ ipheadcrash = (PIP_HEADER)(CrashSendBuffer + mac_head_len); ipheadcrash->FragmentOffset = crash_frag_off; ipheadcrash->TOS |= 0x40; ip_len = crash_buf_len + sizeof(IP_HEADER); ipheadcrash->HeaderCRC = 0; ipheadcrash->LengthL = (USHORT)(ip_len)&0x00ff; ipheadcrash->LengthU = ((USHORT)(ip_len)&0xff00)>>8; New_cksum = In_cksum((PUCHAR)ipheadcrash,IP_HEADER_LEN); ipheadcrash->HeaderCRC = New_cksum; *CrashPktLen = ip_len + mac_head_len; return SUCCESS; } |
|
|
12楼#
发布于:2002-05-28 13:50
胡老大出手,备感荣幸!!
我本来也是用碎包的方法,但不碎包时,都很正常,一碎包,就遇到各种各样的问题,比如:发第二个包时死机,或是两个包都发不出去等等,不过我收、发包都是另开一个线程的。 不知胡老大碎包时,有没有遇到这类问题。 |
|
13楼#
发布于:2002-05-28 14:11
胡老大出手,备感荣幸!! 我要是现在还在这些问题上纠缠,那我不是早就被领导兜屁股 给踢出去了? |
|
|
14楼#
发布于:2002-05-28 14:18
看样子,你领导能使得兵不多了。
呵呵,开玩笑,别见怪。 |
|
|
15楼#
发布于:2002-05-28 14:35
哈!你的领导是军人,我的领导也是军人,但我还没有被我的领导兜屁股给踢出去。
|
|
16楼#
发布于:2002-05-28 15:51
你的领导仁慈,所以,你易相处。
他的领导要求高,所以,他的水平高。 呵呵,都不错。 |
|
|
17楼#
发布于:2002-05-28 16:16
你的领导仁慈,所以,你易相处。 这么会说话,你可以去作部门协调了。 |
|
18楼#
发布于:2002-05-28 18:24
偶看来得新开贴子给分了.hehe
不过偶觉得都答得不错哦. swift的简明易懂,huyg的看来象是正解. 怎么给分呢. |
|
|