Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
7.1 KiB

  1. // Copyright (c) 2000-2001 Microsoft Corporation
  2. //
  3. // Implementation of IConfigureYourServer::IsDhcpConfigured
  4. //
  5. // 20 Apr 2000 sburns
  6. // 06 Feb 2001 jeffjon Copied from CYS HTA sources for use with CYS win32 sources
  7. #include "pch.h"
  8. // make sure the DLLs for all these APIs are present with base install.
  9. // if not, then need to wrap usage in load-lib calls
  10. //
  11. // DhcpLeaseIpAddress DHCPCSVC ok
  12. // DhcpReleaseIpAddressLease DHCPCSVC ok
  13. // DhcpDsInitDS DSAUTH ok
  14. // DhcpAddServerDS DSAUTH ok
  15. // DhcpDsCleanupDS DSAUTH ok
  16. // DhcpGetAllOptions DHCPSAPI ok
  17. // DhcpRpcFreeMemory DHCPSAPI ok
  18. // DhcpEnumSubnets DHCPSAPI ok
  19. // DhcpEnumMscopes DHCPSAPI ok
  20. String
  21. GetIpAddress()
  22. {
  23. LOG_FUNCTION(GetIpAddress);
  24. String result;
  25. HRESULT hr = S_OK;
  26. BYTE* buf = 0;
  27. do
  28. {
  29. // first, determine the size of the table
  30. ULONG tableSize = 0;
  31. DWORD err = ::GetIpAddrTable(0, &tableSize, FALSE);
  32. if (err != ERROR_INSUFFICIENT_BUFFER)
  33. {
  34. LOG(L"GetIpAddrTable for table size failed");
  35. LOG_HRESULT(Win32ToHresult(err));
  36. break;
  37. }
  38. // allocate space for the table.
  39. buf = new BYTE[tableSize + 1];
  40. memset(buf, 0, tableSize + 1);
  41. PMIB_IPADDRTABLE table = reinterpret_cast<PMIB_IPADDRTABLE>(buf);
  42. LOG(L"Calling GetIpAddrTable");
  43. hr =
  44. Win32ToHresult(
  45. ::GetIpAddrTable(
  46. table,
  47. &tableSize,
  48. FALSE));
  49. BREAK_ON_FAILED_HRESULT2(hr, L"GetIpAddrTable failed");
  50. LOG(String::format(L"dwNumEntries: %1!d!", table->dwNumEntries));
  51. for (DWORD i = 0; i < table->dwNumEntries; ++i)
  52. {
  53. DWORD addr = table->table[i].dwAddr;
  54. LOG(String::format(L"entry %1!d!", i));
  55. LOG(String::format(
  56. L"dwAddr %1!X! (%2!d!.%3!d!.%4!d!.%5!d!)",
  57. addr,
  58. ((BYTE*)&addr)[0],
  59. ((BYTE*)&addr)[1],
  60. ((BYTE*)&addr)[2],
  61. ((BYTE*)&addr)[3]));
  62. // skip loopback, etc.
  63. if (
  64. INADDR_ANY == addr
  65. || INADDR_BROADCAST == addr
  66. || INADDR_LOOPBACK == addr
  67. || 0x0100007f == addr )
  68. {
  69. LOG(L"is loopback/broadcast -- skipping");
  70. continue;
  71. }
  72. // Exclude MCAST addresses (class D).
  73. if (
  74. IN_CLASSA(htonl(addr))
  75. || IN_CLASSB(htonl(addr))
  76. || IN_CLASSC(htonl(addr)) )
  77. {
  78. LOG(L"is class A/B/C");
  79. result =
  80. String::format(
  81. L"%1!d!.%2!d!.%3!d!.%4!d!",
  82. ((BYTE*)&addr)[0],
  83. ((BYTE*)&addr)[1],
  84. ((BYTE*)&addr)[2],
  85. ((BYTE*)&addr)[3]);
  86. break;
  87. }
  88. LOG(L"not class A/B/C -- skipping");
  89. }
  90. }
  91. while (0);
  92. delete[] buf;
  93. LOG(result);
  94. LOG_HRESULT(hr);
  95. return result;
  96. }
  97. bool
  98. AreDhcpOptionsPresent(const String& ipAddress)
  99. {
  100. LOG_FUNCTION2(AreDhcpOptionsPresent, ipAddress);
  101. ASSERT(!ipAddress.empty());
  102. bool result = false;
  103. LPDHCP_ALL_OPTIONS options = 0;
  104. do
  105. {
  106. DWORD err =
  107. ::DhcpGetAllOptions(
  108. const_cast<wchar_t*>(ipAddress.c_str()),
  109. 0,
  110. &options);
  111. if (err != ERROR_SUCCESS)
  112. {
  113. LOG(String::format(L"DhcpGetAllOptions failed with 0x%1!08X!", err));
  114. break;
  115. }
  116. if (options)
  117. {
  118. // options are set, so some dhcp configuration was done.
  119. result = true;
  120. break;
  121. }
  122. }
  123. while (0);
  124. if (options)
  125. {
  126. ::DhcpRpcFreeMemory(options);
  127. }
  128. LOG_BOOL(result);
  129. return result;
  130. }
  131. bool
  132. AreDhcpSubnetsPresent(const String& ipAddress)
  133. {
  134. LOG_FUNCTION2(AreDhcpSubnetsPresent, ipAddress);
  135. ASSERT(!ipAddress.empty());
  136. bool result = false;
  137. LPDHCP_IP_ARRAY subnets = 0;
  138. do
  139. {
  140. DHCP_RESUME_HANDLE resume = 0;
  141. DWORD unused1 = 0;
  142. DWORD unused2 = 0;
  143. DWORD err =
  144. ::DhcpEnumSubnets(
  145. ipAddress.c_str(),
  146. &resume,
  147. ~(static_cast<DWORD>(0)),
  148. &subnets,
  149. &unused1,
  150. &unused2);
  151. if (err == ERROR_NO_MORE_ITEMS)
  152. {
  153. // no subnets.
  154. break;
  155. }
  156. if (err != NO_ERROR and err != ERROR_MORE_DATA)
  157. {
  158. LOG(String::format(L"DhcpEnumSubnets failed with 0x%1!08X!", err));
  159. break;
  160. }
  161. ASSERT(subnets);
  162. result = true;
  163. // the resume handle is simply discarded...
  164. }
  165. while (0);
  166. if (subnets)
  167. {
  168. ::DhcpRpcFreeMemory(subnets);
  169. }
  170. LOG_BOOL(result);
  171. return result;
  172. }
  173. bool
  174. AreDhcpMscopesPresent(const String& ipAddress)
  175. {
  176. LOG_FUNCTION2(AreDhcpMscopesPresent, ipAddress);
  177. ASSERT(!ipAddress.empty());
  178. bool result = false;
  179. LPDHCP_MSCOPE_TABLE mscopes = 0;
  180. do
  181. {
  182. DHCP_RESUME_HANDLE resume = 0;
  183. DWORD unused1 = 0;
  184. DWORD unused2 = 0;
  185. DWORD err =
  186. ::DhcpEnumMScopes(
  187. ipAddress.c_str(),
  188. &resume,
  189. ~(static_cast<DWORD>(0)),
  190. &mscopes,
  191. &unused1,
  192. &unused2);
  193. if (err == ERROR_NO_MORE_ITEMS)
  194. {
  195. // no mscopes.
  196. break;
  197. }
  198. if (err != NO_ERROR and err != ERROR_MORE_DATA)
  199. {
  200. LOG(String::format(L"DhcpEnumMscopes failed with 0x%1!08X!", err));
  201. break;
  202. }
  203. ASSERT(mscopes);
  204. result = true;
  205. // the resume handle is simply discarded...
  206. }
  207. while (0);
  208. if (mscopes)
  209. {
  210. ::DhcpRpcFreeMemory(mscopes);
  211. }
  212. LOG_BOOL(result);
  213. return result;
  214. }
  215. bool
  216. IsDhcpConfigured()
  217. {
  218. LOG_FUNCTION(IsDhcpConfigured);
  219. bool result = false;
  220. do
  221. {
  222. // if any of the following return any results, then we consider dhcp to
  223. // have been configured.
  224. //
  225. // DhcpGetAllOptions retrieves the options configured.
  226. // DhcpEnumSubnets retrieves the list of subnets configured.
  227. // DhcpEnumMscopes retrieves the list of mscopes configured.
  228. String ipAddress = GetIpAddress();
  229. if (ipAddress.empty())
  230. {
  231. LOG(L"no ip address");
  232. break;
  233. }
  234. if (AreDhcpOptionsPresent(ipAddress))
  235. {
  236. LOG(L"dchp options found");
  237. result = true;
  238. break;
  239. }
  240. // no options found. go on to next test
  241. if (AreDhcpSubnetsPresent(ipAddress))
  242. {
  243. LOG(L"dchp subnets found");
  244. result = true;
  245. break;
  246. }
  247. // no subnets found. go on.
  248. if (AreDhcpMscopesPresent(ipAddress))
  249. {
  250. LOG(L"dchp mscopes found");
  251. result = true;
  252. break;
  253. }
  254. }
  255. while (0);
  256. LOG_BOOL(result);
  257. return result;
  258. }