📄 2005-03-21_protocol.c
字号:
// Since our request is not outstanding anymore
//
pAdapt->OutstandingRequests = FALSE;
//
// Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be.
//
switch(NdisRequest->RequestType)
{
case NdisRequestQueryInformation:
//
// This should not have been passsed to the miniport below us
//
ASSERT(Oid != OID_PNP_QUERY_POWER);
//
// If oid == OID_PNP_CAPABILITIES and query was successsful
// then fill the buffer with the required values
//
if(Oid == OID_PNP_CAPABILITIES && Status == NDIS_STATUS_SUCCESS)
{
MPQueryPNPCapbilities(pAdapt,&Status);
}
*pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
*pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
NdisMQueryInformationComplete(pAdapt->MiniportHandle,
Status);
break;
case NdisRequestSetInformation:
ASSERT( Oid != OID_PNP_SET_POWER);
*pAdapt->BytesReadOrWritten = NdisRequest->DATA.SET_INFORMATION.BytesRead;
*pAdapt->BytesNeeded = NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
NdisMSetInformationComplete(pAdapt->MiniportHandle,
Status);
break;
default:
ASSERT(0);
break;
}
}
VOID
PtStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
/*++
Routine Description:
Status handler for the lower-edge(protocol).
Arguments:
ProtocolBindingContext Pointer to the adapter structure
GeneralStatus Status code
StatusBuffer Status buffer
StatusBufferSize Size of the status buffer
Return Value:
None
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
//
// If we get a status indication before our miniport is initialized, ignore it
// If the SampleIM is not ON, we do not pass on the status indication
//
if(pAdapt->MiniportHandle != NULL &&
pAdapt->MPDeviceState == NdisDeviceStateD0 &&
pAdapt->PTDeviceState == NdisDeviceStateD0 )
{
NdisMIndicateStatus(pAdapt->MiniportHandle,
GeneralStatus,
StatusBuffer,
StatusBufferSize);
}
}
VOID
PtStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
//
// If we get a status indication before our miniport is initialized, ignore it
//
if(pAdapt->MiniportHandle != NULL &&
pAdapt->MPDeviceState == NdisDeviceStateD0 &&
pAdapt->PTDeviceState == NdisDeviceStateD0 )
{
NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
}
}
VOID
PtSendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Interesting case:
We wish to send all sends down the secondary NIC. But when we indicate to the protocol above,
we need to revert back to the original miniport that Protocol wished to use for the Send
Arguments:
Return Value:
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET Pkt;
PRSVD Rsvd;
//
// Returning the Send on the Primary, will point to itself if there is no bundle
//
pAdapt = pAdapt->pPrimaryAdapt;
Rsvd =(PRSVD)(Packet->ProtocolReserved);
Pkt = Rsvd->OriginalPkt;
NdisIMCopySendCompletePerPacketInfo (Pkt, Packet);
NdisDprFreePacket(Packet);
NdisMSendComplete(pAdapt->MiniportHandle,
Pkt,
Status);
}
//+此函数实现将包描符描述的数据包的内容复制到指定的缓存中
void CopyPacket2Buffer(IN PNDIS_PACKET pPacket,IN OUT PUCHAR pBuff,IN OUT PUINT pLength)
{
PNDIS_BUFFER BuffDT;
PUCHAR BuffVA;
UINT BuffLen;
*pLength=0;
BuffLen=0;
NdisQueryPacket(pPacket,NULL,NULL,&BuffDT,NULL);
while(BuffDT!=(PNDIS_BUFFER)NULL)
{
NdisQueryBuffer(BuffDT,&BuffVA,&BuffLen);
NdisMoveMemory(pBuff,BuffVA,BuffLen);
pBuff=pBuff+BuffLen;
*pLength+=BuffLen;
NdisGetNextBuffer(BuffDT,&BuffDT);
}
return;
}
VOID
PtTransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred
)
/*----------------------------------------------------------------------------------
在底层网卡驱动调用介质相关函数(NdisMXxxIndicateReceive)向上指示 数 据 包 时,如 果
LookAheadBuffer 中不包括全部数据,协议驱动会调用 NdisTransferData 来获得其余的数据,
如果 NdisTransferData 返回PENDING,则这个函数会在传输完成后自动被调用。
由于在 PtReceive 中没有采用介质相关函数(NdisMXxxIndicateReceive)向上指示数据包,而
是用 NdisMIndicateReceivePacket,所以上层协议(tcp/ip等)不会调用 NdisTransferData,
因此这个函数不会被自动调用。
----------------------------------------------------------------------------------*/
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
PUCHAR pPacketContent;
PRSVD Rsvd;
UINT OffsetSize, Result, PacketLen;
PNDIS_BUFFER pPacketBuffer;
PNDIS_PACKET pBakPacket;
PNDIS_BUFFER pBakBuffer;
PUCHAR pBakContent;
UINT BufferLen;
UINT flag = 1;
DbgPrint(("In PtTransferDataComplete\n"));
//
// Returning the Send on the Primary, will point to itself if there is no LBFO
//
pAdapt = pAdapt->pPrimaryAdapt;
Rsvd = (PRSVD)(Packet->MiniportReserved);
// pBakPacket 里是 HeaderBuffer + LookAheadBuffer 的内容。
pBakPacket = (PNDIS_PACKET)(Rsvd->OriginalPkt);
if(pAdapt->MiniportHandle)
{
if(pBakPacket == NULL)
NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred);
else
{
Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax);
CopyPacket2Buffer(pBakPacket, pPacketContent, &OffsetSize);
CopyPacket2Buffer(Packet, pPacketContent+OffsetSize, &PacketLen);
// }
if (ICMP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 1)
{
flag = 0;
}
}
else {}
PacketLen += OffsetSize;
// 释放包描述符pBakPacket、缓冲描述符pBakBuffer、内存pBakContent。
NdisUnchainBufferAtFront(pBakPacket, &pBakBuffer);
NdisQueryBufferSafe(pBakBuffer, &pBakContent, &BufferLen, 32);
NdisFreeBuffer(pBakBuffer);
NdisFreeMemory(pBakContent, BUFFER_SIZE, 0);
NdisFreePacket(pBakPacket);
memset(Packet->MiniportReserved, 0, sizeof(Packet->MiniportReserved));
NdisUnchainBufferAtFront(Packet, &pPacketBuffer);
NdisQueryBufferSafe(pPacketBuffer, &pBakContent, &BufferLen, 32);
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pBakContent, BUFFER_SIZE, 0);
if(!flag)
{
// 释放资源并返回
NdisFreePacket(Packet);
return;
}
NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketLen);
NdisChainBufferAtFront(Packet, pPacketBuffer);
Packet->Private.Head->Next=NULL;
Packet->Private.Tail=NULL;
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
// 向上层协议驱动指示数据包,防真网卡行为。
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &Packet, 1);
if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING)
{
MPReturnPacket((NDIS_HANDLE)pAdapt, Packet);
}
}
}
return;
}
NDIS_STATUS
PtReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer, // 包头
IN UINT HeaderBufferSize, // 包头大小,以太网环境下为14
IN PVOID LookAheadBuffer, // 前视缓冲
IN UINT LookAheadBufferSize, // 前视缓冲区大小
IN UINT PacketSize // 数据包总大小(不包括包头)
)
/*-----------------------------------------------------------------------------------
ProtocolReceive这个函数是在低层面向无连接的NIC驱动程序调用NdisMXxxIndicateReceive 函
数向上Indicate数据包时被 NDIS 调 用 的。 同 时 传 递 了 一 个 LookAheadBuffer,但 这
个LookAheadBuffer 里 面 可 能 不 是 数 据 包 的 全 部 内 容, 如 果 不 是 的 话
(LookAheadBufferSize < PacketSize)则需要调用NdisTransferData来获得这个数据包其余的内
容,NdisTransferData只是传递在LookaheadBuffer中没有出现的数据内容, 不是传递整个数据
包。
-----------------------------------------------------------------------------------*/
{
PADAPT OutAdapt, pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPacket, Packet, MyPacket1;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNDIS_BUFFER pPacketBuffer, pBakBuffer;
PUCHAR pPacketContent, pBakContent;
UINT PacketLen;
UINT OffsetSize;
UINT BytesTransferred;
PRSVD Rsvd = NULL;
PVOID MediaSpecificInfo = NULL;
ULONG MediaSpecificSize= 0;
DBGPRINT(("In PtReceive\n"));
if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else do
{
// We should not be getting Receives on a Secondary, this is just specific to our LBFO driver
if(pAdapt->isSecondary)
{
DbgPrint("PASSTHRU GETTING RECIEVES ON SECONDARY\n");
ASSERT(0);
}
/* 注释掉,不采用这种方法取得数据包。
// 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,
&MyPacket,
pAdapt->RecvPacketPoolHandle);
if(Status == NDIS_STATUS_SUCCESS)
{
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->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(MyPacket, NDIS_GET_ORIGINAL_PACKET(Packet));
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);
//
// Set Packet Flags
//
NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);
//
// Make sure the status is set to NDIS_STATUS_RESOURCES.
//
NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);
ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
NdisDprFreePacket(MyPacket);
break;
}
}
// Fall through if the miniport below us has either not indicated a packet or we could not
// allocate one
*/
if(FALSE){}
else if(PacketSize <= LookAheadBufferSize) // 如果 LookAheadBuffer 中包含了全部数据
{
// 分配内存
Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint("PTReceive:NdisAllocateMemory Failed\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent == NULL)
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
// 将包头和 LookAheadBuffer 复制到新分配的内存中
NdisZeroMemory(pPacketContent, BUFFER_SIZE);
NdisMoveMemory(pPacketContent, HeaderBuffer, HeaderBufferSize);
NdisMoveMemory(pPacketContent+ HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);
PacketLen = PacketSize+HeaderBufferSize;
//规则判断
if (ICMP == 1)
{
if(((char *)pPacketContent)[12] == 8 &&
((char *)pPacketContent)[13] == 0 &&
((char *)pPacketContent)[23] == 1)
{
DbgPrint("ICMP被拦截!\n");
NdisFreeMemory(pPacketContent, 2000, 0);
return NDIS_STATUS_NOT_ACCEPTED;
}
}
else {}
// 在包池中分配包描述符
NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);
if(Status == NDIS_STATUS_SUCCESS)
{
// 在缓冲池中分配缓冲描述符,将包描述符与缓冲描述符关联。
NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketLen);
NdisChainBufferAtFront(MyPacket, pPacketBuffer);
MyPacket->Private.Head->Next = NULL;
MyPacket->Private.Tail = NULL;
Rsvd=(PRSVD)(MyPacket->MiniportReserved);
Rsvd->OriginalPkt = NULL;
NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);
// 向上层协议驱动指示数据包,防真网卡行为。
NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);
if(NDIS_GET_PACKET_STATUS(MyPacket) != NDIS_STATUS_PENDING)
{
DBGPRINT(("In PtReceive And Free Memory\n"));
NdisFreeBuffer(pPacketBuffer);
NdisFreeMemory(pPacketContent, BUFFER_SIZE, 0);
NdisDprFreePacket(MyPacket);
}
}
break;
}
else // 如果 LookAheadBuffer 中没有包含全部数据
{
// 分配内存 pPacketContent,存放要传输的除 LookAheadBuffer 之外的数据。
Status = NdisAllocateMemory(&pPacketContent, BUFFER_SIZE, 0, HighestAcceptableMax);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pPacketContent==NULL)
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
NdisZeroMemory(pPacketContent,BUFFER_SIZE);
// 分配包描述符 MyPacket。
NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);
// 分配内存 pBakContent,存放HeaderBuffer + LookAheadBuffer。
Status = NdisAllocateMemory(&pBakContent, BUFFER_SIZE, 0, HighestAcceptableMax);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint("PtReceive:NdisAllocateMemory Failed.\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
if(pBakContent == NULL)
{
DbgPrint("PTReceive:pPacketContent==NULL\n");
return(NDIS_STATUS_NOT_ACCEPTED);
}
// 将 HeaderBuffer + LookAheadBuffer 复制到 pBakContent 指向的内存中。
NdisZeroMemory(pBakContent, BUFFER_SIZE);
NdisMoveMemory(pBakContent, HeaderBuffer, HeaderBufferSize);
NdisMoveMemory(pBakContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize);
PacketLen = HeaderBufferSize + PacketSize;
// 为要传输的除 LookAheadBuffer 之外的数据分配缓冲描述符(该缓冲描述符与 pPacketContent 指向的内存关联)。
NdisAllocateBuffer(&Status, &pPacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent, PacketSize-LookAheadBufferSize);
// 关联包描述符 MyPacket 与缓冲描述符 pPacketBuffer。
NdisChainBufferAtFront(MyPacket, pPacketBuffer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -