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.

1443 lines
49 KiB

  1. //++
  2. //
  3. // Copyright (C) Microsoft Corporation, 1987 - 1999
  4. //
  5. // Module Name:
  6. //
  7. // netstat.c
  8. //
  9. // Abstract:
  10. //
  11. // Queries into network drivers
  12. //
  13. // Author:
  14. //
  15. // Anilth - 4-20-1998
  16. //
  17. // Environment:
  18. //
  19. // User mode only.
  20. // Contains NT-specific code.
  21. //
  22. // Revision History:
  23. //
  24. //--
  25. #include "precomp.h"
  26. #include <snmp.h>
  27. #include "snmputil.h"
  28. #include "tcpinfo.h"
  29. #include "ipinfo.h"
  30. #include "llinfo.h"
  31. #define MAX_HOST_NAME_SIZE ( 260)
  32. #define MAX_SERVICE_NAME_SIZE ( 200)
  33. #define MAX_NUM_DIGITS 30
  34. BOOL NumFlag = FALSE;
  35. LPTSTR FormatNumber(DWORD dwNumber);
  36. VOID DisplayInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  37. IfEntry *pEntry, IfEntry *ListHead ); //used in DoInterface()
  38. HRESULT DoInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  39. static DWORD
  40. GenerateHostNameServiceString(
  41. OUT char * pszBuffer,
  42. IN OUT int * lpcbBufLen,
  43. IN BOOL fNumFlag,
  44. IN BOOL fLocalHost,
  45. IN const char * pszProtocol,
  46. IN ulong uAddress,
  47. IN ulong uPort
  48. );
  49. void DisplayTcpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  50. TcpConnEntry *pTcp );
  51. void DisplayUdpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  52. UdpConnEntry *pUdp );
  53. HRESULT DoConnections( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  54. void DisplayIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  55. IpEntry *pEntry); //called by DoIp
  56. HRESULT DoIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  57. void DisplayTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  58. TcpEntry *pEntry );
  59. HRESULT DoTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  60. VOID DisplayUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  61. UdpEntry *pEntry ); // called by DoUDP()
  62. HRESULT DoUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  63. void DisplayICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  64. IcmpEntry *pEntry );
  65. HRESULT DoICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults );
  66. BOOL
  67. NetstatTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  68. //++
  69. // Description:
  70. // This test prints all the stats that netstat outputs
  71. //
  72. // Arguments:
  73. // None.
  74. //
  75. // Author:
  76. // Rajkumar 08/04/98
  77. //--
  78. {
  79. HRESULT hr = S_OK;
  80. ulong Result;
  81. InitializeListHead(&pResults->Netstat.lmsgGlobalOutput);
  82. InitializeListHead(&pResults->Netstat.lmsgInterfaceOutput);
  83. InitializeListHead(&pResults->Netstat.lmsgConnectionGlobalOutput);
  84. InitializeListHead(&pResults->Netstat.lmsgTcpConnectionOutput);
  85. InitializeListHead(&pResults->Netstat.lmsgUdpConnectionOutput);
  86. InitializeListHead(&pResults->Netstat.lmsgIpOutput);
  87. InitializeListHead(&pResults->Netstat.lmsgTcpOutput);
  88. InitializeListHead(&pResults->Netstat.lmsgUdpOutput);
  89. InitializeListHead(&pResults->Netstat.lmsgIcmpOutput);
  90. if (!pParams->fReallyVerbose)
  91. return hr;
  92. PrintStatusMessage( pParams, 4, IDS_NETSTAT_STATUS_MSG );
  93. //
  94. // initialize the snmp interface
  95. //
  96. Result = InitSnmp();
  97. if( NO_ERROR != Result )
  98. {
  99. //IDS_NETSTAT_14401 "Initialization of SNMP failed.\n"
  100. AddMessageToListId( &pResults->Netstat.lmsgGlobalOutput, Nd_Quiet, IDS_NETSTAT_14401);
  101. return S_FALSE;
  102. }
  103. //
  104. // Show ethernet statistics
  105. //
  106. hr = DoInterface( pParams, pResults );
  107. //
  108. // Show connections
  109. //
  110. if( S_OK == hr )
  111. hr = DoConnections( pParams, pResults );
  112. //
  113. // Display IP statistics
  114. //
  115. if( S_OK == hr )
  116. hr = DoIP( pParams, pResults );
  117. //
  118. // Display TCP statistics
  119. //
  120. if( S_OK == hr )
  121. hr = DoTCP( pParams, pResults );
  122. //
  123. // Display UDP statistics
  124. //
  125. if( S_OK == hr )
  126. hr = DoUDP( pParams, pResults );
  127. //
  128. // Display ICMP statistics
  129. //
  130. if( S_OK == hr )
  131. hr = DoICMP( pParams, pResults );
  132. pResults->Netstat.hrTestResult = hr;
  133. return hr;
  134. }
  135. //*****************************************************************************
  136. //
  137. // Name: DisplayInterface
  138. //
  139. // Description: Display interface statistics.
  140. //
  141. // Parameters: IfEntry *pEntry: pointer to summary data entry.
  142. // ulong VerboseFlag: boolean indicating desire for verbosity.
  143. // IfEntry *ListHead: pointer to list of entries. Used if
  144. // verbosity desired.
  145. //
  146. // Returns: void.
  147. //
  148. // History:
  149. // 01/21/94 JayPh Created.
  150. //
  151. //*****************************************************************************
  152. VOID DisplayInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  153. IfEntry *pEntry, IfEntry *ListHead )
  154. {
  155. char *TmpStr;
  156. IfEntry *pIfList;
  157. char PhysAddrStr[32];
  158. //IDS_NETSTAT_14402 "\n\nInterface Statistics\n\n"
  159. AddMessageToListId( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14402);
  160. //IDS_NETSTAT_14403 " Received Sent\n"
  161. AddMessageToListId( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14403);
  162. //IDS_NETSTAT_14404 "Unicast Packets %12u %12u\n"
  163. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  164. IDS_NETSTAT_14404,
  165. pEntry->Info.if_inoctets,
  166. pEntry->Info.if_outoctets );
  167. //IDS_NETSTAT_14405 "Non-unicast packets %12u %12u\n"
  168. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  169. IDS_NETSTAT_14405,
  170. pEntry->Info.if_innucastpkts,
  171. pEntry->Info.if_outnucastpkts );
  172. //IDS_NETSTAT_14406 "Discards %12u %12u\n"
  173. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  174. IDS_NETSTAT_14406,
  175. pEntry->Info.if_indiscards,
  176. pEntry->Info.if_outdiscards );
  177. //IDS_NETSTAT_14407 "Errors %12u %12u\n"
  178. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  179. IDS_NETSTAT_14407,
  180. pEntry->Info.if_inerrors,
  181. pEntry->Info.if_outerrors );
  182. //IDS_NETSTAT_14408 "Unknown protocols %12u %12u\n"
  183. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  184. IDS_NETSTAT_14408,
  185. pEntry->Info.if_inunknownprotos );
  186. if ( pParams->fReallyVerbose)
  187. {
  188. // Also display configuration info
  189. // Traverse the list of interfaces, displaying config info
  190. pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  191. IfEntry,
  192. ListEntry );
  193. while ( pIfList != ListHead )
  194. {
  195. //IDS_NETSTAT_14409 "\nInterface index = %u\n"
  196. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  197. IDS_NETSTAT_14409,
  198. pIfList->Info.if_index );
  199. //IDS_NETSTAT_14410 "Description = %s\n"
  200. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  201. IDS_NETSTAT_14410,
  202. pIfList->Info.if_descr );
  203. //IDS_NETSTAT_14411 "Type = %u\n"
  204. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  205. IDS_NETSTAT_14411,
  206. pIfList->Info.if_type );
  207. //IDS_NETSTAT_14412 "MTU = %u\n"
  208. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  209. IDS_NETSTAT_14412,
  210. pIfList->Info.if_mtu );
  211. //IDS_NETSTAT_14413 "Speed = %u\n"
  212. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  213. IDS_NETSTAT_14413,
  214. pIfList->Info.if_speed );
  215. sprintf( PhysAddrStr,
  216. "%02x-%02X-%02X-%02X-%02X-%02X",
  217. pIfList->Info.if_physaddr[0],
  218. pIfList->Info.if_physaddr[1],
  219. pIfList->Info.if_physaddr[2],
  220. pIfList->Info.if_physaddr[3],
  221. pIfList->Info.if_physaddr[4],
  222. pIfList->Info.if_physaddr[5] );
  223. //IDS_NETSTAT_14414 "Physical Address = %s\n"
  224. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  225. IDS_NETSTAT_14414,
  226. PhysAddrStr );
  227. //IDS_NETSTAT_14415 "Administrative Status = %u\n"
  228. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  229. IDS_NETSTAT_14415,
  230. pIfList->Info.if_adminstatus );
  231. //IDS_NETSTAT_14416 "Operational Status = %u\n"
  232. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  233. IDS_NETSTAT_14416,
  234. pIfList->Info.if_operstatus );
  235. //IDS_NETSTAT_14417 "Last Changed = %u\n"
  236. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  237. IDS_NETSTAT_14417,
  238. pIfList->Info.if_lastchange );
  239. //IDS_NETSTAT_14418 "Output Queue Length = %u\n\n"
  240. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose,
  241. IDS_NETSTAT_14418,
  242. pIfList->Info.if_outqlen );
  243. // Get pointer to next entry in list
  244. pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink,
  245. IfEntry,
  246. ListEntry );
  247. }
  248. }
  249. }
  250. HRESULT DoInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults )
  251. //++
  252. // Description:
  253. // Displays statistics of current connections
  254. //--
  255. {
  256. IfEntry *ListHead;
  257. IfEntry *pIfList;
  258. IfEntry SumOfEntries;
  259. ulong Result;
  260. // Get the statistics
  261. ListHead = (IfEntry *)GetTable( TYPE_IF, &Result );
  262. if ( ListHead == NULL )
  263. {
  264. //IDS_NETSTAT_14419 "Getting interface statistics table failed.\n"
  265. AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_Quiet, IDS_NETSTAT_14419);
  266. return S_FALSE;
  267. }
  268. // Clear the summation structure
  269. ZeroMemory( &SumOfEntries, sizeof( IfEntry ) );
  270. // Traverse the list of interfaces, summing the different fields
  271. pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  272. IfEntry,
  273. ListEntry );
  274. while (pIfList != ListHead)
  275. {
  276. SumOfEntries.Info.if_inoctets += pIfList->Info.if_inoctets;
  277. SumOfEntries.Info.if_inucastpkts += pIfList->Info.if_inucastpkts;
  278. SumOfEntries.Info.if_innucastpkts += pIfList->Info.if_innucastpkts;
  279. SumOfEntries.Info.if_indiscards += pIfList->Info.if_indiscards;
  280. SumOfEntries.Info.if_inerrors += pIfList->Info.if_inerrors;
  281. SumOfEntries.Info.if_inunknownprotos +=
  282. pIfList->Info.if_inunknownprotos;
  283. SumOfEntries.Info.if_outoctets += pIfList->Info.if_outoctets;
  284. SumOfEntries.Info.if_outucastpkts += pIfList->Info.if_outucastpkts;
  285. SumOfEntries.Info.if_outnucastpkts += pIfList->Info.if_outnucastpkts;
  286. SumOfEntries.Info.if_outdiscards += pIfList->Info.if_outdiscards;
  287. SumOfEntries.Info.if_outerrors += pIfList->Info.if_outerrors;
  288. // Get pointer to next entry in list
  289. pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink,
  290. IfEntry,
  291. ListEntry );
  292. }
  293. DisplayInterface( pParams, pResults, &SumOfEntries, ListHead );
  294. // All done with list, free it.
  295. FreeTable( (GenericTable *)ListHead );
  296. return S_OK;
  297. }
  298. //*****************************************************************************
  299. //
  300. // Name: DisplayTcpConnEntry
  301. //
  302. // Description: Display information about 1 tcp connection.
  303. //
  304. // Parameters: TcpConnEntry *pTcp: pointer to a tcp connection structure.
  305. //
  306. // Returns: void.
  307. //
  308. // History:
  309. //
  310. //*****************************************************************************
  311. void DisplayTcpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  312. TcpConnEntry *pTcp )
  313. {
  314. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  315. char RemoteStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  316. DWORD dwErr;
  317. int BufLen;
  318. int FlagVerbose;
  319. if( pTcp->Info.tct_state != TCP_CONN_LISTEN )
  320. FlagVerbose = Nd_Verbose;
  321. else
  322. FlagVerbose = Nd_ReallyVerbose;
  323. //IDS_NETSTAT_14420 "TCP"
  324. AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  325. IDS_NETSTAT_14420);
  326. BufLen = sizeof( LocalStr);
  327. dwErr = GenerateHostNameServiceString( LocalStr,
  328. &BufLen,
  329. NumFlag != 0, TRUE,
  330. "tcp",
  331. pTcp->Info.tct_localaddr,
  332. pTcp->Info.tct_localport);
  333. ASSERT( dwErr == NO_ERROR);
  334. BufLen = sizeof( RemoteStr);
  335. dwErr = GenerateHostNameServiceString( RemoteStr,
  336. &BufLen,
  337. NumFlag != 0, FALSE,
  338. "tcp",
  339. pTcp->Info.tct_remoteaddr,
  340. pTcp->Info.tct_remoteport );
  341. ASSERT( dwErr == NO_ERROR);
  342. //IDS_NETSTAT_14421 " %-20s %-40s"
  343. AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  344. IDS_NETSTAT_14421,LocalStr,RemoteStr);
  345. switch ( pTcp->Info.tct_state )
  346. {
  347. case TCP_CONN_CLOSED:
  348. //IDS_NETSTAT_14422 " CLOSED\n"
  349. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  350. IDS_NETSTAT_14422);
  351. break;
  352. case TCP_CONN_LISTEN:
  353. // Tcpip generates dummy sequential remote ports for
  354. // listening connections to avoid getting stuck in snmp.
  355. // MohsinA, 12-Feb-97.
  356. pTcp->Info.tct_remoteport = 0;
  357. //IDS_NETSTAT_14423 " LISTENING\n"
  358. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  359. IDS_NETSTAT_14423);
  360. break;
  361. case TCP_CONN_SYN_SENT:
  362. //IDS_NETSTAT_14424 " SYN_SENT\n"
  363. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  364. IDS_NETSTAT_14424);
  365. break;
  366. case TCP_CONN_SYN_RCVD:
  367. //IDS_NETSTAT_14425 " SYN_RECEIVED\n"
  368. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  369. IDS_NETSTAT_14425);
  370. break;
  371. case TCP_CONN_ESTAB:
  372. //IDS_NETSTAT_14426 " ESTABLISHED\n"
  373. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  374. IDS_NETSTAT_14426);
  375. break;
  376. case TCP_CONN_FIN_WAIT1:
  377. //IDS_NETSTAT_14427 " FIN_WAIT_1\n"
  378. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  379. IDS_NETSTAT_14427);
  380. break;
  381. case TCP_CONN_FIN_WAIT2:
  382. //IDS_NETSTAT_14428 " FIN_WAIT_2\n"
  383. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  384. IDS_NETSTAT_14428);
  385. break;
  386. case TCP_CONN_CLOSE_WAIT:
  387. //IDS_NETSTAT_14429 " CLOSE_WAIT\n"
  388. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  389. IDS_NETSTAT_14429);
  390. break;
  391. case TCP_CONN_CLOSING:
  392. //IDS_NETSTAT_14430 " CLOSING\n"
  393. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  394. IDS_NETSTAT_14430);
  395. break;
  396. case TCP_CONN_LAST_ACK:
  397. //IDS_NETSTAT_14431 " LAST_ACK\n"
  398. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  399. IDS_NETSTAT_14431);
  400. break;
  401. case TCP_CONN_TIME_WAIT:
  402. //IDS_NETSTAT_14432 " TIME_WAIT\n"
  403. AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose,
  404. IDS_NETSTAT_14432);
  405. break;
  406. default:
  407. DEBUG_PRINT(("DisplayTcpConnEntry: State=%d?\n ",
  408. pTcp->Info.tct_state ));
  409. }
  410. }
  411. //*****************************************************************************
  412. //
  413. // Name: DisplayUdpConnEntry
  414. //
  415. // Description: Display information on 1 udp connection
  416. //
  417. // Parameters: UdpConnEntry *pUdp: pointer to udp connection structure.
  418. //
  419. // Returns: void.
  420. //
  421. //
  422. //*****************************************************************************
  423. void DisplayUdpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  424. UdpConnEntry *pUdp )
  425. {
  426. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  427. int BufLen;
  428. DWORD dwErr;
  429. //IDS_NETSTAT_14433 "UDP"
  430. AddMessageToListId( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_ReallyVerbose, IDS_NETSTAT_14433);
  431. BufLen = sizeof( LocalStr);
  432. dwErr = GenerateHostNameServiceString( LocalStr,
  433. &BufLen,
  434. NumFlag != 0, TRUE,
  435. "udp",
  436. pUdp->Info.ue_localaddr,
  437. pUdp->Info.ue_localport);
  438. ASSERT( dwErr == NO_ERROR);
  439. //IDS_NETSTAT_14434 " %-20s %-40s\n"
  440. AddMessageToList( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_ReallyVerbose, IDS_NETSTAT_14434,LocalStr, _T("*:*") );
  441. }
  442. static DWORD
  443. GenerateHostNameServiceString(
  444. OUT char * pszBuffer,
  445. IN OUT int * lpcbBufLen,
  446. IN BOOL fNumFlag,
  447. IN BOOL fLocalHost,
  448. IN const char * pszProtocol,
  449. IN ulong uAddress,
  450. IN ulong uPort
  451. )
  452. /*++
  453. Description:
  454. Generates the <hostname>:<service-string> from the address and port
  455. information supplied. The result is stored in the pszBuffer passed in.
  456. If fLocalHost == TRUE, then the cached local host name is used to
  457. improve performance.
  458. Arguments:
  459. pszBuffer Buffer to store the resulting string.
  460. lpcbBufLen pointer to integer containing the count of bytes in Buffer
  461. and on return contains the number of bytes written.
  462. If the buffer is insufficient, then the required bytes is
  463. stored here.
  464. fNumFlag generates the output using numbers for host and port number.
  465. fLocalHost indicates if we want the service string for local host or
  466. remote host. Also for local host, this function generates
  467. the local host name without FQDN.
  468. pszProtocol specifies the protocol used for the service.
  469. uAddress unisgned long address of the service.
  470. uPort unsinged long port number.
  471. Returns:
  472. Win32 error codes. NO_ERROR on success.
  473. History:
  474. Added this function to avoid FQDNs for local name + abstract the common
  475. code used multiple times in old code.
  476. Also this function provides local host name caching.
  477. --*/
  478. {
  479. char LocalBuffer[MAX_HOST_NAME_SIZE]; // to hold dummy output
  480. char LocalServiceEntry[MAX_SERVICE_NAME_SIZE];
  481. int BufferLen;
  482. char * pszHostName = NULL; // init a pointer.
  483. char * pszServiceName = NULL;
  484. DWORD dwError = NO_ERROR;
  485. struct hostent * pHostEnt;
  486. struct servent * pServEnt;
  487. uchar * pTmp;
  488. // for caching local host name
  489. static char s_LocalHostName[MAX_HOST_NAME_SIZE];
  490. static BOOL s_fLocalHostName = FALSE;
  491. if ( pszBuffer == NULL) {
  492. return ( ERROR_INSUFFICIENT_BUFFER);
  493. }
  494. *pszBuffer = '\0'; // initialize to null string
  495. if ( !fNumFlag) {
  496. if ( fLocalHost) {
  497. if ( s_fLocalHostName) {
  498. pszHostName = s_LocalHostName; // pull from the cache
  499. } else {
  500. int Result = gethostname( s_LocalHostName,
  501. sizeof( s_LocalHostName));
  502. if ( Result == 0) {
  503. char * pszFirstDot;
  504. //
  505. // Cache the copy of local host name now.
  506. // Limit the host name to first part of host name.
  507. // NO FQDN
  508. //
  509. s_fLocalHostName = TRUE;
  510. pszFirstDot = strchr( s_LocalHostName, '.');
  511. if ( pszFirstDot != NULL) {
  512. *pszFirstDot = '\0'; // terminate string
  513. }
  514. pszHostName = s_LocalHostName;
  515. }
  516. } // if ( s_fLocalhost)
  517. } else {
  518. // Remote Host Name.
  519. pHostEnt = gethostbyaddr( (uchar *) &uAddress,
  520. 4, // IP address is 4 bytes,
  521. PF_INET);
  522. pszHostName = ( pHostEnt != NULL) ? pHostEnt->h_name: NULL;
  523. }
  524. pServEnt = getservbyport( htons( ( u_short) uPort), pszProtocol);
  525. pszServiceName = ( pServEnt != NULL) ? pServEnt->s_name : NULL;
  526. } else { // !fNumFlag
  527. pszServiceName = NULL;
  528. pszHostName = NULL;
  529. }
  530. //
  531. // Format the data for output.
  532. //
  533. if ( pszHostName == NULL) {
  534. //
  535. // Print the IP address itself
  536. //
  537. uchar * pTmp = ( uchar *) & uAddress;
  538. pszHostName = LocalBuffer;
  539. sprintf( pszHostName, "%u.%u.%u.%u",
  540. pTmp[0],
  541. pTmp[1],
  542. pTmp[2],
  543. pTmp[3]);
  544. }
  545. // Now pszHostName has the name of the host.
  546. if ( pszServiceName == NULL) {
  547. pszServiceName = LocalServiceEntry;
  548. //IDS_NETSTAT_14436 "%u"
  549. sprintf( pszServiceName, "%u", uPort);
  550. }
  551. // Now pszServiceName has the service name/portnumber
  552. BufferLen = strlen( pszHostName) + strlen( pszServiceName) + 2;
  553. // 2 bytes extra for ':' and null-character.
  554. if ( *lpcbBufLen < BufferLen ) {
  555. dwError = ERROR_INSUFFICIENT_BUFFER;
  556. } else {
  557. sprintf( pszBuffer, "%s:%s", pszHostName, pszServiceName);
  558. }
  559. *lpcbBufLen = BufferLen;
  560. return ( dwError);
  561. } // GenerateHostNameServiceString()
  562. HRESULT DoConnections( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  563. //++
  564. // Description:
  565. // Displays ethernet statistics
  566. //
  567. //--
  568. {
  569. HRESULT hr = S_OK;
  570. TcpConnEntry *pTcpHead;
  571. UdpConnEntry *pUdpHead;
  572. TcpConnEntry *pTcp;
  573. UdpConnEntry *pUdp;
  574. ulong Result;
  575. //IDS_NETSTAT_14438 "\n\nActive Connections\n"
  576. AddMessageToListId( &pResults->Netstat.lmsgConnectionGlobalOutput, Nd_Verbose, IDS_NETSTAT_14438);
  577. //IDS_NETSTAT_14439 "\nProto Local Address Foreign Address State\n"
  578. AddMessageToListId( &pResults->Netstat.lmsgConnectionGlobalOutput, Nd_Verbose, IDS_NETSTAT_14439);
  579. // Get TCP connection table
  580. pTcpHead = (TcpConnEntry *)GetTable( TYPE_TCPCONN, &Result );
  581. if ( pTcpHead == NULL )
  582. {
  583. //IDS_NETSTAT_14440 "Getting TCP connections failed!\n"
  584. AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, Nd_Quiet,IDS_NETSTAT_14440);
  585. hr = S_FALSE;
  586. }
  587. else
  588. {
  589. // Get pointer to first entry in list
  590. pTcp = CONTAINING_RECORD( pTcpHead->ListEntry.Flink,
  591. TcpConnEntry,
  592. ListEntry );
  593. while (pTcp != pTcpHead)
  594. {
  595. if ( ( pTcp->Info.tct_state != TCP_CONN_LISTEN ) ||
  596. (( pTcp->Info.tct_state == TCP_CONN_LISTEN )) )
  597. {
  598. // Display the Tcp connection info
  599. DisplayTcpConnEntry( pParams, pResults, pTcp );
  600. }
  601. // Get the next entry in the table
  602. pTcp = CONTAINING_RECORD( pTcp->ListEntry.Flink,
  603. TcpConnEntry,
  604. ListEntry );
  605. }
  606. FreeTable( (GenericTable *)pTcpHead );
  607. }
  608. // Get UDP connection table
  609. pUdpHead = (UdpConnEntry *)GetTable( TYPE_UDPCONN, &Result );
  610. if ( pUdpHead == NULL )
  611. {
  612. //IDS_NETSTAT_14441 "Getting UDP connections failed!\n"
  613. AddMessageToList( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_Quiet, IDS_NETSTAT_14441);
  614. hr = S_FALSE;
  615. }
  616. else
  617. {
  618. // Get pointer to first entry in list
  619. pUdp = CONTAINING_RECORD( pUdpHead->ListEntry.Flink,
  620. UdpConnEntry,
  621. ListEntry );
  622. while (pUdp != pUdpHead)
  623. {
  624. // Display the Udp connection info
  625. DisplayUdpConnEntry( pParams, pResults, pUdp);
  626. // Get the next entry in the table
  627. pUdp = CONTAINING_RECORD( pUdp->ListEntry.Flink,
  628. UdpConnEntry,
  629. ListEntry );
  630. }
  631. FreeTable( (GenericTable *)pUdpHead );
  632. }
  633. return hr;
  634. }
  635. void DisplayIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  636. IpEntry *pEntry)
  637. {
  638. //IDS_NETSTAT_14442 "\n\nIP Statistics\n\n"
  639. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  640. IDS_NETSTAT_14442);
  641. //IDS_NETSTAT_14443 "Packets Received = %s\n"
  642. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  643. IDS_NETSTAT_14443, FormatNumber( pEntry->Info.ipsi_inreceives ));
  644. //IDS_NETSTAT_14444 "Received Header Errors = %u\n"
  645. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  646. IDS_NETSTAT_14444,
  647. FormatNumber( pEntry->Info.ipsi_inhdrerrors ) );
  648. //IDS_NETSTAT_14445 "Received Address Errors = %u\n"
  649. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  650. IDS_NETSTAT_14445,
  651. FormatNumber( pEntry->Info.ipsi_inaddrerrors ) );
  652. //IDS_NETSTAT_14446 "Datagrams Forwarded = %u\n"
  653. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  654. IDS_NETSTAT_14446,
  655. FormatNumber( pEntry->Info.ipsi_forwdatagrams ) );
  656. //IDS_NETSTAT_14447 "Unknown Protocols Received = %u\n"
  657. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  658. IDS_NETSTAT_14447,
  659. FormatNumber( pEntry->Info.ipsi_inunknownprotos ) );
  660. //IDS_NETSTAT_14448 "Received Packets Discarded = %u\n"
  661. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  662. IDS_NETSTAT_14448,
  663. FormatNumber( pEntry->Info.ipsi_indiscards ) );
  664. //IDS_NETSTAT_14449 "Received Packets Delivered = %u\n"
  665. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  666. IDS_NETSTAT_14449,
  667. FormatNumber( pEntry->Info.ipsi_indelivers ) );
  668. //IDS_NETSTAT_14450 "Output Requests = %u\n"
  669. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  670. IDS_NETSTAT_14450,
  671. FormatNumber( pEntry->Info.ipsi_outrequests ) );
  672. //IDS_NETSTAT_14451 "Routing Discards = %u\n"
  673. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  674. IDS_NETSTAT_14451,
  675. FormatNumber( pEntry->Info.ipsi_routingdiscards ) );
  676. //IDS_NETSTAT_14452 "Discarded Output Packets = %u\n"
  677. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  678. IDS_NETSTAT_14452,
  679. FormatNumber( pEntry->Info.ipsi_outdiscards ) );
  680. //IDS_NETSTAT_14453 "Output Packet No Route = %u\n"
  681. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  682. IDS_NETSTAT_14453,
  683. FormatNumber( pEntry->Info.ipsi_outnoroutes ) );
  684. //IDS_NETSTAT_14454 "Reassembly Required = %u\n"
  685. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  686. IDS_NETSTAT_14454,
  687. FormatNumber( pEntry->Info.ipsi_reasmreqds ) );
  688. //IDS_NETSTAT_14455 "Reassembly Successful = %u\n"
  689. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  690. IDS_NETSTAT_14455,
  691. FormatNumber( pEntry->Info.ipsi_reasmoks ) );
  692. //IDS_NETSTAT_14456 "Reassembly Failures = %u\n"
  693. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  694. IDS_NETSTAT_14456,
  695. FormatNumber( pEntry->Info.ipsi_reasmfails ));
  696. //IDS_NETSTAT_14457 "Datagrams successfully fragmented = %u\n"
  697. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  698. IDS_NETSTAT_14457,
  699. FormatNumber( pEntry->Info.ipsi_fragoks ) );
  700. //IDS_NETSTAT_14458 "Datagrams failing fragmentation = %u\n"
  701. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  702. IDS_NETSTAT_14458,
  703. FormatNumber( pEntry->Info.ipsi_fragfails ) );
  704. //IDS_NETSTAT_14459 "Fragments Created = %u\n"
  705. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  706. IDS_NETSTAT_14459,
  707. FormatNumber( pEntry->Info.ipsi_fragcreates ) );
  708. //IDS_NETSTAT_14460 "Forwarding = %u\n"
  709. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  710. IDS_NETSTAT_14460,
  711. FormatNumber( pEntry->Info.ipsi_forwarding ) );
  712. //IDS_NETSTAT_14461 "Default TTL = %u\n"
  713. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  714. IDS_NETSTAT_14461,
  715. FormatNumber( pEntry->Info.ipsi_defaultttl ));
  716. //IDS_NETSTAT_14462 "Reassembly timeout = %u\n"
  717. AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose,
  718. IDS_NETSTAT_14462,
  719. FormatNumber( pEntry->Info.ipsi_reasmtimeout ) );
  720. }
  721. HRESULT DoIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults )
  722. {
  723. IpEntry *ListHead;
  724. IpEntry *pIpList;
  725. ulong Result;
  726. // Get the statistics
  727. ListHead = (IpEntry *)GetTable( TYPE_IP, &Result );
  728. if ( ListHead == NULL )
  729. {
  730. //IDS_NETSTAT_14463 "Getting IP statistics failed.\n"
  731. AddMessageToListId( &pResults->Netstat.lmsgIpOutput, Nd_Quiet, IDS_NETSTAT_14463);
  732. return S_FALSE;
  733. }
  734. // Traverse the list of interfaces, summing the different fields
  735. pIpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  736. IpEntry,
  737. ListEntry );
  738. DisplayIP( pParams, pResults, pIpList );
  739. // All done with list, free it.
  740. FreeTable( (GenericTable *)ListHead );
  741. return S_OK;
  742. }
  743. HRESULT DoTCP(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  744. {
  745. TcpEntry *ListHead;
  746. TcpEntry *pTcpList;
  747. ulong Result;
  748. // Get the statistics
  749. ListHead = (TcpEntry *)GetTable( TYPE_TCP, &Result );
  750. if ( ListHead == NULL )
  751. {
  752. //IDS_NETSTAT_14464 "Getting TCP statistics failed.\n"
  753. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_Quiet, IDS_NETSTAT_14464);
  754. return S_FALSE;
  755. }
  756. // Traverse the list, summing the different fields
  757. pTcpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  758. TcpEntry,
  759. ListEntry );
  760. DisplayTCP( pParams, pResults, pTcpList );
  761. // All done with list, free it.
  762. FreeTable( (GenericTable *)ListHead );
  763. return S_OK;
  764. }
  765. void DisplayTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  766. TcpEntry *pEntry)
  767. {
  768. //IDS_NETSTAT_14465 "\n\nTCP Statistics \n\n"
  769. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14465);
  770. // FormatNumber( pEntry->Info.ts_activeopens, szNumberBuffer, sizeof(szNumberBuffer)/sizeof(TCHAR), FALSE);
  771. //IDS_NETSTAT_14466 "Active Opens = %s\n"
  772. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  773. IDS_NETSTAT_14466,
  774. FormatNumber( pEntry->Info.ts_activeopens ) );
  775. //IDS_NETSTAT_14467 "Passive Opens = %s\n"
  776. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  777. IDS_NETSTAT_14467,
  778. FormatNumber( pEntry->Info.ts_passiveopens ) );
  779. //IDS_NETSTAT_14468 "Failed Connection Attempts = %s\n"
  780. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  781. IDS_NETSTAT_14468,
  782. FormatNumber( pEntry->Info.ts_attemptfails ) );
  783. //IDS_NETSTAT_14469 "Reset Connections = %s\n"
  784. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  785. IDS_NETSTAT_14469,
  786. FormatNumber( pEntry->Info.ts_estabresets ) );
  787. //IDS_NETSTAT_14470 "Current Connections = %s\n"
  788. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  789. IDS_NETSTAT_14470,
  790. FormatNumber( pEntry->Info.ts_currestab ) );
  791. //IDS_NETSTAT_14471 "Received Segments = %s\n"
  792. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  793. IDS_NETSTAT_14471,
  794. FormatNumber( pEntry->Info.ts_insegs ) );
  795. //IDS_NETSTAT_14472 "Segment Sent = %s\n"
  796. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  797. IDS_NETSTAT_14472,
  798. FormatNumber( pEntry->Info.ts_outsegs ) );
  799. //IDS_NETSTAT_14473 "Segment Retransmitted = %s\n"
  800. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  801. IDS_NETSTAT_14473,
  802. FormatNumber( pEntry->Info.ts_retranssegs ) );
  803. //IDS_NETSTAT_14474 "Retransmission Timeout Algorithm = "
  804. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  805. IDS_NETSTAT_14474);
  806. switch ( pEntry->Info.ts_rtoalgorithm )
  807. {
  808. case 1:
  809. //IDS_NETSTAT_14475 "other\n"
  810. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  811. IDS_NETSTAT_14475);
  812. break;
  813. case 2:
  814. //IDS_NETSTAT_14476 "constant\n"
  815. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  816. IDS_NETSTAT_14476);
  817. break;
  818. case 3:
  819. //IDS_NETSTAT_14477 "rsre\n"
  820. AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  821. IDS_NETSTAT_14477);
  822. break;
  823. case 4:
  824. //IDS_NETSTAT_14478 "vanj\n "
  825. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  826. IDS_NETSTAT_14478);
  827. break;
  828. default:
  829. //IDS_NETSTAT_14479 "unknown\n "
  830. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  831. IDS_NETSTAT_14479,
  832. pEntry->Info.ts_rtoalgorithm );
  833. break;
  834. }
  835. //IDS_NETSTAT_14480 "Minimum Retransmission Timeout = %s\n"
  836. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  837. IDS_NETSTAT_14480,
  838. FormatNumber( pEntry->Info.ts_rtomin ) );
  839. //IDS_NETSTAT_14481 "Maximum Retransmission Timeout = %s\n"
  840. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  841. IDS_NETSTAT_14481,
  842. FormatNumber( pEntry->Info.ts_rtomax ) );
  843. //IDS_NETSTAT_14482 "Maximum Number of Connections = %s\n"
  844. AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose,
  845. IDS_NETSTAT_14482,
  846. FormatNumber( pEntry->Info.ts_maxconn ) );
  847. }
  848. HRESULT DoUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults )
  849. {
  850. UdpEntry *ListHead;
  851. UdpEntry *pUdpList;
  852. ulong Result;
  853. // Get the statistics
  854. ListHead = (UdpEntry *)GetTable( TYPE_UDP, &Result );
  855. if ( ListHead == NULL )
  856. {
  857. //IDS_NETSTAT_14483 "Getting UDP statistics failed.\n"
  858. AddMessageToListId( &pResults->Netstat.lmsgUdpOutput, Nd_Quiet, IDS_NETSTAT_14483 );
  859. return S_FALSE;
  860. }
  861. // Traverse the list of interfaces, summing the different fields
  862. pUdpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  863. UdpEntry,
  864. ListEntry );
  865. DisplayUDP( pParams, pResults, pUdpList );
  866. // All done with list, free it.
  867. FreeTable( (GenericTable *)ListHead );
  868. return S_OK;
  869. }
  870. VOID DisplayUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  871. UdpEntry *pEntry)
  872. {
  873. //IDS_NETSTAT_14484 "\n\nUDP Statistics\n\n"
  874. AddMessageToListId( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14484);
  875. //IDS_NETSTAT_14485 "Datagrams Received = %s\n"
  876. AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose,
  877. IDS_NETSTAT_14485, FormatNumber( pEntry->Info.us_indatagrams ) );
  878. //IDS_NETSTAT_14486 "No Ports = %s\n"
  879. AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose,
  880. IDS_NETSTAT_14486, FormatNumber(pEntry->Info.us_noports) );
  881. //IDS_NETSTAT_14487 "Receive Errors = %s\n"
  882. AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose,
  883. IDS_NETSTAT_14487, FormatNumber(pEntry->Info.us_inerrors) );
  884. //IDS_NETSTAT_14488 "Datagrams Sent = %s\n"
  885. AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose,
  886. IDS_NETSTAT_14488, FormatNumber(pEntry->Info.us_outdatagrams) );
  887. }
  888. HRESULT DoICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults )
  889. {
  890. IcmpEntry *ListHead;
  891. IcmpEntry *pIcmpList;
  892. ulong Result;
  893. // Get the statistics
  894. ListHead = (IcmpEntry *)GetTable( TYPE_ICMP, &Result );
  895. if ( ListHead == NULL )
  896. {
  897. //IDS_NETSTAT_14489 "Getting ICMP statistics failed.\n"
  898. AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_Quiet,
  899. IDS_NETSTAT_14489);
  900. return S_FALSE;
  901. }
  902. // Traverse the list of interfaces, summing the different fields
  903. pIcmpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  904. IcmpEntry,
  905. ListEntry );
  906. DisplayICMP( pParams, pResults, pIcmpList );
  907. // All done with list, free it.
  908. FreeTable( (GenericTable *)ListHead );
  909. return S_OK;
  910. }
  911. void DisplayICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults,
  912. IcmpEntry *pEntry )
  913. {
  914. //IDS_NETSTAT_14490 "\n\nICMP Statistics \n\n"
  915. AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  916. IDS_NETSTAT_14490);
  917. //IDS_NETSTAT_14491 "\t\t\t Received Sent\n"
  918. AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  919. IDS_NETSTAT_14491);
  920. //IDS_NETSTAT_14492 "Messages %7s %7s\n"
  921. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  922. IDS_NETSTAT_14492,
  923. FormatNumber(pEntry->InInfo.icmps_msgs),
  924. FormatNumber(pEntry->OutInfo.icmps_msgs) );
  925. //IDS_NETSTAT_14493 "Errors %7s %7s\n"
  926. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  927. IDS_NETSTAT_14493,
  928. FormatNumber(pEntry->InInfo.icmps_errors),
  929. FormatNumber(pEntry->OutInfo.icmps_errors) );
  930. //IDS_NETSTAT_14494 "Destination Unreachable %7s %7s\n"
  931. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  932. IDS_NETSTAT_14494,
  933. FormatNumber(pEntry->InInfo.icmps_destunreachs),
  934. FormatNumber(pEntry->OutInfo.icmps_destunreachs) );
  935. //IDS_NETSTAT_14495 "Time Exceeded %7s %7s\n"
  936. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  937. IDS_NETSTAT_14495,
  938. FormatNumber(pEntry->InInfo.icmps_timeexcds),
  939. FormatNumber(pEntry->OutInfo.icmps_timeexcds) );
  940. //IDS_NETSTAT_14496 "Parameter Problems %7s %7s\n"
  941. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  942. IDS_NETSTAT_14496,
  943. FormatNumber(pEntry->InInfo.icmps_parmprobs),
  944. FormatNumber(pEntry->OutInfo.icmps_parmprobs) );
  945. //IDS_NETSTAT_14497 "Source Quenchs %7s %7s\n"
  946. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  947. IDS_NETSTAT_14497,
  948. FormatNumber(pEntry->InInfo.icmps_srcquenchs),
  949. FormatNumber(pEntry->OutInfo.icmps_srcquenchs) );
  950. //IDS_NETSTAT_14498 "Redirects %7s %7s\n"
  951. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  952. IDS_NETSTAT_14498,
  953. FormatNumber(pEntry->InInfo.icmps_redirects),
  954. FormatNumber(pEntry->OutInfo.icmps_redirects) );
  955. //IDS_NETSTAT_14499 "Echos %7s %7s\n"
  956. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  957. IDS_NETSTAT_14499,
  958. FormatNumber(pEntry->InInfo.icmps_echos),
  959. FormatNumber(pEntry->OutInfo.icmps_echos) );
  960. //IDS_NETSTAT_14500 "Echo Replies %7s %7s\n"
  961. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  962. IDS_NETSTAT_14500,
  963. FormatNumber(pEntry->InInfo.icmps_echoreps),
  964. FormatNumber(pEntry->OutInfo.icmps_echoreps) );
  965. //IDS_NETSTAT_14501 "Timestamps %7s %7s\n"
  966. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  967. IDS_NETSTAT_14501,
  968. FormatNumber(pEntry->InInfo.icmps_timestamps),
  969. FormatNumber(pEntry->OutInfo.icmps_timestamps) );
  970. //IDS_NETSTAT_14502 "Timestamp Replies %7s %7s\n"
  971. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  972. IDS_NETSTAT_14502,
  973. FormatNumber(pEntry->InInfo.icmps_timestampreps),
  974. FormatNumber(pEntry->OutInfo.icmps_timestampreps) );
  975. //IDS_NETSTAT_14503 "Address Masks %7s %7s\n"
  976. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  977. IDS_NETSTAT_14503,
  978. FormatNumber(pEntry->InInfo.icmps_addrmasks),
  979. FormatNumber(pEntry->OutInfo.icmps_addrmasks) );
  980. //IDS_NETSTAT_14504 "Address Mask Replies %7s %7s\n"
  981. AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose,
  982. IDS_NETSTAT_14504,
  983. FormatNumber(pEntry->InInfo.icmps_addrmaskreps),
  984. FormatNumber(pEntry->OutInfo.icmps_addrmaskreps) );
  985. }
  986. //----------------------------------------------------------------------------
  987. // Function: FormatNumber
  988. //
  989. // This function takes an integer and formats a string with the value
  990. // represented by the number, grouping digits by powers of one-thousand
  991. //----------------------------------------------------------------------------
  992. LPTSTR FormatNumber(DWORD dwNumber)
  993. {
  994. // assert(cchBuffer > 14);
  995. static TCHAR s_szBuffer[MAX_NUM_DIGITS];
  996. BOOL fSigned = TRUE;
  997. static TCHAR szNegativeSign[4] = TEXT("");
  998. static TCHAR szThousandsSeparator[4] = TEXT("");
  999. DWORD i, dwLength;
  1000. TCHAR szDigits[12], pszTemp[20];
  1001. TCHAR* pszsrc, *pszdst;
  1002. //
  1003. // Retrieve the thousands-separator for the user's locale
  1004. //
  1005. if (szThousandsSeparator[0] == TEXT('\0'))
  1006. {
  1007. GetLocaleInfo(
  1008. LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandsSeparator, 4
  1009. );
  1010. }
  1011. //
  1012. // If we are formatting a signed value, see if the value is negative
  1013. //
  1014. if (fSigned)
  1015. {
  1016. if ((INT)dwNumber >= 0)
  1017. fSigned = FALSE;
  1018. else
  1019. {
  1020. //
  1021. // The value is negative; retrieve the locale's negative-sign
  1022. //
  1023. if (szNegativeSign[0] == TEXT('\0')) {
  1024. GetLocaleInfo(
  1025. LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, szNegativeSign, 4
  1026. );
  1027. }
  1028. dwNumber = abs((INT)dwNumber);
  1029. }
  1030. }
  1031. //
  1032. // Convert the number to a string without thousands-separators
  1033. //
  1034. _ltot(dwNumber, szDigits, 10);
  1035. //padultoa(dwNumber, szDigits, 0);
  1036. dwLength = lstrlen(szDigits);
  1037. //
  1038. // If the length of the string without separators is n,
  1039. // then the length of the string with separators is n + (n - 1) / 3
  1040. //
  1041. i = dwLength;
  1042. dwLength += (dwLength - 1) / 3;
  1043. //
  1044. // Write the number to the buffer in reverse
  1045. //
  1046. pszsrc = szDigits + i - 1; pszdst = pszTemp + dwLength;
  1047. *pszdst-- = TEXT('\0');
  1048. while (TRUE) {
  1049. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  1050. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  1051. if (i--) { *pszdst-- = *pszsrc--; } else { break; }
  1052. if (i) { *pszdst-- = *szThousandsSeparator; } else { break; }
  1053. }
  1054. s_szBuffer[0] = 0;
  1055. if (fSigned)
  1056. lstrcat(s_szBuffer, szNegativeSign);
  1057. lstrcat(s_szBuffer, pszTemp);
  1058. return s_szBuffer;
  1059. }
  1060. void NetstatGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults)
  1061. {
  1062. if (!pParams->fReallyVerbose)
  1063. return;
  1064. if (pParams->fVerbose || !FHrOK(pResults->Netstat.hrTestResult))
  1065. {
  1066. PrintNewLine(pParams, 2);
  1067. PrintTestTitleResult(pParams,
  1068. IDS_NETSTAT_LONG,
  1069. IDS_NETSTAT_SHORT,
  1070. TRUE,
  1071. pResults->Netstat.hrTestResult,
  1072. 0);
  1073. }
  1074. PrintMessageList(pParams, &pResults->Netstat.lmsgGlobalOutput);
  1075. PrintMessageList(pParams, &pResults->Netstat.lmsgInterfaceOutput);
  1076. PrintMessageList(pParams, &pResults->Netstat.lmsgConnectionGlobalOutput);
  1077. PrintMessageList(pParams, &pResults->Netstat.lmsgTcpConnectionOutput);
  1078. PrintMessageList(pParams, &pResults->Netstat.lmsgUdpConnectionOutput);
  1079. PrintMessageList(pParams, &pResults->Netstat.lmsgIpOutput);
  1080. PrintMessageList(pParams, &pResults->Netstat.lmsgTcpOutput);
  1081. PrintMessageList(pParams, &pResults->Netstat.lmsgUdpOutput);
  1082. PrintMessageList(pParams, &pResults->Netstat.lmsgIcmpOutput);
  1083. }
  1084. void NetstatPerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults)
  1085. {
  1086. if (!pParams->fReallyVerbose)
  1087. return;
  1088. }
  1089. void NetstatCleanup(IN NETDIAG_PARAMS *pParams,
  1090. IN OUT NETDIAG_RESULT *pResults)
  1091. {
  1092. MessageListCleanUp(&pResults->Netstat.lmsgGlobalOutput);
  1093. MessageListCleanUp(&pResults->Netstat.lmsgInterfaceOutput);
  1094. MessageListCleanUp(&pResults->Netstat.lmsgConnectionGlobalOutput);
  1095. MessageListCleanUp(&pResults->Netstat.lmsgTcpConnectionOutput);
  1096. MessageListCleanUp(&pResults->Netstat.lmsgUdpConnectionOutput);
  1097. MessageListCleanUp(&pResults->Netstat.lmsgIpOutput);
  1098. MessageListCleanUp(&pResults->Netstat.lmsgTcpOutput);
  1099. MessageListCleanUp(&pResults->Netstat.lmsgUdpOutput);
  1100. MessageListCleanUp(&pResults->Netstat.lmsgIcmpOutput);
  1101. }