liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1878回复:5

IMD下MPSendPackets中转发数据包问题(有代码)

楼主#
更多 发布于:2008-02-01 16:32
SendBuffer是将一个数据包缓冲区(完整包内容,从NDIS_PACKET中取得)发送出去的
并不是自定义包。而是根据系统原来的Packet 发送。

现在的问题是,调用这个函数后对8139等老网卡支持不好。
TCP连接不太稳定,有些机器蓝屏。

请高手帮忙解决。


NDIS_STATUS
SendBuffer(
           PUCHAR    SndBuffer,
           ULONG    BufferSize,
           PNDIS_PACKET Packet,
           PADAPT    pAdapter
           )
{
    NDIS_STATUS        status = NDIS_STATUS_SUCCESS;
    PNDIS_BUFFER    pNdisBuffer;
    PNDIS_PACKET    pNdisPacket;

    ULONG            bufLength;
    PVOID            MediaSpecificInfo        = NULL;
    ULONG            MediaSpecificInfoSize    = 0;
    PUCHAR pPacketContent8;
    UINT BufferLen;

    do
    {
        // 自己构造发送的包,不要NdisMSendComplete通知上层释放
        NdisAcquireSpinLock(&pAdapter->Lock);
        if (pAdapter->PTDeviceState > NdisDeviceStateD0)
        {
            NdisReleaseSpinLock(&pAdapter->Lock);
            status = NDIS_STATUS_FAILURE;
            break;
        }
        pAdapter->OutstandingSends++;
        NdisReleaseSpinLock(&pAdapter->Lock);

        if (status == NDIS_STATUS_SUCCESS)
        {
            PSEND_RSVD        SendRsvd;

            //分配Packet
            NdisAllocatePacket( &status, &pNdisPacket, pAdapter->SendPacketPoolHandle);
            if (status != NDIS_STATUS_SUCCESS)
            {
                DBGPRINT(("NdisAllocatePacket Error!\n"));
                return status;
            }

            //分配Buffer
            NdisAllocateBuffer(&status, &pNdisBuffer, pAdapter->SendPacketPoolHandle, SndBuffer, BufferSize);
            if( status != NDIS_STATUS_SUCCESS )
            {
                DBGPRINT(("NdisAllocateBuffer Error!\n"));
                return status;
            }

            //DBGPRINT(("buffer(%d):%08X - %08X(%08X) - %08X - %08X(%08X)!\n",BufferSize,Packet->Private.Head,pNdisBuffer,&pNdisBuffer,pNdisPacket->Private.Head,SndBuffer,&SndBuffer));


            pNdisBuffer->Next = NULL;
            //连接packet
            NdisChainBufferAtFront(pNdisPacket, pNdisBuffer);

            SendRsvd = (PSEND_RSVD)(pNdisPacket->ProtocolReserved);
            SendRsvd->OriginalPkt = Packet;
            SendRsvd->Flag = 0x1721;

            pNdisPacket->Private.Head->Next=NULL;
            pNdisPacket->Private.Tail=NULL;

            NdisGetPacketFlags(pNdisPacket) = NdisGetPacketFlags(Packet);
            //NdisSetPacketFlags(pNdisPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包
            NDIS_SET_PACKET_HEADER_SIZE(pNdisPacket,14);

            NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(pNdisPacket),
                NDIS_OOB_DATA_FROM_PACKET(Packet),
                sizeof(NDIS_PACKET_OOB_DATA));

            NdisIMCopySendPerPacketInfo(pNdisPacket, Packet);

            NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(
                Packet,    &MediaSpecificInfo,    &MediaSpecificInfoSize);

            if (MediaSpecificInfo || MediaSpecificInfoSize)
            {
                NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(
                    pNdisPacket, MediaSpecificInfo, MediaSpecificInfoSize);
            }

            NdisSend(&status, pAdapter->BindingHandle, pNdisPacket);
            if (status != NDIS_STATUS_PENDING)
            {
                /*
                DBGPRINT(("-------->2\n"));
                NdisIMCopySendCompletePerPacketInfo (Packet, pNdisPacket);
                NdisUnchainBufferAtFront(pNdisPacket ,&pNdisBuffer);
                while (pNdisBuffer!=NULL)
                {
                    NdisFreeMemory((UCHAR *)(pNdisBuffer->StartVa) + pNdisBuffer->ByteOffset,pNdisBuffer->ByteCount,0);            
                    NdisFreeBuffer(pNdisBuffer);
                    NdisUnchainBufferAtFront(pNdisPacket,&pNdisBuffer);
                }
                NdisDprFreePacket(pNdisPacket);
                */
                
                
                NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
                DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer));

                NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent8,&BufferLen,32);

                DBGPRINT(("<!> NdisQueryBufferSafe :%08X,%d----------\n",pPacketContent8,BufferLen));

                NdisFreeBuffer(pNdisBuffer);

                NdisFreeMemory(pPacketContent8,BufferLen,0);

                NdisDprFreePacket(Packet);
                

            }
        }
        else
        {
            // 若这里编译不过,请直接返回NDIS_STATUS_FAILURE代替
            ADAPT_DECR_PENDING_SENDS(pAdapter);
        }

    }while(FALSE);

    return status;

}



VOID
PtSendComplete(
    IN  NDIS_HANDLE            ProtocolBindingContext,
    IN  PNDIS_PACKET           Packet,
    IN  NDIS_STATUS            Status
    )
/*++

Routine Description:

    Called by NDIS when the miniport below had completed a send. We should
    complete the corresponding upper-edge send this represents.

Arguments:

    ProtocolBindingContext - Points to ADAPT structure
    Packet - Low level packet being completed
    Status - status of send

Return Value:

    None

--*/
{
    PADAPT            pAdapt = (PADAPT)ProtocolBindingContext;
    PNDIS_PACKET      Pkt;
    NDIS_HANDLE       PoolHandle;

    PNDIS_BUFFER pNdisBuffer;
    PUCHAR pPacketContent8;
    UINT BufferLen;

#ifdef NDIS51
    //
    // Packet stacking:
    //
    // Determine if the packet we are completing is the one we allocated. If so, then
    // get the original packet from the reserved area and completed it and free the
    // allocated packet. If this is the packet that was sent down to us, then just
    // complete it
    //
    PoolHandle = NdisGetPoolFromPacket(Packet);
    if (PoolHandle != pAdapt->SendPacketPoolHandle)
    {
        //
        // We had passed down a packet belonging to the protocol above us.
        //
        // DBGPRINT(("PtSendComp: Adapt %p, Stacked Packet %p\n", pAdapt, Packet));

        NdisMSendComplete(pAdapt->MiniportHandle,
                          Packet,
                          Status);
    }
    else
#endif // NDIS51
    {
        PSEND_RSVD        SendRsvd;

        SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
        Pkt = SendRsvd->OriginalPkt;
        if(SendRsvd->Flag == 0x1721)
        {
/*
            NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
            DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer));
            
            while (pNdisBuffer!=NULL)
            {
                NdisFreeMemory((UCHAR *)(pNdisBuffer->StartVa) + pNdisBuffer->ByteOffset,pNdisBuffer->ByteCount,0);            
                NdisFreeBuffer(pNdisBuffer);
                NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
            }

#ifndef WIN9X
            NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
#endif

            NdisDprFreePacket(Packet);

            NdisMSendComplete(pAdapt->MiniportHandle,
                Pkt,
                Status);
                */

            NdisUnchainBufferAtFront(Packet,&pNdisBuffer);
            DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer));

            NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent8,&BufferLen,32);

            DBGPRINT(("<!> NdisQueryBufferSafe :%08X,%d----------\n",pPacketContent8,BufferLen));

            NdisFreeBuffer(pNdisBuffer);

            NdisFreeMemory(pPacketContent8,BufferLen,0);

            NdisDprFreePacket(Packet);

        }
        else
        {


#ifndef WIN9X
            NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
#endif

            NdisDprFreePacket(Packet);

            NdisMSendComplete(pAdapt->MiniportHandle,
                Pkt,
                Status);
        }
    }
    //
    // Decrease the outstanding send count
    //
    ADAPT_DECR_PENDING_SENDS(pAdapt);
}    
yellowzzp
驱动小牛
驱动小牛
  • 注册日期2007-07-16
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1015分
  • 威望131点
  • 贡献值0点
  • 好评度117点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-02-18 17:45
直接用MpSendPackets不就成了。。。。。。。。

你跟他的区别就差距在一个是原始数据,一个是自己填充的
我的代码是这样的。
NdisAllocatePacket(&Status,&MyPacket,pAdapt->SendPacketPoolHandle);
    if(NT_SUCCESS(Status))
    {
        //用上面的包内容 pPacketContent 分配一个新的缓冲区  PacketBuffer
        NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->SendPacketPoolHandle,pPacketContent,PacketLen);
        

        //把这个新分配的缓冲区 连接到 刚分配的新的包上
        NdisChainBufferAtFront( MyPacket, PacketBuffer);
        
        Rsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
        Rsvd ->OriginalPkt = NULL;

        MyPacket->Private.Head->Next=NULL;
        MyPacket->Private.Tail=NULL;
        NdisSetPacketFlags(MyPacket, NDIS_FLAGS_DONT_LOOPBACK);//自己定义的包

跟你的基本一样吧。。

出问题可能就在一些标志位的设置上应该。我也遇到了一定的问题。
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2008-02-20 09:40
xp 2k3 nt5下我过了
vista又出问题了
标志位?
g_force
驱动牛犊
驱动牛犊
  • 注册日期2008-02-19
  • 最后登录2008-03-04
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-02-20 10:08
你说的对 老网卡支持不好 最后是怎么解决的

我的程序跟你差距不大 可是也是对一些卡没作用
liio
驱动小牛
驱动小牛
  • 注册日期2005-12-24
  • 最后登录2022-06-16
  • 粉丝4
  • 关注1
  • 积分24分
  • 威望343点
  • 贡献值0点
  • 好评度171点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2008-02-20 10:42
留个QQ,交流下
g_force
驱动牛犊
驱动牛犊
  • 注册日期2008-02-19
  • 最后登录2008-03-04
  • 粉丝0
  • 关注0
  • 积分100分
  • 威望11点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-02-21 11:15
MSN:gonina@sina.com

QQ:5754888

加哪个都成

1周了,,至今都没解决好一部分卡 不能发包的问题
游客

返回顶部