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.

806 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000
  5. //
  6. // File: N E T I P. C P P
  7. //
  8. // Contents: Routines supporting RAS interoperability
  9. //
  10. // Notes:
  11. //
  12. // Author: billi 07 03 2001
  13. //
  14. // History:
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "stdafx.h"
  18. #include "Util.h"
  19. #include "TheApp.h"
  20. #include <lmjoin.h>
  21. #include <devguid.h>
  22. #include "NetIp.h"
  23. #include "netutil.h"
  24. HRESULT HrGetHostIpList( char* pszHost, IPAddr* pIpAddress, LPHOSTENT* ppHostEnt )
  25. //+---------------------------------------------------------------------------
  26. //
  27. // Function: HrGetHostIpList
  28. //
  29. // Purpose:
  30. //
  31. // Arguments:
  32. //
  33. // Returns: S_OK on success, otherwise an error code
  34. //
  35. // Notes:
  36. //
  37. {
  38. ASSERT( pszHost );
  39. ASSERT( pIpAddress );
  40. ASSERT( ppHostEnt );
  41. HRESULT hr = E_INVALIDARG;
  42. if ( pIpAddress )
  43. *pIpAddress = INADDR_NONE;
  44. if ( ppHostEnt )
  45. *ppHostEnt = NULL;
  46. if ( pszHost && ( pIpAddress || ppHostEnt ) )
  47. {
  48. hr = E_FAIL;
  49. *pIpAddress = inet_addr( pszHost );
  50. if ( INADDR_NONE == *pIpAddress )
  51. {
  52. LPHOSTENT pHost;
  53. pHost = gethostbyname( pszHost );
  54. if ( pHost && pHost->h_addr_list )
  55. {
  56. #ifdef DBG // checked build
  57. for ( DWORD i=0; pHost->h_addr_list[i]; i++ )
  58. {
  59. char* pszName = (char *)(pHost->h_addr_list[i]) + sizeof(DWORD);
  60. DWORD* pdwAddr = (DWORD *)(pHost->h_addr_list[i]);
  61. struct in_addr in;
  62. in.S_un.S_addr = *pdwAddr;
  63. char* pszAddr = inet_ntoa( in );
  64. TraceMsg(TF_ALWAYS, " Addr[%d] = %S %p %S", i, pszName, pdwAddr, pszAddr );
  65. }
  66. #endif // DBG
  67. if ( pIpAddress )
  68. *pIpAddress = *(IPAddr*)(pHost->h_addr);
  69. if ( ppHostEnt )
  70. *ppHostEnt = pHost;
  71. }
  72. }
  73. if ( INADDR_NONE != *pIpAddress )
  74. {
  75. hr = S_OK;
  76. }
  77. }
  78. TraceMsg(TF_ALWAYS, "HrGetHostIpList = %lx pHostEnt = %lx IpAddress = %lx", hr, *ppHostEnt, *pIpAddress );
  79. return hr;
  80. }
  81. HRESULT HrGetHostIpList( WCHAR* pszwHost, IPAddr* pIpAddress, LPHOSTENT* ppHostEnt )
  82. //+---------------------------------------------------------------------------
  83. //
  84. // Function: HrGetHostIpList
  85. //
  86. // Purpose:
  87. //
  88. // Arguments:
  89. //
  90. // Returns: S_OK on success, otherwise an error code
  91. //
  92. // Notes:
  93. //
  94. {
  95. HRESULT hr;
  96. char* pszHost = NULL;
  97. hr = HrWideCharToMultiByte( pszwHost, &pszHost );
  98. if ( SUCCEEDED(hr) )
  99. {
  100. hr = HrGetHostIpList( pszHost, pIpAddress, ppHostEnt );
  101. delete [] pszHost;
  102. }
  103. return hr;
  104. }
  105. HRESULT HrGetBestAdapter( IPAddr IpAddress, PIP_ADAPTER_INDEX_MAP pAdapter )
  106. //+---------------------------------------------------------------------------
  107. //
  108. // Function: HrGetBestAdapter
  109. //
  110. // Purpose:
  111. //
  112. // Arguments:
  113. //
  114. // Returns: S_OK on success, otherwise an error code
  115. //
  116. // Notes:
  117. //
  118. {
  119. ASSERT( pAdapter );
  120. HRESULT hr = E_FAIL;
  121. TraceMsg(TF_ALWAYS, " %lu:", IpAddress);
  122. DWORD dwBestIfIndex = 0;
  123. DWORD dwErr = GetBestInterface( IpAddress, &dwBestIfIndex );
  124. if ( ERROR_SUCCESS == dwErr )
  125. {
  126. ULONG ulLen = 1024;
  127. for ( int i=0; i<2; i++ )
  128. {
  129. PIP_INTERFACE_INFO pIfTable = (PIP_INTERFACE_INFO)new BYTE[ ulLen ];
  130. if ( NULL != pIfTable )
  131. {
  132. ZeroMemory( pIfTable, ulLen*sizeof(BYTE) );
  133. dwErr = GetInterfaceInfo( pIfTable, &ulLen );
  134. if ( ERROR_SUCCESS == dwErr )
  135. {
  136. for ( LONG j=0L; j<pIfTable->NumAdapters; j++ )
  137. {
  138. TraceMsg(TF_ALWAYS, " %lu %s", pIfTable->Adapter[j].Index, pIfTable->Adapter[j].Name);
  139. if ( pIfTable->Adapter[j].Index == dwBestIfIndex )
  140. {
  141. memcpy( pAdapter, pIfTable->Adapter, sizeof(IP_ADAPTER_INDEX_MAP) );
  142. hr = S_OK;
  143. break;
  144. }
  145. }
  146. }
  147. delete [] (BYTE *)pIfTable;
  148. }
  149. else
  150. {
  151. TraceMsg(TF_ERROR, "new Failed!" );
  152. break;
  153. }
  154. if ( ERROR_INSUFFICIENT_BUFFER != dwErr )
  155. break;
  156. }
  157. }
  158. else
  159. {
  160. TraceMsg(TF_ERROR, "GetBestInterface Failed = %lx", dwErr);
  161. }
  162. TraceMsg(TF_ALWAYS, "HrGetBestAdapter = %lx", hr);
  163. return hr;
  164. }
  165. HRESULT HrCheckForAdapterMatch(
  166. INetConnection* pConnection,
  167. PIP_ADAPTER_INDEX_MAP pAdapter,
  168. BOOL* pfAssociated )
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Function: HrCheckForAdapterMatch
  172. //
  173. // Purpose:
  174. //
  175. // Arguments:
  176. //
  177. // Returns: S_OK on success, otherwise an error code
  178. //
  179. // Notes:
  180. //
  181. {
  182. HRESULT hr;
  183. NETCON_PROPERTIES* pProps;
  184. ASSERT( pConnection );
  185. ASSERT( pAdapter );
  186. ASSERT( pfAssociated );
  187. *pfAssociated = FALSE;
  188. hr = pConnection->GetProperties( &pProps );
  189. if ( SUCCEEDED(hr) )
  190. {
  191. OLECHAR szwGuid[ GUID_LENGTH + 1 ];
  192. if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
  193. {
  194. long index = wcslen( pAdapter->Name ) - wcslen( szwGuid );
  195. ASSERT( 0 <= index );
  196. WCHAR* pszwGuidName = &(pAdapter->Name[index]);
  197. TraceMsg(TF_ALWAYS, " - %s", szwGuid );
  198. TraceMsg(TF_ALWAYS, " - %s", pszwGuidName );
  199. if ( ( wcscmp( szwGuid, pszwGuidName ) == 0 ) )
  200. {
  201. TraceMsg(TF_ALWAYS, " FOUNT IT! %s", pProps->pszwName );
  202. *pfAssociated = TRUE;
  203. }
  204. }
  205. NcFreeNetconProperties( pProps );
  206. }
  207. TraceMsg(TF_ALWAYS, "HrCheckForAdapterMatch = %lx", hr);
  208. return hr;
  209. }
  210. HRESULT HrCheckListForMatch(
  211. INetConnection* pConnection,
  212. IPAddr IpAddress,
  213. LPHOSTENT pHostEnt,
  214. BOOL* pfAssociated )
  215. //+---------------------------------------------------------------------------
  216. //
  217. // Function: HrCheckListForMatch
  218. //
  219. // Purpose:
  220. //
  221. // Arguments:
  222. //
  223. // Returns: S_OK on success, otherwise an error code
  224. //
  225. // Notes:
  226. //
  227. {
  228. // If IpAdress or pHostEnt->h_addr INADDR_NONE then the HRESULT is still successful
  229. HRESULT hr = S_OK;
  230. ASSERT( pConnection );
  231. ASSERT( pfAssociated );
  232. IP_ADAPTER_INDEX_MAP Adapter;
  233. *pfAssociated = FALSE;
  234. if ( NULL != pHostEnt )
  235. {
  236. int i;
  237. for ( i=0; pHostEnt->h_addr_list[i]; i++ )
  238. {
  239. IpAddress = *(IPAddr *)(pHostEnt->h_addr_list[i]);
  240. if ( INADDR_NONE != IpAddress )
  241. {
  242. hr = HrGetBestAdapter( IpAddress, &Adapter );
  243. if ( SUCCEEDED(hr) )
  244. {
  245. hr = HrCheckForAdapterMatch( pConnection, &Adapter, pfAssociated );
  246. if ( *pfAssociated )
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. else
  253. {
  254. if ( INADDR_NONE != IpAddress )
  255. {
  256. // The name was an ip address
  257. hr = HrGetBestAdapter( IpAddress, &Adapter );
  258. if ( SUCCEEDED(hr) )
  259. {
  260. hr = HrCheckForAdapterMatch( pConnection, &Adapter, pfAssociated );
  261. }
  262. }
  263. }
  264. TraceMsg(TF_ALWAYS, "HrCheckListForMatch = %lx", hr);
  265. return hr;
  266. }
  267. HRESULT HrInternalGetAdapterInfo(
  268. PIP_ADAPTER_INFO* ppAdapter
  269. )
  270. //+---------------------------------------------------------------------------
  271. //
  272. // Function: HrInternalGetAdapterInfo
  273. //
  274. // Purpose:
  275. //
  276. // Arguments: PIP_ADAPTER_INFO* ppAdapter
  277. //
  278. // Returns: HRESULT
  279. //
  280. // Author: billi 12/02/01
  281. //
  282. // Notes:
  283. //
  284. {
  285. HRESULT hr;
  286. PIP_ADAPTER_INFO paAdapterInfo = NULL;
  287. ASSERT( ppAdapter );
  288. if ( NULL == ppAdapter )
  289. {
  290. ppAdapter = &paAdapterInfo;
  291. hr = E_POINTER;
  292. }
  293. else
  294. {
  295. ULONG uLen = 1024;
  296. *ppAdapter = NULL;
  297. hr = E_FAIL;
  298. for ( int i=0; i<2; i++ )
  299. {
  300. PIP_ADAPTER_INFO pInfo = (PIP_ADAPTER_INFO)new BYTE[ uLen ];
  301. ZeroMemory( pInfo, uLen );
  302. if ( NULL != pInfo )
  303. {
  304. DWORD dwErr = GetAdaptersInfo( pInfo, &uLen );
  305. if ( ERROR_SUCCESS == dwErr )
  306. {
  307. hr = S_OK;
  308. *ppAdapter = pInfo;
  309. break;
  310. }
  311. delete [] (BYTE *)pInfo;
  312. }
  313. else
  314. {
  315. hr = E_OUTOFMEMORY;
  316. break;
  317. }
  318. }
  319. }
  320. TraceMsg(TF_ALWAYS, "HrInternalGetAdapterInfo = %lx Info = %lx", hr, *ppAdapter);
  321. return hr;
  322. }
  323. HRESULT HrGetAdapterInfo(
  324. INetConnection* pConnection,
  325. PIP_ADAPTER_INFO* ppAdapter
  326. )
  327. //+---------------------------------------------------------------------------
  328. //
  329. // Function: HrGetAdapterInfo
  330. //
  331. // Purpose:
  332. //
  333. // Arguments: INetConnection* pConnection
  334. // PIP_ADAPTER_INFO* ppAdapter
  335. //
  336. // Returns: HRESULT
  337. //
  338. // Author: billi 12/02/01
  339. //
  340. // Notes:
  341. //
  342. {
  343. HRESULT hr;
  344. NETCON_PROPERTIES* pProps;
  345. ASSERT( pConnection );
  346. ASSERT( ppAdapter );
  347. *ppAdapter = NULL;
  348. hr = pConnection->GetProperties( &pProps );
  349. if ( SUCCEEDED(hr) )
  350. {
  351. OLECHAR szwGuid[ GUID_LENGTH + 1 ];
  352. hr = E_FAIL; // assume failure
  353. if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
  354. {
  355. char* szGuid = NULL;
  356. hr = HrWideCharToMultiByte( szwGuid, &szGuid );
  357. if ( SUCCEEDED(hr) )
  358. {
  359. PIP_ADAPTER_INFO pInfo;
  360. TraceMsg(TF_ALWAYS, "%S:", szGuid);
  361. hr = HrInternalGetAdapterInfo( &pInfo );
  362. if ( SUCCEEDED(hr) )
  363. {
  364. PIP_ADAPTER_INFO pAdapter = pInfo;
  365. hr = E_FAIL; // Assume the loop fails...
  366. while ( pAdapter )
  367. {
  368. TraceMsg(TF_ALWAYS, " %S", pAdapter->AdapterName);
  369. if ( ( strcmp( szGuid, pAdapter->AdapterName ) == 0 ) )
  370. {
  371. TraceMsg(TF_ALWAYS, " Found It!");
  372. PIP_ADAPTER_INFO pBuf = new IP_ADAPTER_INFO;
  373. if ( NULL != pBuf )
  374. {
  375. memcpy( pBuf, pAdapter, sizeof(IP_ADAPTER_INFO) );
  376. *ppAdapter = pBuf;
  377. hr = S_OK;
  378. break;
  379. }
  380. } // if ( ( strcmp( szGuid, pAdapter->AdapterName ) == 0 ) )
  381. pAdapter = pAdapter->Next;
  382. } // while ( pAdapter )
  383. if ( NULL == *ppAdapter )
  384. {
  385. hr = HrFromWin32Error( ERROR_FILE_NOT_FOUND );
  386. }
  387. delete pInfo;
  388. } // if ( SUCCEEDED(hr) )
  389. delete [] szGuid;
  390. } // if ( SUCCEEDED(hr) )
  391. } // if ( StringFromGUID2( pProps->guidId, szwGuid, GUID_LENGTH+1 ) )
  392. NcFreeNetconProperties( pProps );
  393. } // if ( SUCCEEDED(hr) )
  394. TraceMsg(TF_ALWAYS, "HrGetAdapterInfo = %lx Info = %lx", hr, *ppAdapter);
  395. return hr;
  396. }
  397. HRESULT HrGetHostByAddr(
  398. IPAddr IpAddress,
  399. WCHAR** ppszHost,
  400. PDWORD pdwSize
  401. )
  402. //+---------------------------------------------------------------------------
  403. //
  404. // Function: HrGetHostByAddr
  405. //
  406. // Purpose:
  407. //
  408. // Arguments:
  409. //
  410. // Returns: HRESULT
  411. //
  412. // Author: billi 05/08/01
  413. //
  414. // Notes:
  415. //
  416. {
  417. HRESULT hr = E_INVALIDARG;
  418. if ( ppszHost )
  419. *ppszHost = 0;
  420. if ( pdwSize )
  421. *pdwSize = 0;
  422. if ( INADDR_NONE != IpAddress )
  423. {
  424. LPHOSTENT pHostEnt = gethostbyaddr( (char*)&IpAddress, sizeof(IPAddr), AF_INET );
  425. int iErr = WSAGetLastError();
  426. switch ( iErr )
  427. {
  428. case WSANOTINITIALISED:
  429. case WSAENETDOWN:
  430. case WSANO_RECOVERY:
  431. case WSAEFAULT:
  432. hr = E_FAIL;
  433. break;
  434. case NO_ERROR:
  435. hr = S_OK;
  436. ASSERT( pHostEnt );
  437. break;
  438. case WSAHOST_NOT_FOUND:
  439. default:
  440. hr = S_FALSE;
  441. break;
  442. }
  443. if ( SUCCEEDED(hr) && pHostEnt && pHostEnt->h_name && ppszHost && pdwSize )
  444. {
  445. char* pName = pHostEnt->h_name;
  446. int iLen = strlen( pName ) + 1;
  447. DWORD dwSize = 0;
  448. dwSize = MultiByteToWideChar( CP_ACP, 0, pName, iLen, NULL, 0 );
  449. if ( dwSize > 0 )
  450. {
  451. WCHAR* pszName = new WCHAR[ ++dwSize ];
  452. if ( pszName )
  453. {
  454. if ( MultiByteToWideChar( CP_ACP, 0, pName, iLen, pszName, dwSize ) == 0 )
  455. {
  456. hr = HrFromLastWin32Error();
  457. *ppszHost = 0;
  458. delete [] pszName;
  459. }
  460. else
  461. {
  462. *pdwSize = dwSize;
  463. *ppszHost = pszName;
  464. }
  465. }
  466. else
  467. {
  468. hr = E_OUTOFMEMORY;
  469. }
  470. } // if ( dwSize > 0 )
  471. else
  472. {
  473. TraceMsg(TF_ERROR, " MultiByteToWideChar returned %lx wchars", dwSize );
  474. }
  475. TraceMsg(TF_ALWAYS, " %lx: %S", IpAddress, pHostEnt->h_name, pHostEnt->h_name );
  476. } // if ( SUCCEEDED(hr) && ...
  477. } // if ( INADDR_NONE != IpAddress )
  478. TraceMsg(TF_ALWAYS, "HrGetHostByAddr = %lx", hr);
  479. return hr;
  480. }
  481. HRESULT HrSendArp(
  482. INetConnection* pConnection,
  483. IPAddr DestIp,
  484. PULONG pMacAddr,
  485. PULONG pAddrLen
  486. )
  487. //+---------------------------------------------------------------------------
  488. //
  489. // Function: HrSendArp
  490. //
  491. // Purpose:
  492. //
  493. // Arguments:
  494. //
  495. // Returns: HRESULT
  496. //
  497. // Author: billi 05/08/01
  498. //
  499. // Notes:
  500. //
  501. {
  502. HRESULT hr = E_POINTER;
  503. ASSERT( pMacAddr );
  504. ASSERT( pAddrLen );
  505. if ( pMacAddr ) *pMacAddr = 0L;
  506. if ( pMacAddr && pAddrLen )
  507. {
  508. hr = E_INVALIDARG;
  509. if ( pConnection && ( INADDR_NONE != DestIp ) )
  510. {
  511. PIP_ADAPTER_INFO pAdapter;
  512. hr = HrGetAdapterInfo( pConnection, &pAdapter );
  513. if ( NULL == pAdapter )
  514. {
  515. hr = E_FAIL;
  516. }
  517. if ( SUCCEEDED(hr) )
  518. {
  519. hr = E_FAIL;
  520. // Make sure the target IP address isn't already cached,
  521. // by removing it from the ARP cache if present using the interface index
  522. // determined above.
  523. MIB_IPNETROW IpNetRow;
  524. CHAR HardwareAddress[MAXLEN_PHYSADDR];
  525. ULONG HardwareAddressLength;
  526. ULONG SrcIp;
  527. DWORD dwRet;
  528. SrcIp = inet_addr( pAdapter->IpAddressList.IpAddress.String );
  529. ZeroMemory( &IpNetRow, sizeof(IpNetRow) );
  530. IpNetRow.dwIndex = pAdapter->Index;
  531. IpNetRow.dwPhysAddrLen = MAXLEN_PHYSADDR;
  532. IpNetRow.dwAddr = DestIp;
  533. IpNetRow.dwType = MIB_IPNET_TYPE_INVALID;
  534. dwRet = DeleteIpNetEntry( &IpNetRow );
  535. TraceMsg( TF_ALWAYS, "SendArp: DestIp = %lu SrcIp = %lu Ret = %lx", DestIp, SrcIp, dwRet );
  536. if ( ( INADDR_NONE != SrcIp ) && ( NO_ERROR == dwRet ) )
  537. {
  538. HardwareAddressLength = MAXLEN_PHYSADDR;
  539. if ( SendARP( DestIp, SrcIp, (PULONG)HardwareAddress, &HardwareAddressLength ) == NO_ERROR )
  540. {
  541. hr = S_OK;
  542. if ( HardwareAddressLength < *pAddrLen )
  543. {
  544. *pAddrLen = HardwareAddressLength;
  545. }
  546. memcpy( pMacAddr, HardwareAddress, *pAddrLen );
  547. }
  548. TraceMsg(TF_ALWAYS, "\t%02x %02x %02x %02x %02x %02x Len=%lu",
  549. HardwareAddress[0] & 0x0ff,
  550. HardwareAddress[1] & 0x0ff,
  551. HardwareAddress[2] & 0x0ff,
  552. HardwareAddress[3] & 0x0ff,
  553. HardwareAddress[4] & 0x0ff,
  554. HardwareAddress[5] & 0x0ff,
  555. *pAddrLen);
  556. }
  557. delete pAdapter;
  558. } // if ( SUCCEEDED(hr) )
  559. } // if ( pConnection && ( INADDR_NONE != DestIp ) )
  560. } // if ( pMacAddr && pAddrLen )
  561. TraceMsg( TF_ALWAYS, "HrSendArp = %lx", hr );
  562. return hr;
  563. }
  564. HRESULT HrLookupForIpAddress(
  565. INetConnection* pConnection,
  566. IPAddr IpAddress,
  567. BOOL* pfExists,
  568. WCHAR** ppszHost,
  569. PDWORD pdwSize
  570. )
  571. //+---------------------------------------------------------------------------
  572. //
  573. // Function: HrLookupForIpAddress
  574. //
  575. // Purpose:
  576. //
  577. // Arguments:
  578. //
  579. // Returns: HRESULT
  580. //
  581. // Author: billi 12/02/01
  582. //
  583. // Notes:
  584. //
  585. {
  586. HRESULT hr = E_POINTER;
  587. ASSERT( pfExists );
  588. ASSERT( pConnection );
  589. ASSERT( INADDR_NONE != IpAddress );
  590. if ( ppszHost && *ppszHost ) *ppszHost = NULL;
  591. if ( pdwSize ) *pdwSize = NULL;
  592. if ( pfExists )
  593. {
  594. hr = E_INVALIDARG;
  595. *pfExists = FALSE;
  596. if ( pConnection && ( INADDR_NONE != IpAddress ) )
  597. {
  598. WSADATA WsaData;
  599. int iErr;
  600. iErr = WSAStartup( MAKEWORD(2, 0), &WsaData );
  601. if ( ERROR_SUCCESS == iErr )
  602. {
  603. // This is taking to long and No One is using the host name in the wizard.
  604. // hr = HrGetHostByAddr( IpAddress, ppszHost, pdwSize );
  605. hr = S_OK;
  606. if ( S_OK == hr )
  607. {
  608. CHAR MacAddr[6];
  609. ULONG ulAddrLen = 6L;
  610. hr = HrSendArp( pConnection, IpAddress, (PULONG)MacAddr, &ulAddrLen );
  611. if ( SUCCEEDED(hr) && ulAddrLen )
  612. {
  613. *pfExists = TRUE;
  614. }
  615. }
  616. else if ( S_FALSE == hr )
  617. {
  618. hr = S_OK;
  619. *pfExists = FALSE;
  620. }
  621. WSACleanup();
  622. } // if ( ERROR_SUCCESS == iErr )
  623. else
  624. {
  625. TraceMsg(TF_ERROR, "WSAStartup Failed = %lu", iErr );
  626. hr = E_FAIL;
  627. }
  628. } // if ( pConnection && ( INADDR_NONE != IpAddress ) )
  629. } // if ( pfExists )
  630. TraceMsg(TF_ALWAYS, "HrLookupForIpAddress = %lx, Exists = %lx", hr, *pfExists);
  631. return hr;
  632. }