|
|
|
@ -48,92 +48,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
|
#include "../pnUtils.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Private |
|
|
|
|
* |
|
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
// hardcoded uint8_t ordering -- Intel only
|
|
|
|
|
#ifdef _M_IX86 |
|
|
|
|
|
|
|
|
|
const unsigned kHostClassALoopbackAddr = 0x7f000001; // 127.0.0.1
|
|
|
|
|
const unsigned kHostClassALoopbackMask = 0x00ffffff; |
|
|
|
|
const unsigned kNetClassALoopbackAddr = 0x0100007f; // 127.0.0.1
|
|
|
|
|
const unsigned kNetClassALoopbackMask = 0xffffff00; |
|
|
|
|
|
|
|
|
|
const unsigned kHostClassANatAddr = 0x000000a0; // 10.0.0.0 - 10.255.255.255
|
|
|
|
|
const unsigned kHostClassANatMask = 0x000000ff;
|
|
|
|
|
const unsigned kNetClassANatAddr = 0x0a000000; // 10.0.0.0 - 10.255.255.255
|
|
|
|
|
const unsigned kNetClassANatMask = 0xff000000;
|
|
|
|
|
|
|
|
|
|
const unsigned kHostClassBNetAddr = 0x000010ac; // 172.16.0.0 - 172.31.255.255
|
|
|
|
|
const unsigned kHostClassBNetMask = 0x0000f0ff; |
|
|
|
|
const unsigned kNetClassBNetAddr = 0xac100000; // 172.16.0.0 - 172.31.255.255
|
|
|
|
|
const unsigned kNetClassBNetMask = 0xfff00000; |
|
|
|
|
|
|
|
|
|
const unsigned kHostClassCNatAddr = 0x0000a8c0; // 192.168.0.0 - 192.168.255.255
|
|
|
|
|
const unsigned kHostClassCNatMask = 0x0000ffff; |
|
|
|
|
const unsigned kNetClassCNatAddr = 0xc0a80000; // 192.168.0.0 - 192.168.255.255
|
|
|
|
|
const unsigned kNetClassCNatMask = 0xffff0000; |
|
|
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
|
|
#error "Must implement for this architecture" |
|
|
|
|
|
|
|
|
|
#endif // ifdef _M_IX86
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* Internal functions |
|
|
|
|
* |
|
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
// Address sort order:
|
|
|
|
|
// (highest)
|
|
|
|
|
// externally visible address
|
|
|
|
|
// 10.0.0.0 - 10.255.255.255
|
|
|
|
|
// 172.16.0.0 - 172.31.255.255
|
|
|
|
|
// 192.168.0.0 - 192.168.255.255
|
|
|
|
|
// 127.0.0.0 - 127.0.0.255
|
|
|
|
|
// (lowest)
|
|
|
|
|
static int NetAddressNodeSortValueNetOrder (NetAddressNode addr) { |
|
|
|
|
// Loopback addresses
|
|
|
|
|
if ((addr & kNetClassALoopbackMask) == (kNetClassALoopbackAddr & kNetClassALoopbackMask)) |
|
|
|
|
return 4; |
|
|
|
|
|
|
|
|
|
// Private addresses
|
|
|
|
|
if ((addr & kNetClassCNatMask) == (kNetClassCNatAddr & kNetClassCNatMask)) |
|
|
|
|
return 3; |
|
|
|
|
if ((addr & kNetClassBNetMask) == (kNetClassBNetAddr & kNetClassBNetMask)) |
|
|
|
|
return 2; |
|
|
|
|
if ((addr & kNetClassANatMask) == (kNetClassANatAddr & kNetClassANatMask)) |
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
// Public addresses
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
static int NetAddressNodeSortValueHostOrder (NetAddressNode addr) { |
|
|
|
|
// Loopback addresses
|
|
|
|
|
if ((addr & kHostClassALoopbackMask) == (kHostClassALoopbackAddr & kHostClassALoopbackMask)) |
|
|
|
|
return 4; |
|
|
|
|
|
|
|
|
|
// Private addresses
|
|
|
|
|
if ((addr & kHostClassCNatMask) == (kHostClassCNatAddr & kHostClassCNatMask)) |
|
|
|
|
return 3; |
|
|
|
|
if ((addr & kHostClassBNetMask) == (kHostClassBNetAddr & kHostClassBNetMask)) |
|
|
|
|
return 2; |
|
|
|
|
if ((addr & kHostClassANatMask) == (kHostClassANatAddr & kHostClassANatMask)) |
|
|
|
|
return 1; |
|
|
|
|
|
|
|
|
|
// Public addresses
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
static NetAddressNode NodeFromString (const wchar_t * string[]) { |
|
|
|
|
// skip leading whitespace
|
|
|
|
@ -183,21 +103,6 @@ int NetAddressCompare (const NetAddress & a1, const NetAddress & a2) {
|
|
|
|
|
return d ? d : i1.sin_port - i2.sin_port; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
bool NetAddressSameSystem (const NetAddress & a1, const NetAddress & a2) { |
|
|
|
|
const sockaddr_in & i1 = * (const sockaddr_in *) &a1; |
|
|
|
|
const sockaddr_in & i2 = * (const sockaddr_in *) &a2; |
|
|
|
|
return i1.sin_addr.S_un.S_addr == i2.sin_addr.S_un.S_addr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
unsigned NetAddressHash (const NetAddress & addr) { |
|
|
|
|
// by using only the node number as the hash value, users can safely use
|
|
|
|
|
// hash value to find addresses by either using either "SameSystem" or "Equal"
|
|
|
|
|
const sockaddr_in & iAddr = * (const sockaddr_in *) &addr; |
|
|
|
|
return iAddr.sin_addr.S_un.S_addr; |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
void NetAddressToString ( |
|
|
|
|
const NetAddress & addr,
|
|
|
|
@ -294,94 +199,3 @@ void NetAddressNodeToString (
|
|
|
|
|
addr.S_un.S_addr = htonl(node); |
|
|
|
|
StrPrintf(str, chars, L"%S", inet_ntoa(addr)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
NetAddressNode NetAddressNodeFromString ( |
|
|
|
|
const wchar_t string[], |
|
|
|
|
const wchar_t * endPtr[] |
|
|
|
|
) { |
|
|
|
|
if (!endPtr) |
|
|
|
|
endPtr = &string; |
|
|
|
|
*endPtr = string; |
|
|
|
|
return NodeFromString(endPtr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
void NetAddressGetLoopback ( |
|
|
|
|
unsigned port, |
|
|
|
|
NetAddress * addr |
|
|
|
|
) { |
|
|
|
|
NetAddressFromNode( |
|
|
|
|
kHostClassALoopbackAddr, |
|
|
|
|
port, |
|
|
|
|
addr |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
unsigned NetAddressGetLocal ( |
|
|
|
|
unsigned count, |
|
|
|
|
NetAddressNode addresses[] |
|
|
|
|
) { |
|
|
|
|
ASSERT(count); |
|
|
|
|
ASSERT(addresses); |
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
// Get local computer name
|
|
|
|
|
char name[MAX_COMPUTERNAME_LENGTH + 1]; |
|
|
|
|
DWORD size = arrsize(name); |
|
|
|
|
if (!GetComputerName(name, &size)) |
|
|
|
|
StrCopy(name, "localhost", arrsize(name)); |
|
|
|
|
|
|
|
|
|
// Get IPv4 addresses for local system
|
|
|
|
|
const struct hostent * host = gethostbyname(name); |
|
|
|
|
if (!host || !host->h_name) |
|
|
|
|
break; |
|
|
|
|
host = gethostbyname(host->h_name); |
|
|
|
|
if (!host) |
|
|
|
|
break; |
|
|
|
|
if (host->h_length != sizeof(uint32_t)) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// Count total number of addresses
|
|
|
|
|
unsigned found = 0; |
|
|
|
|
const uint32_t ** addr = (const uint32_t **) host->h_addr_list; |
|
|
|
|
for (; *addr; ++addr) |
|
|
|
|
++found; |
|
|
|
|
if (!found) |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// Create a buffer to sort the addresses
|
|
|
|
|
NetAddressNode * dst; |
|
|
|
|
if (found > count) |
|
|
|
|
dst = (NetAddressNode*)_alloca(found * sizeof(NetAddressNode)); |
|
|
|
|
else |
|
|
|
|
dst = addresses; |
|
|
|
|
|
|
|
|
|
// Fill address buffer
|
|
|
|
|
const uint32_t * src = * (const uint32_t **) host->h_addr_list; |
|
|
|
|
for (unsigned index = 0; index < found; ++index) |
|
|
|
|
dst[index] = ntohl(src[index]); |
|
|
|
|
|
|
|
|
|
// Sort addresses by priority
|
|
|
|
|
QSORT( |
|
|
|
|
NetAddressNode, |
|
|
|
|
dst, |
|
|
|
|
found, |
|
|
|
|
NetAddressNodeSortValueHostOrder(elem1) - NetAddressNodeSortValueHostOrder(elem2) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// Return the number of addresses the user actually requested
|
|
|
|
|
if (found > count) { |
|
|
|
|
for (unsigned index = 0; index < count; ++index) |
|
|
|
|
addresses[index] = dst[index]; |
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return found; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Initialize with a valid value
|
|
|
|
|
addresses[0] = kHostClassALoopbackAddr; |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|