hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2566回复:22

ProtocolReceivePacket求教

楼主#
更多 发布于:2004-05-20 09:30
  各位高手,我对passthru程序进行了修改。我用的是win2000 ddk,希望用ProtocolReceivePacket函数对接收到的封包进行操作。但是我发现这个函数好像没有起作用。
  我在运行中用dbgview查看protocol.c中ProtocolReceivePacket函数的的DBGPRINT输出时,未见任何输出。是不是ProtocolReceivePacket函数没有执行呀?

最新喜欢:

txysptxysp
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-20 09:52
好像是这样的,接收包的时候调用的都是ptreceive,而没有ptreceivepacket。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-20 10:08
8139等新网卡用PtReceivePacket,老式的RTL8029等用PtReceive.就这么简单。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-05-20 10:19
asmsys老兄,我的网卡是realtek rtl8139(A),应该没有问题呀。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-20 10:32
rtl的有点怪,你看看Ptreceive有没有输出就好了,反正总有一个函数被调用的,如果都没有,就是你的程序有问题了。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-05-20 10:44
asmsys老兄,好像Ptrecive真的也没有输出。可能是我的程序有问题。我仍能接收数据可收到的不是对数据包操作后的数据。你认为我最有可能错在哪里呢?你是发送时错了,还是接收时哪里没设好?
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-05-20 11:09
这个很难说,贴点代码看看。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-05-20 11:41
好的,这是PtReceivePacket函数的代码
INT
PtReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET pPacket
)
/*++

Routine Description:

ReceivePacket handler. Called up by the miniport below when it supports NDIS 4.0 style receives.
Re-package the packet and hand it back to NDIS for protocols above us. The re-package part is
important since NDIS uses the WrapperReserved part of the packet for its own book-keeping. Also
the re-packaging works differently when packets flow-up or down. In the up-path(here) the protocol
reserved is owned by the protocol above. We need to use the miniport reserved here.

Arguments:

ProtocolBindingContext Pointer to our adapter structure.
Packet - Pointer to the packet

Return Value:

== 0 -> We are done with the packet
!= 0 -> We will keep the packet and call NdisReturnPackets() this many times when done.
--*/
{
PADAPT     pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS        Status;
PNDIS_PACKET    pMyPacket;
BOOLEAN             Remaining;

    ULONG               MACAddrComp,                  // ja, 17.08.2003.
                        ulEncPayload,
                        ulUnencPayload;
    #define             szPayloadCopy ETH_MAX_PACKET_SIZE
    char                PayloadCopy[szPayloadCopy];
    pEthHdr             pETH;
    PUCHAR              pCurr,
                        pEnd,
                        pUnencPayload = NULL;
    #define             searchFor2   \"0123456789aBcDeF\"
    ULONG const         lnSearchfor = strlen(searchFor2);
    char  const         chSearchfor[] = searchFor2;

    //
    // Drop the packet silently if the upper miniport edge isn\'t initialized or
    // the miniport edge is in low power state
    //
DBGPRINT((\"PtReceivePacket() \\n\"));
    if ((!pAdapt->MiniportHandle) || (pAdapt->MPDeviceState > NdisDeviceStateD0))
    {
 DBGPRINT((\"PtReceivePacket() miniport error \\n\"));
          return 0;
    }

// ja, 17.08.2003.

    GetPktPayload(pPacket,                            // Copy payload
                  PayloadCopy,                        //   to area.
                  szPayloadCopy,                      // Amount of space in area.
                  &ulEncPayload                       // Return number of bytes in packet.
                 );
    DBGPRINT((\"PtReceivePacket() get pketpayload \\n\"));
    pETH = (pEthHdr)PayloadCopy;                      // Point to ethernet header.

    //ETH_COMPARE_NETWORK_ADDRESSES_EQ(pETH->SrcMAC, pAdapt->MACAddress, &MACAddrComp);

    //if (0==MACAddrComp)                               // A loopback?
      //{
       //return 0;                                      // Drop packet.
      //}

    pCurr = PayloadCopy;                              // Point to first byte of data.
    pEnd = pCurr + ulEncPayload - 1;                  // Point to last byte.

    for (                                             // Go through the data.
         ;
         ((ULONG)(1 + pEnd - pCurr)) >=               // At least as many bytes as that sought after?
           lnSearchfor;
         pCurr++
        )
      if (0==memcmp(pCurr, chSearchfor, lnSearchfor)) // A hit?
        {
         Status = PtBuildOrigPkt(                     // Get original, unencapsulated payload.
                                 PayloadCopy,
                                 &pUnencPayload,
                                 &ulUnencPayload
                                );
         DBGPRINT((\"PtReceivePacket() found string \\n\"));
         if (NDIS_STATUS_SUCCESS!=Status)             // A problem?
           {
            DBGPRINT((\"PtReceivePacket():  Status from PtBuildOrigPkt() = 0x%08x\\n\", Status));
            break;
           }        
        
         break;
        }

   // if (NULL==pUnencPayload)                          // Don\'t have unencapsulated payload?
    //{
   //}

    //
    // Get a packet off the pool and indicate that up
    //
    NdisDprAllocatePacket(&Status,
                           &pMyPacket,
                           pAdapt->RecvPacketPoolHandle);

    if (Status == NDIS_STATUS_SUCCESS)
    {
        PRECV_RSVD            RecvRsvd;
        PNDIS_BUFFER          pNewNdisBfr;

        RecvRsvd = (PRECV_RSVD)(pMyPacket->MiniportReserved);
        RecvRsvd->OriginalPkt = pPacket;

        if (NULL!=pUnencPayload)                      // Have unencapsulated payload?
          {
           NdisAllocateBuffer(&Status,                // Build new buffer descriptor.
                              &pNewNdisBfr,
                              pAdapt->hRecvBufferPool,
                              pUnencPayload,
                              ulUnencPayload
                             );

           if (NDIS_STATUS_SUCCESS!=Status)
             {
              DBGPRINT((\"PtReceivePacket() failed to get a buffer, status = 0x%08x\\n\", Status));
              ASSERT(0);

              /* Do something! */
             }

           RecvRsvd->bNewBuffer = TRUE;               // Show new NDIS_BUFFER used.

           NdisChainBufferAtFront(pMyPacket,          // Chain new buffer descriptor to new packet.
                                  pNewNdisBfr
                                 );
          }                                           // End \'if\' found desired packet.
        else
          {
           RecvRsvd->bNewBuffer = FALSE;              // Original NDIS_BUFFER used.

           pMyPacket->Private.Head = pPacket->Private.Head;
           pMyPacket->Private.Tail = pPacket->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 to protocols above us.
        //
        NDIS_SET_ORIGINAL_PACKET(pMyPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));

        //
        // Set Packet Flags
        //
        NdisGetPacketFlags(pMyPacket) = NdisGetPacketFlags(pPacket);

        Status = NDIS_GET_PACKET_STATUS(pPacket);

        NDIS_SET_PACKET_STATUS(pMyPacket, Status);
        NDIS_SET_PACKET_HEADER_SIZE(pMyPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket));

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

        //
        // Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
        // NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
        // it might have changed! Use the value saved in the local variable.
        //
        if (Status == NDIS_STATUS_RESOURCES)
        {
            if (NULL!=pUnencPayload)                  // Have unencapsulated payload?
              {
               NdisFreeBuffer(pNewNdisBfr);           // Recycle buffer descriptor.                              

               NdisFreeMemory(pUnencPayload,          // Recycle memory.
                              ulUnencPayload,
                              0
                             );

               pUnencPayload = NULL;
              }

            //
            // Our ReturnPackets handler will not be called for this packet.
            // We should reclaim it right here.
            //
            NdisDprFreePacket(pMyPacket);
        }

        return((Status != NDIS_STATUS_RESOURCES) ? 1 : 0);
    }                                                 // end \'if\' allocated packet descriptor from pool.
    else
    {
        if (NULL!=pUnencPayload)                      // Have unencapsulated payload?
          NdisFreeMemory(pUnencPayload,               // Recycle memory.
                         ulUnencPayload,
                         0
                        );

        //
        // We are out of packets. Silently drop it.
        //
        return(0);
    }

}
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-05-20 12:16
把DBGPRINT((\"PtReceivePacket() \\n\"));
改成DbgPrint(\"PtReceivePacket() \\n\");试一下。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-05-20 15:25
好像不行,我试了,看不到。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-05-20 16:23
还是asmsys老大说得对,先要确定到底是调用哪个函数!不然改了还是白改,说不定改了半天,它从来就没有光顾过你这个函数:)
我的网卡也是8139的,调用的是ptreceive好像以前在这个论坛上有关于这个的讨论,你可以去搜搜。在我这里从来都没有调用ptreceivepacket这个函数,你直接运行微软的那个passthru就可以确定你的网卡到底是调用哪个函数了。那个程序是没很大的问题的,虽然有点BUG但运行,查看到底是调用的那个函数还是绰绰有余的:),确定了到底是哪个函数调用了以后,就好做相应的修改了,如果你网卡调用的是ptreceive这个函数,不管你的ptreceivepacket函数多么正确,他都是不会进入的:)
还有你大概是在passthru上修改的吧,这里面对DBGPRINT定义为
#define DBGPRINT(Fmt) \\
{ \\
DbgPrint(\"*** XPASSHTRU.SYS ***\"); \\
DbgPrint (Fmt); \\
}
你可以按照asmsys老大说的改为改成DbgPrint(\"PtReceivePacket() \\n\");看的话可能会更明朗一些,但是不改也无妨,因为就只是多了一个DbgPrint(\"*** XPASSHTRU.SYS ***\");不管他就是了
youngyt
驱动牛犊
驱动牛犊
  • 注册日期2003-11-23
  • 最后登录2006-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-05-20 19:40
8139等新网卡用PtReceivePacket,老式的RTL8029等用PtReceive.就这么简单。


其实这个也不一定的,要看MINIPORT是如何上指数据的啦。我的网卡就是8139的,还是只走PtReceive,Modem包一定走PtReceivePacket,因为它是从NDISWAN指上来的。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-05-21 08:58
我先在ptreceive函数中用dbgview发现了输出,是不是表示8139这块网卡走的是ptreceive函数。但是又发现Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);得到的包是空的(null),这是怎么会事呀?
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-05-21 09:48
从本质上讲,PtReceive被调用有两种情况:
1、当下层的miniport调用NdisMXxxIndicate的时候,NDIS总是调用ProtocolReceive函数。
2、这时候底层的miniport有可能资源不足,为了能够让上层驱动程序迅速放弃对数据包控制权,它在每一个数据包的带外数据块中设置status属性为NDIS_STATUS_SOURCE,这样就迫使NDIS转而调用ProtocolReceive函数,强迫IMD拷贝每一个数据包。
当情况2发生时,Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);就不返回空。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-05-21 10:33

看来我的这块网卡不走ptreceivepacket,我想把原来在pareceivepacket函数中的操作改在ptreceive中,可是发现了Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);为空。不知我该怎么操作?
canoe982
驱动牛犊
驱动牛犊
  • 注册日期2003-04-11
  • 最后登录2005-12-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-05-21 10:58
呵呵。我是一个新手,在测试DDK自带的passthru时,也发现了两样的问题,不过,现在我也不知道该怎么做。
独怜幽草涧边生, 上有黄鹂深树鸣。 春潮带雨晚来急, 野渡无人舟自横。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-05-21 11:38
你的分真难挣呀:)
不过我还是要告诉你,你所说的问题这里已经讨论过N次了。为什么什么都问,不自己动手。
hxsyj
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2004-11-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-05-21 19:18
  自己苦苦作不出来才问的,从来都是会者不难。我看论坛原来的贴子,包括按比较包和前视缓冲区的大小的方式操作,我试着调试总是出错。所以才问。希望各位高手能够帮助解答。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-05-21 21:45
如果你不会用softice的话,可以把你认为有错误的代码段的代码一行一行的加上去,直到出现故障为止,这个时候你就应该知道问题出在哪个地方了!这是一种最原始的方法不过比较麻烦,但是很有效!
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-05-21 21:49
ntStatus = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableMax);
if(ntStatus != NDIS_STATUS_SUCCESS)
{
return ntStatus;
}
NdisZeroMemory(pPacketContent,2000);

NdisMoveMemory(
pPacketContent,
HeaderBuffer,
HeaderBufferSize
);
NdisMoveMemory(
pPacketContent+HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize
);
把包拷贝到内存区pPacketContent,然后你想怎么操作都行,不过别忘了,从新封包然后转发出去就可以了
上一页
游客

返回顶部