443 lines
7.8 KiB
C
443 lines
7.8 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 2001-2001 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
iphelp.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
IP help API routines.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jim Gilroy (jamesg) January 2001
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "local.h"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
IpHelp_Initialize(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Startup IP Help API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if started successfully.
|
|||
|
FALSE on error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
IpHelp_Cleanup(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Cleanup IP Help API
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
IpHelp_GetAdaptersInfo(
|
|||
|
OUT PIP_ADAPTER_INFO * ppAdapterInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Call IP Help GetAdaptersInfo()
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ppAdapterInfo -- addr to receive pointer to adapter info retrieved
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DNS_STATUS status = NO_ERROR;
|
|||
|
DWORD bufferSize;
|
|||
|
INT fretry;
|
|||
|
PIP_ADAPTER_INFO pbuf;
|
|||
|
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"GetAdaptersInfo( %p )\n",
|
|||
|
ppAdapterInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// init IP Help (no-op) if already done
|
|||
|
//
|
|||
|
|
|||
|
*ppAdapterInfo = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// call down to get buffer size
|
|||
|
//
|
|||
|
// start with reasonable alloc, then bump up if too small
|
|||
|
//
|
|||
|
|
|||
|
fretry = 0;
|
|||
|
bufferSize = 1000;
|
|||
|
|
|||
|
while ( fretry < 2 )
|
|||
|
{
|
|||
|
pbuf = (PIP_ADAPTER_INFO) ALLOCATE_HEAP( bufferSize );
|
|||
|
if ( !pbuf )
|
|||
|
{
|
|||
|
status = DNS_ERROR_NO_MEMORY;
|
|||
|
goto Unlock;
|
|||
|
}
|
|||
|
|
|||
|
status = (DNS_STATUS) GetAdaptersInfo(
|
|||
|
pbuf,
|
|||
|
&bufferSize );
|
|||
|
if ( status == NO_ERROR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
FREE_HEAP( pbuf );
|
|||
|
pbuf = NULL;
|
|||
|
|
|||
|
// if buf too small on first try,
|
|||
|
// continue to retry with suggested buffer size
|
|||
|
|
|||
|
if ( status == ERROR_BUFFER_OVERFLOW ||
|
|||
|
status == ERROR_INSUFFICIENT_BUFFER )
|
|||
|
{
|
|||
|
fretry++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// any other error is terminal
|
|||
|
|
|||
|
DNSDBG( ANY, (
|
|||
|
"ERROR: GetAdapterInfo() failed with error %d\n",
|
|||
|
status ));
|
|||
|
status = DNS_ERROR_NO_DNS_SERVERS;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
DNS_ASSERT( !pbuf || status==NO_ERROR );
|
|||
|
|
|||
|
if ( status == NO_ERROR )
|
|||
|
{
|
|||
|
*ppAdapterInfo = pbuf;
|
|||
|
}
|
|||
|
|
|||
|
Unlock:
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"Leave GetAdaptersInfo() => %d\n",
|
|||
|
status ));
|
|||
|
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
IpHelp_GetPerAdapterInfo(
|
|||
|
IN DWORD AdapterIndex,
|
|||
|
OUT PIP_PER_ADAPTER_INFO * ppPerAdapterInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Call IP Help GetPerAdapterInfo()
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
AdapterIndex -- index of adapter to get info for
|
|||
|
|
|||
|
ppPerAdapterInfo -- addr to receive pointer to per adapter info
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DNS_STATUS status = NO_ERROR;
|
|||
|
DWORD bufferSize;
|
|||
|
INT fretry;
|
|||
|
PIP_PER_ADAPTER_INFO pbuf;
|
|||
|
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"GetPerAdapterInfo( %d, %p )\n",
|
|||
|
AdapterIndex,
|
|||
|
ppPerAdapterInfo ));
|
|||
|
|
|||
|
//
|
|||
|
// init IP Help (no-op) if already done
|
|||
|
//
|
|||
|
|
|||
|
*ppPerAdapterInfo = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// call down to get buffer size
|
|||
|
//
|
|||
|
// start with reasonable alloc, then bump up if too small
|
|||
|
//
|
|||
|
|
|||
|
fretry = 0;
|
|||
|
bufferSize = 1000;
|
|||
|
|
|||
|
while ( fretry < 2 )
|
|||
|
{
|
|||
|
pbuf = (PIP_PER_ADAPTER_INFO) ALLOCATE_HEAP( bufferSize );
|
|||
|
if ( !pbuf )
|
|||
|
{
|
|||
|
status = DNS_ERROR_NO_MEMORY;
|
|||
|
goto Unlock;
|
|||
|
}
|
|||
|
|
|||
|
status = (DNS_STATUS) GetPerAdapterInfo(
|
|||
|
AdapterIndex,
|
|||
|
pbuf,
|
|||
|
&bufferSize );
|
|||
|
if ( status == NO_ERROR )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
FREE_HEAP( pbuf );
|
|||
|
pbuf = NULL;
|
|||
|
|
|||
|
// if buf too small on first try,
|
|||
|
// continue to retry with suggested buffer size
|
|||
|
|
|||
|
if ( status == ERROR_BUFFER_OVERFLOW ||
|
|||
|
status == ERROR_INSUFFICIENT_BUFFER )
|
|||
|
{
|
|||
|
fretry++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// any other error is terminal
|
|||
|
|
|||
|
DNSDBG( ANY, (
|
|||
|
"ERROR: GetAdapterInfo() failed with error %d\n",
|
|||
|
status ));
|
|||
|
status = DNS_ERROR_NO_DNS_SERVERS;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
DNS_ASSERT( !pbuf || status==NO_ERROR );
|
|||
|
|
|||
|
if ( status == NO_ERROR )
|
|||
|
{
|
|||
|
*ppPerAdapterInfo = pbuf;
|
|||
|
}
|
|||
|
|
|||
|
Unlock:
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"Leave GetPerAdapterInfo() => %d\n",
|
|||
|
status ));
|
|||
|
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
IpHelp_GetBestInterface(
|
|||
|
IN IP4_ADDRESS Ip4Addr,
|
|||
|
OUT PDWORD pdwInterfaceIndex
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Call IP Help GetBestInterface()
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Ip4Addr -- IP address to check
|
|||
|
|
|||
|
pdwInterfaceIndex -- addr to recv interface index
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
ErrorCode on failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"GetBestInterface( %08x, %p )\n",
|
|||
|
Ip4Addr,
|
|||
|
pdwInterfaceIndex ));
|
|||
|
|
|||
|
//
|
|||
|
// init IP Help (no-op) if already done
|
|||
|
//
|
|||
|
|
|||
|
status = (DNS_STATUS) GetBestInterface(
|
|||
|
Ip4Addr,
|
|||
|
pdwInterfaceIndex );
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"Leave GetBestInterface() => %d\n"
|
|||
|
"\tinterface = %d\n",
|
|||
|
status,
|
|||
|
*pdwInterfaceIndex ));
|
|||
|
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
IpHelp_ParseIpAddressString(
|
|||
|
IN OUT PIP_ARRAY pIpArray,
|
|||
|
IN PIP_ADDR_STRING pIpAddrString,
|
|||
|
IN BOOL fGetSubnetMask,
|
|||
|
IN BOOL fReverse
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Build IP array from IP help IP_ADDR_STRING structure.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pIpArray -- IP array of DNS servers
|
|||
|
|
|||
|
pIpAddrString -- pointer to address info with address data
|
|||
|
|
|||
|
fGetSubnetMask -- get subnet masks
|
|||
|
|
|||
|
fReverse -- reverse the IP array
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful.
|
|||
|
DNS_ERROR_NO_DNS_SERVERS if nothing parsed.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PIP_ADDR_STRING pipBlob = pIpAddrString;
|
|||
|
IP_ADDRESS ip;
|
|||
|
DWORD countServers = pIpArray->AddrCount;
|
|||
|
|
|||
|
DNSDBG( TRACE, (
|
|||
|
"IpHelp_ParseIpAddressString()\n"
|
|||
|
"\tout IP array = %p\n"
|
|||
|
"\tIP string = %p\n"
|
|||
|
"\tsubnet? = %d\n"
|
|||
|
"\treverse? = %d\n",
|
|||
|
pIpArray,
|
|||
|
pIpAddrString,
|
|||
|
fGetSubnetMask,
|
|||
|
fReverse ));
|
|||
|
|
|||
|
//
|
|||
|
// loop reading IP or subnet
|
|||
|
//
|
|||
|
// DCR_FIX0: address and subnet will be misaligned if read separately
|
|||
|
//
|
|||
|
// DCR: move to count\allocate model and if getting subnets get together
|
|||
|
//
|
|||
|
|
|||
|
while ( pipBlob &&
|
|||
|
countServers < DNS_MAX_IP_INTERFACE_COUNT )
|
|||
|
{
|
|||
|
if ( fGetSubnetMask )
|
|||
|
{
|
|||
|
ip = inet_addr( pipBlob->IpMask.String );
|
|||
|
|
|||
|
if ( ip != INADDR_ANY )
|
|||
|
{
|
|||
|
pIpArray->AddrArray[ countServers ] = ip;
|
|||
|
countServers++;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ip = inet_addr( pipBlob->IpAddress.String );
|
|||
|
|
|||
|
if ( ip != INADDR_ANY && ip != INADDR_NONE )
|
|||
|
{
|
|||
|
pIpArray->AddrArray[ countServers ] = ip;
|
|||
|
countServers++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
pipBlob = pipBlob->Next;
|
|||
|
}
|
|||
|
|
|||
|
// reset IP count
|
|||
|
|
|||
|
pIpArray->AddrCount = countServers;
|
|||
|
|
|||
|
// reverse array if desired
|
|||
|
|
|||
|
if ( fReverse )
|
|||
|
{
|
|||
|
Dns_ReverseOrderOfIpArray( pIpArray );
|
|||
|
}
|
|||
|
|
|||
|
DNSDBG( NETINFO, (
|
|||
|
"Leave IpHelp_ParseIpAddressString()\n"
|
|||
|
"\tcount = %d\n"
|
|||
|
"\tfirst IP = %s\n",
|
|||
|
countServers,
|
|||
|
countServers
|
|||
|
? IP_STRING( pIpArray->AddrArray[0] )
|
|||
|
: "" ));
|
|||
|
|
|||
|
return ( pIpArray->AddrCount ) ? ERROR_SUCCESS : DNS_ERROR_NO_DNS_SERVERS;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// End iphelp.c
|
|||
|
//
|
|||
|
|