⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpgpnetfilteradapter.cpp

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: CPGPnetFilterAdapter.cpp,v 1.5 2002/08/06 20:10:26 dallen Exp $
____________________________________________________________________________*/

#include "pgpnetBase.h"

#include "pgpnetGlobal.h"
#include "pgpnetPacket.h"
#include "pgpnetPacketHelper.h"
#include "CPGPnetAdapter.h"
#include "CPGPnetFilterAdapter.h"
#include "pgpNetComm.h"
#include "pgpNetIPdef.h"
#include "pgpnetIpHelper.h"
#include "pgpKernelTiming.h"

/* PM includes */
#include "pgpNetPM.h"
#include "pgpNetWin32.h"

#include "CPGPnetDriver.h"
#include "CPGPnetFilterDriver.h"

#include "CPGPnetIPPacket.h"

#include "pgpnetDebug.h"

static PGPnetLastFragmentList* 
LastFragmentListQuery(PGPnetLastFragmentList *list,
					  PGPUInt32 ipAddress,
					  USHORT ipId);

static PGPnetLastFragmentList* 
LastFragmentListAdd(PGPnetLastFragmentList **list,
					PGPUInt32 ipAddress,
					USHORT ipId);

static VOID
LastFragmentListFree(PGPnetLastFragmentList **list,
					 PGPUInt32 ipAddress,
					 USHORT ipId);

static VOID
LastFragmentListFreeAll(PGPnetLastFragmentList *list);

VOID CPGPnetFilterAdapter::DoCfgEthernetTransform(PGPnetPacket *inPacket)
{
	PGPnetPacket* packet = inPacket;

	DBG_FUNC("DoCfgEthernetTransform");

	while (packet != NULL) {
		NdisMoveMemory((PCHAR)packet->xformBlock + 6, mHardwareAddress, 6);
		packet = packet->link;
	}
}

VOID CPGPnetFilterAdapter::DoMTUTransform(PGPnetPacket* packet)
{
	PETHERNET_HEADER	src_eth_header;
	PIP_HEADER			src_ip_header;

	PETHERNET_HEADER	xform_eth_header;
	USHORT				xform_eth_protocol;
	PIP_HEADER			xform_ip_header;

	PICMP_HEADER		icmp_header;
	PTYPE3_ICMP_HEADER	type3_icmp_header;

	UCHAR				hardwareAddress[6];
	USHORT				mtu;

	src_eth_header = (PETHERNET_HEADER)packet->srcBlock;
	src_ip_header = (PIP_HEADER)(packet->srcBlock + ETHER_HEADER_SIZE);

	xform_eth_header = (PETHERNET_HEADER)packet->xformBlock;
	xform_eth_protocol = *((PUSHORT)(&xform_eth_header->eth_protocolType[0]));
	xform_ip_header = (PIP_HEADER)(packet->xformBlock + ETHER_HEADER_SIZE);
	icmp_header	= (PICMP_HEADER)((UCHAR*)xform_ip_header + IP_HEADER_SIZE);
	type3_icmp_header = (PTYPE3_ICMP_HEADER)icmp_header;
	
	// switch hardware address
	NdisMoveMemory(hardwareAddress, xform_eth_header->eth_srcAddress, 6);
	NdisMoveMemory(xform_eth_header->eth_srcAddress, xform_eth_header->eth_dstAddress, 6);
	NdisMoveMemory(xform_eth_header->eth_dstAddress, hardwareAddress, 6);

	// change ethernet protocol
	// Still IP packet

	// change misc ip fields

	// change ip address
	xform_ip_header->ip_dest = xform_ip_header->ip_src;

	// change ip protocol
	xform_ip_header->ip_prot = PROTOCOL_ICMP;

	xform_ip_header->ip_chksum = 0;

	// construct icmp header
	icmp_header->icmp_type = ICMP_TYPE_UNREACHABLE;
	icmp_header->icmp_code = ICMP_UNREACHABLE_CODE_FRAGMENT;
	icmp_header->icmp_checksum = 0;

	// copy icmp data
	if (htons(xform_ip_header->ip_len) > htons(src_ip_header->ip_len))
		mtu = htons(xform_ip_header->ip_len) - htons(src_ip_header->ip_len);
	else
		mtu = 0;
	type3_icmp_header->u.icmp_unused = 0;
	type3_icmp_header->u.icmp_code5.code5_mtu = mtu;
	type3_icmp_header->u.icmp_code5.code5_unused = 0;

	NdisMoveMemory(&type3_icmp_header->icmp_ip_header, src_ip_header, IP_HEADER_SIZE);
	NdisMoveMemory(&type3_icmp_header->icmp_ip_data, src_ip_header + IP_HEADER_SIZE, 8);

	// adjust ip len
	xform_ip_header->ip_len = htons(IP_HEADER_SIZE + sizeof(TYPE3_ICMP_HEADER));

	// calculate ip checksum
	xform_ip_header->ip_chksum = HeaderChecksum((USHORT*)xform_ip_header, TYPE_IP);

	// caculate icmp checksum
	icmp_header->icmp_checksum = HeaderChecksum((USHORT*)icmp_header, TYPE_ICMP);

	// adjust transform buffer length
	packet->xformBlockLen = ETHER_HEADER_SIZE + htons(xform_ip_header->ip_len);
	
	// set last fragment
	packet->lastXformBlock = TRUE;
	
}

VOID CPGPnetFilterAdapter::DoCopyTransforms(PGPnetPacket *pgpnetPacket)
{
	DBG_FUNC("CPGPnetFilterAdapter::DoCopyTransform")

	PGPnetPacket* packet = pgpnetPacket;
	PGPnetPacket* next;

	DBG_ENTER();

	while (packet != NULL)
	{
		DoCopyTransform(packet);
		if (packet->lastSrcBlock)
			next = NULL;
		else
			next = packet->link;

		packet = next;
	}

	DBG_LEAVE(0);
}

VOID CPGPnetFilterAdapter::DoCopyTransform(PGPnetPacket* pgpnetPacket)
{
	DBG_FUNC("CPGPnetFilterAdapter::DoCopyTransform")

	DBG_ENTER();

	CopySrcBlockToXformBlock(pgpnetPacket);

	if (pgpnetPacket->firstSrcBlock)
		pgpnetPacket->firstXformBlock = TRUE;
	if (pgpnetPacket->lastSrcBlock)
		pgpnetPacket->lastXformBlock = TRUE;

	PGPnetAdjustXformPacket(pgpnetPacket);

	DBG_LEAVE(0);
}

CPGPnetFilterAdapter::CPGPnetFilterAdapter()
{
	HardwareAddressDetected = FALSE;
	RealAdapterMedia = (NDIS_MEDIUM) (PGPUInt32) -1;
	MaximumFrameSize = MAX_ETHER_FRAME_SIZE - ETHER_HEADER_SIZE;
}

CPGPnetFilterAdapter::~CPGPnetFilterAdapter()
{
}

PGPBoolean CPGPnetFilterAdapter::SetRealAdapterName(PNDIS_STRING String)
{

	DBG_FUNC("CPGPnetFitlerAdapter::SetRealAdapterName")

	NDIS_STATUS status;
	
	DBG_ENTER();
/*
	status = NdisAllocateMemory((VOID**)&RealAdapterName.Buffer, String->Length, 0, HighestAcceptableAddress);
    if (status != NDIS_STATUS_SUCCESS)
	{
        DBG_PRINT(("!!!!! NdisAllocateMemory failed status=%Xh\n", status););
		DBG_LEAVE(0);
		return (FALSE);
	}

	NdisMoveMemory(RealAdapterName.Buffer, String->Buffer, String->Length);
	RealAdapterName.MaximumLength = String->Length;
	RealAdapterName.Length = String->Length;
*/
	RtlInitUnicodeString(
	&RealAdapterName,
	String->Buffer
	);

	DBG_LEAVE(0);
	return TRUE;
}

VOID CPGPnetFilterAdapter::AllocatePacketPool()
{
	sent_plainpacket_list = (PGPnetPacket*)NULL;
	incoming_plaintransferComplete_wait_list	= (PGPnetPacket*)NULL;
	incoming_ipsectransferComplete_wait_list	= (PGPnetPacket*)NULL;
	incoming_indicateComplete_wait_list = (PGPnetPacket*)NULL;
	incoming_fragment_indicateComplete_wait_list = (PGPnetPacket*)NULL;
	incoming_mac_transferdata_wait_list = (PGPnetPacket*)NULL;

	outgoing_multiple_ipsecpacket_list = (PGPnetPacket*)NULL;

	outgoing_multiple_cfgpacket_list = (PGPnetPacket*)NULL;

	outgoing_local_packet_head_list = (PPGPnetPacketHead)NULL;
	outgoing_cfg_packet_head_list = (PPGPnetPacketHead)NULL;
	incoming_packet_head_list = (PPGPnetPacketHead)NULL;
	sent_packet_head_list = (PPGPnetPacketHead)NULL;

	last_fragment_list = (PGPnetLastFragmentList*)NULL;
}

VOID CPGPnetFilterAdapter::FreePacketPool()
{
	PPGPnetPacketHead		head;

	while ((head = PacketHeadDequeue(&outgoing_local_packet_head_list)) != NULL)
	{
		PGPNdisPacketHeadFreeList(head);
		PGPNdisPacketHeadFree(head);
	}
	while ((head = PacketHeadDequeue(&outgoing_cfg_packet_head_list)) != NULL)
	{
		PGPNdisPacketHeadFreeList(head);
		PGPNdisPacketHeadFree(head);
	}
	while ((head = PacketHeadDequeue(&incoming_packet_head_list)) != NULL)
	{
		PGPNdisPacketHeadFreeList(head);
		PGPNdisPacketHeadFree(head);
	}

	LastFragmentListFreeAll(last_fragment_list);

	sent_plainpacket_list = (PGPnetPacket*)NULL;
	incoming_plaintransferComplete_wait_list	= (PGPnetPacket*)NULL;
	incoming_ipsectransferComplete_wait_list	= (PGPnetPacket*)NULL;
	incoming_indicateComplete_wait_list = (PGPnetPacket*)NULL;
	incoming_fragment_indicateComplete_wait_list = (PGPnetPacket*)NULL;

	outgoing_multiple_ipsecpacket_list = (PGPnetPacket*)NULL;
	outgoing_multiple_cfgpacket_list = (PGPnetPacket*)NULL;

	outgoing_local_packet_head_list = (PPGPnetPacketHead)NULL;
	outgoing_cfg_packet_head_list = (PPGPnetPacketHead)NULL;
	incoming_packet_head_list = (PPGPnetPacketHead)NULL;
	sent_packet_head_list = (PPGPnetPacketHead)NULL;

	last_fragment_list = (PGPnetLastFragmentList*)NULL;
}

PGPnetPacketStatus	
CPGPnetFilterAdapter::PGPnetFilterPacketCheck(PGPnetPacket *pgpnetPacket, PGPBoolean incoming)
{

	PGPnetPacketStatus	packetStatus = PacketFurtherCheck;

	PVOID				working_block;
	UINT				working_block_len;

	PETHERNET_HEADER	eth_header;
	USHORT				eth_protocol;

	USHORT				eth_header_len;

	PIP_HEADER			ip_header;

	PGPUInt16			port = 0;

#if !defined(CHICAGO) && !defined(NDIS40)
	PGPBoolean			Broadcast = FALSE;
#endif
	DBG_FUNC("PGPnetFilterPacketCheck");

	working_block = pgpnetPacket->srcBlock;
	working_block_len = pgpnetPacket->srcBlockLen;

	do 
	{
		if (Media != NdisMedium802_3 && Media != NdisMediumWan)
		{
			packetStatus = PacketDrop;
			break;
		}


		/*
		 *	Stage 1. Get the ethernet header. Determines if this is an ip packet. If not bail out early,
		 *	otherwise go to stage 2.
		 */
		eth_header   = (PETHERNET_HEADER) working_block;
		eth_protocol = *((PUSHORT)(&eth_header->eth_protocolType[0]));
		eth_header_len = sizeof(ETHERNET_HEADER);

		if ( RealAdapterMedia == NdisMediumWan &&
			(eth_protocol == PPPOE_DISCOVERY_PORT_NET || eth_protocol == PPPOE_SESSION_PORT_NET))
		{
			packetStatus = PacketDrop;
			break;
		}

		if (eth_protocol != IPPROT_NET)
		{
			if (eth_protocol == ARPPROT_NET && Media != NdisMediumWan && !incoming)
			{
				PGPUInt32 IpAddress;
				IpAddress = GetIPAddressFromARP((PVOID)((UCHAR*)eth_header + eth_header_len));
				if (IpAddress)
					mIpAddress = IpAddress;
			}
			packetStatus = PacketPassthrough;
			break;
		}

		if (BroadcastEthernetAddress(eth_header->eth_dstAddress) && !incoming)
		{
#if !defined(CHICAGO) && !defined(NDIS40)
			Broadcast = TRUE;
#else
			packetStatus = PacketPassthrough;
			break;
#endif
		}

		if (incoming)
			NdisMoveMemory(pgpnetPacket->xformBlock, pgpnetPacket->srcBlock, ETHER_HEADER_SIZE);
		else if (!HardwareAddressDetected && 
			(eth_header->eth_srcAddress[0] != 0xFF ||
			eth_header->eth_srcAddress[1] != 0xFF ||
			eth_header->eth_srcAddress[2] != 0xFF ||
			eth_header->eth_srcAddress[3] != 0 ||
			eth_header->eth_srcAddress[4] != 0 ||
			eth_header->eth_srcAddress[5] != 0))
		{
			HardwareAddressDetected = TRUE;
			NdisMoveMemory(mHardwareAddress, eth_header->eth_srcAddress, 6);
#if defined(NDIS40)
			if (RealAdapterMedia == NdisMediumWan)
				PGPnetRASconnect();
#endif
		}

		/*
		 *	Stage 2 Get the ip header.
		 */
		
		if (working_block_len >= eth_header_len + sizeof(IP_HEADER))
		{

			ip_header = (PIP_HEADER) ( (PCHAR)working_block + eth_header_len);
			working_block = (PCHAR)working_block + eth_header_len;
			working_block_len -= eth_header_len;
		}
		else
		{
			packetStatus = PacketDrop;
			break;
		}


		if (!mWanIPAddressDetected && !incoming)
		{
			mIpAddress = ip_header->ip_src;
			mWanIPAddressDetected = TRUE;
		}

		/*
		 *	Stage 4. If it's UDP, Get the UDP header.
		 *	Determine if this is a UDP 500 packet. If it is, bail out.
		 */

		if (ip_header->ip_prot == PROTOCOL_UDP)
		{
			if( working_block_len <= sizeof(struct tag_IP_HEADER) )		// FIX!!! ONLY work for ordinary ipv4 header.
			{
				packetStatus = PacketDrop;
				break;
			}
			else
			{
				port = ((PUDP_HEADER)( (UCHAR*)working_block + sizeof(IP_HEADER)))->dest_port;

#if !defined(CHICAGO) && !defined(NDIS40)
				if (port == UDP_PORT_BOOTPS_NET || port == UDP_PORT_BOOTPC_NET)
				{
					PUDP_HEADER			udp_header;
					PDHCP_HEADER		dhcp_header;
					CPGPnetDHCPPacket	*dhcpPacket;

					udp_header = (PUDP_HEADER) ( (PCHAR)working_block + sizeof(IP_HEADER));
					working_block = (PCHAR)working_block + sizeof(IP_HEADER);
					working_block_len -= sizeof(IP_HEADER);

					dhcp_header = (PDHCP_HEADER) ( (PCHAR)working_block + sizeof(UDP_HEADER));
					working_block = (PCHAR)working_block + sizeof(UDP_HEADER);
					working_block_len -= sizeof(UDP_HEADER);

					if (working_block_len <= sizeof(DHCP_HEADER))
						break;

					// now we have the DHCP Packet
					dhcpPacket = new CPGPnetDHCPPacket(working_block, working_block_len);

					switch (dhcpPacket->GetDHCPType())
					{
					case TYPE_DISCOVER:
						break;

					case TYPE_OFFER:
						break;

					case TYPE_REQUEST:
						break;

					case TYPE_DECLINE:
						break;

					case TYPE_ACK:
						{
							PGPUInt32 dns1;
							PGPUInt32 dns2;

							dhcpPacket->GetDHCPDNSServer(&dns1, &dns2);
							PGPnetFilterDriver->dns1 = dns1;
							PGPnetFilterDriver->dns2 = dns2;
						}
						break;
					case TYPE_NAK:
						break;

					case TYPE_RELEASE:
						break;

					case TYPE_INFORM:
						break;

					case TYPE_INVALID:
						break;

					default:
						ASSERT(0);
						break;
					}

					delete dhcpPacket;
				}
#endif
			}
		} else if (ip_header->ip_prot == PROTOCOL_TCP)	{
			if( working_block_len <= sizeof(struct tag_IP_HEADER) )		// FIX!!! ONLY work for ordinary ipv4 header.
			{
				packetStatus = PacketDrop;
				break;
			}
			else
				NdisMoveMemory(&(port), (UCHAR*)working_block + sizeof(IP_HEADER) + 2, 2);
		}

	} while (0);

#if !defined(CHICAGO) && !defined(NDIS40)
	if(Broadcast && !incoming)
		packetStatus = PacketPassthrough;
#endif

	return packetStatus;
}


NDIS_STATUS	CPGPnetFilterAdapter::SendPacket(PGPnetPacket *pgpnetPacket)
{
	DBG_FUNC("CPGPnetFilterAdapter::SendPacket")

	NDIS_STATUS status;

	DBG_ENTER();

	PacketEnqueue(&sent_plainpacket_list, pgpnetPacket);

#ifdef NDIS_MINIPORT_DRIVER
	NdisSetPacketFlags(pgpnetPacket->xformPacket, pgpnetPacket->SendFlag);
#endif
	ProtocolSendRequest(&status,
				NdisBindingHandleToRealAdapter,
				pgpnetPacket->xformPacket);

	if (status != NDIS_STATUS_PENDING)
	{
		pgpnetPacket = PacketRemoveByXformPacket(&sent_plainpacket_list, pgpnetPacket->xformPacket);
		FreePGPnetPacket(pgpnetPacket);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -