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.

317 lines
6.9 KiB

  1. /*++
  2. Copyright (c) 1994-2001 Microsoft Corporation
  3. Module Name:
  4. iplist.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Contains functions to get IP addresses from TCP/IP stack
  8. Contents:
  9. Dns_GetIpAddresses
  10. Author:
  11. Glenn A Curtis (glennc) 10-Sept-1997
  12. Revision History:
  13. 10-Sept-1997 glennc
  14. Created
  15. --*/
  16. #include "local.h"
  17. //
  18. // Temp structure for holding adapter IP info
  19. //
  20. typedef struct
  21. {
  22. BOOL IsDhcpEnabled;
  23. PIP_ARRAY pIpAddrArray;
  24. PIP_ARRAY pipSubnetMasks;
  25. }
  26. TEMP_ADAPTER_INFO, *PTEMP_ADAPTER_INFO;
  27. //
  28. // DCR: need IP6\cluster aware IP reading
  29. //
  30. /*******************************************************************************
  31. *
  32. * Dns_GetIpAddresses
  33. *
  34. * Retrieves all active IP addresses from all active adapters on this machine.
  35. * Returns them as an array
  36. *
  37. * ENTRY IpAddressList - pointer to array of IP addresses
  38. * ListCount - number of IP address IpAddressList can hold
  39. *
  40. * EXIT IpAddressList - filled with retrieved IP addresses
  41. *
  42. * RETURNS number of IP addresses retrieved, or 0 if error
  43. *
  44. * ASSUMES 1. an IP address can be represented in a DWORD
  45. * 2. ListCount > 0
  46. *
  47. ******************************************************************************/
  48. DWORD
  49. Dns_GetIpAddresses(
  50. IN OUT PDNS_ADDRESS_INFO IpAddressInfoList,
  51. IN DWORD ListCount
  52. )
  53. {
  54. DWORD status = NO_ERROR;
  55. DWORD addressCount = 0;
  56. DWORD i;
  57. DWORD j;
  58. DWORD countAdapters;
  59. PTEMP_ADAPTER_INFO ptempList = NULL;
  60. PIP_ARRAY ptempArray = NULL;
  61. PIP_ADAPTER_INFO padapterInfo = NULL;
  62. PIP_ADAPTER_INFO ptempAdapterInfo = NULL;
  63. //
  64. // clear result buffer
  65. //
  66. RtlZeroMemory(
  67. IpAddressInfoList,
  68. sizeof(DNS_ADDRESS_INFO) * ListCount
  69. );
  70. //
  71. // read adapters info data.
  72. //
  73. status = IpHelp_GetAdaptersInfo( &padapterInfo );
  74. if ( status != ERROR_SUCCESS )
  75. {
  76. return 0;
  77. }
  78. //
  79. // Count up the number of active adapters
  80. //
  81. ptempAdapterInfo = padapterInfo;
  82. countAdapters = 0;
  83. while ( ptempAdapterInfo )
  84. {
  85. ptempAdapterInfo = ptempAdapterInfo->Next;
  86. countAdapters++;
  87. }
  88. //
  89. // allocate memory for the TEMP_ADAPTER_INFO array.
  90. //
  91. ptempList = ALLOCATE_HEAP_ZERO( sizeof(TEMP_ADAPTER_INFO) * countAdapters );
  92. ptempArray = DnsCreateIpArray( DNS_MAX_IP_INTERFACE_COUNT );
  93. if ( !ptempList || !ptempArray )
  94. {
  95. goto Cleanup;
  96. }
  97. //
  98. // build temp structure for each adapter:
  99. // - IP array
  100. // - subnet array
  101. // - DHCP enabled flag
  102. //
  103. // note that IP and subnet arrays are in reverse order from IP help
  104. // to preserve binding order for gethostbyname()
  105. //
  106. // DCR: should have single interface (DNS_ADAPTER) build routine
  107. // and use it to build specific sub-info like global IP list
  108. // DCR: also IPs returned should be name specific -- matching only
  109. // those on a particular adapter
  110. //
  111. countAdapters = 0;
  112. ptempAdapterInfo = padapterInfo;
  113. while ( ptempAdapterInfo )
  114. {
  115. PIP_ARRAY parray;
  116. ptempList[countAdapters].IsDhcpEnabled = ptempAdapterInfo->DhcpEnabled;
  117. // build IP array
  118. ptempArray->AddrCount = 0;
  119. status = IpHelp_ParseIpAddressString(
  120. ptempArray,
  121. &ptempAdapterInfo->IpAddressList,
  122. FALSE, // Get the ip address
  123. TRUE ); // Reverse the order
  124. if ( status != NO_ERROR ||
  125. ! (parray = Dns_CreateIpArrayCopy( ptempArray )) )
  126. {
  127. goto Next;
  128. }
  129. ptempList[countAdapters].pIpAddrArray = parray;
  130. // subnet array
  131. ptempArray->AddrCount = 0;
  132. status = IpHelp_ParseIpAddressString(
  133. ptempArray,
  134. &ptempAdapterInfo->IpAddressList,
  135. TRUE, // Get the subnet mask
  136. TRUE ); // Reverse the order
  137. if ( status != NO_ERROR ||
  138. ! (parray = Dns_CreateIpArrayCopy( ptempArray )) )
  139. {
  140. FREE_HEAP( ptempList[countAdapters].pIpAddrArray );
  141. goto Next;
  142. }
  143. ptempList[countAdapters].pipSubnetMasks = parray;
  144. countAdapters++;
  145. Next:
  146. ptempAdapterInfo = ptempAdapterInfo->Next;
  147. }
  148. //
  149. // fill up address info blob
  150. // - fill with first IP on each adapter
  151. // - then fill with remaining IPs
  152. //
  153. addressCount = 0;
  154. for ( i = 0;
  155. (i < countAdapters) && ListCount;
  156. i++ )
  157. {
  158. IpAddressInfoList[addressCount].ipAddress =
  159. ptempList[i].pIpAddrArray->AddrArray[0];
  160. IpAddressInfoList[addressCount].subnetMask =
  161. ptempList[i].pipSubnetMasks->AddrArray[0];
  162. ListCount--;
  163. addressCount++;
  164. }
  165. for ( i = 0;
  166. (i < countAdapters) && ListCount;
  167. i++ )
  168. {
  169. for ( j = 1;
  170. j < ptempList[i].pIpAddrArray->AddrCount && ListCount;
  171. j++ )
  172. {
  173. IpAddressInfoList[addressCount].ipAddress =
  174. ptempList[i].pIpAddrArray->AddrArray[j];
  175. IpAddressInfoList[addressCount].subnetMask =
  176. ptempList[i].pipSubnetMasks->AddrArray[j];
  177. ListCount--;
  178. addressCount++;
  179. }
  180. }
  181. Cleanup:
  182. if ( padapterInfo )
  183. {
  184. FREE_HEAP( padapterInfo );
  185. }
  186. if ( ptempArray )
  187. {
  188. FREE_HEAP( ptempArray );
  189. }
  190. if ( ptempList )
  191. {
  192. for ( i = 0; i < countAdapters; i++ )
  193. {
  194. if( ptempList[i].pIpAddrArray )
  195. FREE_HEAP( ptempList[i].pIpAddrArray );
  196. if( ptempList[i].pipSubnetMasks )
  197. FREE_HEAP( ptempList[i].pipSubnetMasks );
  198. }
  199. FREE_HEAP( ptempList );
  200. }
  201. return addressCount;
  202. }
  203. PIP_ARRAY
  204. Dns_GetLocalIpAddressArray(
  205. VOID
  206. )
  207. /*++
  208. Routine Description:
  209. Return the local IP list as IP array.
  210. Arguments:
  211. None.
  212. Return Value:
  213. Ptr to IP array of addresses on local machine.
  214. NULL only on memory allocation failure.
  215. --*/
  216. {
  217. DWORD count;
  218. DWORD i;
  219. PIP_ARRAY pipArray;
  220. PDNS_ADDRESS_INFO pipInfo = NULL;
  221. DNSDBG( NETINFO, ( "Dns_GetLocalIpAddressArray()\n" ));
  222. pipInfo = ALLOCATE_HEAP( DNS_MAX_IP_INTERFACE_COUNT *
  223. sizeof(DNS_ADDRESS_INFO) );
  224. if ( !pipInfo )
  225. {
  226. return NULL;
  227. }
  228. count = Dns_GetIpAddresses(
  229. pipInfo,
  230. DNS_MAX_IP_INTERFACE_COUNT );
  231. pipArray = Dns_CreateIpArray( count );
  232. if ( pipArray )
  233. {
  234. for ( i = 0; i < count; i++ )
  235. {
  236. pipArray->AddrArray[i] = pipInfo[i].ipAddress;
  237. }
  238. }
  239. FREE_HEAP( pipInfo );
  240. return pipArray;
  241. }
  242. //
  243. // End iplist.c
  244. //