csm_529
驱动牛犊
驱动牛犊
  • 注册日期2008-09-03
  • 最后登录2009-04-13
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望27点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2021回复:5

求助:在PtReceivePacket中创建ARP包,调用NdisSend发送,调试时电脑重启……

楼主#
更多 发布于:2008-09-13 00:59
小弟刚刚学习NDIS中间层编程。想利用passthru实现一个在PtReceivePacket中创建ARP包,调用NdisSend发送的程序。看了以前的一些帖子,仿照论坛上前辈的代码自己写了一个,在PtReceivePacket添加了创建包和发送包的代码,在PtSendComplete中添加了处理Pending的代码。但是一调试机器就重启。水平有限实在是改不出来了,只能求各位前辈指点一下了。非常感谢!代码如下:
INT
PtReceivePacket(
    IN NDIS_HANDLE            ProtocolBindingContext,
    IN PNDIS_PACKET           Packet
    )
{
    PADAPT              pAdapt =(PADAPT)ProtocolBindingContext;
    NDIS_STATUS         Status;
    PNDIS_PACKET        MyPacket;
    BOOLEAN             Remaining;

    //////////////////////////////////////////////////////////////////
    PNDIS_PACKET        MyARPPacket;
    PNDIS_BUFFER        MyARPBuffer;
    PUCHAR                MyARPPacketContent;
    PSEND_RSVD            SendRsvd;
    NDIS_PHYSICAL_ADDRESS        HighestAcceptableAddress;
    //////////////////////////////////////////////////////////////////

    if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
    {
          return 0;
    }


    //////////////////////////////////////////////////////////////////
    ////创建一个自己的ARP包发出去
    HighestAcceptableAddress.LowPart = -1;
    HighestAcceptableAddress.HighPart = -1;

    Status = NdisAllocateMemory(&MyARPPacketContent, 60, 0, HighestAcceptableAddress);

    if (Status !=  NDIS_STATUS_SUCCESS)
    {
        return  NDIS_STATUS_FAILURE;
    }
    else//手写一个ARP包
    {
        //目的MAC
        MyARPPacketContent[0] = 0x00;
        MyARPPacketContent[1] = 0x15;
        MyARPPacketContent[2] = 0xF2;
        MyARPPacketContent[3] = 0xC1;
        MyARPPacketContent[4] = 0xB7;
        MyARPPacketContent[5] = 0x26;

        //源MAC
        MyARPPacketContent[6] = 0x00;
        MyARPPacketContent[7] = 0x22;
        MyARPPacketContent[8] = 0x19;
        MyARPPacketContent[9] = 0x0E;
        MyARPPacketContent[10] = 0x2D;
        MyARPPacketContent[11] = 0x1F;

        //协议类型
        MyARPPacketContent[12] = 0x08;
        MyARPPacketContent[13] = 0x06;

        //硬件类型
        MyARPPacketContent[14] = 0x00;
        MyARPPacketContent[15] = 0x01;

        //协议类型
        MyARPPacketContent[16] = 0x08;
        MyARPPacketContent[17] = 0x00;

        //硬件地址长度
        MyARPPacketContent[18] = 0x06;

        //协议地址长度
        MyARPPacketContent[19] = 0x04;

        //操作
        MyARPPacketContent[20] = 0x00;
        MyARPPacketContent[21] = 0x01;

        //发送者硬件地址
        MyARPPacketContent[22] = 0x00;
        MyARPPacketContent[23] = 0x22;
        MyARPPacketContent[24] = 0x19;
        MyARPPacketContent[25] = 0x0E;
        MyARPPacketContent[26] = 0x2D;
        MyARPPacketContent[27] = 0x1F;

        //发送者IP地址
        MyARPPacketContent[28] = 0xc0;
        MyARPPacketContent[29] = 0xa8;
        MyARPPacketContent[30] = 0x00;
        MyARPPacketContent[31] = 0x25;

        //目的硬件地址
        MyARPPacketContent[32] = 0x00;
        MyARPPacketContent[33] = 0x15;
        MyARPPacketContent[34] = 0xF2;
        MyARPPacketContent[35] = 0xC1;
        MyARPPacketContent[36] = 0xB7;
        MyARPPacketContent[37] = 0x26;

        //目的IP地址
        MyARPPacketContent[38] = 0xc0;
        MyARPPacketContent[39] = 0xa8;
        MyARPPacketContent[40] = 0x00;
        MyARPPacketContent[41] = 0x21;

        MyARPPacketContent[42] = 0x00;
        MyARPPacketContent[43] = 0x00;
        MyARPPacketContent[44] = 0x00;
        MyARPPacketContent[45] = 0x00;
        MyARPPacketContent[46] = 0x00;
        MyARPPacketContent[47] = 0x00;
        MyARPPacketContent[48] = 0x00;
        MyARPPacketContent[49] = 0x00;
        MyARPPacketContent[50] = 0x00;
        MyARPPacketContent[51] = 0x00;
        MyARPPacketContent[52] = 0x00;
        MyARPPacketContent[53] = 0x00;
        MyARPPacketContent[54] = 0x00;
        MyARPPacketContent[55] = 0x00;
        MyARPPacketContent[56] = 0x00;
        MyARPPacketContent[57] = 0x00;
        MyARPPacketContent[58] = 0x00;
        MyARPPacketContent[59] = 0x00;
    }

    NdisAllocateBuffer(&Status, &MyARPBuffer, pAdapt->SendPacketPoolHandle, MyARPPacketContent, 60);//分配一个缓冲描述符
    if (Status == NDIS_STATUS_FAILURE)
    {
        NdisFreeMemory(MyARPPacketContent, 60, 0);
        return NDIS_STATUS_FAILURE;
    }
    NdisAllocatePacket(&Status, &MyARPPacket, pAdapt->SendPacketPoolHandle);//分配一个包描述符
    if (Status == NDIS_STATUS_FAILURE)
    {
        NdisFreeMemory(MyARPPacketContent, 60, 0);
        return NDIS_STATUS_FAILURE;
    }
    NdisChainBufferAtFront(MyARPPacket, MyARPBuffer);//将缓冲描述符链入包描述符
    MyARPPacket->Private.Head->Next = NULL;
    MyARPPacket->Private.Tail = NULL;

    SendRsvd = (PSEND_RSVD)(MyARPPacket->ProtocolReserved);//设置Reserved
    SendRsvd->OriginalPkt = NULL;

    NdisSetPacketFlags(MyARPPacket, NDIS_FLAGS_DONT_LOOPBACK);

    NdisSend(&Status, pAdapt->BindingHandle, MyARPPacket);//发送

    if (Status != NDIS_STATUS_PENDING)
    {
        NdisUnchainBufferAtFront(MyARPPacket, &MyARPBuffer);//释放包描述符与缓冲描述符的连接
        NdisDprFreePacket(MyARPPacket);//释放包描述符
        NdisFreeBuffer(MyARPBuffer);//释放缓冲描述符
        NdisFreeMemory(MyARPPacketContent, 60, 0);//释放内存
    }
    //////////////////////////////////////////////////////////////////

#ifdef NDIS51
    (VOID)NdisIMGetCurrentPacketStack(Packet, &Remaining);
    if (Remaining)
    {
        Status = NDIS_GET_PACKET_STATUS(Packet);
        NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
        return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
    }
#endif

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

    if (Status == NDIS_STATUS_SUCCESS)
    {
        PRECV_RSVD            RecvRsvd;

        RecvRsvd = (PRECV_RSVD)(MyPacket->MiniportReserved);
        RecvRsvd->OriginalPkt = Packet;

        MyPacket->Private.Head = Packet->Private.Head;
        MyPacket->Private.Tail = Packet->Private.Tail;

        NDIS_SET_ORIGINAL_PACKET(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));

        NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);

        Status = NDIS_GET_PACKET_STATUS(Packet);

        NDIS_SET_PACKET_STATUS(MyPacket, Status);
        NDIS_SET_PACKET_HEADER_SIZE(MyPacket, NDIS_GET_PACKET_HEADER_SIZE(Packet));

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

        if (Status == NDIS_STATUS_RESOURCES)
        {
            NdisDprFreePacket(MyPacket);
        }

        return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
    }
    else
    {
        return(0);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

VOID
PtSendComplete(
    IN  NDIS_HANDLE            ProtocolBindingContext,
    IN  PNDIS_PACKET           Packet,
    IN  NDIS_STATUS            Status
    )
{
    PADAPT            pAdapt = (PADAPT)ProtocolBindingContext;
    PNDIS_PACKET      Pkt;
    NDIS_HANDLE       PoolHandle;

    //////////////////////////////////////////////////////////////////
    PNDIS_BUFFER        MyARPBuffer;
    PVOID                MyARPPacketContent;
    PSEND_RSVD            SendRsvd;
    //////////////////////////////////////////////////////////////////

#ifdef NDIS51
    PoolHandle = NdisGetPoolFromPacket(Packet);
    if (PoolHandle != pAdapt->SendPacketPoolHandle)
    {
        NdisMSendComplete(pAdapt->MiniportHandle,
                          Packet,
                          Status);
    }
    else
#endif // NDIS51
    {
        SendRsvd = (PSEND_RSVD)(Packet->ProtocolReserved);
        Pkt = SendRsvd->OriginalPkt;
#ifndef WIN9X
        NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
#endif
        //////////////////////////////////////////////////////////////////
        ////释放内存
        if (Pkt == NULL)
        {
            NdisQueryPacket(Packet, NULL, NULL, &MyARPBuffer, NULL);//找到第一个缓冲描述符
            NdisQueryBuffer(MyARPBuffer, &MyARPPacketContent, NULL);//找到缓冲描述符的映射的内存地址

            NdisUnchainBufferAtFront(Packet, &MyARPBuffer);//释放包描述符与缓冲描述符的连接
            NdisDprFreePacket(Packet);//释放包描述符
            NdisFreeBuffer(MyARPBuffer);//释放缓冲描述符
            NdisFreeMemory(MyARPPacketContent, 60, 0);//释放内存
        }
        else
        {
            NdisDprFreePacket(Packet);
            NdisMSendComplete(pAdapt->MiniportHandle,
                Pkt,
                Status);
        }
        ///////////////////////////////////////////////////////////////////
    }
    ADAPT_DECR_PENDING_SENDS(pAdapt);
}

祝大家中秋快乐哈!
mister
驱动牛犊
驱动牛犊
  • 注册日期2001-11-25
  • 最后登录2013-02-26
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望26点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-09-13 12:51
#ifndef WIN9X
        NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
#endif

当Pkt为NULL时会出错的。
csm_529
驱动牛犊
驱动牛犊
  • 注册日期2008-09-03
  • 最后登录2009-04-13
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望27点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-09-15 22:14
Re:求助:在PtReceivePacket中创建ARP包,调用NdisSend发送,调试
楼上的大哥:我把那一句屏蔽了还是不行啊。而且我觉得问题好像不是在那儿,我是在xp环境下编译的应该不会走到那一句。谢谢!
king00star
驱动牛犊
驱动牛犊
  • 注册日期2006-08-17
  • 最后登录2014-04-19
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望92点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-09-16 09:49
楼上的大哥:我把那一句屏蔽了还是不行啊。而且我觉得问题好像不是在那儿,我是在xp环境下编译的应该不会走到那一句。谢谢!
==>那是#ifndef   如果没有定义WIN9X
NDISVCBoy
驱动牛犊
驱动牛犊
  • 注册日期2008-10-11
  • 最后登录2008-10-15
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望8点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-10-11 13:58
有两点:
1 NdisAllocateBuffer(&Status, &MyARPBuffer, pAdapt->SendPacketPoolHandle, MyARPPacketContent, 60);//分配一个缓冲描述符 从包池去分配缓冲区描述表?
2 最好不要在接受函数里去发送包
驱网无线,快乐无限
numby
驱动牛犊
驱动牛犊
  • 注册日期2007-03-09
  • 最后登录2010-06-14
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望32点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2008-10-11 22:35
Before calling NdisFreePacket, the driver either must call NdisFreeBuffer as many times as necessary to release all buffer descriptors chained to the packet, or it must call an NdisUnchainBufferAtXxx function as many times as necessary to save all pointers to buffer descriptors.
--from ddk

read above carefully, either...or..., not both, that's the reason I think.
游客

返回顶部