wqtao
驱动牛犊
驱动牛犊
  • 注册日期2001-09-03
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3803回复:17

斑竹:在passthru里面如何转发包?

楼主#
更多 发布于:2001-10-09 18:12
我正在用passthru做两个网卡之间住转发数据,主要是在ptreceive
里面收到包后转发到另一个网卡上去,(用NdisSend)但出错,系统
兰屏,错误是DRIVER_IRQL_NOT_LESS_OR_EQUAL
我现在贴出我的代码,恳请帮助:
NDIS_STATUS
PtReceive(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  NDIS_HANDLE MacReceiveContext,
IN  PVOID HeaderBuffer,
IN  UINT HeaderBufferSize,
IN  PVOID LookAheadBuffer,
IN  UINT LookAheadBufferSize,
IN  UINT PacketSize
)
/*++

Routine Description:
LBFO - need to use primary for all receives

Arguments:


Return Value:

--*/
{
PADAPT OutgoingAdapt, pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPkt,Packet;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
        PUCHAR          pEnetAddrDest;
        UINT            nDataSize;
        PNDIS_BUFFER    pNdisBuffer;
        PEnetHeader     pEnetHeader;
        PRSVD           Rsvd;
        PVOID           MediaSpecificInfo=NULL;
        ULONG           MediaSpecificInfoSize=0;
        
        
      
if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else do
{

//
// If this was indicated by the miniport below as a packet, then get that packet pointer and indicate
// it as a packet as well(with appropriate status). This way the OOB stuff is accessible to the
// transport above us.
//
Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
if(Packet != NULL)
{
//
// Get a packet off the pool and indicate that up
//
NdisDprAllocatePacket(&Status,
                      &MyPkt,
      pAdapt->RecvPacketPoolHandle);

if(Status == NDIS_STATUS_SUCCESS)
{        

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

 //
 // Get the original packet(it could be the same packet as one received or a different one
 // based on # of layered MPs) and set it on the indicated packet so the OOB stuff is visible
 // correctly at the top.
 //
 NDIS_SET_ORIGINAL_PACKET(MyPkt, NDIS_GET_ORIGINAL_PACKET(Packet));
 NDIS_SET_PACKET_HEADER_SIZE(MyPkt, HeaderBufferSize);

 //
 // Set Packet Flags
 //
 NdisGetPacketFlags(MyPkt) = NdisGetPacketFlags(Packet);

 //
 // Make sure the status is set to NDIS_STATUS_RESOURCES.
 //
 NDIS_SET_PACKET_STATUS(MyPkt, NDIS_STATUS_RESOURCES);
 //

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

 ASSERT(NDIS_GET_PACKET_STATUS(MyPkt) == NDIS_STATUS_RESOURCES);
 
 NdisDprFreePacket(MyPkt);
 
 break;
}
}


// 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:
       
     {
      nDataSize=HeaderBufferSize+LookAheadBufferSize;
     
     
      pEnetAddrDest=((PUCHAR)HeaderBuffer);
     
     
       
        if ( pEnetAddrDest)
        {      
        DBGPRINT("Ethernet packet received.\n");
       
       
       
             if ( ETH_IS_BROADCAST(pEnetAddrDest))
             {
 DBGPRINT("Broadcast packet,dropping it.\n");
 
 return ( NDIS_STATUS_SUCCESS);
     }
     else
     {  
      pEnetHeader=(UNALIGNED EnetHeader*)HeaderBuffer;
      DbgPrint("Enet Dest Addr: 0x%2x-%2x-%2x-%2x-%2x-%2x\n",
                               pEnetHeader->EH_Dest.EA_Addr[0],
                               pEnetHeader->EH_Dest.EA_Addr[1],
                               pEnetHeader->EH_Dest.EA_Addr[2],
                               pEnetHeader->EH_Dest.EA_Addr[3],
                               pEnetHeader->EH_Dest.EA_Addr[4],
                               pEnetHeader->EH_Dest.EA_Addr[5]);
   
     }      
       }
       
        //Forward the packet.
      OutgoingAdapt=pAdapt->Next;

      if (OutgoingAdapt==NULL)
      {
      OutgoingAdapt=pAdaptList;

DBGPRINT("Forward the packet in the first adapt\n");
}

else
{
DBGPRINT("Forward the packet in the second Adapt!\n")
}

NdisAllocatePacket(
&Status,
&Packet,
pAdapt->RecvPacketPoolHandle);



NdisAllocateBuffer(
&Status,
&pNdisBuffer,
pAdapt->BufferPool,
Packet->ProtocolReserved,
nDataSize);

NdisChainBufferAtFront(
Packet,
pNdisBuffer);

// Header Buffer to the Packet
NdisMoveMemory(
Packet->ProtocolReserved,
HeaderBuffer,
HeaderBufferSize
);
NdisMoveMemory(
&Packet->ProtocolReserved[HeaderBufferSize],
LookAheadBuffer,
LookAheadBufferSize);
Packet->Private.TotalLength=nDataSize;

if(IsIMDeviceStateOn(OutgoingAdapt)==FALSE)
{
return NDIS_STATUS_FAILURE;
}

NdisAllocatePacket(
            &Status,
            &MyPkt,
            OutgoingAdapt->SendPacketPoolHandle);
if(Status==NDIS_STATUS_SUCCESS)
{  
  PNDIS_PACKET_EXTENSION Old,New;
 
    Rsvd=(PRSVD)(MyPkt->ProtocolReserved);
  Rsvd->OriginalPkt=Packet;
  MyPkt->Private.Head=Packet->Private.Head;
  MyPkt->Private.Tail=Packet->Private.Tail;
 
  NdisSetPacketFlags(MyPkt,NDIS_FLAGS_DONT_LOOPBACK);
 
  NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPkt),
                 NDIS_OOB_DATA_FROM_PACKET(Packet),
                 sizeof(NDIS_PACKET_OOB_DATA));
  NdisIMCopySendPerPacketInfo(MyPkt,Packet);
  NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
                                     &MediaSpecificInfo,
                                     &MediaSpecificInfoSize);
  if(MediaSpecificInfo||MediaSpecificInfoSize)
  {
  NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPkt,
                                     MediaSpecificInfo,
                                     MediaSpecificInfoSize);
  DBGPRINT("MEDIA INFO SET.\n");
  }  
 
                                   
 
  DBGPRINT("sending...\n");
 
 
  /*NdisSend(&Status,
           OutgoingAdapt->BindingHandle,
           MyPkt);*/
  if(Status!=NDIS_STATUS_PENDING)
  {
  NdisIMCopySendCompletePerPacketInfo(Packet,MyPkt);
  NdisFreePacket(MyPkt);
  DBGPRINT("send completed.\n");
  }
 
  else
 
  {
  return ( Status);
  }
                 

}


       





   
/*NdisMEthIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);*/
break;
}

NdisMTrIndicateReceive(pAdapt->MiniportHandle,
MacReceiveContext,
HeaderBuffer,
HeaderBufferSize,
LookAheadBuffer,
LookAheadBufferSize,
PacketSize);
break;
 

 case NdisMediumFddi:
NdisMFddiIndicateReceive(pAdapt->MiniportHandle,
 MacReceiveContext,
 HeaderBuffer,
 HeaderBufferSize,
 LookAheadBuffer,
 LookAheadBufferSize,
 PacketSize);
break;

 default:
ASSERT(0);
break;
}

} while(FALSE);

return Status;
}


最新喜欢:

wingmanwingma... temptemptempte... jzyhummeljzyhum...
WY.lslrt
驱动牛犊
驱动牛犊
  • 注册日期2004-07-30
  • 最后登录2009-10-27
  • 粉丝0
  • 关注0
  • 积分116分
  • 威望15点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-09-20 10:02
关注
---传说中的分割线--------
darkme
驱动牛犊
驱动牛犊
  • 注册日期2004-07-17
  • 最后登录2006-03-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-09-07 20:26
请问这个问题的最终解决方法是怎样的?
论坛里相关的讨论不少,可是一直没有给出最后的解答。
或许有很多种解答吧:)
继续关注,并进行调试。。。。
liusz
驱动牛犊
驱动牛犊
  • 注册日期2004-03-16
  • 最后登录2018-05-26
  • 粉丝0
  • 关注0
  • 积分29分
  • 威望43点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-04-23 10:13

高深  实用   关注

flyhobo
驱动小牛
驱动小牛
  • 注册日期2004-03-05
  • 最后登录2005-05-18
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-21 21:52
关注
好好过日子
chen001
驱动小牛
驱动小牛
  • 注册日期2001-12-24
  • 最后登录2005-05-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2001-12-28 09:40
我对这个问题也比较感兴趣,如有消息请通知我!谢谢!
???
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-10-12 12:17
消费了这个包(consume??)
是不是高消费??
hoho
111
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2001-10-11 16:52
ptreceive里面得到的数据,你必须先分配一块内存,
拷贝这些数据,然后转发,如果ndissend不是pending,
那么你当然可以释放你自己分配的内存和相关的packet/buffer,
否则在ptsendcomplete释放。

如果你要这个包继续给ip,那么你还要indicatepacket,
如果不要,直接返回nt_success,表示你已经消费了这个包。
不再回忆从前,我已经生活在幸福当中。
wqtao
驱动牛犊
驱动牛犊
  • 注册日期2001-09-03
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2001-10-11 11:58
如果NdisSend返回不为Pending,直接再PtReceive里面释放,否
则在PtSendComplete里面释放。不知是否正确?
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
9楼#
发布于:2001-10-10 19:54
下面这是你的代码,汉字的注释是我的理解。
NdisAllocatePacket(
&Status,
&Packet,
pAdapt->RecvPacketPoolHandle);

//你分配了一个ndis_packet结构

NdisAllocateBuffer(
&Status,
&pNdisBuffer,
pAdapt->BufferPool,
Packet->ProtocolReserved,
nDataSize);

//你分配了一个ndis_buffer结构,
//此外,你指定这个buffer结构的内存
//为packet->protocolreserved
//但是未初始化的packet的这个值
//到底指向何处?我建议你看看
//protocolreserved的定义。



NdisChainBufferAtFront(
Packet,
pNdisBuffer);
//这行代码是不会出错的。

// Header Buffer to the Packet
NdisMoveMemory(
Packet->ProtocolReserved,
HeaderBuffer,
HeaderBufferSize
);
我相信这行代码会导致访问未分配的内存
从而引起错误。


NdisMoveMemory(
&Packet->ProtocolReserved[HeaderBufferSize],
LookAheadBuffer,
LookAheadBufferSize);
Packet->Private.TotalLength=nDataSize;

你应该先调用
Status = NdisAllocateMemory(
&pPacketContent,
2000,
0,
HighestAcceptableAddress);
分配一个2k的缓冲区,然后判断是否应该调用transferdata,
总之得到所有数据之后,然后把这些数据拷贝到pPacketContent,
然后才是allcatebuffer,最后才是NdisChainBufferAtFront。
此外,我真是没有搞懂,你在后面分配一个mypacket到底是
干什么的,而且还把packet的oob拷贝到mypacket,这个packet
是你自己构造的,有没有oob数据你自己难道不知道吗?

总之,我的感觉是你的代码让我深度困惑和不解。

分配的packet和mypacket你可想到应该在那里释放吗?
内核内存泄漏可是很可怕的事情。
不再回忆从前,我已经生活在幸福当中。
wqtao
驱动牛犊
驱动牛犊
  • 注册日期2001-09-03
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2001-10-10 19:30
就是将headerbuffer和lookaheadbuffer里面的数据考到packet里面
packet->protocolreserved是packet的 buffer的vitualaddress.
我很急,希望斑竹不吝赐教!!
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
11楼#
发布于:2001-10-10 19:12
// Header Buffer to the Packet
NdisMoveMemory(
Packet->ProtocolReserved,
HeaderBuffer,
HeaderBufferSize
);
NdisMoveMemory(
&Packet->ProtocolReserved[HeaderBufferSize],
LookAheadBuffer,
LookAheadBufferSize);
Packet->Private.TotalLength=nDataSize;

这段代码是什么意思?
不再回忆从前,我已经生活在幸福当中。
wqtao
驱动牛犊
驱动牛犊
  • 注册日期2001-09-03
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2001-10-10 18:15
 我的网卡是802。3,packet返回为空,程序流程就转到case语句了,更本不会再使用packet了。 我是在case NdisMedium802_3里面做转发的,
分配了一个packet,并将数据从Headerbuffer和lookAheadBuffer里面
拷到packet里面的,然后转发。
希望不吝赐教!!十分感谢!!
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
13楼#
发布于:2001-10-10 14:22


case NdisMedium802_5:

毫无关系,我想你的网卡不至于是TOKEN_RING的吧?
这种网卡和网络环境我从来就没有见到过。
不再回忆从前,我已经生活在幸福当中。
saki
驱动牛犊
驱动牛犊
  • 注册日期2001-09-17
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2001-10-10 14:01
通过和passthru代码仔细比较,发现你的代码
掉了
 case NdisMedium802_5:
这一行代码,你仔细看一下是不是这里出了问题。

saki


海浪是我的理想
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
15楼#
发布于:2001-10-10 12:30
你的代码发生错误的地方并不是ndissend这一行吧?
似乎在此之前,你使用packet就不正确了。
packet返回null,不知道为什么你还要使用packet,
而且又继续分配了一个mypacket,而且还拷贝oob数据
等等。其实如果返回null,那么就意味着这些数据根本
就没有oob data。你只要分配一个mypacket,然后
把这些数据拷贝到mypacket里面去就行了。
另外,你还需要判断包是否完整,还要调用transferdata。
不再回忆从前,我已经生活在幸福当中。
wqtao
驱动牛犊
驱动牛犊
  • 注册日期2001-09-03
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2001-10-10 08:35
不是这样的,PtReceive里面的NdisgetRecievedPacket返回为空,
即NdisMIndicateReceivePacket不会起作用的,我是从lookaheadbuffer和headerbuffer自己组包后再发出去的。再次恳请帮助!!
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
17楼#
发布于:2001-10-09 19:35
我耐着性子大致看了看你的代码。
你的错误似乎是因为引用了非法内存。
原因在于你把数据包通过NDISIndicatepacket
交给了上层,然后再把这个数据包转发出去,
可是这个内存交给上层之后就被释放了,你
转发的指针是个空指针,当然要出错。


不再回忆从前,我已经生活在幸福当中。
游客

返回顶部