aeolusdri
驱动牛犊
驱动牛犊
  • 注册日期2009-07-13
  • 最后登录2009-10-10
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望21点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1760回复:0

NDIS 收报文截获问题

楼主#
更多 发布于:2009-07-30 10:52
将收上来的报文是 IP AH ICMP 格式的报文,我在PPReceive函数中去掉报文中的AH层,然后存储在新申请的buffer中,
将该buffer挂载在新的 Packet 中提交给上层,但发现上层返回的ICMP报文是IP ICMP [IP AH ICMP]格式,寻思良久,不知道问题出在哪里?
请高人指点呀。 谢谢!!

PPReceive函数如下:

NDIS_STATUS PPReceive
                (
                    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;
    BOOLEAN              bDecision;    
    pEthHdr             pETH;

    if ((!pAdapt->MiniportHandle) || (pAdapt->MiniportDeviceState > 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 (Packet != NULL)
        {
            //
            // The miniport below did indicate up a packet. Use information
            // from that packet to construct a new packet to indicate up.
            //
                //
                // Make our packet point to data from the original
                // packet. NOTE: this works only because we are
                // indicating a receive directly from the context of
                // our receive indication. If we need to queue this
                // packet and indicate it from another thread context,
                // we will also have to allocate a new buffer and copy
                // over the packet contents, OOB data and per-packet
                // information. This is because the packet data
                // is available only for the duration of this
                // receive indication call.
                //
                //
                // Get a packet off the pool and indicate that up
                //

                
                //drop loopback packet
                if (IsLoopbackPacket(pAdapt, Packet))                               // A loopback?
                {
                    return 0;                                      // Drop packet.
                }

                NdisDprAllocatePacket(&Status,
                                &MyPacket,
                                pAdapt->RecvPacketPoolHandle);


                if (Status == NDIS_STATUS_SUCCESS)
                {
                    PRECV_RSVD            RecvRsvd;
                    PNDIS_BUFFER          NewNdisBfr;
                    BOOLEAN             Ret;
                    
                    RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
                    RecvRsvd->OriginalPkt = Packet;

                    //filter for ESP/AH
                    Status = FilterPacket(    pAdapt,
                                            Packet,
                                            NULL,
                                            FALSE,              
                                            &bDecision
                                         );
                    if(bDecision)
                    {
                        Ret = PStripAhEsp(pAdapt, Packet, MyPacket);
                    }


                    if(!bDecision || !Ret )
                    {
                        RecvRsvd->bNewBuffer = FALSE;              
                        MyPacket->Private.Head = Packet->Private.Head;
                        MyPacket->Private.Tail = Packet->Private.Tail;
                    }
        
                    //
                    // Get the original packet (it could be the same packet as the
                    // one received or a different one based on the number of layered
                    // miniports below) and set it on the indicated packet so the OOB
                    // data is visible correctly at protocols above.
                    //
                    NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
                    NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

                    //
                    // Copy packet flags.
                    //
                    NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

                    //
                    // Force protocols above to make a copy if they want to hang
                    // on to data in this packet. This is because we are in our
                    // Receive handler (not ReceivePacket) and we can't return a
                    // ref count from here.
                    //
                    NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

                    //
                    // By setting NDIS_STATUS_RESOURCES, we also know that we can reclaim
                    // this packet as soon as the call to NdisMIndicateReceivePacket
                    // returns.
                    //

                    NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

                    //
                    // Reclaim the indicated packet. Since we had set its status
                    // to NDIS_STATUS_RESOURCES, we are guaranteed that protocols
                    // above are done with it.
                    //
                    DestroyMyPacket(MyPacket);
                    NdisDprFreePacket(MyPacket);
    
                    break;
                }

        }
        else
        {

            //
            // The miniport below us uses the old-style (not packet)
            // receive indication. Fall through.
            //
        }

        //
        // Fall through if the miniport below us has either not
        // indicated a packet or we could not allocate one
        //
        pAdapt->IndicateRcvComplete = TRUE;
        switch (pAdapt->Medium)
        {
            case NdisMedium802_3:
            case NdisMediumWan:
                NdisMEthIndicateReceive(pAdapt->MiniportHandle,
                                             MacReceiveContext,
                                             HeaderBuffer,
                                             HeaderBufferSize,
                                             LookAheadBuffer,
                                             LookAheadBufferSize,
                                             PacketSize);
                break;

            default:
                break;
        }

    } while(FALSE);

    return Status;
}


BOOLEAN  PStripAhEsp
            (
                IN PADAPT pAdapt,
                IN PNDIS_PACKET original_packet,
                OUT PNDIS_PACKET MyPacket
            )
{

    NDIS_STATUS                Status;
    #define                szPayloadCopy    ETH_MAX_PACKET_SIZE
    char                    PayloadCopy[szPayloadCopy];

    pIPHdr                pIPH;
    pAHHdr                pAH;
    USHORT                IPHdrl;
            
    PUCHAR                pUnencPayload    =    NULL;
    ULONG                UnEncPayloadl;
    ULONG                EncPayloadl;

    PNDIS_BUFFER            NewNdisBfr;
    PRECV_RSVD              RecvRsvd;


    //get a copy of the packet to local buffer
    GetPktPayload(    original_packet,
                    PayloadCopy,
                    szPayloadCopy,
                    &EncPayloadl
                    );
                    
    pIPH = (pIPHdr)(PayloadCopy + sizeof(EthHdr));

    IPHdrl = pIPH->IPHdrLen * 4;

                    
    //alloc new memery
    UnEncPayloadl = EncPayloadl - sizeof(AHHdr);
    Status = NdisAllocateMemoryWithTag(    &pUnencPayload,
                                UnEncPayloadl,
                                TAG
                            );

    if (NDIS_STATUS_SUCCESS != Status)
    {
        return FALSE;
    }
    
    //build new packet with no AH/ESP
    NdisMoveMemory( pUnencPayload,
                    PayloadCopy,
                    sizeof(EthHdr) + IPHdrl
                  );

    NdisMoveMemory( pUnencPayload + sizeof(EthHdr) + IPHdrl,
                    PayloadCopy      + sizeof(EthHdr) + IPHdrl + sizeof(AHHdr),
                    EncPayloadl   - sizeof(EthHdr) - IPHdrl - sizeof(AHHdr)
                  );

    pIPH = (pIPHdr)(pUnencPayload + sizeof(EthHdr));

    pIPH->TotalLength = (USHORT)RtlUlongByteSwap((UnEncPayloadl - sizeof(EthHdr))<<16);

    pIPH->Protocol = 1;
    
    pIPH->Checksum = 0;                                

    pIPH->Checksum = GetIPChecksum((PUSHORT)pIPH, IPHdrl);
    
    //build new buffer descriptor and chain it to MyPacket

    NdisAllocateBuffer(    &Status,                
                    &NewNdisBfr,
                    pAdapt->hRecvBufferPool,
                    pUnencPayload,
                    UnEncPayloadl
                    );

    if(  NDIS_STATUS_SUCCESS  !=  Status  )
    {
        NdisFreeMemory(    pUnencPayload,        
                    UnEncPayloadl,
                    0
                    );

        pUnencPayload = NULL;
        return FALSE;
    }

    RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
    RecvRsvd->bNewBuffer = TRUE;              

    NdisChainBufferAtFront(    MyPacket,        
                        NewNdisBfr
                        );
                        


    /*
    MyPacket->Private.Head = original_packet->Private.Head;
    MyPacket->Private.Tail = original_packet->Private.Tail;
    */
    return TRUE;

}
游客

返回顶部