/*++ 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 //