windows-nt/Source/XPSP1/NT/ds/dns/dnsapi/iplist.c
2020-09-26 16:20:57 +08:00

318 lines
6.9 KiB
C

/*++
Copyright (c) 1994-2001 Microsoft Corporation
Module Name:
iplist.c
Abstract:
Domain Name System (DNS) Library
Contains functions to get IP addresses from TCP/IP stack
Contents:
Dns_GetIpAddresses
Author:
Glenn A Curtis (glennc) 10-Sept-1997
Revision History:
10-Sept-1997 glennc
Created
--*/
#include "local.h"
//
// Temp structure for holding adapter IP info
//
typedef struct
{
BOOL IsDhcpEnabled;
PIP_ARRAY pIpAddrArray;
PIP_ARRAY pipSubnetMasks;
}
TEMP_ADAPTER_INFO, *PTEMP_ADAPTER_INFO;
//
// DCR: need IP6\cluster aware IP reading
//
/*******************************************************************************
*
* Dns_GetIpAddresses
*
* 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_GetIpAddresses(
IN OUT PDNS_ADDRESS_INFO IpAddressInfoList,
IN DWORD ListCount
)
{
DWORD status = NO_ERROR;
DWORD addressCount = 0;
DWORD i;
DWORD j;
DWORD countAdapters;
PTEMP_ADAPTER_INFO ptempList = NULL;
PIP_ARRAY ptempArray = NULL;
PIP_ADAPTER_INFO padapterInfo = NULL;
PIP_ADAPTER_INFO ptempAdapterInfo = NULL;
//
// clear result buffer
//
RtlZeroMemory(
IpAddressInfoList,
sizeof(DNS_ADDRESS_INFO) * ListCount
);
//
// read adapters info data.
//
status = IpHelp_GetAdaptersInfo( &padapterInfo );
if ( status != ERROR_SUCCESS )
{
return 0;
}
//
// Count up the number of active adapters
//
ptempAdapterInfo = padapterInfo;
countAdapters = 0;
while ( ptempAdapterInfo )
{
ptempAdapterInfo = ptempAdapterInfo->Next;
countAdapters++;
}
//
// allocate memory for the TEMP_ADAPTER_INFO array.
//
ptempList = ALLOCATE_HEAP_ZERO( sizeof(TEMP_ADAPTER_INFO) * countAdapters );
ptempArray = DnsCreateIpArray( DNS_MAX_IP_INTERFACE_COUNT );
if ( !ptempList || !ptempArray )
{
goto Cleanup;
}
//
// build temp structure for each adapter:
// - IP array
// - subnet array
// - DHCP enabled flag
//
// note that IP and subnet arrays are in reverse order from IP help
// to preserve binding order for gethostbyname()
//
// DCR: should have single interface (DNS_ADAPTER) build routine
// and use it to build specific sub-info like global IP list
// DCR: also IPs returned should be name specific -- matching only
// those on a particular adapter
//
countAdapters = 0;
ptempAdapterInfo = padapterInfo;
while ( ptempAdapterInfo )
{
PIP_ARRAY parray;
ptempList[countAdapters].IsDhcpEnabled = ptempAdapterInfo->DhcpEnabled;
// build IP array
ptempArray->AddrCount = 0;
status = IpHelp_ParseIpAddressString(
ptempArray,
&ptempAdapterInfo->IpAddressList,
FALSE, // Get the ip address
TRUE ); // Reverse the order
if ( status != NO_ERROR ||
! (parray = Dns_CreateIpArrayCopy( ptempArray )) )
{
goto Next;
}
ptempList[countAdapters].pIpAddrArray = parray;
// subnet array
ptempArray->AddrCount = 0;
status = IpHelp_ParseIpAddressString(
ptempArray,
&ptempAdapterInfo->IpAddressList,
TRUE, // Get the subnet mask
TRUE ); // Reverse the order
if ( status != NO_ERROR ||
! (parray = Dns_CreateIpArrayCopy( ptempArray )) )
{
FREE_HEAP( ptempList[countAdapters].pIpAddrArray );
goto Next;
}
ptempList[countAdapters].pipSubnetMasks = parray;
countAdapters++;
Next:
ptempAdapterInfo = ptempAdapterInfo->Next;
}
//
// fill up address info blob
// - fill with first IP on each adapter
// - then fill with remaining IPs
//
addressCount = 0;
for ( i = 0;
(i < countAdapters) && ListCount;
i++ )
{
IpAddressInfoList[addressCount].ipAddress =
ptempList[i].pIpAddrArray->AddrArray[0];
IpAddressInfoList[addressCount].subnetMask =
ptempList[i].pipSubnetMasks->AddrArray[0];
ListCount--;
addressCount++;
}
for ( i = 0;
(i < countAdapters) && ListCount;
i++ )
{
for ( j = 1;
j < ptempList[i].pIpAddrArray->AddrCount && ListCount;
j++ )
{
IpAddressInfoList[addressCount].ipAddress =
ptempList[i].pIpAddrArray->AddrArray[j];
IpAddressInfoList[addressCount].subnetMask =
ptempList[i].pipSubnetMasks->AddrArray[j];
ListCount--;
addressCount++;
}
}
Cleanup:
if ( padapterInfo )
{
FREE_HEAP( padapterInfo );
}
if ( ptempArray )
{
FREE_HEAP( ptempArray );
}
if ( ptempList )
{
for ( i = 0; i < countAdapters; i++ )
{
if( ptempList[i].pIpAddrArray )
FREE_HEAP( ptempList[i].pIpAddrArray );
if( ptempList[i].pipSubnetMasks )
FREE_HEAP( ptempList[i].pipSubnetMasks );
}
FREE_HEAP( ptempList );
}
return addressCount;
}
PIP_ARRAY
Dns_GetLocalIpAddressArray(
VOID
)
/*++
Routine Description:
Return the local IP list as IP array.
Arguments:
None.
Return Value:
Ptr to IP array of addresses on local machine.
NULL only on memory allocation failure.
--*/
{
DWORD count;
DWORD i;
PIP_ARRAY pipArray;
PDNS_ADDRESS_INFO pipInfo = NULL;
DNSDBG( NETINFO, ( "Dns_GetLocalIpAddressArray()\n" ));
pipInfo = ALLOCATE_HEAP( DNS_MAX_IP_INTERFACE_COUNT *
sizeof(DNS_ADDRESS_INFO) );
if ( !pipInfo )
{
return NULL;
}
count = Dns_GetIpAddresses(
pipInfo,
DNS_MAX_IP_INTERFACE_COUNT );
pipArray = Dns_CreateIpArray( count );
if ( pipArray )
{
for ( i = 0; i < count; i++ )
{
pipArray->AddrArray[i] = pipInfo[i].ipAddress;
}
}
FREE_HEAP( pipInfo );
return pipArray;
}
//
// End iplist.c
//