📄 vpnsupport.c
字号:
PPGPNDIS_REQUEST RequestDequeue(
PVPN_ADAPTER adapter,
PPGPNDIS_REQUEST *reqeust_list)
{
PPGPNDIS_REQUEST request;
NdisAcquireSpinLock(&adapter->general_lock);
if (*reqeust_list == (PPGPNDIS_REQUEST) NULL) {
request = (PPGPNDIS_REQUEST) NULL;
} else {
request = (*reqeust_list)->link;
if (request == *reqeust_list) {
*reqeust_list = (PPGPNDIS_REQUEST) NULL;
} else {
(*reqeust_list)->link = request->link;
}
}
NdisReleaseSpinLock(&adapter->general_lock);
return request;
}
PPGPNDIS_REQUEST RequestRemoveByNdisRequest(
PVPN_ADAPTER adapter,
PPGPNDIS_REQUEST *reqeust_list,
PNDIS_REQUEST packet)
{
PPGPNDIS_REQUEST pgpRequest;
NdisAcquireSpinLock(&adapter->general_lock);
if ( (pgpRequest = *reqeust_list) != NULL )
{
do
{
PPGPNDIS_REQUEST next = pgpRequest->link;
if (next->NdisRequest == packet)
{
if (next == pgpRequest)
*reqeust_list = NULL;
else
{
pgpRequest->link = next->link;
if (*reqeust_list == next)
*reqeust_list = pgpRequest;
}
NdisReleaseSpinLock(&adapter->general_lock);
return next;
}
pgpRequest = next;
} while (pgpRequest != *reqeust_list);
};
NdisReleaseSpinLock(&adapter->general_lock);
return NULL;
}
PPGPNDIS_REQUEST PGPNdisRequestAlloc(
PNDIS_STATUS status,
PVPN_ADAPTER adapter)
{
PPGPNDIS_REQUEST request;
DBG_FUNC("PGPNdisRequestAlloc")
request = (PPGPNDIS_REQUEST) RequestDequeue( adapter, &adapter->free_request_list);
if (request == (PPGPNDIS_REQUEST) NULL) {
DBG_PRINT(("!!!!! FATAL!!! PreAllocated PGPRequest Exhausted!!!\n"););
ASSERT(FALSE);
*status = NDIS_STATUS_RESOURCES;
return NULL;
}
*status = NDIS_STATUS_SUCCESS;
request->NdisRequest = NULL;
request->Binding = NULL;
return request;
}
VOID PGPNdisRequestFree(
PVPN_ADAPTER adapter,
PPGPNDIS_REQUEST request)
{
DBG_FUNC("PGPNdisRequestFree")
DBG_ENTER();
RequestEnqueue(adapter, &adapter->free_request_list, request);
DBG_LEAVE(0);
}
NDIS_STATUS QueueForTransferComplete(
PVPN_ADAPTER adapter,
NDIS_HANDLE MacReceiveContext,
PUCHAR HeaderBuffer,
UINT HeaderBufferLength,
PUCHAR LookAheadBuffer,
UINT LookAheadBufferSize,
UINT PacketSize)
{
DBG_FUNC("QueueForTransferComplete")
NDIS_STATUS status;
PPGPNDIS_PACKET pgpPacket;
UINT BytesTransferred;
PIP_HEADER ip_header;
UINT ip_len;
DBG_ENTER();
// If we have to decrypt the packet, we can not indicate it to protocol. Cause it is not complete yet.
pgpPacket = PGPNdisPacketAllocWithSrcPacket(&status, adapter);
if (status != NDIS_STATUS_SUCCESS)
{
DBG_LEAVE(status);
return status;
}
if (HeaderBuffer != NULL)
NdisMoveMemory(pgpPacket->srcBlock, HeaderBuffer, adapter->eth_hdr_len);
pgpPacket->HeaderBuffer = pgpPacket->srcBlock;
pgpPacket->HeaderBufferSize = adapter->eth_hdr_len;
pgpPacket->LookaheadBuffer = pgpPacket->srcBlock + adapter->eth_hdr_len;
ip_header = (PIP_HEADER) ( (UCHAR*)LookAheadBuffer);
ip_len = ntohs(ip_header->ip_len);
if (ip_len <= LookAheadBufferSize)
{
NdisMoveMemory(pgpPacket->LookaheadBuffer, ip_header, ip_len);
pgpPacket->srcBlockLen = ip_len + adapter->eth_hdr_len;
status = NDIS_STATUS_SUCCESS;
PacketEnqueue(adapter, &adapter->incoming_indicateComplete_wait_list, pgpPacket);
}
else
{
PacketEnqueue(adapter, &adapter->incoming_ipsectransferComplete_wait_list, pgpPacket);
NdisTransferData(&status, adapter->NdisBindingHandleToRealMac, MacReceiveContext, 0, //adapter->eth_hdr_len,
PacketSize, pgpPacket->srcPacket, &BytesTransferred);
if (status == NDIS_STATUS_PENDING) {
status = NDIS_STATUS_SUCCESS;
DBG_LEAVE(status);
return status;
}
pgpPacket = PacketDequeue(adapter, &adapter->incoming_ipsectransferComplete_wait_list);
if (status == NDIS_STATUS_SUCCESS) {
PGPnetAdjustTransferCompletePacket(pgpPacket);
PacketEnqueue(adapter, &adapter->incoming_indicateComplete_wait_list, pgpPacket);
}
else {
PGPNdisPacketFreeSrcPacket(adapter, pgpPacket);
}
}
DBG_LEAVE(status);
return status;
#if 0
pgpPacket->ipAddress = ntohl(ip_header->ip_src);
PGPnetPMDoTransform(PGPnetDriver.PolicyManagerHandle, pgpPacket, TRUE); //&srcPGPnetPacket, &dstPGPnetPacket);
// No need to adjust packet.
// PGPnetAdjustPacket(pgpPacket);
NdisIndicateReceive(&status, adapter->NdisBindingContextFromProtocol, MacReceiveContext,
pgpPacket->xformBlock, pgpPacket->xformBlockLen,
pgpPacket->xformBlock, pgpPacket->xformBlockLen,
pgpPacket->xformBlockLen);
PGPNdisPacketFree(adapter, pgpPacket);
DBG_LEAVE(status);
#endif
}
NDIS_STATUS TransformAndIndicate(
PVPN_ADAPTER adapter,
PPGPNDIS_PACKET pgpPacket)
{
DBG_FUNC("TransformAndIndicate")
NDIS_STATUS status;
PIP_HEADER ip_header;
PUDP_HEADER udp_header = 0; /* EML 04/05/99 */
UINT ip_len;
PGPnetPMStatus pmstatus;
PPGPNDIS_PACKET_HEAD packetHead;
BOOLEAN newHead = FALSE;
DBG_ENTER()
status = NDIS_STATUS_SUCCESS;
pgpPacket->HeaderBuffer = pgpPacket->srcBlock;
pgpPacket->HeaderBufferSize = adapter->eth_hdr_len;
pgpPacket->LookaheadBuffer = pgpPacket->srcBlock + adapter->eth_hdr_len;
ip_header = (PIP_HEADER) ( (UCHAR*)pgpPacket->LookaheadBuffer );
ip_len = ntohs(ip_header->ip_len);
pgpPacket->srcBlockLen = ip_len + adapter->eth_hdr_len;
pgpPacket->ipAddress = ntohl(ip_header->ip_src);
/* Start EML 05/04/99 */
if (ip_header->ip_prot == PROTOCOL_UDP)
{
udp_header = (PUDP_HEADER) ( (UCHAR*)ip_header + sizeof(IP_HEADER) );
}
pgpPacket->port = udp_header ? udp_header->dest_port : 0;
/* End EML */
pmstatus = PGPnetPMNeedTransformLight(PGPnetDriver.PolicyManagerHandle,
ip_header->ip_src,
TRUE,
adapter);
if ( kPGPNetPMPacketEncrypt == pmstatus )
{
// Now we have the whole secured incoming packet.
NdisMoveMemory(pgpPacket->xformBlock, pgpPacket->srcBlock, adapter->eth_hdr_len);
pgpPacket->offset = ntohs(ip_header->ip_foff & IP_OFFSET) << 3;
if (pgpPacket->offset == 0)
pgpPacket->firstSrcBlock = TRUE;
// Check to see if it's in the incoming fragment list.
packetHead = PacketHeadListQuery(adapter,
&adapter->incoming_packet_head_list,
ip_header->ip_id,
pgpPacket->ipAddress);
// If there is no incoming fragment list for this one. Create one.
if (packetHead == NULL)
{
newHead = TRUE;
packetHead = PGPNdisPacketHeadAlloc(&status, adapter);
}
if (status != NDIS_STATUS_SUCCESS)
goto failout;
// Add timestamp, update head information.
if (packetHead->id == 0)
{
// Initialize packetHead
packetHead->ipAddress = pgpPacket->ipAddress;
packetHead->id = ip_header->ip_id;
packetHead->timeStamp = PgpKernelGetSystemTime();
}
if (packetHead->numFragments ==0)
packetHead->accumulatedLength = htons(ip_header->ip_len);
else
packetHead->accumulatedLength += htons(ip_header->ip_len) - IP_HEADER_SIZE;
packetHead->numFragments++;
if (IP_LAST_FRAGMENT(ip_header->ip_foff))
{
ASSERT(packetHead->totalLength == 0);
pgpPacket->lastSrcBlock = TRUE;
packetHead->totalLength = htons(ip_header->ip_len) + pgpPacket->offset;
}
// Insert this pgpPacket to the packet list
InsertPGPNdisPacket(adapter, packetHead, pgpPacket);
// Check status, if finished fire up the send sequence.
if ((packetHead->totalLength) && (packetHead->totalLength == packetHead->accumulatedLength))
{
// Got them all, send them all.
PGPnetPMStatus pm_status;
PPGPNDIS_PACKET extraPacket;
extraPacket = PGPNdisPacketAllocWithSrcPacket(&status, adapter);
AppendPGPNdisPacket(adapter, packetHead, extraPacket);
if ( !(packetHead->link)->lastSrcBlock )
{
// More fragment. Adjust packet length.
PIP_HEADER first_ip_hdr;
PUCHAR first_srcBlock;
first_srcBlock = (packetHead->link)->srcBlock;
first_ip_hdr = (PIP_HEADER)(first_srcBlock + ETHER_HEADER_SIZE);
first_ip_hdr->ip_len = htons(packetHead->totalLength);
}
pm_status = PGPnetPMDoTransform(PGPnetDriver.PolicyManagerHandle,
packetHead->link,
TRUE,
adapter);
if (pm_status != kPGPNetPMPacketSent)
{
DBG_PRINT(("!!!!! Yellow Alert! PGPnetPMDoTransform Error!\n"););
PGPNdisPacketHeadFreeList(adapter, packetHead, FALSE);
PacketHeadListRemove(adapter, &adapter->incoming_packet_head_list, packetHead);
PGPNdisPacketHeadFree(adapter, packetHead);
status = NDIS_STATUS_FAILURE;
goto failout;
}
ProtocolIndicatePackets(adapter, packetHead);
}
else
{
// Not finished, add to the incoming list
if (newHead)
PacketHeadEnqueue(adapter, &adapter->incoming_packet_head_list, packetHead);
}
status = NDIS_STATUS_PENDING;
goto bailout;
#if 0
PGPnetPMStatus pm_status;
pm_status = PGPnetPMDoTransform(PGPnetDriver.PolicyManagerHandle,
pgpPacket,
TRUE,
adapter);
if (pm_status != kPGPNetPMPacketSent)
{
DBG_PRINT(("!!!!! Yellow Alert! PGPnetPMDoTransform Error!\n"););
status = NDIS_STATUS_FAILURE;
goto failout;
}
#endif
}
else if ( kPGPNetPMPacketClear == pmstatus )
{
CopySrcBlockToXformBlock(pgpPacket);
IndicateReceiveClear(adapter, pgpPacket);
goto bailout;
}
else
{
// Shouldn't get here in the first place. But this did happen.
DBG_PRINT(("!!!!!FATAL!!!!!, Invalid status!\n"););
//ASSERT(FALSE);
status = NDIS_STATUS_FAILURE;
goto failout;
}
pgpPacket->HeaderBuffer = pgpPacket->xformBlock;
pgpPacket->HeaderBufferSize = adapter->eth_hdr_len;
pgpPacket->LookaheadBuffer = pgpPacket->xformBlock + adapter->eth_hdr_len;
ip_header = (PIP_HEADER) ( (UCHAR*)pgpPacket->LookaheadBuffer );
ip_len = ntohs(ip_header->ip_len);
//ip_len = pgpPacket->xformBlockLen - adapter->eth_hdr_len;
ProtocolIndicateReceive(adapter,
pgpPacket->srcPacket,
pgpPacket->HeaderBuffer,
pgpPacket->HeaderBufferSize,
pgpPacket->LookaheadBuffer,
ip_len,
ip_len);
#ifdef INCOMING_FRAGMENT
if ( pgpPacket->xformBlockLen <= MAX_ETHER_FRAME_SIZE - MAX_IPSEC_PACKETSIZE_INCREASE)
{
NdisIndicateReceive(&status, adapter->NdisBindingContextFromProtocol, pgpPacket->srcPacket,
pgpPacket->HeaderBuffer, pgpPacket->HeaderBufferSize,
pgpPacket->LookaheadBuffer, ip_len,
ip_len);
}
else
{
FragmentAndIndicate(adapter, pgpPacket);
adapter->receive_fragmented = TRUE;
}
#endif
bailout:
failout:
DBG_LEAVE(status); // We do care about the status
return status;
}
USHORT iphdr_cksum(USHORT *iph)
{
USHORT i;
ULONG sum;
i = 0;
sum = 0;
while(i++ < (sizeof(IP_HEADER)/2))
sum += *iph++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
sum = ~sum;
return (USHORT)sum;
}
void CopySrcBlockToXformBlock(PGPNDIS_PACKET *packet)
{
if (packet->srcBlockLen)
NdisMoveMemory(packet->xformBlock, packet->srcBlock, packet->srcBlockLen);
packet->xformBlockLen = packet->srcBlockLen;
}
void GetIPAddressFromARP(PVPN_ADAPTER adapter, PVOID block)
{
PARP_HEADER arp_header;
arp_header = (PARP_HEADER)block;
if ( (arp_header->arp_src_ip_addr == arp_header->arp_dst_ip_addr) &&
arp_header->arp_src_ip_addr != 0L)
{
adapter->ip_address = arp_header->arp_src_ip_addr;
}
}
/*******************************************************************************
// New fragmentation related routines.
*******************************************************************************/
void PacketHeadEnqueue(
PVPN_ADAPTER adapter,
PPGPNDIS_PACKET_HEAD *packet_head_list,
PPGPNDIS_PACKET_HEAD packetHead)
{
NdisAcquireSpinLock(&adapter->general_lock);
if (*packet_head_list == (PPGPNDIS_PACKET_HEAD) NULL) {
packetHead->next = packetHead;
} else {
packetHead->next = (*packet_head_list)->next;
(*packet_head_list)->next = packetHead;
}
*packet_head_list = packetHead;
NdisReleaseSpinLock(&adapter->general_lock);
}
PPGPNDIS_PACKET_HEAD PacketHeadDequeue(
PVPN_ADAPTER adapter,
PPGPNDIS_PACKET_HEAD *packet_head_list)
{
PPGPNDIS_PACKET_HEAD packetHead;
NdisAcquireSpinLock(&adapter->general_lock);
if (*packet_head_list == (PPGPNDIS_PACKET_HEAD) NULL) {
packetHead = (PPGPNDIS_PACKET_HEAD) NULL;
} else {
packetHead = (*packet_head_list)->next;
if (packetHead == *packet_head_list) {
*packet_head_list = (PPGPNDIS_PACKET_HEAD) NULL;
} else {
(*packet_head_list)->next = packetHead->next;
}
}
NdisReleaseSpinLock(&adapter->general_lock);
return packetHead;
}
VOID PacketHeadListRemove(
PVPN_ADAPTER adapter,
PPGPNDIS_PACKET_HEAD *packet_list,
PPGPNDIS_PACKET_HEAD packetHead)
{
PPGPNDIS_PACKET_HEAD pgpPacket;
NdisAcquireSpinLock(&adapter->general_lock);
if ( (pgpPacket = *packet_list) != NULL )
{
do
{
PPGPNDIS_PACKET_HEAD next = pgpPacket->next;
if (next == packetHead)
{
if (next == pgpPacket)
*packet_list = NULL;
else
{
pgpPacket->next = next->next;
if (*packet_list == next)
*packet_list = pgpPacket;
}
NdisReleaseSpinLock(&adapter->general_lock);
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -