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.

442 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 2001-2001 Microsoft Corporation
  3. Module Name:
  4. iphelp.c
  5. Abstract:
  6. IP help API routines.
  7. Author:
  8. Jim Gilroy (jamesg) January 2001
  9. Revision History:
  10. --*/
  11. #include "local.h"
  12. BOOL
  13. IpHelp_Initialize(
  14. VOID
  15. )
  16. /*++
  17. Routine Description:
  18. Startup IP Help API
  19. Arguments:
  20. None
  21. Return Value:
  22. TRUE if started successfully.
  23. FALSE on error.
  24. --*/
  25. {
  26. return TRUE;
  27. }
  28. VOID
  29. IpHelp_Cleanup(
  30. VOID
  31. )
  32. /*++
  33. Routine Description:
  34. Cleanup IP Help API
  35. Arguments:
  36. None
  37. Return Value:
  38. None
  39. --*/
  40. {
  41. }
  42. DNS_STATUS
  43. IpHelp_GetAdaptersInfo(
  44. OUT PIP_ADAPTER_INFO * ppAdapterInfo
  45. )
  46. /*++
  47. Routine Description:
  48. Call IP Help GetAdaptersInfo()
  49. Arguments:
  50. ppAdapterInfo -- addr to receive pointer to adapter info retrieved
  51. Return Value:
  52. None
  53. --*/
  54. {
  55. DNS_STATUS status = NO_ERROR;
  56. DWORD bufferSize;
  57. INT fretry;
  58. PIP_ADAPTER_INFO pbuf;
  59. DNSDBG( TRACE, (
  60. "GetAdaptersInfo( %p )\n",
  61. ppAdapterInfo ));
  62. //
  63. // init IP Help (no-op) if already done
  64. //
  65. *ppAdapterInfo = NULL;
  66. //
  67. // call down to get buffer size
  68. //
  69. // start with reasonable alloc, then bump up if too small
  70. //
  71. fretry = 0;
  72. bufferSize = 1000;
  73. while ( fretry < 2 )
  74. {
  75. pbuf = (PIP_ADAPTER_INFO) ALLOCATE_HEAP( bufferSize );
  76. if ( !pbuf )
  77. {
  78. status = DNS_ERROR_NO_MEMORY;
  79. goto Unlock;
  80. }
  81. status = (DNS_STATUS) GetAdaptersInfo(
  82. pbuf,
  83. &bufferSize );
  84. if ( status == NO_ERROR )
  85. {
  86. break;
  87. }
  88. FREE_HEAP( pbuf );
  89. pbuf = NULL;
  90. // if buf too small on first try,
  91. // continue to retry with suggested buffer size
  92. if ( status == ERROR_BUFFER_OVERFLOW ||
  93. status == ERROR_INSUFFICIENT_BUFFER )
  94. {
  95. fretry++;
  96. continue;
  97. }
  98. // any other error is terminal
  99. DNSDBG( ANY, (
  100. "ERROR: GetAdapterInfo() failed with error %d\n",
  101. status ));
  102. status = DNS_ERROR_NO_DNS_SERVERS;
  103. break;
  104. }
  105. DNS_ASSERT( !pbuf || status==NO_ERROR );
  106. if ( status == NO_ERROR )
  107. {
  108. *ppAdapterInfo = pbuf;
  109. }
  110. Unlock:
  111. DNSDBG( TRACE, (
  112. "Leave GetAdaptersInfo() => %d\n",
  113. status ));
  114. return status;
  115. }
  116. DNS_STATUS
  117. IpHelp_GetPerAdapterInfo(
  118. IN DWORD AdapterIndex,
  119. OUT PIP_PER_ADAPTER_INFO * ppPerAdapterInfo
  120. )
  121. /*++
  122. Routine Description:
  123. Call IP Help GetPerAdapterInfo()
  124. Arguments:
  125. AdapterIndex -- index of adapter to get info for
  126. ppPerAdapterInfo -- addr to receive pointer to per adapter info
  127. Return Value:
  128. None
  129. --*/
  130. {
  131. DNS_STATUS status = NO_ERROR;
  132. DWORD bufferSize;
  133. INT fretry;
  134. PIP_PER_ADAPTER_INFO pbuf;
  135. DNSDBG( TRACE, (
  136. "GetPerAdapterInfo( %d, %p )\n",
  137. AdapterIndex,
  138. ppPerAdapterInfo ));
  139. //
  140. // init IP Help (no-op) if already done
  141. //
  142. *ppPerAdapterInfo = NULL;
  143. //
  144. // call down to get buffer size
  145. //
  146. // start with reasonable alloc, then bump up if too small
  147. //
  148. fretry = 0;
  149. bufferSize = 1000;
  150. while ( fretry < 2 )
  151. {
  152. pbuf = (PIP_PER_ADAPTER_INFO) ALLOCATE_HEAP( bufferSize );
  153. if ( !pbuf )
  154. {
  155. status = DNS_ERROR_NO_MEMORY;
  156. goto Unlock;
  157. }
  158. status = (DNS_STATUS) GetPerAdapterInfo(
  159. AdapterIndex,
  160. pbuf,
  161. &bufferSize );
  162. if ( status == NO_ERROR )
  163. {
  164. break;
  165. }
  166. FREE_HEAP( pbuf );
  167. pbuf = NULL;
  168. // if buf too small on first try,
  169. // continue to retry with suggested buffer size
  170. if ( status == ERROR_BUFFER_OVERFLOW ||
  171. status == ERROR_INSUFFICIENT_BUFFER )
  172. {
  173. fretry++;
  174. continue;
  175. }
  176. // any other error is terminal
  177. DNSDBG( ANY, (
  178. "ERROR: GetAdapterInfo() failed with error %d\n",
  179. status ));
  180. status = DNS_ERROR_NO_DNS_SERVERS;
  181. break;
  182. }
  183. DNS_ASSERT( !pbuf || status==NO_ERROR );
  184. if ( status == NO_ERROR )
  185. {
  186. *ppPerAdapterInfo = pbuf;
  187. }
  188. Unlock:
  189. DNSDBG( TRACE, (
  190. "Leave GetPerAdapterInfo() => %d\n",
  191. status ));
  192. return status;
  193. }
  194. DNS_STATUS
  195. IpHelp_GetBestInterface(
  196. IN IP4_ADDRESS Ip4Addr,
  197. OUT PDWORD pdwInterfaceIndex
  198. )
  199. /*++
  200. Routine Description:
  201. Call IP Help GetBestInterface()
  202. Arguments:
  203. Ip4Addr -- IP address to check
  204. pdwInterfaceIndex -- addr to recv interface index
  205. Return Value:
  206. ERROR_SUCCESS if successful.
  207. ErrorCode on failure.
  208. --*/
  209. {
  210. DNS_STATUS status;
  211. DNSDBG( TRACE, (
  212. "GetBestInterface( %08x, %p )\n",
  213. Ip4Addr,
  214. pdwInterfaceIndex ));
  215. //
  216. // init IP Help (no-op) if already done
  217. //
  218. status = (DNS_STATUS) GetBestInterface(
  219. Ip4Addr,
  220. pdwInterfaceIndex );
  221. DNSDBG( TRACE, (
  222. "Leave GetBestInterface() => %d\n"
  223. "\tinterface = %d\n",
  224. status,
  225. *pdwInterfaceIndex ));
  226. return status;
  227. }
  228. DNS_STATUS
  229. IpHelp_ParseIpAddressString(
  230. IN OUT PIP_ARRAY pIpArray,
  231. IN PIP_ADDR_STRING pIpAddrString,
  232. IN BOOL fGetSubnetMask,
  233. IN BOOL fReverse
  234. )
  235. /*++
  236. Routine Description:
  237. Build IP array from IP help IP_ADDR_STRING structure.
  238. Arguments:
  239. pIpArray -- IP array of DNS servers
  240. pIpAddrString -- pointer to address info with address data
  241. fGetSubnetMask -- get subnet masks
  242. fReverse -- reverse the IP array
  243. Return Value:
  244. ERROR_SUCCESS if successful.
  245. DNS_ERROR_NO_DNS_SERVERS if nothing parsed.
  246. --*/
  247. {
  248. PIP_ADDR_STRING pipBlob = pIpAddrString;
  249. IP_ADDRESS ip;
  250. DWORD countServers = pIpArray->AddrCount;
  251. DNSDBG( TRACE, (
  252. "IpHelp_ParseIpAddressString()\n"
  253. "\tout IP array = %p\n"
  254. "\tIP string = %p\n"
  255. "\tsubnet? = %d\n"
  256. "\treverse? = %d\n",
  257. pIpArray,
  258. pIpAddrString,
  259. fGetSubnetMask,
  260. fReverse ));
  261. //
  262. // loop reading IP or subnet
  263. //
  264. // DCR_FIX0: address and subnet will be misaligned if read separately
  265. //
  266. // DCR: move to count\allocate model and if getting subnets get together
  267. //
  268. while ( pipBlob &&
  269. countServers < DNS_MAX_IP_INTERFACE_COUNT )
  270. {
  271. if ( fGetSubnetMask )
  272. {
  273. ip = inet_addr( pipBlob->IpMask.String );
  274. if ( ip != INADDR_ANY )
  275. {
  276. pIpArray->AddrArray[ countServers ] = ip;
  277. countServers++;
  278. }
  279. }
  280. else
  281. {
  282. ip = inet_addr( pipBlob->IpAddress.String );
  283. if ( ip != INADDR_ANY && ip != INADDR_NONE )
  284. {
  285. pIpArray->AddrArray[ countServers ] = ip;
  286. countServers++;
  287. }
  288. }
  289. pipBlob = pipBlob->Next;
  290. }
  291. // reset IP count
  292. pIpArray->AddrCount = countServers;
  293. // reverse array if desired
  294. if ( fReverse )
  295. {
  296. Dns_ReverseOrderOfIpArray( pIpArray );
  297. }
  298. DNSDBG( NETINFO, (
  299. "Leave IpHelp_ParseIpAddressString()\n"
  300. "\tcount = %d\n"
  301. "\tfirst IP = %s\n",
  302. countServers,
  303. countServers
  304. ? IP_STRING( pIpArray->AddrArray[0] )
  305. : "" ));
  306. return ( pIpArray->AddrCount ) ? ERROR_SUCCESS : DNS_ERROR_NO_DNS_SERVERS;
  307. }
  308. //
  309. // End iphelp.c
  310. //