阅读:2094回复:1
NDIS中间驱动MPsend OR MPSendPackets中 获得数据的问题
NDIS中间驱动MPsend OR MPSendPackets中 获得了数据包首地址,然后用结构体分析,可以取得正确的 MAC地址,在取IP地址的时候输出全是0,检查发现除了以太头以外,包括IP头,TCP等其他的部分全部都是空的??这是怎么会事啊??
|
|
沙发#
发布于:2008-06-02 11:31
这些是别人的程序的代码,把相关部分截取出来的!你看看有没有参考价值,这里面能够正确获取ip包的ip地址
typedef struct _ETHeader // 14 bytes { UCHAR dhost[6]; // 目的MAC地址destination mac address UCHAR shost[6]; // 源MAC地址source mac address USHORT type; // 下层协议类型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等 } ETHeader, *PETHeader; 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; typedef struct _UDPHeader { USHORT sourcePort; // 源端口号 USHORT destinationPort;// 目的端口号 USHORT len; // 封包长度 USHORT checksum; // 校验和 } UDPHeader, *PUDPHeader; VOID MPSendPackets( IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets ) /*++ Routine Description: Send Packet Array handler. Either this or our SendPacket handler is called based on which one is enabled in our Miniport Characteristics. Arguments: MiniportAdapterContext Pointer to our adapter PacketArray Set of packets to send NumberOfPackets Self-explanatory Return Value: None --*/ { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status; UINT i; PVOID MediaSpecificInfo = NULL; UINT MediaSpecificInfoSize = 0; ///加密数据包数据类型 PNDIS_PACKET MyPacket; PVOID MemoryVA; ULONG BufferCount; ULONG TotalPacketLength; PNDIS_BUFFER CurrentBuffer; ULONG CurrentBufferLength; PVOID CurrentBufferVA = NULL; PUCHAR TempVA = NULL; PNDIS_BUFFER PktBuffer = NULL; /// PNDIS_HANDLE PktBufferPool = NULL; NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress; for (i = 0; i < NumberOfPackets; i++) { PNDIS_PACKET Packet, MyPacket; Packet = PacketArray; ///ADD BY Sh NdisAllocatePacket(&Status, &MyPacket, pAdapt->SendPacketPoolHandle); if(Status != NDIS_STATUS_SUCCESS) { return ; } NdisQueryPacket(Packet,NULL,&BufferCount,&CurrentBuffer,&TotalPacketLength); if(!BufferCount) { return ; } // Allocate memory with NdisAllocateMemory HighestAcceptableAddress.LowPart = -1; HighestAcceptableAddress.HighPart = -1; Status = NdisAllocateMemory(&MemoryVA,TotalPacketLength,0,HighestAcceptableAddress); if(Status == NDIS_STATUS_FAILURE) { return ; } // Allocate buffer-pool /// NdisAllocateBufferPool(&Status,PktBufferPool,1); // Allocate buffer NdisAllocateBuffer(&Status,&PktBuffer,pAdapt->SendPacketPoolHandle,MemoryVA,TotalPacketLength);//Maybe add a checksum length if(Status == NDIS_STATUS_FAILURE) { // Release the memory NdisFreeMemory(MemoryVA, TotalPacketLength, //Maybe add a checksum length 0); return ; } // Copy the packet to the buffer TempVA = (PUCHAR)MemoryVA; NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); while(CurrentBuffer != NULL) { NdisMoveMemory(TempVA, CurrentBufferVA, CurrentBufferLength); TempVA = (PUCHAR)TempVA + CurrentBufferLength; NdisGetNextBuffer(CurrentBuffer, &CurrentBuffer); if(CurrentBuffer == NULL) break; NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); } // TODO encrypt and checksum EnDecryptData(MemoryVA, 1) ; // Chain the buffer to Mypacket NdisChainBufferAtBack(MyPacket,PktBuffer); ///ADD BY SH // // The driver should fail the send if the virtual miniport is in low // power state // if (pAdapt->MPDeviceState > NdisDeviceStateD0) { NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), Packet, NDIS_STATUS_FAILURE); continue; } // BEGIN_PTEX_FILTER // // 调用过滤发送封包的函数,调用者运行在IRQL <= DISPATCH_LEVEL级别 // /// if(OpenState && !FltFilterSendPacket(pAdapt,Packet,FALSE)) /// { // // 如果拒绝的话,就欺骗上层,说已经发送成功了(虽然并没有真正地发送) // /// NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), /// Packet, /// NDIS_STATUS_SUCCESS); /// continue; /// } // END_PTEX_FILTER /*#ifdef NDIS51 // // Use NDIS 5.1 packet stacking: // { PNDIS_PACKET_STACK pStack; BOOLEAN Remaining; // // Packet stacks: Check if we can use the same packet for sending down. // pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining); if (Remaining) { // // We can reuse "Packet". // // NOTE: if we needed to keep per-packet information in packets // sent down, we can use pStack->IMReserved[]. // ASSERT(pStack); // // If the below miniport is going to low power state, stop sending down any packet. // NdisAcquireSpinLock(&pAdapt->Lock); if (pAdapt->PTDeviceState > NdisDeviceStateD0) { NdisReleaseSpinLock(&pAdapt->Lock); NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), Packet, NDIS_STATUS_FAILURE); } else { pAdapt->OutstandingSends++; NdisReleaseSpinLock(&pAdapt->Lock); NdisSend(&Status, pAdapt->BindingHandle, Packet); if (Status != NDIS_STATUS_PENDING) { NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), Packet, Status); ADAPT_DECR_PENDING_SENDS(pAdapt); } } continue; } } #endif*/ do { NdisAcquireSpinLock(&pAdapt->Lock); // // If the below miniport is going to low power state, stop sending down any packet. // if (pAdapt->PTDeviceState > NdisDeviceStateD0) { NdisReleaseSpinLock(&pAdapt->Lock); Status = NDIS_STATUS_FAILURE; break; } pAdapt->OutstandingSends++; NdisReleaseSpinLock(&pAdapt->Lock); /// NdisAllocatePacket(&Status, /// &MyPacket, /// pAdapt->SendPacketPoolHandle); /// if (Status == NDIS_STATUS_SUCCESS) { PNDIS_PACKET_EXTENSION Old, New; PSEND_RSVD SendRsvd; SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved); SendRsvd->OriginalPkt = Packet; MyPacket->Private.Flags = NdisGetPacketFlags(Packet); /// MyPacket->Private.Head = Packet->Private.Head; /// MyPacket->Private.Tail = Packet->Private.Tail; NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK); Old = NDIS_PACKET_EXTENSION_FROM_PACKET(Packet); New = NDIS_PACKET_EXTENSION_FROM_PACKET(MyPacket); New->NdisPacketInfo[TcpIpChecksumPacketInfo] = Old->NdisPacketInfo[TcpIpChecksumPacketInfo]; New->NdisPacketInfo[IpSecPacketInfo] = Old->NdisPacketInfo[IpSecPacketInfo]; New->NdisPacketInfo[TcpLargeSendPacketInfo] = Old->NdisPacketInfo[TcpLargeSendPacketInfo]; New->NdisPacketInfo[ClassificationHandlePacketInfo] = Old->NdisPacketInfo[ClassificationHandlePacketInfo]; New->NdisPacketInfo[Ieee8021pPriority] = Old->NdisPacketInfo[Ieee8021pPriority]; #ifdef WIN9X // // Work around the fact that NDIS does not initialize this // to FALSE on Win9x. // MyPacket->Private.ValidCounts = FALSE; #endif // WIN9X // // Copy the OOB data from the original packet to the new // packet. // NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket), NDIS_OOB_DATA_FROM_PACKET(Packet), sizeof(NDIS_PACKET_OOB_DATA)); // // Copy relevant parts of the per packet info into the new packet // #ifndef WIN9X NdisIMCopySendPerPacketInfo(MyPacket, Packet); #endif // // Copy the Media specific information // NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet, &MediaSpecificInfo, &MediaSpecificInfoSize); if (MediaSpecificInfo || MediaSpecificInfoSize) { NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket, MediaSpecificInfo, MediaSpecificInfoSize); } NdisSend(&Status, pAdapt->BindingHandle, MyPacket); if (Status != NDIS_STATUS_PENDING) { #ifndef WIN9X NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); #endif NdisUnchainBufferAtBack(MyPacket,&PktBuffer); NdisFreeBuffer(PktBuffer); NdisFreeMemory(MemoryVA, TotalPacketLength, //Maybe add a checksum length 0); NdisFreePacket(MyPacket); ADAPT_DECR_PENDING_SENDS(pAdapt); } } /// else /// { // // The driver cannot allocate a packet. // /// ADAPT_DECR_PENDING_SENDS(pAdapt); /// } } while (FALSE); if (Status != NDIS_STATUS_PENDING) { NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt), Packet, Status); } } } void EnDecryptData(PVOID pData, int flag) { PIPHeader pIpHeader ; PTCPHeader pTcpHeader ; PUDPHeader pUdpHeader ; PVOID pTempData ; ULONG uDataLen ; ULONG i ; unsigned short uIpHeaderLen ; unsigned short uIpLen ; pIpHeader = (PIPHeader)((char *)pData + sizeof(ETHeader)) ; uIpLen = (pIpHeader->ipLength >> 8) + ((pIpHeader->ipLength & 0xff00) << 8) ; uIpLen = (pIpHeader->ipLength >> 8) + ((pIpHeader->ipLength & 0xff00) << 8) ; uIpHeaderLen = (pIpHeader->iphVerLen&0x0f) << 2 ; if ( pIpHeader->ipProtocol == 17 ) ///UDP { pUdpHeader = (PUDPHeader)((char *)pIpHeader + uIpHeaderLen) ; pTempData = (PVOID)((char *)(pUdpHeader) + 8) ; uDataLen = uIpLen - uIpHeaderLen - 8 ; if ((int)uDataLen < 0 ) return ; if (flag) { for (i = 0 ; i<uDataLen; i ++) { ((unsigned char *)pTempData) = ((unsigned char *)pTempData) + 1 ; } } else { for (i = 0 ; i<uDataLen; i ++) { ((unsigned char *)pTempData) = ((unsigned char *)pTempData) - 1 ; } } UdpCheckSum(pIpHeader) ; } else if ( pIpHeader->ipProtocol == 6 ) ///TCP { pTcpHeader = (PTCPHeader)((char *)pIpHeader + uIpHeaderLen) ; pTempData = (PVOID)((char *)(pTcpHeader) + (pTcpHeader->dataoffset>>4)*4) ; uDataLen = uIpLen - uIpHeaderLen - (pTcpHeader->dataoffset>>4)*4 ; if ((int)uDataLen < 0) return ; if (flag) { for (i = 0 ; i<uDataLen; i ++) { ((unsigned char *)pTempData) = ((unsigned char *)pTempData) + 1 ; } } else { for (i = 0 ; i<uDataLen; i ++) { ((unsigned char *)pTempData) = ((unsigned char *)pTempData) - 1 ; } } TcpCheckSum(pIpHeader) ; } return ; } void UdpCheckSum(PIPHeader buffer) { __asm { pushad xor eax,eax xor edx,edx mov esi,buffer add esi,12 //srcip mov ecx,4 lable1: lodsw add edx,eax loop lable1 add edx,1100h //udp type mov [esi+6],cx //clear old checksum to 0 mov cx,[esi+4] add edx,ecx //udp length xchg cl,ch mov edi,esi mov ebx,ecx shr ecx,1 lable2: lodsw add edx,eax loop lable2 and ebx,1 jz lable3 xor eax,eax lodsb add edx,eax lable3: mov eax,edx shr eax,16 and edx,0ffffh add edx,eax mov eax,edx shr eax,16 add edx,eax not edx mov [edi+6],dx popad } } void TcpCheckSum(PIPHeader buffer) { //buffer是IP头的指针 unsigned short size, sizetemp; unsigned char * pSize; unsigned char tempchar; unsigned long cksum = 0; unsigned short * TempAddr; unsigned short * TempAddr1; int i = 0; unsigned short uIpLen ; //加伪首 TempAddr = (unsigned short *)(&(buffer->ipSource)); for(i=0;i<4;i++) { cksum += *TempAddr; TempAddr++; } cksum += 0x0600; //类型 uIpLen = (buffer->ipLength >> 8) + ((buffer->ipLength & 0xff00) << 8) ; size = uIpLen - (buffer->iphVerLen&0x0f)*4 ;//tcp包长度 sizetemp = size ; //转换网络字节 pSize = (unsigned char *)(&sizetemp); tempchar = pSize[0]; pSize[0] = pSize[1]; pSize[1] = tempchar; cksum += sizetemp; //校验和位置清0 *(TempAddr + 8) = 0; //size = tcp size //buffer = tcp packet addr TempAddr1 = TempAddr; while (size > 1) { cksum = cksum + *TempAddr ; TempAddr = TempAddr + 1; size = size - sizeof(unsigned short); } if (size) { cksum += *(unsigned char*)TempAddr; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); *(TempAddr1 + 8) = (unsigned short)(~cksum); } |
|