📄 pgpnethostutils.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 + -