windows-nt/Source/XPSP1/NT/admin/cys/win32/isdhcpconfigured.cpp
2020-09-26 16:20:57 +08:00

341 lines
6.7 KiB
C++

// Copyright (c) 2000 Microsoft Corporation
//
// Implementation of IConfigureYourServer::IsDhcpConfigured
//
// 20 Apr 2000 sburns
// 06 Feb 2001 jeffjon Copied from CYS HTA sources for use with CYS win32 sources
#include "pch.h"
// make sure the DLLs for all these APIs are present with base install.
// if not, then need to wrap usage in load-lib calls
//
// DhcpLeaseIpAddress DHCPCSVC ok
// DhcpReleaseIpAddressLease DHCPCSVC ok
// DhcpDsInitDS DSAUTH ok
// DhcpAddServerDS DSAUTH ok
// DhcpDsCleanupDS DSAUTH ok
// DhcpGetAllOptions DHCPSAPI ok
// DhcpRpcFreeMemory DHCPSAPI ok
// DhcpEnumSubnets DHCPSAPI ok
// DhcpEnumMscopes DHCPSAPI ok
String
GetIpAddress()
{
LOG_FUNCTION(GetIpAddress);
String result;
HRESULT hr = S_OK;
BYTE* buf = 0;
do
{
// first, determine the size of the table
ULONG tableSize = 0;
DWORD err = ::GetIpAddrTable(0, &tableSize, FALSE);
if (err != ERROR_INSUFFICIENT_BUFFER)
{
LOG(L"GetIpAddrTable for table size failed");
LOG_HRESULT(Win32ToHresult(err));
break;
}
// allocate space for the table.
buf = new BYTE[tableSize + 1];
memset(buf, 0, tableSize + 1);
PMIB_IPADDRTABLE table = reinterpret_cast<PMIB_IPADDRTABLE>(buf);
LOG(L"Calling GetIpAddrTable");
hr =
Win32ToHresult(
::GetIpAddrTable(
table,
&tableSize,
FALSE));
BREAK_ON_FAILED_HRESULT2(hr, L"GetIpAddrTable failed");
LOG(String::format(L"dwNumEntries: %1!d!", table->dwNumEntries));
for (int i = 0; i < table->dwNumEntries; ++i)
{
DWORD addr = table->table[i].dwAddr;
LOG(String::format(L"entry %1!d!", i));
LOG(String::format(
L"dwAddr %1!X! (%2!d!.%3!d!.%4!d!.%5!d!)",
addr,
((BYTE*)&addr)[0],
((BYTE*)&addr)[1],
((BYTE*)&addr)[2],
((BYTE*)&addr)[3]));
// skip loopback, etc.
if (
INADDR_ANY == addr
|| INADDR_BROADCAST == addr
|| INADDR_LOOPBACK == addr
|| 0x0100007f == addr )
{
LOG(L"is loopback/broadcast -- skipping");
continue;
}
// Exclude MCAST addresses (class D).
if (
IN_CLASSA(htonl(addr))
|| IN_CLASSB(htonl(addr))
|| IN_CLASSC(htonl(addr)) )
{
LOG(L"is class A/B/C");
result =
String::format(
L"%1!d!.%2!d!.%3!d!.%4!d!",
((BYTE*)&addr)[0],
((BYTE*)&addr)[1],
((BYTE*)&addr)[2],
((BYTE*)&addr)[3]);
break;
}
LOG(L"not class A/B/C -- skipping");
}
}
while (0);
delete[] buf;
LOG(result);
LOG_HRESULT(hr);
return result;
}
bool
AreDhcpOptionsPresent(const String& ipAddress)
{
LOG_FUNCTION2(AreDhcpOptionsPresent, ipAddress);
ASSERT(!ipAddress.empty());
bool result = false;
LPDHCP_ALL_OPTIONS options = 0;
do
{
DWORD err =
::DhcpGetAllOptions(
const_cast<wchar_t*>(ipAddress.c_str()),
0,
&options);
if (err != ERROR_SUCCESS)
{
LOG(String::format(L"DhcpGetAllOptions failed with 0x%1!08X!", err));
break;
}
if (options)
{
// options are set, so some dhcp configuration was done.
result = true;
break;
}
}
while (0);
if (options)
{
::DhcpRpcFreeMemory(options);
}
LOG_BOOL(result);
return result;
}
bool
AreDhcpSubnetsPresent(const String& ipAddress)
{
LOG_FUNCTION2(AreDhcpSubnetsPresent, ipAddress);
ASSERT(!ipAddress.empty());
bool result = false;
LPDHCP_IP_ARRAY subnets = 0;
do
{
DHCP_RESUME_HANDLE resume = 0;
DWORD unused1 = 0;
DWORD unused2 = 0;
DWORD err =
::DhcpEnumSubnets(
ipAddress.c_str(),
&resume,
~(static_cast<DWORD>(0)),
&subnets,
&unused1,
&unused2);
if (err == ERROR_NO_MORE_ITEMS)
{
// no subnets.
break;
}
if (err != NO_ERROR and err != ERROR_MORE_DATA)
{
LOG(String::format(L"DhcpEnumSubnets failed with 0x%1!08X!", err));
break;
}
ASSERT(subnets);
result = true;
// the resume handle is simply discarded...
}
while (0);
if (subnets)
{
::DhcpRpcFreeMemory(subnets);
}
LOG_BOOL(result);
return result;
}
bool
AreDhcpMscopesPresent(const String& ipAddress)
{
LOG_FUNCTION2(AreDhcpMscopesPresent, ipAddress);
ASSERT(!ipAddress.empty());
bool result = false;
LPDHCP_MSCOPE_TABLE mscopes = 0;
do
{
DHCP_RESUME_HANDLE resume = 0;
DWORD unused1 = 0;
DWORD unused2 = 0;
DWORD err =
::DhcpEnumMScopes(
ipAddress.c_str(),
&resume,
~(static_cast<DWORD>(0)),
&mscopes,
&unused1,
&unused2);
if (err == ERROR_NO_MORE_ITEMS)
{
// no mscopes.
break;
}
if (err != NO_ERROR and err != ERROR_MORE_DATA)
{
LOG(String::format(L"DhcpEnumMscopes failed with 0x%1!08X!", err));
break;
}
ASSERT(mscopes);
result = true;
// the resume handle is simply discarded...
}
while (0);
if (mscopes)
{
::DhcpRpcFreeMemory(mscopes);
}
LOG_BOOL(result);
return result;
}
bool
IsDhcpConfigured()
{
LOG_FUNCTION(IsDhcpConfigured);
bool result = false;
do
{
// if any of the following return any results, then we consider dhcp to
// have been configured.
//
// DhcpGetAllOptions retrieves the options configured.
// DhcpEnumSubnets retrieves the list of subnets configured.
// DhcpEnumMscopes retrieves the list of mscopes configured.
String ipAddress = GetIpAddress();
if (ipAddress.empty())
{
LOG(L"no ip address");
break;
}
if (AreDhcpOptionsPresent(ipAddress))
{
LOG(L"dchp options found");
result = true;
break;
}
// no options found. go on to next test
if (AreDhcpSubnetsPresent(ipAddress))
{
LOG(L"dchp subnets found");
result = true;
break;
}
// no subnets found. go on.
if (AreDhcpMscopesPresent(ipAddress))
{
LOG(L"dchp mscopes found");
result = true;
break;
}
}
while (0);
LOG_BOOL(result);
return result;
}