474 lines
14 KiB
C
474 lines
14 KiB
C
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
iplist4.c
|
|
|
|
Abstract:
|
|
|
|
Domain Name System (DNS) Library
|
|
|
|
NT4 version of routines to get IP addresses of stack.
|
|
|
|
Contents:
|
|
Dns_GetIpAddressesNT4
|
|
Dns_GetLocalIpAddressArrayNt4
|
|
|
|
Author:
|
|
|
|
Glenn A. Curtis (glennc) 05-May-1997
|
|
|
|
Revision History:
|
|
|
|
05-May-1997 glennc
|
|
Copied from the (NT4 SP3) winsock2 directory
|
|
|
|
--*/
|
|
|
|
//
|
|
// includes
|
|
//
|
|
|
|
#include "local.h"
|
|
|
|
#define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
|
|
#define ADAPTER_TCPIP_PARMS_KEY "Parameters\\TCPIP"
|
|
#define BIND_VALUE "Bind"
|
|
#define DHCP_ENABLED_VALUE "EnableDHCP"
|
|
#define DHCP_ADDRESS_VALUE "DhcpIPAddress"
|
|
#define DHCP_SUBNET_VALUE "DhcpSubnetMask"
|
|
#define STATIC_ADDRESS_VALUE "IPAddress"
|
|
#define STATIC_SUBNET_VALUE "SubnetMask"
|
|
#define KEY_CONNECT "\\"
|
|
#define KEY_CONNECT_CHAR '\\'
|
|
#define LINKAGE_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Linkage"
|
|
#define BIND_VALUE_TYPE REG_MULTI_SZ
|
|
#define DHCP_ENABLED_VALUE_TYPE REG_DWORD
|
|
#define DHCP_ADDRESS_VALUE_TYPE REG_SZ
|
|
#define DHCP_SUBNET_VALUE_TYPE REG_SZ
|
|
#define STATIC_ADDRESS_VALUE_TYPE REG_MULTI_SZ
|
|
#define STATIC_SUBNET_VALUE_TYPE REG_MULTI_SZ
|
|
|
|
typedef DWORD IP_ADDRESS, *PIP_ADDRESS;
|
|
|
|
typedef struct _ADAPTER_INFO_
|
|
{
|
|
BOOL IsDhcpEnabled;
|
|
PIP_ARRAY pipAddresses;
|
|
PIP_ARRAY pipSubnetMasks;
|
|
|
|
} ADAPTER_INFO, *LPADAPTER_INFO;
|
|
|
|
extern PIP_ARRAY GetIpArray( BOOL, LPSTR );
|
|
extern PIP_ARRAY GetMaskArray( BOOL, LPSTR );
|
|
|
|
//
|
|
// Heap operations
|
|
//
|
|
|
|
#define ALLOCATE_HEAP(size) Dns_AllocZero( size )
|
|
#define REALLOCATE_HEAP(p,size) Dns_Realloc( (p), (size) )
|
|
#define FREE_HEAP(p) Dns_Free( p )
|
|
#define ALLOCATE_HEAP_ZERO(size) Dns_AllocZero( size )
|
|
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* Dns_GetIpAddressesNT4
|
|
*
|
|
* Retrieves all active IP addresses from all active adapters on this machine.
|
|
* Returns them as an array
|
|
*
|
|
* ENTRY IpAddressList - pointer to array of IP addresses
|
|
* ListCount - number of IP address IpAddressList can hold
|
|
*
|
|
* EXIT IpAddressList - filled with retrieved IP addresses
|
|
*
|
|
* RETURNS number of IP addresses retrieved, or 0 if error
|
|
*
|
|
* ASSUMES 1. an IP address can be represented in a DWORD
|
|
* 2. ListCount > 0
|
|
*
|
|
******************************************************************************/
|
|
|
|
DWORD
|
|
Dns_GetIpAddressesNT4(
|
|
IN OUT PDNS_ADDRESS_INFO IpAddressInfoList,
|
|
IN DWORD ListCount
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DWORD addressCount = 0;
|
|
HKEY LinkageKeyHandle = NULL;
|
|
LPSTR BindString = NULL;
|
|
LPSTR StringPtr;
|
|
DWORD StringLen;
|
|
DWORD iter, iter2;
|
|
DWORD NumberOfNets;
|
|
DWORD TotalNumberOfNets;
|
|
HKEY AdapterKeyHandle = NULL;
|
|
LPSTR IpAddressString = NULL;
|
|
LPADAPTER_INFO AdapterInfoList = NULL;
|
|
|
|
RtlZeroMemory( IpAddressInfoList, sizeof( DNS_ADDRESS_INFO ) * ListCount );
|
|
|
|
//
|
|
// open linkage key in the to determine the the nets we are bound
|
|
// to.
|
|
//
|
|
|
|
Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
LINKAGE_KEY,
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&LinkageKeyHandle );
|
|
|
|
if( Error != ERROR_SUCCESS )
|
|
goto Cleanup;
|
|
|
|
//
|
|
// read BIND value.
|
|
//
|
|
|
|
Error = GetRegistryValue( LinkageKeyHandle,
|
|
FALSE,
|
|
BIND_VALUE,
|
|
BIND_VALUE_TYPE,
|
|
(LPBYTE)&BindString );
|
|
|
|
if ( Error != ERROR_SUCCESS )
|
|
goto Cleanup;
|
|
|
|
RegCloseKey( LinkageKeyHandle );
|
|
LinkageKeyHandle = NULL;
|
|
|
|
//
|
|
// determine number of string in BindStrings, that many NETs are
|
|
// bound.
|
|
//
|
|
|
|
StringPtr = BindString;
|
|
NumberOfNets = 0;
|
|
while ( (StringLen = strlen(StringPtr)) != 0 )
|
|
{
|
|
//
|
|
// found another NET.
|
|
//
|
|
NumberOfNets++;
|
|
StringPtr += (StringLen + 1); // move to next string.
|
|
}
|
|
|
|
//
|
|
// allocate memory for the ADAPTER_INFO array.
|
|
//
|
|
|
|
AdapterInfoList =
|
|
ALLOCATE_HEAP( sizeof(ADAPTER_INFO) * NumberOfNets );
|
|
|
|
if( AdapterInfoList == NULL ) {
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// enum the NETs.
|
|
//
|
|
|
|
TotalNumberOfNets = 0;
|
|
|
|
for ( iter = 0, StringPtr = BindString;
|
|
( ( StringLen = strlen( StringPtr ) ) != 0 );
|
|
iter++, StringPtr += ( StringLen + 1 ) )
|
|
{
|
|
LPSTR AdapterName;
|
|
char AdapterParamKey[256];
|
|
DWORD EnableDHCPFlag;
|
|
|
|
//
|
|
// open Parameter key of the adapter that is bound to DHCP.
|
|
//
|
|
|
|
AdapterName = strrchr( StringPtr, KEY_CONNECT_CHAR);
|
|
|
|
if( AdapterName == NULL )
|
|
continue;
|
|
|
|
//
|
|
// skip CONNECT_CHAR
|
|
//
|
|
|
|
AdapterName += 1;
|
|
|
|
if( AdapterName == '\0' )
|
|
continue;
|
|
|
|
strcpy( AdapterParamKey, SERVICES_KEY);
|
|
strcat( AdapterParamKey, AdapterName);
|
|
strcat( AdapterParamKey, KEY_CONNECT);
|
|
strcat( AdapterParamKey, ADAPTER_TCPIP_PARMS_KEY );
|
|
|
|
Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
|
AdapterParamKey,
|
|
0,
|
|
KEY_QUERY_VALUE,
|
|
&AdapterKeyHandle );
|
|
|
|
if( Error != ERROR_SUCCESS )
|
|
goto Skip;
|
|
|
|
//
|
|
// read DHCPEnableFlag.
|
|
//
|
|
|
|
Error = GetRegistryValue( AdapterKeyHandle,
|
|
FALSE,
|
|
DHCP_ENABLED_VALUE,
|
|
DHCP_ENABLED_VALUE_TYPE,
|
|
(LPBYTE)&EnableDHCPFlag );
|
|
|
|
if ( Error == ERROR_SUCCESS )
|
|
{
|
|
if ( EnableDHCPFlag )
|
|
{
|
|
AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = TRUE;
|
|
|
|
TryRas:
|
|
|
|
//
|
|
// Get the DHCP IP address value
|
|
//
|
|
Error = GetRegistryValue( AdapterKeyHandle,
|
|
FALSE,
|
|
DHCP_ADDRESS_VALUE,
|
|
DHCP_ADDRESS_VALUE_TYPE,
|
|
(LPBYTE)&IpAddressString );
|
|
|
|
if( Error != ERROR_SUCCESS )
|
|
goto Skip;
|
|
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses =
|
|
GetIpArray( FALSE, IpAddressString );
|
|
|
|
if ( IpAddressString )
|
|
{
|
|
FREE_HEAP( IpAddressString );
|
|
IpAddressString = NULL;
|
|
}
|
|
|
|
//
|
|
// Get the DHCP subnet mask value
|
|
//
|
|
Error = GetRegistryValue( AdapterKeyHandle,
|
|
FALSE,
|
|
DHCP_SUBNET_VALUE,
|
|
DHCP_SUBNET_VALUE_TYPE,
|
|
(LPBYTE)&IpAddressString );
|
|
|
|
if ( Error != ERROR_SUCCESS )
|
|
{
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
|
|
}
|
|
|
|
goto Skip;
|
|
}
|
|
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
|
|
GetMaskArray( FALSE, IpAddressString );
|
|
|
|
//
|
|
// add this adpter to the list only if the ip address is
|
|
// non-zero.
|
|
//
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses &&
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
|
|
{
|
|
TotalNumberOfNets++;
|
|
}
|
|
else
|
|
{
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
|
|
}
|
|
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks );
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks = NULL;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = FALSE;
|
|
|
|
//
|
|
// Get the Static IP address value(s)
|
|
//
|
|
Error = GetRegistryValue( AdapterKeyHandle,
|
|
FALSE,
|
|
STATIC_ADDRESS_VALUE,
|
|
STATIC_ADDRESS_VALUE_TYPE,
|
|
(LPBYTE)&IpAddressString );
|
|
|
|
if ( Error != ERROR_SUCCESS )
|
|
goto TryRas;
|
|
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses =
|
|
GetIpArray( TRUE, IpAddressString );
|
|
|
|
if ( IpAddressString )
|
|
{
|
|
FREE_HEAP( IpAddressString );
|
|
IpAddressString = NULL;
|
|
}
|
|
|
|
//
|
|
// Get the Static subnet mask value
|
|
//
|
|
Error = GetRegistryValue( AdapterKeyHandle,
|
|
FALSE,
|
|
STATIC_SUBNET_VALUE,
|
|
STATIC_SUBNET_VALUE_TYPE,
|
|
(LPBYTE)&IpAddressString );
|
|
|
|
if ( Error != ERROR_SUCCESS )
|
|
{
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
|
|
}
|
|
|
|
goto Skip;
|
|
}
|
|
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
|
|
GetMaskArray( TRUE, IpAddressString );
|
|
|
|
//
|
|
// add this adpter to the list only if the ip address is
|
|
// non-zero.
|
|
//
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses &&
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
|
|
{
|
|
TotalNumberOfNets++;
|
|
}
|
|
else
|
|
{
|
|
FREE_HEAP( IpAddressString );
|
|
IpAddressString = NULL;
|
|
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
|
|
AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
|
|
}
|
|
|
|
if ( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
|
|
{
|
|
FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks );
|
|
AdapterInfoList[TotalNumberOfNets].pipSubnetMasks = NULL;
|
|
}
|
|
|
|
goto TryRas;
|
|
}
|
|
}
|
|
}
|
|
|
|
Skip :
|
|
|
|
if ( AdapterKeyHandle )
|
|
{
|
|
RegCloseKey( AdapterKeyHandle );
|
|
AdapterKeyHandle = NULL;
|
|
}
|
|
|
|
if ( IpAddressString )
|
|
{
|
|
FREE_HEAP( IpAddressString );
|
|
IpAddressString = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We now have a data structure that represents the current
|
|
// net adapters and assigned IP addresses based on the binding
|
|
// order described by the adapter protocol bindings for TCPIP.
|
|
//
|
|
// Now stuff as many as we can into the users buffer provided.
|
|
//
|
|
|
|
//
|
|
// Start by putting the first address from each adapter into the
|
|
// IP list.
|
|
//
|
|
for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
|
|
{
|
|
IpAddressInfoList[addressCount].ipAddress =
|
|
AdapterInfoList[iter].pipAddresses->AddrArray[0];
|
|
IpAddressInfoList[addressCount++].subnetMask =
|
|
AdapterInfoList[iter].pipSubnetMasks->AddrArray[0];
|
|
ListCount--;
|
|
}
|
|
|
|
for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
|
|
{
|
|
for ( iter2 = 1;
|
|
iter2 < AdapterInfoList[iter].pipAddresses->AddrCount;
|
|
iter2++ )
|
|
{
|
|
IpAddressInfoList[addressCount].ipAddress =
|
|
AdapterInfoList[iter].pipAddresses->AddrArray[iter2];
|
|
IpAddressInfoList[addressCount++].subnetMask =
|
|
AdapterInfoList[iter].pipSubnetMasks->AddrArray[iter2];
|
|
ListCount--;
|
|
}
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if( LinkageKeyHandle )
|
|
RegCloseKey( LinkageKeyHandle );
|
|
|
|
if( BindString )
|
|
FREE_HEAP( BindString );
|
|
|
|
if( AdapterKeyHandle )
|
|
RegCloseKey( AdapterKeyHandle );
|
|
|
|
if( IpAddressString )
|
|
FREE_HEAP( IpAddressString );
|
|
|
|
for ( iter = 0; iter < TotalNumberOfNets; iter++ )
|
|
{
|
|
if( AdapterInfoList[iter].pipAddresses )
|
|
FREE_HEAP( AdapterInfoList[iter].pipAddresses );
|
|
|
|
if( AdapterInfoList[iter].pipSubnetMasks )
|
|
FREE_HEAP( AdapterInfoList[iter].pipSubnetMasks );
|
|
}
|
|
|
|
FREE_HEAP( AdapterInfoList );
|
|
|
|
AdapterInfoList = NULL;
|
|
|
|
return addressCount;
|
|
}
|
|
|
|
//
|
|
// End iplist4.c
|
|
//
|
|
|