阅读:1650回复:8
撑不住了,passthru的ptreceive的LookAheadBuffer中取得IP头数据是对的,但TCP头怎么不对??
撑不住了,搞了两天了,passthru的ptreceive的LookAheadBuffer中取得IP头数据是对的,但TCP头怎么不对??
我的代码: NDIS_STATUS PtReceive( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookAheadBuffer, IN UINT LookAheadBufferSize, IN UINT PacketSize ) { PADAPT pAdapt = (PADAPT)ProtocolBindingContext; PNDIS_PACKET MyPacket, Packet; NDIS_STATUS Status = NDIS_STATUS_SUCCESS; if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0)) { Status = NDIS_STATUS_FAILURE; } else do { // // Get at the packet, if any, indicated up by the miniport below. // Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext); ////////////////////////////我加入的代码////////////////////////////// if ( HeaderBufferSize >= sizeof(ETHeader) ) KdPrint(( "ETHeader type : %x\n", ((PETHeader)HeaderBuffer)->type )); FilterReceive( LookAheadBuffer, LookAheadBufferSize); ///////////////////////////////////////////////////////////////////////////////// if (Packet != NULL) { 。。。。。。。。。。。。。。。。。。。。。passthru原来的代码 。。。。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。。。。。 } VOID FilterReceive(I N PVOID pData, IN UINT pDataSize ) { //剩下数据的长度 ULONG ulLeavingLen = pDataSize; PIPHeader pIPHdr; PTCPHeader pTCPHdr; if ( ulLeavingLen < sizeof( IPHeader ) ) { KdPrint(( "ulLeavingLen < sizeof( IPHeader )\n" )); return; } pIPHdr = ( PIPHeader )( pData ); DbgPrint( "The Src address is %d.%d.%d.%d\n", pIPHdr->ipSource << 24 >> 24, pIPHdr->ipSource << 16 >> 24, pIPHdr->ipSource << 8 >> 24, pIPHdr->ipSource >> 24 ); DbgPrint( "The Dest address is %d.%d.%d.%d\n", pIPHdr->ipDestination << 24 >> 24, pIPHdr->ipDestination << 16 >> 24, pIPHdr->ipDestination << 8 >> 24, pIPHdr->ipDestination >> 24 ); ulLeavingLen -= sizeof( IPHeader ); KdPrint(( "pIPHdr->ipProtocol = %d\n", pIPHdr->ipProtocol )); //不是TCP退出 if ( pIPHdr->ipProtocol != 6 ) { KdPrint(( "pIPHdr->ipProtocol != 6\n" )); return; } if ( ulLeavingLen < sizeof(TCPHeader) ) { KdPrint(( "ulLeavingLen < sizeof(TCPHeader)\n" )); return; } pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + sizeof(IPHeader) ); KdPrint(( "TCPHeader sourcePort : %d\n", pTCPHdr->sourcePort )); KdPrint(( "TCPHeader destinationPort : %d\n", pTCPHdr->destinationPort )); //不是80端口退出 if ( pTCPHdr->destinationPort != 80 ) return; KdPrint(( "TCPHeader destinationPort : http80\n")); } //IP头和TCP头声明 typedef struct _IPHeader // 20 { UCHAR iphVerLen; // 版本号和头长度(各占4位) UCHAR ipTOS; // 服务类型 USHORT ipLength; // 封包总长度,即整个IP报的长度 USHORT ipID; // 封包标识,惟一标识发送的每一个数据报 USHORT ipFlags; // 标志 UCHAR ipTTL; // 生存时间,就是TTL UCHAR ipProtocol; // 协议,可能是TCP、UDP、ICMP等 USHORT ipChecksum; // 校验和 ULONG ipSource; // 源IP地址 ULONG ipDestination; // 目标IP地址 } IPHeader, *PIPHeader; typedef struct _TCPHeader //20 bytes { USHORT sourcePort; // 16位源端口号 USHORT destinationPort; // 16位目的端口号 ULONG sequenceNumber; // 32位序列号 ULONG acknowledgeNumber; // 32位确认号 UCHAR dataoffset; // 高4位表示数据偏移 UCHAR flags; // 6位标志位 USHORT windows; // 16位窗口大小 USHORT checksum; // 16位校验和 USHORT urgentPointer; // 16位紧急数据偏移量 } TCPHeader, *PTCPHeader; 请指教!谢谢! |
|
沙发#
发布于:2008-05-19 22:48
不懂,学习中,帮顶一下
|
|
板凳#
发布于:2008-05-20 06:52
取不到吗?没有试过你这种,你可以试试
NdisQueryPacket(packet, NULL, NULL, &ndisBuffer, &totalLen); while (NULL != ndisBuffer) { NdisQueryBufferSafe(ndisBuffer, &address, &curLen, NormalPagePriority); NdisMoveMemory(pcontent, address, curLen); (PUCHAR)pcontent += curLen; NdisGetNextBuffer(ndisBuffer, &ndisBuffer); } 我这样是可以取到的 |
|
地板#
发布于:2008-05-20 10:11
lgr98,我也用过你这种方法了,取到的数据和我这个方法是一样的,难道是我TCP头位置截错了?不可能的呀
|
|
地下室#
发布于:2008-05-20 22:55
ip头取到了,ip头中的协议类型是tcp, 那ip头加上ip头的长度不就是tcp头吗?我这样取是可以取到的呀!!(ip头长度的单位是4字节的)
|
|
5楼#
发布于:2008-05-21 14:13
pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + sizeof(IPHeader) );
如果IP头有可选头的话,这样定位就有问题了。。。 UCHAR iphVerLen; // 版本号和头长度(各占4位) (iphVerLen&0x0F)*4 |
|
6楼#
发布于:2008-05-21 14:55
我已经改成这样了:
pTCPHdr = ( PTCPHeader )( (char*)pIPHdr + (pIPHdr->iphVerLen & 0xf) * 4 ); 但取到的源端口和目的端口都是很大的值,怎么回事? 还真是不知道错在哪? 驱动网的大小牛们都没看出来吗? |
|
7楼#
发布于:2008-05-22 12:40
数据不再同一片上,需要遍历packet的里面的buffer(不是数据阿)数据片联表。你这样直接+数据,谁知道你读的数据是什么了。
似乎有什么NdisNextbuffer之类接口,好久了不写windows code了,忘记了。你可以从ndis的数据格式的api里面找到答案。 |
|
|
8楼#
发布于:2008-05-22 22:09
NdisQueryPacket( Packet, NULL, NULL, &firstBuffer, &totalLength );
j = 0; while( firstBuffer != NULL ) { j ++; NdisQueryBufferSafe( firstBuffer, &virtualAddress, &totalLength, NormalPagePriority ); //DBGPRINT( ( "PtReceive --- Buffer %d Length : %d\n", j, totalLength ) ); if( ! virtualAddress ) return STATUS_INSUFFICIENT_RESOURCES; if ( j == 1 ) FilterReceive( (char*)virtualAddress + sizeof(ETHeader), totalLength-sizeof(ETHeader) ); NdisGetNextBuffer( firstBuffer, &nextBuffer ); firstBuffer = nextBuffer; } 可是,版主,上边这个代码没问题吧,而且第一个Buffer是够 以太网头 + IP头 + TCP头 的长度,但是这段代码得到的TCP头和我上边的那段代码得到的是一样的,怎么说这个? 好像LookAheadBuffer是连续的吧? |
|