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

📄 pgpnethostutils.c

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

	$Id: pgpNetHostUtils.c,v 1.4 2002/08/06 20:10:25 dallen Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"

#include "pgpNetHostUtils.h"
#include "pgpPFLErrors.h"
#include "pgpMem.h"
#include "pgpPFLPriv.h"

#define	INSECURE_HOST		0
#define INSECURE_SUBNET		1
#define INSECURE_RANGE		2
#define SECURE_HOST			3
#define	SECURE_SUBNET		4
#define SECURE_GATEWAY		5
#define SECURE_RANGE		6

#if PGP_WORDSBIGENDIAN
# define sntohl(x)	(x)
#else
static PGPUInt32
sntohl (PGPUInt32 x)
{
	unsigned int y = x;
	unsigned char *s = (unsigned char *)&y;
	
	return ((int)s[0]) << 24 | ((int)s[1]) << 16
		| ((int)s[2]) << 8 | ((int)s[3]);
}
#endif /* PGP_WORDSBIGENDIAN */


//	____________________________________
//
//  Determine if the ips/masks of specified entries overlap

static PGPBoolean
sDoesRangeOverlapSubnet (
		PGPNetPrefHostEntry*	pHostRange,
		PGPNetPrefHostEntry*	pHostSubnet)
{
	PGPUInt32	uSubnetStart;
	PGPUInt32	uSubnetEnd;

	uSubnetStart = sntohl (pHostSubnet->ipAddrStart & pHostSubnet->ipMaskEnd);
	uSubnetEnd = sntohl (pHostSubnet->ipAddrStart | ~pHostSubnet->ipMaskEnd);

	if ((uSubnetStart >= sntohl (pHostRange->ipAddrStart)) &&
		(uSubnetStart <= sntohl (pHostRange->ipMaskEnd)))
	{
		 return TRUE;
	}

	if ((uSubnetEnd >= sntohl (pHostRange->ipAddrStart)) &&
		(uSubnetEnd <= sntohl (pHostRange->ipMaskEnd)))
	{
		 return TRUE;
	}

	if ((sntohl (pHostRange->ipAddrStart) >= uSubnetStart) &&
		(sntohl (pHostRange->ipAddrStart) <= uSubnetEnd))
	{
		 return TRUE;
	}

	return FALSE;
}


//	____________________________________
//
//  Determine if the ips/masks of specified entries overlap

static PGPBoolean
sDoRangesOverlap (
		PGPNetPrefHostEntry*	pHostNew,
		PGPNetPrefHostEntry*	pHostExisting)
{
	if ((sntohl (pHostNew->ipAddrStart) >= sntohl (pHostExisting->ipAddrStart)) &&
		(sntohl (pHostNew->ipAddrStart) <= sntohl (pHostExisting->ipMaskEnd)))
	{
		 return TRUE;
	}

	if ((sntohl (pHostNew->ipMaskEnd) >= sntohl (pHostExisting->ipAddrStart)) &&
		(sntohl (pHostNew->ipMaskEnd) <= sntohl (pHostExisting->ipMaskEnd)))
	{
		 return TRUE;
	}

	if ((sntohl (pHostExisting->ipAddrStart) >= sntohl (pHostNew->ipAddrStart)) &&
		(sntohl (pHostExisting->ipAddrStart) <= sntohl (pHostNew->ipMaskEnd)))
	{
		 return TRUE;
	}

	return FALSE;
}


//	____________________________________
//
//  Determine if the ips/masks of specified entries overlap

static PGPBoolean
sDoIPsOverlap (
		PGPNetPrefHostEntry*	pHostNew,
		PGPNetPrefHostEntry*	pHostExisting)
{
	PGPUInt32	uMask;

	uMask = pHostNew->ipMaskEnd;
	if ((pHostNew->ipAddrStart & uMask) == (pHostExisting->ipAddrStart & uMask))
	{
		 return TRUE;
	}

	uMask = pHostExisting->ipMaskEnd;
	if ((pHostNew->ipAddrStart & uMask) == (pHostExisting->ipAddrStart & uMask))
	{
		 return TRUE;
	}

	return FALSE;
}


//	____________________________________
//
//  Determine if the specified host entries conflict with each other

PGPBoolean
pgpDoNetHostsConflict (
		PGPNetPrefHostEntry*	pHostNew,
		PGPNetPrefHostEntry*	pHostExisting)
{
	PGPUInt32	uNewType;
	PGPUInt32	uExistingType;

	pgpAssert (IsntNull (pHostNew));
	pgpAssert (IsntNull (pHostExisting));

	// determine new host type
	switch (pHostNew->hostType) {
		case kPGPnetInsecureHost :
			if (pHostNew->destIsRange)
				uNewType = INSECURE_RANGE;
			else
			{
				if (pHostNew->ipMaskEnd == 0xFFFFFFFF)
					uNewType = INSECURE_HOST;
				else
					uNewType = INSECURE_SUBNET;
			}
			break;

		case kPGPnetSecureHost :
			if (pHostNew->destIsRange)
				uNewType = SECURE_RANGE;
			else
			{
				if (pHostNew->ipMaskEnd == 0xFFFFFFFF)
					uNewType = SECURE_HOST;
				else
					uNewType = SECURE_SUBNET;
			}
			break;

		default :
			uNewType = SECURE_GATEWAY;
			break;
	}

	// determine existing host type
	switch (pHostExisting->hostType) {
		case kPGPnetInsecureHost :
			if (pHostExisting->destIsRange)
				uExistingType = INSECURE_RANGE;
			else
			{
				if (pHostExisting->ipMaskEnd == 0xFFFFFFFF)
					uExistingType = INSECURE_HOST;
				else
					uExistingType = INSECURE_SUBNET;
			}
			break;

		case kPGPnetSecureHost :
			if (pHostExisting->destIsRange)
				uExistingType = SECURE_RANGE;
			else
			{
				if (pHostExisting->ipMaskEnd == 0xFFFFFFFF)
					uExistingType = SECURE_HOST;
				else
					uExistingType = SECURE_SUBNET;
			}
			break;

		default :
			uExistingType = SECURE_GATEWAY;
			break;
	}

	// determine if there are conflicts
	switch (uNewType) {
	case INSECURE_HOST :
		switch (uExistingType) {
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				return sDoIPsOverlap (pHostNew, pHostExisting);
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
			case INSECURE_RANGE :
			case SECURE_RANGE :
				break;
		}
		break;

	case INSECURE_SUBNET :
		switch (uExistingType) {
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
				return sDoIPsOverlap (pHostNew, pHostExisting);
			case INSECURE_RANGE :
			case SECURE_RANGE :
				return sDoesRangeOverlapSubnet (pHostExisting, pHostNew);
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				break;
		}
		break;

	case INSECURE_RANGE :
		switch (uExistingType) {
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
				return sDoesRangeOverlapSubnet (pHostNew, pHostExisting);
			case INSECURE_RANGE :
			case SECURE_RANGE :
				return sDoRangesOverlap (pHostNew, pHostExisting);
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				break;
		}
		break;

	case SECURE_HOST :
		switch (uExistingType) {
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				return sDoIPsOverlap (pHostNew, pHostExisting);
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
			case INSECURE_RANGE :
			case SECURE_RANGE :
				break;
		}
		break;

	case SECURE_SUBNET :
		switch (uExistingType) {
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
				return sDoIPsOverlap (pHostNew, pHostExisting);
			case INSECURE_RANGE :
			case SECURE_RANGE :
				return sDoesRangeOverlapSubnet (pHostExisting, pHostNew);
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				break;
		}
		break;

	case SECURE_GATEWAY :
		switch (uExistingType) {
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				return sDoIPsOverlap (pHostNew, pHostExisting);
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
			case INSECURE_RANGE :
			case SECURE_RANGE :
				break;
		}
		break;

	case SECURE_RANGE :
		switch (uExistingType) {
			case INSECURE_SUBNET :
			case SECURE_SUBNET :
				return sDoesRangeOverlapSubnet (pHostNew, pHostExisting);
			case INSECURE_RANGE :
			case SECURE_RANGE :
				return sDoRangesOverlap (pHostNew, pHostExisting);
			case INSECURE_HOST :
			case SECURE_HOST :
			case SECURE_GATEWAY :
				break;
		}
		break;
	}

	return FALSE;
}


//	____________________________________
//
//  Merge two host lists into a third list.
//	All entries in the Base list will be carried over.
//	Only non-conflicting entries in the Adjunct list will 
//  carried over.

PGPError
pgpMergeNetHostLists (
		PGPMemoryMgrRef			memmgr,
		PGPNetPrefHostEntry*	pHostListBase,
		PGPUInt32				uHostCountBase,
		PGPNetPrefHostEntry*	pHostListAdjunct,
		PGPUInt32				uHostCountAdjunct,
		PGPNetPrefHostEntry**	ppHostListMerged,
		PGPUInt32*				puHostCountMerged)
{
	PGPError				err					= kPGPError_NoErr;
	PGPNetPrefHostEntry*	pHostListWorking	= NULL;
	PGPNetPrefHostEntry*	pHostListMerged		= NULL;
	PGPUInt32				uHostCountMerged	= 0;
	PGPUInt32				u, u2, uMerged;
	PGPUInt32				uMergedParent;
	PGPInt32				iRedirectedGateway;

	PGPValidatePtr(pHostListBase);
	PGPValidatePtr(pHostListAdjunct);
	PGPValidatePtr(ppHostListMerged);
	PGPValidatePtr(puHostCountMerged);

	uHostCountMerged = uHostCountBase + uHostCountAdjunct;

	if (uHostCountMerged > 0)
	{
		// allocate space for Working copy of Adjunct list
		pHostListWorking = PGPNewData (memmgr, 
				uHostCountAdjunct * sizeof(PGPNetPrefHostEntry), 
				kPGPMemoryMgrFlags_Clear);

		if (!pHostListWorking)
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}

		// copy the Adjunct list over to new Working list
		pgpCopyMemory (pHostListAdjunct, pHostListWorking, 
				uHostCountAdjunct * sizeof(PGPNetPrefHostEntry));

		// loop through all Adjunct hosts which are not behind gateways
		// and flag all conflicting hosts
		for (u=0; u<uHostCountAdjunct; u++)
		{
			if (pHostListWorking[u].childOf == -1)
			{
				// check against each Base list host
				for (u2=0; u2<uHostCountBase; u2++)
				{
					// if they conflict, then flag the Working copy.
					// A childOf value of -2 indicates that the entry is to 
					// be removed.  A childOf value < -2 indicates that this
					// entry is equivalent to an existing gateway and any
					// children of this gateway should be placed under the
					// existing gateway entry.  The existing gateway entry
					// is encoded in the childOf value as
					//
					//		redirectedGateway = (-childOf) -3
					//
					if (pgpDoNetHostsConflict (
							&pHostListWorking[u], &pHostListBase[u2]))
					{
						if ((pHostListWorking[u].hostType == kPGPnetSecureGateway) &&
							(pHostListBase[u2].hostType == kPGPnetSecureGateway))
						{
							pHostListWorking[u].childOf = -3 - u2;
						}
						else
						{
							pHostListWorking[u].childOf = -2;
						}
						uHostCountMerged--;
					}
				}
			}
		}

		// now loop through all Adjunct hosts which are behind gateways.
		// flag all hosts which are behind flagged gateways or which
		// conflict with the Base list
		for (u=0; u<uHostCountAdjunct; u++)
		{
			if (pHostListWorking[u].childOf >= 0)
			{
				// check if it is behind an already flagged gateway
				if (pHostListWorking[pHostListWorking[u].childOf].childOf == -2)
				{
					pHostListWorking[u].childOf = -2;
					uHostCountMerged--;
				}
				else
				{
					// check against each Base list host
					for (u2=0; u2<uHostCountBase; u2++)
					{
						// if they conflict, then flag the Working copy
						if (pgpDoNetHostsConflict (
								&pHostListWorking[u], &pHostListBase[u2]))
						{
							pHostListWorking[u].childOf = -2;
							uHostCountMerged--;
						}
					}
				}
			}
		}

		// now allocate the Merged list
		pHostListMerged = PGPNewData (memmgr, 
				uHostCountMerged * sizeof(PGPNetPrefHostEntry), 
				kPGPMemoryMgrFlags_Clear);

		if (!pHostListMerged)
		{
			err = kPGPError_OutOfMemory;
			goto done;
		}

		// copy over the entire Base list
		pgpCopyMemory (pHostListBase, pHostListMerged,
				uHostCountBase * sizeof(PGPNetPrefHostEntry));

		// copy over all the unflagged entries from the Working
		// list which are not behind gateways.  copy each
		// entry's children as needed
		uMerged = uHostCountBase;
		for (u=0; u<uHostCountAdjunct; u++)
		{
			if (pHostListWorking[u].childOf == -1)
			{
				pgpCopyMemory (&pHostListWorking[u], 
						&pHostListMerged[uMerged],
						sizeof(PGPNetPrefHostEntry));

				// check for any children and copy them, renumbering
				uMergedParent = uMerged++;
				for (u2=0; u2<uHostCountAdjunct; u2++)
				{
					if (pHostListWorking[u2].childOf == (PGPInt32)u)
					{
						pgpCopyMemory (&pHostListWorking[u2], 
								&pHostListMerged[uMerged],
								sizeof(PGPNetPrefHostEntry));
						pHostListMerged[uMerged].childOf = uMergedParent;

						uMerged++;
					}
				}
			}
		}

		// finally copy over all the unflagged entries from the Working
		// list which are behind redirected gateways. 
		for (u=0; u<uHostCountAdjunct; u++)
		{
			if (pHostListWorking[u].childOf >= 0)
			{
				iRedirectedGateway = 
						pHostListWorking[pHostListWorking[u].childOf].childOf;

				if (iRedirectedGateway < -2)
				{
					pHostListWorking[u].childOf = (-iRedirectedGateway) - 3;

					pgpCopyMemory (&pHostListWorking[u], 
							&pHostListMerged[uMerged],
							sizeof(PGPNetPrefHostEntry));

					uMerged++;
				}
			}
		}
	}

done:
	if (pHostListWorking)
		PGPFreeData (pHostListWorking);

	*puHostCountMerged = uHostCountMerged;
	*ppHostListMerged = pHostListMerged;

	return err;
}



/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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