|
|
// Copyright (c) 2000-2001 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 (DWORD 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; }
|