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.

592 lines
15 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. iplist9x.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. NT4 version of routines to get IP addresses of stack.
  8. Contents:
  9. Dns_GetIpAddressesWin9X
  10. Dns_GetLocalIpAddressArrayWin9X
  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 WIN95_TCPIP_PARAMETERS_KEY "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
  22. #define WIN95_DHCP_KEY "System\\CurrentControlSet\\Services\\VxD\\DHCP"
  23. #define WIN95_NET_TRANS_KEY "System\\CurrentControlSet\\Services\\Class\\NetTrans"
  24. #define DHCP_IP_ADDRESS_VALUE_WIN95 "DhcpIPAddress"
  25. #define DHCP_SUBNET_VALUE_WIN95 "DhcpSubnetMask"
  26. #define STATIC_ADDRESS_VALUE "IPAddress"
  27. #define STATIC_SUBNET_VALUE "IPMask"
  28. #define DHCP_INFO_VALUE "DhcpInfo"
  29. #define DRIVER_DESCRIPTION_VALUE "DriverDesc"
  30. #define TCPIP_DRIVER_DESCRIPTION "TCP/IP"
  31. #define NDISWAN_DRIVER_DESCRIPTION "NDISWAN"
  32. #define KEY_CONNECT "\\"
  33. #define KEY_CONNECT_CHAR '\\'
  34. #define DHCP_IP_ADDRESS_VALUE_TYPE_WIN95 REG_DWORD
  35. #define DHCP_SUBNET_VALUE_TYPE_WIN95 REG_DWORD
  36. #define STATIC_ADDRESS_VALUE_TYPE REG_SZ
  37. #define STATIC_SUBNET_VALUE_TYPE REG_SZ
  38. #define DHCP_INFO_VALUE_TYPE REG_BINARY
  39. #define DRIVER_DESCRIPTION_VALUE_TYPE REG_SZ
  40. typedef DWORD IP_ADDRESS, *PIP_ADDRESS;
  41. typedef struct _ADAPTER_INFO_
  42. {
  43. BOOL IsDhcpEnabled;
  44. PIP_ARRAY pipAddresses;
  45. PIP_ARRAY pipSubnetMasks;
  46. } ADAPTER_INFO, *LPADAPTER_INFO;
  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. PIP_ARRAY
  58. GetIpArray(
  59. BOOL IsMultiSzString,
  60. LPSTR IpAddressString )
  61. {
  62. DWORD NumberOfAddresses;
  63. DWORD StringLen;
  64. LPSTR StringPtr;
  65. DWORD iter;
  66. PIP_ARRAY pIpArray = NULL;
  67. //
  68. // determine number of strings in IpAddressString, that many
  69. // addresses are assigned.
  70. //
  71. StringPtr = IpAddressString;
  72. NumberOfAddresses = 0;
  73. while ( ( StringLen = strlen( StringPtr ) ) != 0 )
  74. {
  75. //
  76. // found another NET.
  77. //
  78. NumberOfAddresses++;
  79. if ( IsMultiSzString )
  80. StringPtr += (StringLen + 1);
  81. else
  82. StringPtr += StringLen;
  83. }
  84. //
  85. // allocate memory for the ADAPTER_INFO array.
  86. //
  87. pIpArray =
  88. ALLOCATE_HEAP_ZERO( sizeof(IP_ADDRESS) * NumberOfAddresses +
  89. sizeof(IP_ARRAY) );
  90. if( pIpArray == NULL )
  91. {
  92. return NULL;
  93. }
  94. //
  95. // enum the addresses.
  96. //
  97. StringPtr = IpAddressString;
  98. NumberOfAddresses = 0;
  99. while ( ( StringLen = strlen( StringPtr ) ) != 0 )
  100. {
  101. IP_ADDRESS ip;
  102. ip = inet_addr( StringPtr );
  103. if( ip != INADDR_ANY && ip != INADDR_NONE )
  104. {
  105. pIpArray->AddrArray[NumberOfAddresses] = ip;
  106. NumberOfAddresses++;
  107. }
  108. if ( IsMultiSzString )
  109. StringPtr += (StringLen + 1);
  110. else
  111. StringPtr += StringLen;
  112. }
  113. pIpArray->AddrCount = NumberOfAddresses;
  114. if ( pIpArray->AddrCount == 0 )
  115. {
  116. FREE_HEAP( pIpArray );
  117. pIpArray = NULL;
  118. }
  119. return pIpArray;
  120. }
  121. PIP_ARRAY
  122. GetMaskArray(
  123. BOOL IsMultiSzString,
  124. LPSTR SubnetMaskString )
  125. {
  126. DWORD NumberOfAddresses;
  127. DWORD StringLen;
  128. LPSTR StringPtr;
  129. DWORD iter;
  130. PIP_ARRAY pIpArray = NULL;
  131. //
  132. // determine number of strings in SubnetMaskString, that many
  133. // addresses are assigned.
  134. //
  135. StringPtr = SubnetMaskString;
  136. NumberOfAddresses = 0;
  137. while ( ( StringLen = strlen( StringPtr ) ) != 0 )
  138. {
  139. //
  140. // found another NET.
  141. //
  142. NumberOfAddresses++;
  143. if ( IsMultiSzString )
  144. StringPtr += (StringLen + 1);
  145. else
  146. StringPtr += StringLen;
  147. }
  148. //
  149. // allocate memory for the ADAPTER_INFO array.
  150. //
  151. pIpArray =
  152. ALLOCATE_HEAP_ZERO( sizeof(IP_ADDRESS) * NumberOfAddresses +
  153. sizeof(IP_ARRAY) );
  154. if( pIpArray == NULL )
  155. {
  156. return NULL;
  157. }
  158. //
  159. // enum the addresses.
  160. //
  161. StringPtr = SubnetMaskString;
  162. NumberOfAddresses = 0;
  163. while ( ( StringLen = strlen( StringPtr ) ) != 0 )
  164. {
  165. IP_ADDRESS ip;
  166. ip = inet_addr( StringPtr );
  167. if( ip != INADDR_ANY )
  168. {
  169. pIpArray->AddrArray[NumberOfAddresses] = ip;
  170. NumberOfAddresses++;
  171. }
  172. if ( IsMultiSzString )
  173. StringPtr += (StringLen + 1);
  174. else
  175. StringPtr += StringLen;
  176. }
  177. pIpArray->AddrCount = NumberOfAddresses;
  178. if ( pIpArray->AddrCount == 0 )
  179. {
  180. FREE_HEAP( pIpArray );
  181. pIpArray = NULL;
  182. }
  183. return pIpArray;
  184. }
  185. /*******************************************************************************
  186. *
  187. * Dns_GetIpAddressesWin9X
  188. *
  189. * Retrieves all active IP addresses from all active adapters on this machine.
  190. * Returns them as an array
  191. *
  192. * ENTRY IpAddressList - pointer to array of IP addresses
  193. * ListCount - number of IP address IpAddressList can hold
  194. *
  195. * EXIT IpAddressList - filled with retrieved IP addresses
  196. *
  197. * RETURNS number of IP addresses retrieved, or 0 if error
  198. *
  199. * ASSUMES 1. an IP address can be represented in a DWORD
  200. * 2. ListCount > 0
  201. *
  202. ******************************************************************************/
  203. DWORD
  204. Dns_GetIpAddressesWin9X(
  205. IN OUT PDNS_ADDRESS_INFO IpAddressInfoList,
  206. IN DWORD ListCount
  207. )
  208. {
  209. DWORD status = NO_ERROR;
  210. DWORD addressCount = 0;
  211. DWORD iter, iter2;
  212. DWORD TotalNumberOfNets;
  213. HKEY AdapterKeyHandle = NULL;
  214. LPADAPTER_INFO AdapterInfoList = NULL;
  215. RtlZeroMemory( IpAddressInfoList, sizeof( DNS_ADDRESS_INFO ) * 10 );
  216. //
  217. // allocate memory for the ADAPTER_INFO array.
  218. //
  219. AdapterInfoList =
  220. ALLOCATE_HEAP( sizeof(ADAPTER_INFO) * 10 );
  221. if( !AdapterInfoList )
  222. return 0;
  223. //
  224. // enum the static and WAN networks.
  225. //
  226. TotalNumberOfNets = 0;
  227. for ( iter = 0; iter < 10; iter++ )
  228. {
  229. char AdapterParamKey[256];
  230. DWORD dwFlags = 0;
  231. char szCount[4];
  232. LPSTR DriverDescription = NULL;
  233. LPSTR IpAddressString = NULL;
  234. //
  235. // open Parameter key of the adapter that is bound to TCPIP.
  236. //
  237. sprintf( szCount, "%d", iter );
  238. strcpy( AdapterParamKey, WIN95_NET_TRANS_KEY );
  239. strcat( AdapterParamKey, "\\000" );
  240. strcat( AdapterParamKey, szCount );
  241. status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  242. AdapterParamKey,
  243. 0,
  244. KEY_QUERY_VALUE,
  245. &AdapterKeyHandle );
  246. if ( status != ERROR_SUCCESS )
  247. {
  248. AdapterKeyHandle = NULL;
  249. goto Skip1;
  250. }
  251. //
  252. // See if this is a TCPIP adapter
  253. //
  254. status = GetRegistryValue( AdapterKeyHandle,
  255. TRUE,
  256. DRIVER_DESCRIPTION_VALUE,
  257. DRIVER_DESCRIPTION_VALUE_TYPE,
  258. (LPBYTE)&DriverDescription );
  259. if ( status != ERROR_SUCCESS || !DriverDescription )
  260. goto Skip1;
  261. if ( DriverDescription &&
  262. strlen( DriverDescription ) == 0 )
  263. {
  264. FREE_HEAP( DriverDescription );
  265. goto Skip1;
  266. }
  267. if ( strcmp( DriverDescription, TCPIP_DRIVER_DESCRIPTION ) )
  268. {
  269. FREE_HEAP( DriverDescription );
  270. goto Skip1;
  271. }
  272. FREE_HEAP( DriverDescription );
  273. //
  274. // This is a TCP/IP adapter, now see if there is an address
  275. // assigned to it
  276. //
  277. status = GetRegistryValue( AdapterKeyHandle,
  278. TRUE,
  279. STATIC_ADDRESS_VALUE,
  280. STATIC_ADDRESS_VALUE_TYPE,
  281. (LPBYTE)&IpAddressString );
  282. if ( status != ERROR_SUCCESS )
  283. goto Skip1;
  284. AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = FALSE;
  285. AdapterInfoList[TotalNumberOfNets].pipAddresses =
  286. GetIpArray( FALSE, IpAddressString );
  287. FREE_HEAP( IpAddressString );
  288. IpAddressString = NULL;
  289. if ( !AdapterInfoList[TotalNumberOfNets].pipAddresses )
  290. goto Skip1;
  291. status = GetRegistryValue( AdapterKeyHandle,
  292. TRUE,
  293. STATIC_SUBNET_VALUE,
  294. STATIC_SUBNET_VALUE_TYPE,
  295. (LPBYTE)&IpAddressString );
  296. if ( status != ERROR_SUCCESS )
  297. {
  298. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  299. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  300. goto Skip1;
  301. }
  302. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
  303. GetMaskArray( FALSE, IpAddressString );
  304. FREE_HEAP( IpAddressString );
  305. IpAddressString = NULL;
  306. if ( !AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  307. {
  308. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  309. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  310. goto Skip1;
  311. }
  312. TotalNumberOfNets++;
  313. Skip1 :
  314. status = ERROR_SUCCESS;
  315. if ( AdapterKeyHandle )
  316. {
  317. RegCloseKey( AdapterKeyHandle );
  318. AdapterKeyHandle = NULL;
  319. }
  320. }
  321. if ( TotalNumberOfNets )
  322. goto Exit;
  323. //
  324. // Loop through each DHCP binding to read the adapter information.
  325. //
  326. for ( iter = 0; iter < 8; iter++ )
  327. {
  328. char AdapterParamKey[256];
  329. DWORD dwFlags = 0;
  330. char szCount[4];
  331. DWORD IpAddress = 0;
  332. DWORD SubnetMask = 0;
  333. //
  334. // open Parameter key of the adapter that is bound to DHCP.
  335. //
  336. sprintf( szCount, "0%d", iter );
  337. strcpy( AdapterParamKey, WIN95_DHCP_KEY );
  338. strcat( AdapterParamKey, "\\DhcpInfo" );
  339. strcat( AdapterParamKey, szCount );
  340. status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  341. AdapterParamKey,
  342. 0,
  343. KEY_QUERY_VALUE,
  344. &AdapterKeyHandle );
  345. if ( status != ERROR_SUCCESS )
  346. {
  347. AdapterKeyHandle = NULL;
  348. goto Skip2;
  349. }
  350. status = GetRegistryValue( AdapterKeyHandle,
  351. TRUE,
  352. DHCP_IP_ADDRESS_VALUE_WIN95,
  353. DHCP_IP_ADDRESS_VALUE_TYPE_WIN95,
  354. (LPBYTE)&IpAddress );
  355. if ( status != ERROR_SUCCESS )
  356. IpAddress = 0;
  357. if ( IpAddress == 0xffffffff )
  358. IpAddress = 0;
  359. if ( IpAddress )
  360. {
  361. //
  362. // It is active, now read the subnet mask
  363. //
  364. status = GetRegistryValue( AdapterKeyHandle,
  365. TRUE,
  366. DHCP_SUBNET_VALUE_WIN95,
  367. DHCP_SUBNET_VALUE_TYPE_WIN95,
  368. (LPBYTE)&SubnetMask );
  369. if ( status != ERROR_SUCCESS )
  370. SubnetMask = 0;
  371. }
  372. else
  373. {
  374. LPBYTE DhcpInfo = NULL;
  375. //
  376. // This may be a Win95 machine, the adapter IP address
  377. // is stored in the DhcpInfo blob.
  378. //
  379. status = GetRegistryValue( AdapterKeyHandle,
  380. TRUE,
  381. DHCP_INFO_VALUE,
  382. DHCP_INFO_VALUE_TYPE,
  383. (LPBYTE)&DhcpInfo );
  384. if ( status != ERROR_SUCCESS )
  385. goto Skip2;
  386. if ( !DhcpInfo )
  387. goto Skip2;
  388. IpAddress = *((LPDWORD)(DhcpInfo+sizeof(DWORD)));
  389. SubnetMask = *((LPDWORD)(DhcpInfo+sizeof(DWORD)+sizeof(DWORD)));
  390. FREE_HEAP( DhcpInfo );
  391. }
  392. if ( IpAddress == 0x00000000 || IpAddress == 0xffffffff )
  393. goto Skip2;
  394. AdapterInfoList[TotalNumberOfNets].IsDhcpEnabled = TRUE;
  395. AdapterInfoList[TotalNumberOfNets].pipAddresses =
  396. Dns_CreateIpArray( 1 );
  397. if ( !AdapterInfoList[TotalNumberOfNets].pipAddresses )
  398. goto Skip2;
  399. AdapterInfoList[TotalNumberOfNets].pipAddresses->AddrArray[0] =
  400. IpAddress;
  401. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks =
  402. Dns_CreateIpArray( 1 );
  403. if ( !AdapterInfoList[TotalNumberOfNets].pipSubnetMasks )
  404. {
  405. FREE_HEAP( AdapterInfoList[TotalNumberOfNets].pipAddresses );
  406. AdapterInfoList[TotalNumberOfNets].pipAddresses = NULL;
  407. goto Skip2;
  408. }
  409. AdapterInfoList[TotalNumberOfNets].pipSubnetMasks->AddrArray[0] =
  410. SubnetMask;
  411. TotalNumberOfNets++;
  412. Skip2 :
  413. status = ERROR_SUCCESS;
  414. if ( AdapterKeyHandle )
  415. {
  416. RegCloseKey( AdapterKeyHandle );
  417. AdapterKeyHandle = NULL;
  418. }
  419. }
  420. Exit :
  421. //
  422. // We now have a data structure that represents the current
  423. // net adapters and assigned IP addresses based on the binding
  424. // order described by the adapter protocol bindings for TCPIP.
  425. //
  426. // Now stuff as many as we can into the users buffer provided.
  427. //
  428. //
  429. // Start by putting the first address from each adapter into the
  430. // IP list.
  431. //
  432. for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
  433. {
  434. IpAddressInfoList[addressCount].ipAddress =
  435. AdapterInfoList[iter].pipAddresses->AddrArray[0];
  436. IpAddressInfoList[addressCount++].subnetMask =
  437. AdapterInfoList[iter].pipSubnetMasks->AddrArray[0];
  438. ListCount--;
  439. }
  440. for ( iter = 0; iter < TotalNumberOfNets && ListCount; iter++ )
  441. {
  442. for ( iter2 = 1;
  443. iter2 < AdapterInfoList[iter].pipAddresses->AddrCount;
  444. iter2++ )
  445. {
  446. IpAddressInfoList[addressCount].ipAddress =
  447. AdapterInfoList[iter].pipAddresses->AddrArray[iter2];
  448. IpAddressInfoList[addressCount++].subnetMask =
  449. AdapterInfoList[iter].pipSubnetMasks->AddrArray[iter2];
  450. ListCount--;
  451. }
  452. }
  453. if( AdapterKeyHandle )
  454. RegCloseKey( AdapterKeyHandle );
  455. for ( iter = 0; iter < TotalNumberOfNets; iter++ )
  456. {
  457. if( AdapterInfoList[iter].pipAddresses )
  458. FREE_HEAP( AdapterInfoList[iter].pipAddresses );
  459. if( AdapterInfoList[iter].pipSubnetMasks )
  460. FREE_HEAP( AdapterInfoList[iter].pipSubnetMasks );
  461. }
  462. FREE_HEAP( AdapterInfoList );
  463. AdapterInfoList = NULL;
  464. return addressCount;
  465. }
  466. //
  467. // End iplist9x.c
  468. //