Source code of Windows XP (NT5)
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.

473 lines
14 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. iplist4.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. NT4 version of routines to get IP addresses of stack.
  8. Contents:
  9. Dns_GetIpAddressesNT4
  10. Dns_GetLocalIpAddressArrayNt4
  11. Author:
  12. Glenn A. Curtis (glennc) 05-May-1997
  13. Revision History:
  14. 05-May-1997 glennc
  15. Copied from the (NT4 SP3) winsock2 directory
  16. --*/
  17. //
  18. // includes
  19. //
  20. #include "local.h"
  21. #define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
  22. #define ADAPTER_TCPIP_PARMS_KEY "Parameters\\TCPIP"
  23. #define BIND_VALUE "Bind"
  24. #define DHCP_ENABLED_VALUE "EnableDHCP"
  25. #define DHCP_ADDRESS_VALUE "DhcpIPAddress"
  26. #define DHCP_SUBNET_VALUE "DhcpSubnetMask"
  27. #define STATIC_ADDRESS_VALUE "IPAddress"
  28. #define STATIC_SUBNET_VALUE "SubnetMask"
  29. #define KEY_CONNECT "\\"
  30. #define KEY_CONNECT_CHAR '\\'
  31. #define LINKAGE_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Linkage"
  32. #define BIND_VALUE_TYPE REG_MULTI_SZ
  33. #define DHCP_ENABLED_VALUE_TYPE REG_DWORD
  34. #define DHCP_ADDRESS_VALUE_TYPE REG_SZ
  35. #define DHCP_SUBNET_VALUE_TYPE REG_SZ
  36. #define STATIC_ADDRESS_VALUE_TYPE REG_MULTI_SZ
  37. #define STATIC_SUBNET_VALUE_TYPE REG_MULTI_SZ
  38. typedef DWORD IP_ADDRESS, *PIP_ADDRESS;
  39. typedef struct _ADAPTER_INFO_
  40. {
  41. BOOL IsDhcpEnabled;
  42. PIP_ARRAY pipAddresses;
  43. PIP_ARRAY pipSubnetMasks;
  44. } ADAPTER_INFO, *LPADAPTER_INFO;
  45. extern PIP_ARRAY GetIpArray( BOOL, LPSTR );
  46. extern PIP_ARRAY GetMaskArray( BOOL, LPSTR );
  47. //
  48. // Heap operations
  49. //
  50. #define ALLOCATE_HEAP(size) Dns_AllocZero( size )
  51. #define REALLOCATE_HEAP(p,size) Dns_Realloc( (p), (size) )
  52. #define FREE_HEAP(p) Dns_Free( p )
  53. #define ALLOCATE_HEAP_ZERO(size) Dns_AllocZero( size )
  54. //
  55. // functions
  56. //
  57. /*******************************************************************************
  58. *
  59. * Dns_GetIpAddressesNT4
  60. *
  61. * Retrieves all active IP addresses from all active adapters on this machine.
  62. * Returns them as an array
  63. *
  64. * ENTRY IpAddressList - pointer to array of IP addresses
  65. * ListCount - number of IP address IpAddressList can hold
  66. *
  67. * EXIT IpAddressList - filled with retrieved IP addresses
  68. *
  69. * RETURNS number of IP addresses retrieved, or 0 if error
  70. *
  71. * ASSUMES 1. an IP address can be represented in a DWORD
  72. * 2. ListCount > 0
  73. *
  74. ******************************************************************************/
  75. DWORD
  76. Dns_GetIpAddressesNT4(
  77. IN OUT PDNS_ADDRESS_INFO IpAddressInfoList,
  78. IN DWORD ListCount
  79. )
  80. {
  81. DWORD Error;
  82. DWORD addressCount = 0;
  83. HKEY LinkageKeyHandle = NULL;
  84. LPSTR BindString = NULL;
  85. LPSTR StringPtr;
  86. DWORD StringLen;
  87. DWORD iter, iter2;
  88. DWORD NumberOfNets;
  89. DWORD TotalNumberOfNets;
  90. HKEY AdapterKeyHandle = NULL;
  91. LPSTR IpAddressString = NULL;
  92. LPADAPTER_INFO AdapterInfoList = NULL;
  93. RtlZeroMemory( IpAddressInfoList, sizeof( DNS_ADDRESS_INFO ) * ListCount );
  94. //
  95. // open linkage key in the to determine the the nets we are bound
  96. // to.
  97. //
  98. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  99. LINKAGE_KEY,
  100. 0,
  101. KEY_QUERY_VALUE,
  102. &LinkageKeyHandle );
  103. if( Error != ERROR_SUCCESS )
  104. goto Cleanup;
  105. //
  106. // read BIND value.
  107. //
  108. Error = GetRegistryValue( LinkageKeyHandle,
  109. FALSE,
  110. BIND_VALUE,
  111. BIND_VALUE_TYPE,
  112. (LPBYTE)&BindString );
  113. if ( Error != ERROR_SUCCESS )
  114. goto Cleanup;
  115. RegCloseKey( LinkageKeyHandle );
  116. LinkageKeyHandle = NULL;
  117. //
  118. // determine number of string in BindStrings, that many NETs are
  119. // bound.
  120. //
  121. StringPtr = BindString;
  122. NumberOfNets = 0;
  123. while ( (StringLen = strlen(StringPtr)) != 0 )
  124. {
  125. //
  126. // found another NET.
  127. //
  128. NumberOfNets++;
  129. StringPtr += (StringLen + 1); // move to next string.
  130. }
  131. //
  132. // allocate memory for the ADAPTER_INFO array.
  133. //
  134. AdapterInfoList =
  135. ALLOCATE_HEAP( sizeof(ADAPTER_INFO) * NumberOfNets );
  136. if( AdapterInfoList == NULL ) {
  137. Error = ERROR_NOT_ENOUGH_MEMORY;
  138. goto Cleanup;
  139. }
  140. //
  141. // enum the NETs.
  142. //
  143. TotalNumberOfNets = 0;
  144. for ( iter = 0, StringPtr = BindString;
  145. ( ( StringLen = strlen( StringPtr ) ) != 0 );
  146. iter++, StringPtr += ( StringLen + 1 ) )
  147. {
  148. LPSTR AdapterName;
  149. char AdapterParamKey[256];
  150. DWORD EnableDHCPFlag;
  151. //
  152. // open Parameter key of the adapter that is bound to DHCP.
  153. //
  154. AdapterName = strrchr( StringPtr, KEY_CONNECT_CHAR);
  155. if( AdapterName == NULL )
  156. continue;
  157. //
  158. // skip CONNECT_CHAR
  159. //
  160. AdapterName += 1;
  161. if( AdapterName == '\0' )
  162. continue;
  163. strcpy( AdapterParamKey, SERVICES_KEY);
  164. strcat( AdapterParamKey, AdapterName);
  165. strcat( AdapterParamKey, KEY_CONNECT);
  166. strcat( AdapterParamKey, ADAPTER_TCPIP_PARMS_KEY );
  167. Error = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  168. AdapterParamKey,
  169. 0,
  170. KEY_QUERY_VALUE,
  171. &AdapterKeyHandle );
  172. if( Error != ERROR_SUCCESS )
  173. goto Skip;
  174. //
  175. // read DHCPEnableFlag.
  176. //
  177. Error = GetRegistryValue( AdapterKeyHandle,
  178. FALSE,
  179. DHCP_ENABLED_VALUE,
  180. DHCP_ENABLED_VALUE_TYPE,
  181. (LPBYTE)&EnableDHCPFlag );
  182. if ( Error == ERROR_SUCCESS )
  183. {
  184. if ( EnableDHCPFlag )
  185. {
  186. AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = TRUE;
  187. TryRas:
  188. //
  189. // Get the DHCP IP address value
  190. //
  191. Error = GetRegistryValue( AdapterKeyHandle,
  192. FALSE,
  193. DHCP_ADDRESS_VALUE,
  194. DHCP_ADDRESS_VALUE_TYPE,
  195. (LPBYTE)&IpAddressString );
  196. if( Error != ERROR_SUCCESS )
  197. goto Skip;
  198. AdapterInfoList[TotalNumberOfNets].pipAddresses =
  199. GetIpArray( FALSE, IpAddressString );
  200. if ( IpAddressString )
  201. {
  202. FREE_HEAP( IpAddressString );
  203. IpAddressString = NULL;
  204. }
  205. //
  206. // Get the DHCP subnet mask value
  207. //
  208. Error = GetRegistryValue( AdapterKeyHandle,
  209. FALSE,
  210. DHCP_SUBNET_VALUE,
  211. DHCP_SUBNET_VALUE_TYPE,
  212. (LPBYTE)&IpAddressString );
  213. if ( Error != ERROR_SUCCESS )
  214. {
  215. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
  216. {
  217. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  218. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  219. }
  220. goto Skip;
  221. }
  222. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
  223. GetMaskArray( FALSE, IpAddressString );
  224. //
  225. // add this adpter to the list only if the ip address is
  226. // non-zero.
  227. //
  228. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses &&
  229. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  230. {
  231. TotalNumberOfNets++;
  232. }
  233. else
  234. {
  235. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
  236. {
  237. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  238. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  239. }
  240. if ( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  241. {
  242. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks );
  243. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks = NULL;
  244. }
  245. }
  246. }
  247. else
  248. {
  249. AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = FALSE;
  250. //
  251. // Get the Static IP address value(s)
  252. //
  253. Error = GetRegistryValue( AdapterKeyHandle,
  254. FALSE,
  255. STATIC_ADDRESS_VALUE,
  256. STATIC_ADDRESS_VALUE_TYPE,
  257. (LPBYTE)&IpAddressString );
  258. if ( Error != ERROR_SUCCESS )
  259. goto TryRas;
  260. AdapterInfoList[TotalNumberOfNets].pipAddresses =
  261. GetIpArray( TRUE, IpAddressString );
  262. if ( IpAddressString )
  263. {
  264. FREE_HEAP( IpAddressString );
  265. IpAddressString = NULL;
  266. }
  267. //
  268. // Get the Static subnet mask value
  269. //
  270. Error = GetRegistryValue( AdapterKeyHandle,
  271. FALSE,
  272. STATIC_SUBNET_VALUE,
  273. STATIC_SUBNET_VALUE_TYPE,
  274. (LPBYTE)&IpAddressString );
  275. if ( Error != ERROR_SUCCESS )
  276. {
  277. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
  278. {
  279. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  280. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  281. }
  282. goto Skip;
  283. }
  284. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
  285. GetMaskArray( TRUE, IpAddressString );
  286. //
  287. // add this adpter to the list only if the ip address is
  288. // non-zero.
  289. //
  290. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses &&
  291. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  292. {
  293. TotalNumberOfNets++;
  294. }
  295. else
  296. {
  297. FREE_HEAP( IpAddressString );
  298. IpAddressString = NULL;
  299. if ( AdapterInfoList[TotalNumberOfNets].pipAddresses )
  300. {
  301. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  302. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  303. }
  304. if ( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  305. {
  306. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipSubnetMasks );
  307. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks = NULL;
  308. }
  309. goto TryRas;
  310. }
  311. }
  312. }
  313. Skip :
  314. if ( AdapterKeyHandle )
  315. {
  316. RegCloseKey( AdapterKeyHandle );
  317. AdapterKeyHandle = NULL;
  318. }
  319. if ( IpAddressString )
  320. {
  321. FREE_HEAP( IpAddressString );
  322. IpAddressString = NULL;
  323. }
  324. }
  325. //
  326. // We now have a data structure that represents the current
  327. // net adapters and assigned IP addresses based on the binding
  328. // order described by the adapter protocol bindings for TCPIP.
  329. //
  330. // Now stuff as many as we can into the users buffer provided.
  331. //
  332. //
  333. // Start by putting the first address from each adapter into the
  334. // IP list.
  335. //
  336. for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
  337. {
  338. IpAddressInfoList[addressCount].ipAddress =
  339. AdapterInfoList[iter].pipAddresses->AddrArray[0];
  340. IpAddressInfoList[addressCount++].subnetMask =
  341. AdapterInfoList[iter].pipSubnetMasks->AddrArray[0];
  342. ListCount--;
  343. }
  344. for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
  345. {
  346. for ( iter2 = 1;
  347. iter2 < AdapterInfoList[iter].pipAddresses->AddrCount;
  348. iter2++ )
  349. {
  350. IpAddressInfoList[addressCount].ipAddress =
  351. AdapterInfoList[iter].pipAddresses->AddrArray[iter2];
  352. IpAddressInfoList[addressCount++].subnetMask =
  353. AdapterInfoList[iter].pipSubnetMasks->AddrArray[iter2];
  354. ListCount--;
  355. }
  356. }
  357. Cleanup:
  358. if( LinkageKeyHandle )
  359. RegCloseKey( LinkageKeyHandle );
  360. if( BindString )
  361. FREE_HEAP( BindString );
  362. if( AdapterKeyHandle )
  363. RegCloseKey( AdapterKeyHandle );
  364. if( IpAddressString )
  365. FREE_HEAP( IpAddressString );
  366. for ( iter = 0; iter < TotalNumberOfNets; iter++ )
  367. {
  368. if( AdapterInfoList[iter].pipAddresses )
  369. FREE_HEAP( AdapterInfoList[iter].pipAddresses );
  370. if( AdapterInfoList[iter].pipSubnetMasks )
  371. FREE_HEAP( AdapterInfoList[iter].pipSubnetMasks );
  372. }
  373. FREE_HEAP( AdapterInfoList );
  374. AdapterInfoList = NULL;
  375. return addressCount;
  376. }
  377. //
  378. // End iplist4.c
  379. //