kkkhmy
驱动牛犊
驱动牛犊
  • 注册日期2008-04-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分23分
  • 威望198点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:2096回复:1

NDIS中间驱动MPsend OR MPSendPackets中 获得数据的问题

楼主#
更多 发布于:2008-05-31 22:08
NDIS中间驱动MPsend OR MPSendPackets中 获得了数据包首地址,然后用结构体分析,可以取得正确的 MAC地址,在取IP地址的时候输出全是0,检查发现除了以太头以外,包括IP头,TCP等其他的部分全部都是空的??这是怎么会事啊??
vondeny
驱动牛犊
驱动牛犊
  • 注册日期2008-04-30
  • 最后登录2008-08-08
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望25点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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);
}
游客

返回顶部