📄 cpgpnetfilteradapter.cpp
字号:
SentPackets++;
DBG_LEAVE(status);
return status;
}
NDIS_STATUS CPGPnetFilterAdapter::SendCfgPacket(PGPnetPacket *pgpnetPacket)
{
DBG_FUNC("CPGPnetFilterAdapter::SendCfgPacket")
NDIS_STATUS status;
DBG_ENTER();
PacketEnqueue(&sent_cfgpacket_list, pgpnetPacket);
ProtocolSendRequest(&status,
NdisBindingHandleToRealAdapter,
pgpnetPacket->xformPacket);
if (status != NDIS_STATUS_PENDING)
{
pgpnetPacket = PacketRemoveByXformPacket(&sent_cfgpacket_list, pgpnetPacket->xformPacket);
FreePGPnetPacket(pgpnetPacket);
}
SentPackets++;
DBG_LEAVE(status);
return status;
}
NDIS_STATUS CPGPnetFilterAdapter::SendPacket(PNDIS_PACKET Packet, PGPUserValue userValue, PGPBoolean IsCfgPacket)
{
DBG_FUNC("CPGPnetFilterAdapter::SendPacket")
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PGPnetPacket* pgpnetPacket;
PGPnetPacketStatus packetStatus;
PGPnetPMStatus pmStatus;
PGPnetPacketHead** packet_head_list;
DBG_ENTER();
if (!DeviceOn())
{
status = NDIS_STATUS_FAILURE;
DBG_LEAVE(status);
return status;
}
if (IsCfgPacket)
packet_head_list = &outgoing_cfg_packet_head_list;
else
packet_head_list = &outgoing_local_packet_head_list;
CPGPnetFilterDriver::GetCurrentDriver()->activeFilterAdapter = this;
do
{
pgpnetPacket = AllocatePGPnetPacket();
if (pgpnetPacket == NULL)
{
status = NDIS_STATUS_RESOURCES;
break;
}
#ifndef NDIS40_MINIPORT
pgpnetPacket->Binding = (BindingContext*)userValue;
#else
pgpnetPacket->SendFlag = *(PUINT)userValue;
#endif
pgpnetPacket->srcPacket = Packet;
PGPCopyPacketToBlock(pgpnetPacket->srcPacket, pgpnetPacket->srcBlock, &pgpnetPacket->srcBlockLen);
packetStatus = PGPnetFilterPacketCheck(pgpnetPacket, FALSE);
switch (packetStatus)
{
case PacketDrop:
FreePGPnetPacket(pgpnetPacket);
status = NDIS_STATUS_NOT_ACCEPTED;
break;
case PacketPassthrough:
DoCopyTransform(pgpnetPacket);
if (IsCfgPacket)
status = SendCfgPacket(pgpnetPacket);
else
status = SendPacket(pgpnetPacket);
break;
case PacketEncrypt:
ASSERT(0);
break;
case PacketFurtherCheck:
pgpnetPacket->pSrcIPsecBuffer->data = pgpnetPacket->srcBlock + ETHER_HEADER_SIZE;
pgpnetPacket->pSrcIPsecBuffer->dataSize = pgpnetPacket->srcBlockLen - ETHER_HEADER_SIZE;
pgpnetPacket->ethernetAddr = pgpnetPacket->srcBlock;
pgpnetPacket->lastSrcBlock = TRUE;
pgpnetPacket->lastXformBlock = TRUE;
pgpnetPacket->firstSrcBlock = TRUE;
pgpnetPacket->firstXformBlock = TRUE;
pgpnetPacket->defaultAdapterMTU = MaximumFrameSize;
pmStatus = PGPnetHandleOutgoingPacket(PGPnetDriver->PolicyManagerHandle, &pgpnetPacket);
switch (pmStatus) {
case kPGPNetPMPacketSent:
PGPnetAdjustXformPackets(pgpnetPacket);
status = SendPackets(pgpnetPacket, FALSE /* not Cfg */);
break;
case kPGPNetPMPacketWaiting:
case kPGPNetPMPacketDrop:
PGPNdisPacketFreeList(pgpnetPacket);
status = NDIS_STATUS_SUCCESS;
break;
case kPGPNetPMPacketClear:
DoCopyTransforms(pgpnetPacket);
status = SendPackets(pgpnetPacket, IsCfgPacket);
break;
case kPGPNetPMPacketForget:
status = NDIS_STATUS_SUCCESS;
break;
case kPGPNetPMPacketCfg:
PGPnetAdjustXformPackets(pgpnetPacket);
DoCfgEthernetTransform(pgpnetPacket);
status = SendPackets(pgpnetPacket, TRUE /* Cfg */);
break;
default:
ASSERT(0);
}
break;
default:
ASSERT(0);
}
} while (0);
DBG_LEAVE(status);
return status;
}
//#define SEND_OUT_OF_ORDER_PACKETS
NDIS_STATUS CPGPnetFilterAdapter::SendPackets(
PGPnetPacket *pgpNetPacket,
PGPBoolean bIsCfgPacket)
{
DBG_FUNC("CPGPnetFilterAdapter::SendPackets")
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
NDIS_STATUS returnStatus = NDIS_STATUS_SUCCESS;
PGPnetPacket *packet, *next;
PGPnetPacket** packet_list;
DBG_ENTER();
if (bIsCfgPacket)
{
packet_list = &outgoing_multiple_cfgpacket_list;
}
else
{
packet_list = &outgoing_multiple_ipsecpacket_list;
}
// Get Information from the first packet.
packet = pgpNetPacket;
#ifdef SEND_OUT_OF_ORDER_PACKETS
// skip to last packet
while (packet->link != NULL && packet->link->xformBlockLen > 0) {
packet = packet->link;
}
// send out the last packet in the chain first
if (packet) {
PacketEnqueue(packet_list, packet);
NdisSend(&status, NdisBindingHandleToRealAdapter, packet->xformPacket);
if (status == NDIS_STATUS_PENDING)
{
//status = NDIS_STATUS_SUCCESS;
}
else
{
packet = PacketRemoveByXformPacket(packet_list, packet->xformPacket);
FreePGPnetPacket(packet);
}
if (packet->lastSrcBlock)
returnStatus = status;
}
packet = packetHead->link;
#endif
while (packet != NULL)
{
#ifdef SEND_OUT_OF_ORDER_PACKETS
if (packet->lastSrcBlock) // we already sent the last one
break;
#endif
next = packet->link;
if (packet->xformBlockLen == 0) {
FreePGPnetPacket(packet);
break;
}
PacketEnqueue(packet_list, packet);
ProtocolSendRequest(&status, NdisBindingHandleToRealAdapter, packet->xformPacket);
if (status == NDIS_STATUS_PENDING)
{
//status = NDIS_STATUS_SUCCESS;
}
else
{
packet = PacketRemoveByXformPacket(packet_list, packet->xformPacket);
FreePGPnetPacket(packet);
}
#ifdef SEND_OUT_OF_ORDER_PACKETS
if (next->lastSrcBlock)
#else
if (packet->lastSrcBlock)
#endif
returnStatus = status;
packet = next;
}
SentPackets++;
DBG_LEAVE(returnStatus);
return returnStatus;
}
VOID CPGPnetFilterAdapter::FragmentPacket(PGPnetPacketHead* packetHead, PGPBoolean incoming)
{
DBG_FUNC("CPGPnetFilterAdapter::FragmentPacket")
USHORT IPDataTotalLength;
UCHAR ip_prot; // Should always be 0x32?
USHORT offset;
USHORT ip_len;
PGPnetPacket* packet;
PGPnetPacket* next;
PIP_HEADER first_ip_hdr;
PIP_HEADER ip_hdr;
PUCHAR first_xformBlock;
PUCHAR first_srcBlock;
PGPBoolean DF = FALSE;
DBG_ENTER();
packet = packetHead->link;
ASSERT(packet != NULL);
first_srcBlock = packet->srcBlock;
first_xformBlock = packet->xformBlock;
first_ip_hdr = (PIP_HEADER)((UCHAR*)packet->xformBlock + ETHER_HEADER_SIZE);
IPDataTotalLength = htons(first_ip_hdr->ip_len) - IP_HEADER_SIZE;
ip_prot = first_ip_hdr->ip_prot;
NdisMoveMemory(first_xformBlock /*dest*/, packet->srcBlock, ETHER_HEADER_SIZE);
offset = 0;
DF = IP_DONT_FRAGMENT(first_ip_hdr->ip_foff);
if ( (DF) && IP_MORE_FRAGMENT(first_ip_hdr->ip_foff) && !incoming)
{
DoMTUTransform(packet);
PGPNdisPacketFreeList(packet->link);
packet->link = NULL;
DBG_LEAVE(0);
return;
}
DF = FALSE;
while (packet != NULL)
{
packet->HeaderBuffer = packet->xformBlock;
packet->HeaderBufferSize = ETHER_HEADER_SIZE;
NdisMoveMemory(packet->xformBlock /*dest*/, first_xformBlock, ETHER_HEADER_SIZE);
packet->LookaheadBuffer = packet->xformBlock + ETHER_HEADER_SIZE;
ip_hdr = (PIP_HEADER)((UCHAR*)packet->xformBlock + ETHER_HEADER_SIZE);
NdisMoveMemory(ip_hdr /*dest*/, first_ip_hdr, IP_HEADER_SIZE);
if ( (packet->srcBlockLen == packet->xformBlockLen) &&
(htons(ip_hdr->ip_len) < 46) &&
(packet->firstSrcBlock) &&
incoming
)
{
ip_hdr->ip_len = ip_hdr->ip_len;
}
else if ( (packet->srcBlockLen == packet->xformBlockLen) &&
(packet->firstSrcBlock) &&
(packet->lastSrcBlock) &&
(packet->lastXformBlock)
)
{
ip_hdr->ip_len = ip_hdr->ip_len;
}
else
ip_hdr->ip_len = htons(packet->xformBlockLen - ETHER_HEADER_SIZE);
ip_hdr->ip_foff = htons(offset >> 3);
if (packet->lastXformBlock)
ip_hdr->ip_foff = ~(IP_MF) & ip_hdr->ip_foff;
else
ip_hdr->ip_foff = IP_MF | ip_hdr->ip_foff;
if (DF)
ip_hdr->ip_foff = IP_DF | ip_hdr->ip_foff;
ip_hdr->ip_prot = ip_prot;
ip_hdr->ip_chksum = 0;
ip_hdr->ip_chksum = HeaderChecksum((USHORT*)ip_hdr, TYPE_IP);
if (packet->firstSrcBlock)
packet->xformBlockLen += 0;//ETHER_HEADER_SIZE;
else
packet->xformBlockLen += 0; //ETHER_HEADER_SIZE + IP_HEADER_SIZE;
PGPnetAdjustXformPacket(packet);
ip_len = ntohs(ip_hdr->ip_len);
offset += ip_len - IP_HEADER_SIZE;
if (packet->lastXformBlock)
{
PGPNdisPacketFreeList(packet->link);
next = NULL;
packet->link = NULL;
}
else
next = packet->link;
packet = next;
}
DBG_LEAVE(0);
}
#if XXX
VOID CPGPnetFilterAdapter::PreFragmentPacket(PGPnetPacketHead* packetHead, PGPBoolean incoming)
{
DBG_FUNC("CPGPnetFilterAdapter::PreFragmentPacket")
PGPnetPacket* packet;
PGPnetPacket* next;
PGPnetPacket* extraPacket;
DBG_ENTER();
packet = packetHead->link;
while (packet != NULL)
{
PUCHAR carryFrom;
PUCHAR carryTo;
PUCHAR xformIpBuffer;
PUCHAR xformIpDataBuffer;
next = packet->link;
xformIpBuffer = (UCHAR*)packet->xformBlock + ETHER_HEADER_SIZE;
xformIpDataBuffer = xformIpBuffer + IP_HEADER_SIZE;
if ( (packet->xformBlockLen + packet->Carry - ETHER_HEADER_SIZE) > MaximumIPFragmentSize)
{
// Carry over needed;
// Make sure we can carry it over
if(!next)
{
extraPacket = AllocatePGPnetPacket();
if (extraPacket == NULL)
{
PGPNdisPacketHeadFree(packetHead);
break;
}
else
AppendPGPNdisPacket(packetHead, extraPacket);
next = extraPacket;
}
// Carry over
next->Carry = packet->xformBlockLen + packet->Carry - ETHER_HEADER_SIZE - MaximumIPFragmentSize;
carryFrom = xformIpBuffer + MaximumIPFragmentSize - packet->Carry;
carryTo = next->srcBlock;
NdisMoveMemory(carryTo, carryFrom, next->Carry);
packet->xformBlockLen -= next->Carry;
if ( next->xformBlockLen == 0)
next->xformBlockLen = ETHER_HEADER_SIZE + IP_HEADER_SIZE;
if (packet->lastXformBlock)
{
packet->lastXformBlock = FALSE;
next->lastXformBlock = TRUE;
}
}
if (packet->Carry)
{
// Take carry
carryFrom = xformIpDataBuffer;
carryTo = packet->srcBlock + packet->Carry;
NdisMoveMemory(carryTo, carryFrom, packet->xformBlockLen - (ETHER_HEADER_SIZE + IP_HEADER_SIZE));
carryFrom = packet->srcBlock;
carryTo = xformIpDataBuffer;
NdisMoveMemory(carryTo, carryFrom, packet->Carry + packet->xformBlockLen - (ETHER_HEADER_SIZE + IP_HEADER_SIZE));
packet->xformBlockLen += packet->Carry;
}
if (packet->lastXformBlock)
{
PGPNdisPacketFreeList(packet->link);
next = NULL;
packet->link = NULL;
}
else
next = packet->link;
packet = next;
}
DBG_LEAVE(0);
}
#endif
NDIS_STATUS CPGPnetFilterAdapter::IndicatePacket(PGPnetPacket* pgpnetPacket)
{
DBG_FUNC("CPGPnetFilterAdapter::IndicatePacket")
DBG_ENTER();
PGPUInt32 psize = 0;
if (pgpnetPacket->xformBlockLen) {
pgpnetPacket->HeaderBuffer = pgpnetPacket->xformBlock;
pgpnetPacket->LookaheadBuffer = pgpnetPacket->xformBlock + ETHER_HEADER_SIZE;
psize = pgpnetPacket->xformBlockLen - ETHER_HEADER_SIZE;
} else {
pgpnetPacket->HeaderBuffer = pgpnetPacket->srcBlock;
pgpnetPacket->LookaheadBuffer = pgpnetPacket->srcBlock + ETHER_HEADER_SIZE;
psize = pgpnetPacket->srcBlockLen - ETHER_HEADER_SIZE;
}
if (psize < 60)
psize = 60;
IndicateReceive(this,
(PCHAR)pgpnetPacket->HeaderBuffer,
pgpnetPacket->HeaderBufferSize,
pgpnetPacket->LookaheadBuffer,
psize,
psize);
DBG_LEAVE(0);
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS CPGPnetFilterAdapter::IndicateCfgPacket(PGPnetPacket* pgpnetPacket)
{
DBG_FUNC("CPGPnetFilterAdapter::IndicateCfgPacket")
DBG_ENTER();
PGPUInt32 psize = 0;
pgpnetPacket->HeaderBuffer = pgpnetPacket->xformBlock;
pgpnetPacket->LookaheadBuffer = pgpnetPacket->xformBlock + ETHER_HEADER_SIZE;
psize = pgpnetPacket->xformBlockLen - ETHER_HEADER_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -