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.

2242 lines
62 KiB

  1. //*****************************************************************************
  2. //
  3. // Name: netstat.c
  4. //
  5. // Description: Source code for netstat.exe.
  6. //
  7. // History:
  8. // 12/29/93 JayPh Created.
  9. // 12/01/94 MuraliK modified to use toupper instead of CharUpper
  10. //
  11. //*****************************************************************************
  12. //*****************************************************************************
  13. //
  14. // Copyright (c) 1993-2000 by Microsoft Corp. All rights reserved.
  15. //
  16. //*****************************************************************************
  17. //
  18. // Include Files
  19. //
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <time.h>
  25. #include <nt.h>
  26. #include <ntrtl.h>
  27. #include <nturtl.h>
  28. #include <snmp.h>
  29. #include <winsock2.h>
  30. #include <ws2tcpip.h>
  31. #include <icmp6.h>
  32. #include "common2.h"
  33. #include "tcpinfo.h"
  34. #include "ipinfo.h"
  35. #include "llinfo.h"
  36. #include "tcpcmd.h"
  37. #include "netstmsg.h"
  38. #include "mdebug.h"
  39. //#include <iphlpstk.h>
  40. DWORD
  41. AllocateAndGetTcpExTableFromStack(
  42. OUT PVOID *ppTcpTable,
  43. IN BOOL bOrder,
  44. IN HANDLE hHeap,
  45. IN DWORD dwFlags,
  46. IN DWORD dwFamily
  47. );
  48. DWORD
  49. AllocateAndGetUdpExTableFromStack(
  50. OUT PVOID *ppUdpTable,
  51. IN BOOL bOrder,
  52. IN HANDLE hHeap,
  53. IN DWORD dwFlags,
  54. IN DWORD dwFamily
  55. );
  56. //
  57. // Definitions
  58. //
  59. #define PROTO_NONE 0
  60. #define PROTO_TCP 1
  61. #define PROTO_UDP 2
  62. #define PROTO_IP 4
  63. #define PROTO_ICMP 8
  64. #define PROTO_TCP6 0x10
  65. #define PROTO_UDP6 0x20
  66. #define PROTO_IP6 0x40
  67. #define PROTO_ICMP6 0x80
  68. #define MAX_ID_LENGTH 50
  69. #define MAX_RETRY_COUNT 10
  70. //
  71. // Presently FQDNs are of maximum of 255 characters. Be conservative,
  72. // and define the maximum size possible as 260
  73. // MuraliK ( 12/15/94)
  74. //
  75. #define MAX_HOST_NAME_SIZE ( 260)
  76. #define MAX_SERVICE_NAME_SIZE ( 200)
  77. //
  78. // Private ASSERT macro that doesn't depend on NTDLL (so this can run
  79. // under Windows 95) -- KeithMo 01/09/95
  80. //
  81. #if DBG
  82. #ifdef ASSERT
  83. #undef ASSERT
  84. #endif // ASSERT
  85. #define ASSERT(exp) if(!(exp)) MyAssert( #exp, __FILE__, (DWORD)__LINE__ )
  86. void MyAssert( void * exp, void * file, DWORD line )
  87. {
  88. char output[512];
  89. wsprintf( output,
  90. "\n*** Assertion failed: %s\n*** Source file: %s, line %lu\n\n",
  91. exp,
  92. file,
  93. line );
  94. OutputDebugString( output );
  95. DebugBreak();
  96. }
  97. #endif // DBG
  98. //
  99. // Structure Definitions
  100. //
  101. //
  102. // Function Prototypes
  103. //
  104. ulong DoInterface( ulong VerboseFlag );
  105. ulong DoIP( DWORD Type, ulong VerboseFlag );
  106. ulong DoTCP( DWORD Type, ulong VerboseFlag );
  107. ulong DoUDP( DWORD Type, ulong VerboseFlag );
  108. ulong DoICMP( DWORD Type, ulong VerboseFlag );
  109. ulong DoConnections( ulong ProtoFlag,
  110. ulong ProtoVal,
  111. ulong NumFlag,
  112. ulong AllFlag );
  113. ulong DoConnectionsWithOwner( ulong ProtoFlag,
  114. ulong ProtoVal,
  115. ulong NumFlag,
  116. ulong AllFlag );
  117. ulong DoRoutes( void );
  118. void DisplayInterface( IfEntry *pEntry, ulong VerboseFlag, IfEntry *ListHead );
  119. void DisplayIP( DWORD Type, IpEntry *pEntry, ulong VerboseFlag, IpEntry *ListHead );
  120. void DisplayTCP( DWORD Type, TcpEntry *pEntry, ulong VerboseFlag, TcpEntry *ListHead );
  121. void DisplayUDP( DWORD Type, UdpEntry *pEntry, ulong VerboseFlag, UdpEntry *ListHead );
  122. void DisplayICMP( IcmpEntry *pEntry, ulong VerboseFlag, IcmpEntry *ListHead );
  123. void DisplayICMP6( Icmp6Entry *pEntry, ulong VerboseFlag, IcmpEntry *ListHead );
  124. void DisplayTcpConnEntry( TCPConnTableEntry *pTcp, ulong InfoSize, ulong NumFlag );
  125. void DisplayTcp6ConnEntry( TCP6ConnTableEntry *pTcp, ulong NumFlag );
  126. void DisplayUdpConnEntry( UDPEntry *pUdp, ulong InfoSize, ulong NumFlag );
  127. void DisplayUdp6ListenerEntry( UDP6ListenerEntry *pUdp, BOOL WithOwner, ulong NumFlag );
  128. void Usage( void );
  129. //
  130. // Global Variables
  131. //
  132. uchar *PgmName;
  133. extern long verbose; // in ../common2/snmpinfo.c
  134. //*****************************************************************************
  135. //
  136. // Name: main
  137. //
  138. // Description: Entry point for netstat command.
  139. //
  140. // Parameters: int argc: count of command line tokens.
  141. // char argv[]: array of pointers to command line tokens.
  142. //
  143. // Returns: void.
  144. //
  145. // History:
  146. // 12/29/93 JayPh Created.
  147. //
  148. //*****************************************************************************
  149. void __cdecl main( int argc, char *argv[] )
  150. {
  151. ulong VerboseFlag = FALSE;
  152. ulong AllFlag = FALSE;
  153. ulong EtherFlag = FALSE;
  154. ulong NumFlag = FALSE;
  155. ulong StatFlag = FALSE;
  156. ulong ProtoFlag = FALSE;
  157. ulong ProtoVal = PROTO_TCP | PROTO_UDP | PROTO_IP | PROTO_ICMP |
  158. PROTO_TCP6 | PROTO_UDP6 | PROTO_IP6 | PROTO_ICMP6;
  159. ulong RouteFlag = FALSE;
  160. ulong OwnerFlag = FALSE;
  161. ulong IntervalVal = 0;
  162. ulong LastArgWasProtoFlag = FALSE;
  163. ulong ConnectionsShown = FALSE;
  164. ulong Result;
  165. long i;
  166. char *ptr;
  167. WSADATA WsaData;
  168. DEBUG_PRINT(( __FILE__ " built " __DATE__ " " __TIME__ "\n" ));
  169. verbose = 0; // Default for snmpinfo.c
  170. // Convert arguments to Oem strings (whatever that means)
  171. ConvertArgvToOem( argc, argv );
  172. // Save the name of this program for use in messages later.
  173. PgmName = argv[0];
  174. // Initialize the Winsock interface
  175. Result = WSAStartup( 0x0101, &WsaData );
  176. if ( Result == SOCKET_ERROR )
  177. {
  178. PutMsg( STDERR, MSG_WSASTARTUP, PgmName, GetLastError() );
  179. exit( 1 );
  180. }
  181. // Process command line arguments
  182. for ( i = 1; i < argc; i++ )
  183. {
  184. if ( LastArgWasProtoFlag )
  185. {
  186. // Process a protocol argument following the protocol flag
  187. _strupr( argv[i] );
  188. if ( strcmp( argv[i], "TCP" ) == 0 )
  189. {
  190. ProtoVal = PROTO_TCP;
  191. }
  192. else if ( strcmp( argv[i], "TCPV6" ) == 0 )
  193. {
  194. ProtoVal = PROTO_TCP6;
  195. }
  196. else if ( strcmp( argv[i], "UDP" ) == 0 )
  197. {
  198. ProtoVal = PROTO_UDP;
  199. }
  200. else if ( strcmp( argv[i], "UDPV6" ) == 0 )
  201. {
  202. ProtoVal = PROTO_UDP6;
  203. }
  204. else if ( strcmp( argv[i], "IP" ) == 0 )
  205. {
  206. ProtoVal = PROTO_IP;
  207. }
  208. else if ( strcmp( argv[i], "IPV6" ) == 0 )
  209. {
  210. ProtoVal = PROTO_IP6;
  211. }
  212. else if ( strcmp( argv[i], "ICMP" ) == 0 )
  213. {
  214. ProtoVal = PROTO_ICMP;
  215. }
  216. else if ( strcmp( argv[i], "ICMPV6" ) == 0 )
  217. {
  218. ProtoVal = PROTO_ICMP6;
  219. }
  220. else
  221. {
  222. Usage();
  223. }
  224. LastArgWasProtoFlag = FALSE;
  225. continue;
  226. }
  227. if ( ( argv[i][0] == '-' ) || ( argv[i][0] == '/' ) )
  228. {
  229. // Process flag arguments
  230. ptr = &argv[i][1];
  231. while ( *ptr )
  232. {
  233. if ( toupper( *ptr ) == 'A' )
  234. {
  235. AllFlag = TRUE;
  236. }
  237. else if ( toupper( *ptr ) == 'E' )
  238. {
  239. EtherFlag = TRUE;
  240. ProtoVal = PROTO_TCP | PROTO_UDP | PROTO_ICMP | PROTO_IP |
  241. PROTO_TCP6 | PROTO_UDP6 | PROTO_ICMP6 | PROTO_IP6;
  242. }
  243. else if ( toupper( *ptr ) == 'N' )
  244. {
  245. NumFlag = TRUE;
  246. }
  247. else if ( toupper( *ptr ) == 'O' )
  248. {
  249. OwnerFlag = TRUE;
  250. }
  251. else if ( toupper( *ptr ) == 'S' )
  252. {
  253. StatFlag = TRUE;
  254. ProtoVal = PROTO_TCP | PROTO_UDP | PROTO_IP | PROTO_ICMP |
  255. PROTO_TCP6 | PROTO_UDP6 | PROTO_IP6 | PROTO_ICMP6;
  256. }
  257. else if ( toupper( *ptr ) == 'P' )
  258. {
  259. ProtoFlag = TRUE;
  260. LastArgWasProtoFlag = TRUE;
  261. }
  262. else if ( toupper( *ptr ) == 'R' )
  263. {
  264. RouteFlag = TRUE;
  265. }
  266. else if ( toupper( *ptr ) == 'V' )
  267. {
  268. VerboseFlag = TRUE;
  269. #ifdef DBG
  270. verbose++;
  271. #endif
  272. }
  273. else
  274. {
  275. Usage();
  276. }
  277. ptr++;
  278. }
  279. }
  280. else if ( IntervalVal == 0 )
  281. {
  282. // This must be the interval parameter
  283. Result = sscanf( argv[i], "%d", &IntervalVal );
  284. if ( Result != 1 )
  285. {
  286. Usage();
  287. }
  288. }
  289. else
  290. {
  291. Usage();
  292. }
  293. }
  294. // Initialize the SNMP interface.
  295. Result = InitSnmp();
  296. if ( Result != NO_ERROR )
  297. {
  298. PutMsg( STDERR, MSG_SNMP_INIT_FAILED, Result );
  299. exit( 1 );
  300. }
  301. // This loop provides the 'repeat every <interval> seconds' functionality.
  302. // We break out of the loop after one pass if the interval was not
  303. // specified.
  304. while ( TRUE )
  305. {
  306. // If interface statistics requested, give them
  307. if ( EtherFlag )
  308. {
  309. // Show ethernet statistics
  310. DoInterface( VerboseFlag );
  311. }
  312. // If a specific protocol is requested, provide info for only that
  313. // protocol. If no protocol specified, provide info for all protocols.
  314. // ProtoVal is initialized to all protocols.
  315. if ( StatFlag )
  316. {
  317. // Show protocol statistics
  318. if ( ProtoVal & PROTO_IP )
  319. {
  320. DoIP( TYPE_IP, VerboseFlag );
  321. }
  322. if ( ProtoVal & PROTO_IP6 )
  323. {
  324. DoIP( TYPE_IP6, VerboseFlag );
  325. }
  326. if ( ProtoVal & PROTO_ICMP )
  327. {
  328. DoICMP( TYPE_ICMP, VerboseFlag );
  329. }
  330. if ( ProtoVal & PROTO_ICMP6 )
  331. {
  332. DoICMP( TYPE_ICMP6, VerboseFlag );
  333. }
  334. if ( ProtoVal & PROTO_TCP )
  335. {
  336. DoTCP( TYPE_TCP, VerboseFlag );
  337. }
  338. if ( ProtoVal & PROTO_TCP6 )
  339. {
  340. DoTCP( TYPE_TCP6, VerboseFlag );
  341. }
  342. if ( ProtoVal & PROTO_UDP )
  343. {
  344. DoUDP( TYPE_UDP, VerboseFlag );
  345. }
  346. if ( ProtoVal & PROTO_UDP6 )
  347. {
  348. DoUDP( TYPE_UDP6, VerboseFlag );
  349. }
  350. }
  351. // If a protocol is specified and that protocol is either TCP or UDP,
  352. // OR none of (route, statistics, interface ) flags given (this is the
  353. // default, no flags, case )
  354. if ( ( ProtoFlag &&
  355. ( ( ProtoVal & PROTO_TCP ) || ( ProtoVal & PROTO_UDP ) ||
  356. ( ProtoVal & PROTO_TCP6 ) || ( ProtoVal & PROTO_UDP6 ) ) ) ||
  357. ( !EtherFlag && !StatFlag && !RouteFlag ) )
  358. {
  359. // Show active connections
  360. if (OwnerFlag)
  361. {
  362. DoConnectionsWithOwner( ProtoFlag, ProtoVal, NumFlag, AllFlag );
  363. }
  364. else
  365. {
  366. DoConnections( ProtoFlag, ProtoVal, NumFlag, AllFlag );
  367. }
  368. ConnectionsShown = TRUE;
  369. }
  370. // Provide route information if requested
  371. if ( RouteFlag )
  372. {
  373. // Show connections and the route table
  374. DoRoutes();
  375. }
  376. // If interval was not supplied on command line then we are done.
  377. // Otherwise wait for 'interval' seconds and do it again.
  378. if ( IntervalVal == 0 )
  379. {
  380. break;
  381. }
  382. else
  383. {
  384. DEBUG_PRINT(("Sleeping %d ms\n", IntervalVal ));
  385. Sleep( IntervalVal * 1000 );
  386. }
  387. }
  388. }
  389. //*****************************************************************************
  390. //
  391. // Name: DoInterface
  392. //
  393. // Description: Display ethernet statistics.
  394. //
  395. // Parameters: ulong VerboseFlag: indicates whether settings data should be
  396. // displayed.
  397. //
  398. // Returns: ulong: NO_ERROR or some error code.
  399. //
  400. // History:
  401. // 01/21/93 JayPh Created.
  402. //
  403. //*****************************************************************************
  404. ulong DoInterface( ulong VerboseFlag )
  405. {
  406. IfEntry *ListHead;
  407. IfEntry *pIfList;
  408. IfEntry SumOfEntries;
  409. ulong Result;
  410. // Get the statistics
  411. ListHead = (IfEntry *)GetTable( TYPE_IF, &Result );
  412. if ( ListHead == NULL )
  413. {
  414. return ( Result );
  415. }
  416. // Clear the summation structure
  417. ZeroMemory( &SumOfEntries, sizeof( IfEntry ) );
  418. // Traverse the list of interfaces, summing the different fields
  419. pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  420. IfEntry,
  421. ListEntry );
  422. while (pIfList != ListHead)
  423. {
  424. SumOfEntries.Info.if_inoctets += pIfList->Info.if_inoctets;
  425. SumOfEntries.Info.if_inucastpkts += pIfList->Info.if_inucastpkts;
  426. SumOfEntries.Info.if_innucastpkts += pIfList->Info.if_innucastpkts;
  427. SumOfEntries.Info.if_indiscards += pIfList->Info.if_indiscards;
  428. SumOfEntries.Info.if_inerrors += pIfList->Info.if_inerrors;
  429. SumOfEntries.Info.if_inunknownprotos +=
  430. pIfList->Info.if_inunknownprotos;
  431. SumOfEntries.Info.if_outoctets += pIfList->Info.if_outoctets;
  432. SumOfEntries.Info.if_outucastpkts += pIfList->Info.if_outucastpkts;
  433. SumOfEntries.Info.if_outnucastpkts += pIfList->Info.if_outnucastpkts;
  434. SumOfEntries.Info.if_outdiscards += pIfList->Info.if_outdiscards;
  435. SumOfEntries.Info.if_outerrors += pIfList->Info.if_outerrors;
  436. // Get pointer to next entry in list
  437. pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink,
  438. IfEntry,
  439. ListEntry );
  440. }
  441. DisplayInterface( &SumOfEntries, VerboseFlag, ListHead );
  442. // All done with list, free it.
  443. FreeTable( (GenericTable *)ListHead );
  444. return ( NO_ERROR );
  445. }
  446. //*****************************************************************************
  447. //
  448. // Name: DoIP
  449. //
  450. // Description: Display IP statistics.
  451. //
  452. // Parameters: ulong VerboseFlag: indicates whether settings data should be
  453. // displayed.
  454. //
  455. // Returns: ulong: NO_ERROR or some error code.
  456. //
  457. // History:
  458. // 01/21/93 JayPh Created.
  459. //
  460. //*****************************************************************************
  461. ulong DoIP( DWORD Type, ulong VerboseFlag )
  462. {
  463. IpEntry *ListHead;
  464. IpEntry *pIpList;
  465. ulong Result;
  466. // Get the statistics
  467. ListHead = (IpEntry *)GetTable( Type, &Result );
  468. if ( ListHead == NULL )
  469. {
  470. return ( Result );
  471. }
  472. pIpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  473. IpEntry,
  474. ListEntry );
  475. DisplayIP( Type, pIpList, VerboseFlag, ListHead );
  476. // All done with list, free it.
  477. FreeTable( (GenericTable *)ListHead );
  478. return ( NO_ERROR );
  479. }
  480. //*****************************************************************************
  481. //
  482. // Name: DoTCP
  483. //
  484. // Description: Display TCP statistics.
  485. //
  486. // Parameters: ulong VerboseFlag: indicates whether settings data should be
  487. // displayed.
  488. //
  489. // Returns: ulong: NO_ERROR or some error code.
  490. //
  491. // History:
  492. // 01/21/93 JayPh Created.
  493. //
  494. //*****************************************************************************
  495. ulong DoTCP( DWORD Type, ulong VerboseFlag )
  496. {
  497. TcpEntry *ListHead;
  498. TcpEntry *pTcpList;
  499. ulong Result;
  500. // Get the statistics
  501. ListHead = (TcpEntry *)GetTable( Type, &Result );
  502. if ( ListHead == NULL )
  503. {
  504. return ( Result );
  505. }
  506. pTcpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  507. TcpEntry,
  508. ListEntry );
  509. DisplayTCP( Type, pTcpList, VerboseFlag, ListHead );
  510. // All done with list, free it.
  511. FreeTable( (GenericTable *)ListHead );
  512. return ( NO_ERROR );
  513. }
  514. //*****************************************************************************
  515. //
  516. // Name: DoUDP
  517. //
  518. // Description: Display UDP statistics.
  519. //
  520. // Parameters: ulong VerboseFlag: indicates whether settings data should be
  521. // displayed.
  522. //
  523. // Returns: ulong: NO_ERROR or some error code.
  524. //
  525. // History:
  526. // 01/21/93 JayPh Created.
  527. //
  528. //*****************************************************************************
  529. ulong DoUDP( DWORD Type, ulong VerboseFlag )
  530. {
  531. UdpEntry *ListHead;
  532. UdpEntry *pUdpList;
  533. ulong Result;
  534. // Get the statistics
  535. ListHead = (UdpEntry *)GetTable( Type, &Result );
  536. if ( ListHead == NULL )
  537. {
  538. return ( Result );
  539. }
  540. pUdpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  541. UdpEntry,
  542. ListEntry );
  543. DisplayUDP( Type, pUdpList, VerboseFlag, ListHead );
  544. // All done with table, free it.
  545. FreeTable( (GenericTable *)ListHead );
  546. return ( NO_ERROR );
  547. }
  548. //*****************************************************************************
  549. //
  550. // Name: DoICMP
  551. //
  552. // Description: Display ICMP statistics.
  553. //
  554. // Parameters: ulong VerboseFlag: indicates whether settings data should be
  555. // displayed.
  556. //
  557. // Returns: ulong: NO_ERROR or some error code.
  558. //
  559. // History:
  560. // 01/21/93 JayPh Created.
  561. //
  562. //*****************************************************************************
  563. ulong DoICMP( DWORD Type, ulong VerboseFlag )
  564. {
  565. IcmpEntry *ListHead;
  566. IcmpEntry *pIcmpList;
  567. ulong Result;
  568. // Get the statistics
  569. ListHead = (IcmpEntry *)GetTable( Type, &Result );
  570. if ( ListHead == NULL )
  571. {
  572. return ( Result );
  573. }
  574. pIcmpList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  575. IcmpEntry,
  576. ListEntry );
  577. if (Type == TYPE_ICMP) {
  578. DisplayICMP( pIcmpList, VerboseFlag, ListHead );
  579. } else {
  580. DisplayICMP6((Icmp6Entry *)pIcmpList, VerboseFlag, ListHead );
  581. }
  582. // All done with list, free it.
  583. FreeTable( (GenericTable *)ListHead );
  584. return ( NO_ERROR );
  585. }
  586. //*****************************************************************************
  587. //
  588. // Name: DoConnections
  589. //
  590. // Description: List current connections.
  591. //
  592. // Parameters: BOOL ProtoFlag: TRUE if a protocol was specified.
  593. // ulong ProtoVal: which protocol(s) were specified.
  594. //
  595. // Returns: Win32 error code.
  596. //
  597. // History:
  598. // 01/04/93 JayPh Created.
  599. //
  600. //*****************************************************************************
  601. ulong DoConnections( ulong ProtoFlag,
  602. ulong ProtoVal,
  603. ulong NumFlag,
  604. ulong AllFlag )
  605. {
  606. ulong Result = NO_ERROR;
  607. PutMsg( STDOUT, MSG_CONN_HDR );
  608. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_TCP ) ) )
  609. {
  610. TcpConnEntry *pTcpHead, *pTcp;
  611. // Get TCP connection table
  612. pTcpHead = (TcpConnEntry *)GetTable( TYPE_TCPCONN, &Result );
  613. if ( pTcpHead == NULL )
  614. {
  615. return ( Result );
  616. }
  617. // Get pointer to first entry in list
  618. pTcp = CONTAINING_RECORD( pTcpHead->ListEntry.Flink,
  619. TcpConnEntry,
  620. ListEntry );
  621. while (pTcp != pTcpHead)
  622. {
  623. if ( ( pTcp->Info.tct_state != TCP_CONN_LISTEN ) ||
  624. (( pTcp->Info.tct_state == TCP_CONN_LISTEN ) && AllFlag) )
  625. {
  626. // Display the Tcp connection info
  627. DisplayTcpConnEntry( &pTcp->Info, sizeof(TCPConnTableEntry),
  628. NumFlag );
  629. }
  630. // Get the next entry in the table
  631. pTcp = CONTAINING_RECORD( pTcp->ListEntry.Flink,
  632. TcpConnEntry,
  633. ListEntry );
  634. }
  635. FreeTable( (GenericTable *)pTcpHead );
  636. }
  637. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_TCP6 ) ) )
  638. {
  639. Tcp6ConnEntry *pTcpHead, *pTcp;
  640. // Get TCP connection table
  641. pTcpHead = (Tcp6ConnEntry *)GetTable( TYPE_TCP6CONN, &Result );
  642. if ( pTcpHead == NULL )
  643. {
  644. return ( Result );
  645. }
  646. // Get pointer to first entry in list
  647. pTcp = CONTAINING_RECORD( pTcpHead->ListEntry.Flink,
  648. Tcp6ConnEntry,
  649. ListEntry );
  650. while (pTcp != pTcpHead)
  651. {
  652. if ( ( pTcp->Info.tct_state != TCP_CONN_LISTEN ) ||
  653. (( pTcp->Info.tct_state == TCP_CONN_LISTEN ) && AllFlag) )
  654. {
  655. // Display the Tcp connection info
  656. DisplayTcp6ConnEntry( &pTcp->Info, NumFlag );
  657. }
  658. // Get the next entry in the table
  659. pTcp = CONTAINING_RECORD( pTcp->ListEntry.Flink,
  660. Tcp6ConnEntry,
  661. ListEntry );
  662. }
  663. FreeTable( (GenericTable *)pTcpHead );
  664. }
  665. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_UDP ) ) )
  666. {
  667. UdpConnEntry *pUdpHead, *pUdp;
  668. // Get UDP connection table
  669. pUdpHead = (UdpConnEntry *)GetTable( TYPE_UDPCONN, &Result );
  670. if ( pUdpHead == NULL )
  671. {
  672. return ( Result );
  673. }
  674. // Get pointer to first entry in list
  675. pUdp = CONTAINING_RECORD( pUdpHead->ListEntry.Flink,
  676. UdpConnEntry,
  677. ListEntry );
  678. while (pUdp != pUdpHead)
  679. {
  680. // Display the Udp connection info
  681. if (AllFlag)
  682. {
  683. DisplayUdpConnEntry( &pUdp->Info, sizeof(UDPEntry), NumFlag );
  684. }
  685. // Get the next entry in the table
  686. pUdp = CONTAINING_RECORD( pUdp->ListEntry.Flink,
  687. UdpConnEntry,
  688. ListEntry );
  689. }
  690. FreeTable( (GenericTable *)pUdpHead );
  691. }
  692. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_UDP6 ) ) )
  693. {
  694. Udp6ListenerEntry *pUdpHead, *pUdp;
  695. // Get UDP listener table
  696. pUdpHead = (Udp6ListenerEntry *)GetTable( TYPE_UDP6LISTENER, &Result );
  697. if ( pUdpHead == NULL )
  698. {
  699. return ( Result );
  700. }
  701. // Get pointer to first entry in list
  702. pUdp = CONTAINING_RECORD( pUdpHead->ListEntry.Flink,
  703. Udp6ListenerEntry,
  704. ListEntry );
  705. while (pUdp != pUdpHead)
  706. {
  707. // Display the Udp connection info
  708. if (AllFlag)
  709. {
  710. DisplayUdp6ListenerEntry( &pUdp->Info, FALSE, NumFlag );
  711. }
  712. // Get the next entry in the table
  713. pUdp = CONTAINING_RECORD( pUdp->ListEntry.Flink,
  714. Udp6ListenerEntry,
  715. ListEntry );
  716. }
  717. FreeTable( (GenericTable *)pUdpHead );
  718. }
  719. return( Result );
  720. }
  721. //*****************************************************************************
  722. //
  723. // Name: DoConnectionsWithOwner
  724. //
  725. // Description: List current connections and the process id associated with
  726. // each.
  727. //
  728. // Parameters: same as for DoConnections.
  729. //
  730. // Returns: Win32 error code.
  731. //
  732. // History:
  733. // 02/11/00 ShaunCo Created.
  734. //
  735. //*****************************************************************************
  736. ulong DoConnectionsWithOwner( ulong ProtoFlag,
  737. ulong ProtoVal,
  738. ulong NumFlag,
  739. ulong AllFlag )
  740. {
  741. ulong Result = NO_ERROR;
  742. HANDLE hHeap = GetProcessHeap();
  743. ulong i;
  744. PutMsg( STDOUT, MSG_CONN_HDR_EX );
  745. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_TCP ) ) )
  746. {
  747. TCP_EX_TABLE *pTcpTable;
  748. TCPConnTableEntryEx *pTcp;
  749. // Get TCP connection table with onwer PID information
  750. Result = AllocateAndGetTcpExTableFromStack( &pTcpTable, TRUE,
  751. hHeap, 0, AF_INET );
  752. if ( NO_ERROR == Result )
  753. {
  754. for ( i = 0; i < pTcpTable->dwNumEntries; i++ )
  755. {
  756. pTcp = &pTcpTable->table[i];
  757. if ( ( pTcp->tcte_basic.tct_state != TCP_CONN_LISTEN ) ||
  758. (( pTcp->tcte_basic.tct_state == TCP_CONN_LISTEN ) && AllFlag) )
  759. {
  760. // DisplayTcpConnEntry needs the port info in host byte
  761. // order.
  762. pTcp->tcte_basic.tct_localport = (ulong)ntohs(
  763. (ushort)pTcp->tcte_basic.tct_localport);
  764. pTcp->tcte_basic.tct_remoteport = (ulong)ntohs(
  765. (ushort)pTcp->tcte_basic.tct_remoteport);
  766. // Display the Tcp connection info
  767. DisplayTcpConnEntry( (TCPConnTableEntry*)pTcp,
  768. sizeof(TCPConnTableEntryEx),
  769. NumFlag );
  770. }
  771. }
  772. HeapFree(hHeap, 0, pTcpTable);
  773. }
  774. }
  775. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_TCP6 ) ) )
  776. {
  777. TCP6_EX_TABLE *pTcpTable;
  778. TCP6ConnTableEntry *pTcp;
  779. // Get TCP connection table with onwer PID information
  780. Result = AllocateAndGetTcpExTableFromStack( &pTcpTable, TRUE,
  781. hHeap, 0, AF_INET6 );
  782. if ( NO_ERROR == Result )
  783. {
  784. for ( i = 0; i < pTcpTable->dwNumEntries; i++ )
  785. {
  786. pTcp = &pTcpTable->table[i];
  787. if ( ( pTcp->tct_state != TCP_CONN_LISTEN ) ||
  788. (( pTcp->tct_state == TCP_CONN_LISTEN ) && AllFlag) )
  789. {
  790. // DisplayTcpConnEntry needs the port info in host byte
  791. // order.
  792. pTcp->tct_localport = ntohs(
  793. (ushort)pTcp->tct_localport);
  794. pTcp->tct_remoteport = ntohs(
  795. (ushort)pTcp->tct_remoteport);
  796. // Display the Tcp connection info
  797. DisplayTcp6ConnEntry(pTcp, NumFlag);
  798. }
  799. }
  800. HeapFree(hHeap, 0, pTcpTable);
  801. }
  802. }
  803. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_UDP ) ) )
  804. {
  805. UDP_EX_TABLE *pUdpTable;
  806. UDPEntryEx *pUdp;
  807. // Get UDP connection table with owner PID information
  808. Result = AllocateAndGetUdpExTableFromStack ( &pUdpTable, TRUE,
  809. hHeap, 0, AF_INET );
  810. if (NO_ERROR == Result)
  811. {
  812. for ( i = 0; i < pUdpTable->dwNumEntries; i++ )
  813. {
  814. pUdp = &pUdpTable->table[i];
  815. if (AllFlag)
  816. {
  817. // DisplayUdpConnEntry needs the port info in host byte
  818. // order.
  819. pUdp->uee_basic.ue_localport = (ulong)ntohs(
  820. (ushort)pUdp->uee_basic.ue_localport);
  821. DisplayUdpConnEntry( (UDPEntry*)pUdp,
  822. sizeof(UDPEntryEx),
  823. NumFlag );
  824. }
  825. }
  826. HeapFree(hHeap, 0, pUdpTable);
  827. }
  828. }
  829. if ( !ProtoFlag || ( ProtoFlag && ( ProtoVal == PROTO_UDP6 ) ) )
  830. {
  831. UDP6_LISTENER_TABLE *pUdpTable;
  832. UDP6ListenerEntry *pUdp;
  833. // Get UDP connection table with owner PID information
  834. Result = AllocateAndGetUdpExTableFromStack ( &pUdpTable, TRUE,
  835. hHeap, 0, AF_INET6 );
  836. if (NO_ERROR == Result)
  837. {
  838. for ( i = 0; i < pUdpTable->dwNumEntries; i++ )
  839. {
  840. pUdp = &pUdpTable->table[i];
  841. if (AllFlag)
  842. {
  843. // DisplayUdp6ListenerEntry needs the port info in host byte
  844. // order.
  845. pUdp->ule_localport = (ulong)ntohs(
  846. (ushort)pUdp->ule_localport);
  847. DisplayUdp6ListenerEntry(pUdp,
  848. TRUE,
  849. NumFlag);
  850. }
  851. }
  852. HeapFree(hHeap, 0, pUdpTable);
  853. }
  854. }
  855. return( Result );
  856. }
  857. //*****************************************************************************
  858. //
  859. // Name: DoRoutes
  860. //
  861. // Description: Display the route table. Uses the system() API and route.exe
  862. // to do the dirty work.
  863. //
  864. // Parameters: void.
  865. //
  866. // Returns: ulong: NO_ERROR or some error code.
  867. //
  868. // History:
  869. // 01/27/94 JayPh Created.
  870. //
  871. //*****************************************************************************
  872. ulong DoRoutes( void )
  873. {
  874. ulong Result;
  875. PutMsg( STDOUT, MSG_ROUTE_HDR );
  876. Result = system( "route print" );
  877. return ( Result );
  878. }
  879. //*****************************************************************************
  880. //
  881. // Name: DisplayInterface
  882. //
  883. // Description: Display interface statistics.
  884. //
  885. // Parameters: IfEntry *pEntry: pointer to summary data entry.
  886. // ulong VerboseFlag: boolean indicating desire for verbosity.
  887. // IfEntry *ListHead: pointer to list of entries. Used if
  888. // verbosity desired.
  889. //
  890. // Returns: void.
  891. //
  892. // History:
  893. // 01/21/94 JayPh Created.
  894. //
  895. //*****************************************************************************
  896. void DisplayInterface( IfEntry *pEntry, ulong VerboseFlag, IfEntry *ListHead )
  897. {
  898. char *TmpStr;
  899. IfEntry *pIfList;
  900. char PhysAddrStr[32];
  901. PutMsg( STDOUT, MSG_IF_HDR );
  902. PutMsg( STDOUT,
  903. MSG_IF_OCTETS,
  904. pEntry->Info.if_inoctets,
  905. pEntry->Info.if_outoctets );
  906. PutMsg( STDOUT,
  907. MSG_IF_UCASTPKTS,
  908. pEntry->Info.if_inucastpkts,
  909. pEntry->Info.if_outucastpkts );
  910. PutMsg( STDOUT,
  911. MSG_IF_NUCASTPKTS,
  912. pEntry->Info.if_innucastpkts,
  913. pEntry->Info.if_outnucastpkts );
  914. PutMsg( STDOUT,
  915. MSG_IF_DISCARDS,
  916. pEntry->Info.if_indiscards,
  917. pEntry->Info.if_outdiscards );
  918. PutMsg( STDOUT,
  919. MSG_IF_ERRORS,
  920. pEntry->Info.if_inerrors,
  921. pEntry->Info.if_outerrors );
  922. PutMsg( STDOUT,
  923. MSG_IF_UNKNOWNPROTOS,
  924. pEntry->Info.if_inunknownprotos );
  925. if ( VerboseFlag )
  926. {
  927. // Also display configuration info
  928. // Traverse the list of interfaces, displaying config info
  929. pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink,
  930. IfEntry,
  931. ListEntry );
  932. while ( pIfList != ListHead )
  933. {
  934. PutMsg( STDOUT,
  935. MSG_IF_INDEX,
  936. pIfList->Info.if_index );
  937. PutMsg( STDOUT,
  938. MSG_IF_DESCR,
  939. pIfList->Info.if_descr );
  940. PutMsg( STDOUT,
  941. MSG_IF_TYPE,
  942. pIfList->Info.if_type );
  943. PutMsg( STDOUT,
  944. MSG_IF_MTU,
  945. pIfList->Info.if_mtu );
  946. PutMsg( STDOUT,
  947. MSG_IF_SPEED,
  948. pIfList->Info.if_speed );
  949. sprintf( PhysAddrStr,
  950. "%02x-%02X-%02X-%02X-%02X-%02X",
  951. pIfList->Info.if_physaddr[0],
  952. pIfList->Info.if_physaddr[1],
  953. pIfList->Info.if_physaddr[2],
  954. pIfList->Info.if_physaddr[3],
  955. pIfList->Info.if_physaddr[4],
  956. pIfList->Info.if_physaddr[5] );
  957. PutMsg( STDOUT,
  958. MSG_IF_PHYSADDR,
  959. PhysAddrStr );
  960. PutMsg( STDOUT,
  961. MSG_IF_ADMINSTATUS,
  962. pIfList->Info.if_adminstatus );
  963. PutMsg( STDOUT,
  964. MSG_IF_OPERSTATUS,
  965. pIfList->Info.if_operstatus );
  966. PutMsg( STDOUT,
  967. MSG_IF_LASTCHANGE,
  968. pIfList->Info.if_lastchange );
  969. PutMsg( STDOUT,
  970. MSG_IF_OUTQLEN,
  971. pIfList->Info.if_outqlen );
  972. // Get pointer to next entry in list
  973. pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink,
  974. IfEntry,
  975. ListEntry );
  976. }
  977. }
  978. }
  979. //*****************************************************************************
  980. //
  981. // Name: DisplayIP
  982. //
  983. // Description: Display IP statistics.
  984. //
  985. // Parameters: IpEntry *pEntry: pointer to summary data entry.
  986. // ulong VerboseFlag: boolean indicating desire for verbosity.
  987. // IpEntry *ListHead: pointer to list of entries. Used if
  988. // verbosity desired.
  989. //
  990. // Returns: void.
  991. //
  992. // History:
  993. // 01/21/94 JayPh Created.
  994. //
  995. //*****************************************************************************
  996. void DisplayIP( DWORD Type, IpEntry *pEntry, ulong VerboseFlag, IpEntry *ListHead )
  997. {
  998. char *TypeStr = LoadMsg( (Type==TYPE_IP)? MSG_IPV4 : MSG_IPV6 );
  999. if (TypeStr) {
  1000. PutMsg( STDOUT, MSG_IP_HDR, TypeStr );
  1001. LocalFree(TypeStr);
  1002. }
  1003. PutMsg( STDOUT,
  1004. MSG_IP_INRECEIVES,
  1005. pEntry->Info.ipsi_inreceives );
  1006. PutMsg( STDOUT,
  1007. MSG_IP_INHDRERRORS,
  1008. pEntry->Info.ipsi_inhdrerrors );
  1009. PutMsg( STDOUT,
  1010. MSG_IP_INADDRERRORS,
  1011. pEntry->Info.ipsi_inaddrerrors );
  1012. PutMsg( STDOUT,
  1013. MSG_IP_FORWDATAGRAMS,
  1014. pEntry->Info.ipsi_forwdatagrams );
  1015. PutMsg( STDOUT,
  1016. MSG_IP_INUNKNOWNPROTOS,
  1017. pEntry->Info.ipsi_inunknownprotos );
  1018. PutMsg( STDOUT,
  1019. MSG_IP_INDISCARDS,
  1020. pEntry->Info.ipsi_indiscards );
  1021. PutMsg( STDOUT,
  1022. MSG_IP_INDELIVERS,
  1023. pEntry->Info.ipsi_indelivers );
  1024. PutMsg( STDOUT,
  1025. MSG_IP_OUTREQUESTS,
  1026. pEntry->Info.ipsi_outrequests );
  1027. PutMsg( STDOUT,
  1028. MSG_IP_ROUTINGDISCARDS,
  1029. pEntry->Info.ipsi_routingdiscards );
  1030. PutMsg( STDOUT,
  1031. MSG_IP_OUTDISCARDS,
  1032. pEntry->Info.ipsi_outdiscards );
  1033. PutMsg( STDOUT,
  1034. MSG_IP_OUTNOROUTES,
  1035. pEntry->Info.ipsi_outnoroutes );
  1036. PutMsg( STDOUT,
  1037. MSG_IP_REASMREQDS,
  1038. pEntry->Info.ipsi_reasmreqds );
  1039. PutMsg( STDOUT,
  1040. MSG_IP_REASMOKS,
  1041. pEntry->Info.ipsi_reasmoks );
  1042. PutMsg( STDOUT,
  1043. MSG_IP_REASMFAILS,
  1044. pEntry->Info.ipsi_reasmfails );
  1045. PutMsg( STDOUT,
  1046. MSG_IP_FRAGOKS,
  1047. pEntry->Info.ipsi_fragoks );
  1048. PutMsg( STDOUT,
  1049. MSG_IP_FRAGFAILS,
  1050. pEntry->Info.ipsi_fragfails );
  1051. PutMsg( STDOUT,
  1052. MSG_IP_FRAGCREATES,
  1053. pEntry->Info.ipsi_fragcreates );
  1054. if ( VerboseFlag )
  1055. {
  1056. PutMsg( STDOUT,
  1057. MSG_IP_FORWARDING,
  1058. pEntry->Info.ipsi_forwarding );
  1059. PutMsg( STDOUT,
  1060. MSG_IP_DEFAULTTTL,
  1061. pEntry->Info.ipsi_defaultttl );
  1062. PutMsg( STDOUT,
  1063. MSG_IP_REASMTIMEOUT,
  1064. pEntry->Info.ipsi_reasmtimeout );
  1065. }
  1066. }
  1067. //*****************************************************************************
  1068. //
  1069. // Name: DisplayTCP
  1070. //
  1071. // Description: Display TCP statistics.
  1072. //
  1073. // Parameters: TcpEntry *pEntry: pointer to data entry.
  1074. // ulong VerboseFlag: boolean indicating desire for verbosity.
  1075. // TcpEntry *ListHead: pointer to list of entries. Used if
  1076. // verbosity desired.
  1077. //
  1078. // Returns: void.
  1079. //
  1080. // History:
  1081. // 01/26/94 JayPh Created.
  1082. //
  1083. //*****************************************************************************
  1084. void DisplayTCP( DWORD Type, TcpEntry *pEntry, ulong VerboseFlag, TcpEntry *ListHead )
  1085. {
  1086. char *TypeStr = LoadMsg( (Type==TYPE_TCP)? MSG_IPV4 : MSG_IPV6 );
  1087. if (TypeStr) {
  1088. PutMsg( STDOUT, MSG_TCP_HDR, TypeStr );
  1089. LocalFree(TypeStr);
  1090. }
  1091. PutMsg( STDOUT,
  1092. MSG_TCP_ACTIVEOPENS,
  1093. pEntry->Info.ts_activeopens );
  1094. PutMsg( STDOUT,
  1095. MSG_TCP_PASSIVEOPENS,
  1096. pEntry->Info.ts_passiveopens );
  1097. PutMsg( STDOUT,
  1098. MSG_TCP_ATTEMPTFAILS,
  1099. pEntry->Info.ts_attemptfails );
  1100. PutMsg( STDOUT,
  1101. MSG_TCP_ESTABRESETS,
  1102. pEntry->Info.ts_estabresets );
  1103. PutMsg( STDOUT,
  1104. MSG_TCP_CURRESTAB,
  1105. pEntry->Info.ts_currestab );
  1106. PutMsg( STDOUT,
  1107. MSG_TCP_INSEGS,
  1108. pEntry->Info.ts_insegs );
  1109. PutMsg( STDOUT,
  1110. MSG_TCP_OUTSEGS,
  1111. pEntry->Info.ts_outsegs );
  1112. PutMsg( STDOUT,
  1113. MSG_TCP_RETRANSSEGS,
  1114. pEntry->Info.ts_retranssegs );
  1115. if ( VerboseFlag )
  1116. {
  1117. switch ( pEntry->Info.ts_rtoalgorithm )
  1118. {
  1119. case 1:
  1120. PutMsg( STDOUT, MSG_TCP_RTOALGORITHM1 );
  1121. break;
  1122. case 2:
  1123. PutMsg( STDOUT, MSG_TCP_RTOALGORITHM2 );
  1124. break;
  1125. case 3:
  1126. PutMsg( STDOUT, MSG_TCP_RTOALGORITHM3 );
  1127. break;
  1128. case 4:
  1129. PutMsg( STDOUT, MSG_TCP_RTOALGORITHM4 );
  1130. break;
  1131. default:
  1132. PutMsg( STDOUT,
  1133. MSG_TCP_RTOALGORITHMX,
  1134. pEntry->Info.ts_rtoalgorithm );
  1135. break;
  1136. }
  1137. PutMsg( STDOUT,
  1138. MSG_TCP_RTOMIN,
  1139. pEntry->Info.ts_rtomin );
  1140. PutMsg( STDOUT,
  1141. MSG_TCP_RTOMAX,
  1142. pEntry->Info.ts_rtomax );
  1143. PutMsg( STDOUT,
  1144. MSG_TCP_MAXCONN,
  1145. pEntry->Info.ts_maxconn );
  1146. }
  1147. }
  1148. //*****************************************************************************
  1149. //
  1150. // Name: DisplayUDP
  1151. //
  1152. // Description: Display UDP statistics.
  1153. //
  1154. // Parameters: UdpEntry *pEntry: pointer to summary data entry.
  1155. // ulong VerboseFlag: boolean indicating desire for verbosity.
  1156. // UdpEntry *ListHead: pointer to list of entries. Used if
  1157. // verbosity desired.
  1158. //
  1159. // Returns: void.
  1160. //
  1161. // History:
  1162. // 01/21/94 JayPh Created.
  1163. //
  1164. //*****************************************************************************
  1165. void DisplayUDP( DWORD Type, UdpEntry *pEntry, ulong VerboseFlag, UdpEntry *ListHead )
  1166. {
  1167. char *TypeStr = LoadMsg( (Type==TYPE_UDP)? MSG_IPV4 : MSG_IPV6 );
  1168. if (TypeStr) {
  1169. PutMsg( STDOUT, MSG_UDP_HDR, TypeStr );
  1170. LocalFree(TypeStr);
  1171. }
  1172. PutMsg( STDOUT,
  1173. MSG_UDP_INDATAGRAMS,
  1174. pEntry->Info.us_indatagrams );
  1175. PutMsg( STDOUT,
  1176. MSG_UDP_NOPORTS,
  1177. pEntry->Info.us_noports );
  1178. PutMsg( STDOUT,
  1179. MSG_UDP_INERRORS,
  1180. pEntry->Info.us_inerrors );
  1181. PutMsg( STDOUT,
  1182. MSG_UDP_OUTDATAGRAMS,
  1183. pEntry->Info.us_outdatagrams );
  1184. }
  1185. //*****************************************************************************
  1186. //
  1187. // Name: DisplayICMP
  1188. //
  1189. // Description: Display ICMP statistics.
  1190. //
  1191. // Parameters: IcmpEntry *pEntry: pointer to summary data entry.
  1192. // ulong VerboseFlag: boolean indicating desire for verbosity.
  1193. // IcmpEntry *ListHead: pointer to list of entries. Used if
  1194. // verbosity desired.
  1195. //
  1196. // Returns: void.
  1197. //
  1198. // History:
  1199. // 01/21/94 JayPh Created.
  1200. //
  1201. //*****************************************************************************
  1202. void DisplayICMP( IcmpEntry *pEntry, ulong VerboseFlag, IcmpEntry *ListHead )
  1203. {
  1204. PutMsg( STDOUT, MSG_ICMP_HDR );
  1205. PutMsg( STDOUT,
  1206. MSG_ICMP_MSGS,
  1207. pEntry->InInfo.icmps_msgs,
  1208. pEntry->OutInfo.icmps_msgs );
  1209. PutMsg( STDOUT,
  1210. MSG_ICMP_ERRORS,
  1211. pEntry->InInfo.icmps_errors,
  1212. pEntry->OutInfo.icmps_errors );
  1213. PutMsg( STDOUT,
  1214. MSG_ICMP_DESTUNREACHS,
  1215. pEntry->InInfo.icmps_destunreachs,
  1216. pEntry->OutInfo.icmps_destunreachs );
  1217. PutMsg( STDOUT,
  1218. MSG_ICMP_TIMEEXCDS,
  1219. pEntry->InInfo.icmps_timeexcds,
  1220. pEntry->OutInfo.icmps_timeexcds );
  1221. PutMsg( STDOUT,
  1222. MSG_ICMP_PARMPROBS,
  1223. pEntry->InInfo.icmps_parmprobs,
  1224. pEntry->OutInfo.icmps_parmprobs );
  1225. PutMsg( STDOUT,
  1226. MSG_ICMP_SRCQUENCHS,
  1227. pEntry->InInfo.icmps_srcquenchs,
  1228. pEntry->OutInfo.icmps_srcquenchs );
  1229. PutMsg( STDOUT,
  1230. MSG_ICMP_REDIRECTS,
  1231. pEntry->InInfo.icmps_redirects,
  1232. pEntry->OutInfo.icmps_redirects );
  1233. PutMsg( STDOUT,
  1234. MSG_ICMP_ECHOS,
  1235. pEntry->InInfo.icmps_echos,
  1236. pEntry->OutInfo.icmps_echos );
  1237. PutMsg( STDOUT,
  1238. MSG_ICMP_ECHOREPS,
  1239. pEntry->InInfo.icmps_echoreps,
  1240. pEntry->OutInfo.icmps_echoreps );
  1241. PutMsg( STDOUT,
  1242. MSG_ICMP_TIMESTAMPS,
  1243. pEntry->InInfo.icmps_timestamps,
  1244. pEntry->OutInfo.icmps_timestamps );
  1245. PutMsg( STDOUT,
  1246. MSG_ICMP_TIMESTAMPREPS,
  1247. pEntry->InInfo.icmps_timestampreps,
  1248. pEntry->OutInfo.icmps_timestampreps );
  1249. PutMsg( STDOUT,
  1250. MSG_ICMP_ADDRMASKS,
  1251. pEntry->InInfo.icmps_addrmasks,
  1252. pEntry->OutInfo.icmps_addrmasks );
  1253. PutMsg( STDOUT,
  1254. MSG_ICMP_ADDRMASKREPS,
  1255. pEntry->InInfo.icmps_addrmaskreps,
  1256. pEntry->OutInfo.icmps_addrmaskreps );
  1257. }
  1258. typedef struct {
  1259. uint Type;
  1260. uint Message;
  1261. } ICMP_TYPE_MESSAGE;
  1262. //
  1263. // List of messages for known ICMPv6 types. Entries in this list
  1264. // must be in order by Type.
  1265. //
  1266. ICMP_TYPE_MESSAGE Icmp6TypeMessage[] = {
  1267. { ICMPv6_DESTINATION_UNREACHABLE, MSG_ICMP_DESTUNREACHS },
  1268. { ICMPv6_PACKET_TOO_BIG, MSG_ICMP_PACKET_TOO_BIGS },
  1269. { ICMPv6_TIME_EXCEEDED, MSG_ICMP_TIMEEXCDS },
  1270. { ICMPv6_PARAMETER_PROBLEM, MSG_ICMP_PARMPROBS },
  1271. { ICMPv6_ECHO_REQUEST, MSG_ICMP_ECHOS },
  1272. { ICMPv6_ECHO_REPLY, MSG_ICMP_ECHOREPS },
  1273. { ICMPv6_MULTICAST_LISTENER_QUERY, MSG_ICMP_MLD_QUERY },
  1274. { ICMPv6_MULTICAST_LISTENER_REPORT, MSG_ICMP_MLD_REPORT },
  1275. { ICMPv6_MULTICAST_LISTENER_DONE, MSG_ICMP_MLD_DONE },
  1276. { ICMPv6_ROUTER_SOLICIT, MSG_ICMP_ROUTER_SOLICIT },
  1277. { ICMPv6_ROUTER_ADVERT, MSG_ICMP_ROUTER_ADVERT },
  1278. { ICMPv6_NEIGHBOR_SOLICIT, MSG_ICMP_NEIGHBOR_SOLICIT },
  1279. { ICMPv6_NEIGHBOR_ADVERT, MSG_ICMP_NEIGHBOR_ADVERT },
  1280. { ICMPv6_REDIRECT, MSG_ICMP_REDIRECTS },
  1281. { ICMPv6_ROUTER_RENUMBERING, MSG_ICMP_ROUTER_RENUMBERING },
  1282. { 0, 0 }
  1283. };
  1284. void DisplayICMP6( Icmp6Entry *pEntry, ulong VerboseFlag, IcmpEntry *ListHead )
  1285. {
  1286. uint i = 0, Type, Message;
  1287. PutMsg( STDOUT, MSG_ICMP6_HDR );
  1288. PutMsg( STDOUT,
  1289. MSG_ICMP_MSGS,
  1290. pEntry->InInfo.icmps_msgs,
  1291. pEntry->OutInfo.icmps_msgs );
  1292. PutMsg( STDOUT,
  1293. MSG_ICMP_ERRORS,
  1294. pEntry->InInfo.icmps_errors,
  1295. pEntry->OutInfo.icmps_errors );
  1296. for (Type=0; Type<256; Type++) {
  1297. // Figure out message id
  1298. Message = 0;
  1299. if (Type == Icmp6TypeMessage[i].Type)
  1300. {
  1301. Message = Icmp6TypeMessage[i++].Message;
  1302. }
  1303. // Skip types with 0 packets in and out
  1304. if (!pEntry->InInfo.icmps_typecount[Type] &&
  1305. !pEntry->OutInfo.icmps_typecount[Type])
  1306. {
  1307. continue;
  1308. }
  1309. if (Message)
  1310. {
  1311. PutMsg( STDOUT,
  1312. Message,
  1313. pEntry->InInfo.icmps_typecount[Type],
  1314. pEntry->OutInfo.icmps_typecount[Type] );
  1315. }
  1316. else
  1317. {
  1318. PutMsg( STDOUT,
  1319. MSG_ICMP6_TYPECOUNT,
  1320. Type,
  1321. pEntry->InInfo.icmps_typecount[Type],
  1322. pEntry->OutInfo.icmps_typecount[Type] );
  1323. }
  1324. }
  1325. }
  1326. static DWORD
  1327. GenerateHostNameServiceString(
  1328. OUT char * pszBuffer,
  1329. IN OUT int * lpcbBufLen,
  1330. IN BOOL fNumFlag,
  1331. IN BOOL fLocalHost,
  1332. IN BOOL fDatagram,
  1333. IN LPSOCKADDR lpSockaddr,
  1334. IN ulong uSockaddrLen
  1335. )
  1336. /*++
  1337. Description:
  1338. Generates the <hostname>:<service-string> from the address and port
  1339. information supplied. The result is stored in the pszBuffer passed in.
  1340. If fLocalHost == TRUE, then the cached local host name is used to
  1341. improve performance.
  1342. Arguments:
  1343. pszBuffer Buffer to store the resulting string.
  1344. lpcbBufLen pointer to integer containing the count of bytes in Buffer
  1345. and on return contains the number of bytes written.
  1346. If the buffer is insufficient, then the required bytes is
  1347. stored here.
  1348. fNumFlag generates the output using numbers for host and port number.
  1349. fLocalHost indicates if we want the service string for local host or
  1350. remote host. Also for local host, this function generates
  1351. the local host name without FQDN.
  1352. pszProtocol specifies the protocol used for the service.
  1353. uAddress unisgned long address of the service.
  1354. uPort unsinged long port number.
  1355. Returns:
  1356. Win32 error codes. NO_ERROR on success.
  1357. History:
  1358. MuraliK 12/15/94
  1359. Added this function to avoid FQDNs for local name + abstract the common
  1360. code used multiple times in old code.
  1361. Also this function provides local host name caching.
  1362. --*/
  1363. {
  1364. char LocalBuffer[MAX_HOST_NAME_SIZE]; // to hold dummy output
  1365. char LocalServiceEntry[MAX_SERVICE_NAME_SIZE];
  1366. int BufferLen;
  1367. char * pszHostName = NULL; // init a pointer.
  1368. char * pszServiceName = NULL;
  1369. DWORD dwError = NO_ERROR;
  1370. struct addrinfo *ai;
  1371. int Result;
  1372. int Flags = 0;
  1373. // for caching local host name. getnameinfo doesn't seem to find the
  1374. // host name for a local address.
  1375. static char s_LocalHostName[MAX_HOST_NAME_SIZE];
  1376. static BOOL s_fLocalHostName = FALSE;
  1377. if ( pszBuffer == NULL) {
  1378. return ( ERROR_INSUFFICIENT_BUFFER);
  1379. }
  1380. *pszBuffer = '\0'; // initialize to null string
  1381. if (fNumFlag) {
  1382. Flags |= NI_NUMERICHOST | NI_NUMERICSERV;
  1383. }
  1384. if (fLocalHost) {
  1385. Flags |= NI_NOFQDN;
  1386. }
  1387. if (fDatagram) {
  1388. Flags |= NI_DGRAM;
  1389. }
  1390. //
  1391. // This complexity shouldn't be required but unlike the hostname string,
  1392. // getnameinfo doesn't automatically include the numeric form
  1393. // when a service name isn't found. Instead, it fails.
  1394. //
  1395. if (fLocalHost && !fNumFlag) {
  1396. if ( s_fLocalHostName) {
  1397. pszHostName = s_LocalHostName; // pull from the cache
  1398. } else {
  1399. Result = gethostname( s_LocalHostName,
  1400. sizeof( s_LocalHostName));
  1401. if ( Result == 0) {
  1402. char * pszFirstDot;
  1403. //
  1404. // Cache the copy of local host name now.
  1405. // Limit the host name to first part of host name.
  1406. // NO FQDN
  1407. //
  1408. s_fLocalHostName = TRUE;
  1409. pszFirstDot = strchr( s_LocalHostName, '.');
  1410. if ( pszFirstDot != NULL) {
  1411. *pszFirstDot = '\0'; // terminate string
  1412. }
  1413. pszHostName = s_LocalHostName;
  1414. }
  1415. } // if ( s_fLocalhost)
  1416. }
  1417. if (!pszHostName) {
  1418. Result = getnameinfo(lpSockaddr, uSockaddrLen,
  1419. LocalBuffer, sizeof(LocalBuffer),
  1420. NULL, 0,
  1421. Flags);
  1422. if (Result != 0) {
  1423. return Result;
  1424. }
  1425. pszHostName = LocalBuffer;
  1426. }
  1427. Result = getnameinfo(lpSockaddr, uSockaddrLen,
  1428. NULL, 0,
  1429. LocalServiceEntry, sizeof(LocalServiceEntry),
  1430. Flags);
  1431. if ((Result == WSANO_DATA) && !fNumFlag) {
  1432. Result = getnameinfo(lpSockaddr, uSockaddrLen,
  1433. NULL, 0,
  1434. LocalServiceEntry, sizeof(LocalServiceEntry),
  1435. Flags | NI_NUMERICSERV);
  1436. }
  1437. if (Result != 0) {
  1438. return Result;
  1439. }
  1440. pszServiceName = LocalServiceEntry;
  1441. // Now pszServiceName has the service name/portnumber
  1442. BufferLen = strlen( pszHostName) + strlen( pszServiceName) + 4;
  1443. // 4 bytes extra for "[]:" and null-character.
  1444. if ( *lpcbBufLen < BufferLen ) {
  1445. dwError = ERROR_INSUFFICIENT_BUFFER;
  1446. } else if ((lpSockaddr->sa_family == AF_INET6) && strchr(pszHostName, ':')) {
  1447. sprintf( pszBuffer, "[%s]:%s", pszHostName, pszServiceName);
  1448. } else {
  1449. sprintf( pszBuffer, "%s:%s", pszHostName, pszServiceName);
  1450. }
  1451. *lpcbBufLen = BufferLen;
  1452. return ( dwError);
  1453. } // GenerateHostNameServiceString()
  1454. static DWORD
  1455. GenerateV4HostNameServiceString(
  1456. OUT char * pszBuffer,
  1457. IN OUT int * lpcbBufLen,
  1458. IN BOOL fNumFlag,
  1459. IN BOOL fLocalHost,
  1460. IN BOOL fDatagram,
  1461. IN ulong uAddress,
  1462. IN ulong uPort
  1463. )
  1464. {
  1465. SOCKADDR_IN sin;
  1466. ZeroMemory(&sin, sizeof(sin));
  1467. sin.sin_family = AF_INET;
  1468. sin.sin_addr.s_addr = uAddress;
  1469. sin.sin_port = htons((ushort)uPort);
  1470. return GenerateHostNameServiceString(pszBuffer,
  1471. lpcbBufLen,
  1472. fNumFlag,
  1473. fLocalHost,
  1474. fDatagram,
  1475. (LPSOCKADDR)&sin,
  1476. sizeof(sin));
  1477. }
  1478. static DWORD
  1479. GenerateV6HostNameServiceString(
  1480. OUT char * pszBuffer,
  1481. IN OUT int * lpcbBufLen,
  1482. IN BOOL fNumFlag,
  1483. IN BOOL fLocalHost,
  1484. IN BOOL fDatagram,
  1485. IN struct in6_addr *ipAddress,
  1486. IN ulong uScopeId,
  1487. IN ulong uPort
  1488. )
  1489. {
  1490. SOCKADDR_IN6 sin;
  1491. ZeroMemory(&sin, sizeof(sin));
  1492. sin.sin6_family = AF_INET6;
  1493. sin.sin6_addr = *ipAddress;
  1494. sin.sin6_scope_id = uScopeId;
  1495. sin.sin6_port = htons((ushort)uPort);
  1496. return GenerateHostNameServiceString(pszBuffer,
  1497. lpcbBufLen,
  1498. fNumFlag,
  1499. fLocalHost,
  1500. fDatagram,
  1501. (LPSOCKADDR)&sin,
  1502. sizeof(sin));
  1503. }
  1504. //*****************************************************************************
  1505. //
  1506. // Name: DisplayTcpConnEntry
  1507. //
  1508. // Description: Display information about 1 tcp connection.
  1509. //
  1510. // Parameters: TcpConnTableEntry *pTcp: pointer to a tcp connection structure.
  1511. // InfoSize: indicates whether the data is a TCPConnTableEntry or
  1512. // TCPConnTableEntryEx.
  1513. //
  1514. // Returns: void.
  1515. //
  1516. // History:
  1517. // 12/31/93 JayPh Created.
  1518. // 02/01/94 JayPh Use symbolic names for addresses and ports if available
  1519. // 12/15/94 MuraliK Avoid printing FQDNs for local host.
  1520. //
  1521. //*****************************************************************************
  1522. void DisplayTcpConnEntry( TCPConnTableEntry *pTcp, ulong InfoSize, ulong NumFlag )
  1523. {
  1524. char *TypeStr;
  1525. char *StateStr;
  1526. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1527. char RemoteStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1528. DWORD dwErr;
  1529. int BufLen;
  1530. TypeStr = LoadMsg( MSG_CONN_TYPE_TCP );
  1531. if ( TypeStr == NULL )
  1532. {
  1533. return;
  1534. }
  1535. BufLen = sizeof( LocalStr);
  1536. dwErr = GenerateV4HostNameServiceString( LocalStr,
  1537. &BufLen,
  1538. NumFlag != 0, TRUE, FALSE,
  1539. pTcp->tct_localaddr,
  1540. pTcp->tct_localport);
  1541. ASSERT( dwErr == NO_ERROR);
  1542. switch ( pTcp->tct_state )
  1543. {
  1544. case TCP_CONN_CLOSED:
  1545. StateStr = LoadMsg( MSG_CONN_STATE_CLOSED );
  1546. break;
  1547. case TCP_CONN_LISTEN:
  1548. // Tcpip generates dummy sequential remote ports for
  1549. // listening connections to avoid getting stuck in snmp.
  1550. // MohsinA, 12-Feb-97.
  1551. pTcp->tct_remoteport = 0;
  1552. StateStr = LoadMsg( MSG_CONN_STATE_LISTENING );
  1553. break;
  1554. case TCP_CONN_SYN_SENT:
  1555. StateStr = LoadMsg( MSG_CONN_STATE_SYNSENT );
  1556. break;
  1557. case TCP_CONN_SYN_RCVD:
  1558. StateStr = LoadMsg( MSG_CONN_STATE_SYNRECV );
  1559. break;
  1560. case TCP_CONN_ESTAB:
  1561. StateStr = LoadMsg( MSG_CONN_STATE_ESTABLISHED );
  1562. break;
  1563. case TCP_CONN_FIN_WAIT1:
  1564. StateStr = LoadMsg( MSG_CONN_STATE_FIN_WAIT_1 );
  1565. break;
  1566. case TCP_CONN_FIN_WAIT2:
  1567. StateStr = LoadMsg( MSG_CONN_STATE_FIN_WAIT_2 );
  1568. break;
  1569. case TCP_CONN_CLOSE_WAIT:
  1570. StateStr = LoadMsg( MSG_CONN_STATE_CLOSE_WAIT );
  1571. break;
  1572. case TCP_CONN_CLOSING:
  1573. StateStr = LoadMsg( MSG_CONN_STATE_CLOSING );
  1574. break;
  1575. case TCP_CONN_LAST_ACK:
  1576. StateStr = LoadMsg( MSG_CONN_STATE_LAST_ACK );
  1577. break;
  1578. case TCP_CONN_TIME_WAIT:
  1579. StateStr = LoadMsg( MSG_CONN_STATE_TIME_WAIT );
  1580. break;
  1581. default:
  1582. StateStr = NULL;
  1583. DEBUG_PRINT(("DisplayTcpConnEntry: State=%d?\n ",
  1584. pTcp->tct_state ));
  1585. }
  1586. BufLen = sizeof( RemoteStr);
  1587. dwErr = GenerateV4HostNameServiceString( RemoteStr,
  1588. &BufLen,
  1589. NumFlag != 0, FALSE, FALSE,
  1590. pTcp->tct_remoteaddr,
  1591. pTcp->tct_remoteport );
  1592. ASSERT( dwErr == NO_ERROR);
  1593. if ( StateStr == NULL )
  1594. {
  1595. DEBUG_PRINT(("DisplayTcpConnEntry: Problem with the message file\n"));
  1596. LocalFree(TypeStr);
  1597. return;
  1598. }
  1599. if (sizeof(TCPConnTableEntryEx) == InfoSize)
  1600. {
  1601. ulong Pid = ((TCPConnTableEntryEx*)pTcp)->tcte_owningpid;
  1602. PutMsg( STDOUT, MSG_CONN_ENTRY_EX, TypeStr, LocalStr, RemoteStr, StateStr, Pid );
  1603. }
  1604. else
  1605. {
  1606. PutMsg( STDOUT, MSG_CONN_ENTRY, TypeStr, LocalStr, RemoteStr, StateStr );
  1607. }
  1608. LocalFree(TypeStr);
  1609. LocalFree(StateStr);
  1610. }
  1611. //*****************************************************************************
  1612. //
  1613. // Name: DisplayTcp6ConnEntry
  1614. //
  1615. // Description: Display information about 1 tcp connection over IPv6.
  1616. //
  1617. // Parameters: TCP6ConnTableEntry *pTcp: pointer to a tcp connection structure.
  1618. //
  1619. // Returns: void.
  1620. //
  1621. // History:
  1622. // 24/04/01 DThaler Created.
  1623. //
  1624. //*****************************************************************************
  1625. void DisplayTcp6ConnEntry( TCP6ConnTableEntry *pTcp, ulong NumFlag )
  1626. {
  1627. char *TypeStr;
  1628. char *StateStr;
  1629. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1630. char RemoteStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1631. DWORD dwErr;
  1632. int BufLen;
  1633. TypeStr = LoadMsg( MSG_CONN_TYPE_TCP );
  1634. if ( TypeStr == NULL )
  1635. {
  1636. return;
  1637. }
  1638. BufLen = sizeof( LocalStr);
  1639. dwErr = GenerateV6HostNameServiceString( LocalStr,
  1640. &BufLen,
  1641. NumFlag != 0, TRUE, FALSE,
  1642. &pTcp->tct_localaddr,
  1643. pTcp->tct_localscopeid,
  1644. pTcp->tct_localport);
  1645. ASSERT( dwErr == NO_ERROR);
  1646. switch ( pTcp->tct_state )
  1647. {
  1648. case TCP_CONN_CLOSED:
  1649. StateStr = LoadMsg( MSG_CONN_STATE_CLOSED );
  1650. break;
  1651. case TCP_CONN_LISTEN:
  1652. // Tcpip generates dummy sequential remote ports for
  1653. // listening connections to avoid getting stuck in snmp.
  1654. // MohsinA, 12-Feb-97.
  1655. pTcp->tct_remoteport = 0;
  1656. StateStr = LoadMsg( MSG_CONN_STATE_LISTENING );
  1657. break;
  1658. case TCP_CONN_SYN_SENT:
  1659. StateStr = LoadMsg( MSG_CONN_STATE_SYNSENT );
  1660. break;
  1661. case TCP_CONN_SYN_RCVD:
  1662. StateStr = LoadMsg( MSG_CONN_STATE_SYNRECV );
  1663. break;
  1664. case TCP_CONN_ESTAB:
  1665. StateStr = LoadMsg( MSG_CONN_STATE_ESTABLISHED );
  1666. break;
  1667. case TCP_CONN_FIN_WAIT1:
  1668. StateStr = LoadMsg( MSG_CONN_STATE_FIN_WAIT_1 );
  1669. break;
  1670. case TCP_CONN_FIN_WAIT2:
  1671. StateStr = LoadMsg( MSG_CONN_STATE_FIN_WAIT_2 );
  1672. break;
  1673. case TCP_CONN_CLOSE_WAIT:
  1674. StateStr = LoadMsg( MSG_CONN_STATE_CLOSE_WAIT );
  1675. break;
  1676. case TCP_CONN_CLOSING:
  1677. StateStr = LoadMsg( MSG_CONN_STATE_CLOSING );
  1678. break;
  1679. case TCP_CONN_LAST_ACK:
  1680. StateStr = LoadMsg( MSG_CONN_STATE_LAST_ACK );
  1681. break;
  1682. case TCP_CONN_TIME_WAIT:
  1683. StateStr = LoadMsg( MSG_CONN_STATE_TIME_WAIT );
  1684. break;
  1685. default:
  1686. StateStr = NULL;
  1687. DEBUG_PRINT(("DisplayTcp6ConnEntry: State=%d?\n ",
  1688. pTcp->tct_state ));
  1689. }
  1690. BufLen = sizeof( RemoteStr);
  1691. dwErr = GenerateV6HostNameServiceString( RemoteStr,
  1692. &BufLen,
  1693. NumFlag != 0, FALSE, FALSE,
  1694. &pTcp->tct_remoteaddr,
  1695. pTcp->tct_remotescopeid,
  1696. pTcp->tct_remoteport );
  1697. ASSERT( dwErr == NO_ERROR);
  1698. if ( StateStr == NULL )
  1699. {
  1700. DEBUG_PRINT(("DisplayTcp6ConnEntry: Problem with the message file\n"));
  1701. LocalFree(TypeStr);
  1702. return;
  1703. }
  1704. PutMsg( STDOUT, MSG_CONN_ENTRY_EX, TypeStr, LocalStr, RemoteStr, StateStr, pTcp->tct_owningpid );
  1705. LocalFree(TypeStr);
  1706. LocalFree(StateStr);
  1707. }
  1708. //*****************************************************************************
  1709. //
  1710. // Name: DisplayUdpConnEntry
  1711. //
  1712. // Description: Display information on 1 udp connection
  1713. //
  1714. // Parameters: UDPEntry *pUdp: pointer to udp connection structure.
  1715. // InfoSize: indicates whether the data is a UDPEntry or
  1716. // UDPEntryEx.
  1717. //
  1718. // Returns: void.
  1719. //
  1720. // History:
  1721. // 12/31/93 JayPh Created.
  1722. // 02/01/94 JayPh Use symbolic names for addresses and ports if available
  1723. //
  1724. //*****************************************************************************
  1725. void DisplayUdpConnEntry( UDPEntry *pUdp, ulong InfoSize, ulong NumFlag )
  1726. {
  1727. char *TypeStr;
  1728. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1729. char * RemoteStr;
  1730. int BufLen;
  1731. DWORD dwErr;
  1732. TypeStr = LoadMsg( MSG_CONN_TYPE_UDP );
  1733. if ( TypeStr == NULL )
  1734. {
  1735. return;
  1736. }
  1737. BufLen = sizeof( LocalStr);
  1738. dwErr = GenerateV4HostNameServiceString( LocalStr,
  1739. &BufLen,
  1740. NumFlag != 0, TRUE, TRUE,
  1741. pUdp->ue_localaddr,
  1742. pUdp->ue_localport);
  1743. ASSERT( dwErr == NO_ERROR);
  1744. RemoteStr = LoadMsg( MSG_CONN_UDP_FORADDR );
  1745. if ( RemoteStr == NULL )
  1746. {
  1747. DEBUG_PRINT(("DisplayUdpConnEntry: no message?\n"));
  1748. LocalFree(TypeStr);
  1749. return;
  1750. }
  1751. if (sizeof(UDPEntryEx) == InfoSize)
  1752. {
  1753. ulong Pid = ((UDPEntryEx*)pUdp)->uee_owningpid;
  1754. PutMsg( STDOUT, MSG_CONN_ENTRY_EX, TypeStr, LocalStr, RemoteStr, "", Pid );
  1755. }
  1756. else
  1757. {
  1758. PutMsg( STDOUT, MSG_CONN_ENTRY, TypeStr, LocalStr, RemoteStr, "" );
  1759. }
  1760. LocalFree(TypeStr);
  1761. LocalFree(RemoteStr);
  1762. }
  1763. void DisplayUdp6ListenerEntry( UDP6ListenerEntry *pUdp, BOOL WithOwner, ulong NumFlag )
  1764. {
  1765. char *TypeStr;
  1766. char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE];
  1767. char * RemoteStr;
  1768. int BufLen;
  1769. DWORD dwErr;
  1770. TypeStr = LoadMsg( MSG_CONN_TYPE_UDP );
  1771. if ( TypeStr == NULL )
  1772. {
  1773. return;
  1774. }
  1775. BufLen = sizeof( LocalStr);
  1776. dwErr = GenerateV6HostNameServiceString( LocalStr,
  1777. &BufLen,
  1778. NumFlag != 0, TRUE, TRUE,
  1779. &pUdp->ule_localaddr,
  1780. pUdp->ule_localscopeid,
  1781. pUdp->ule_localport);
  1782. ASSERT( dwErr == NO_ERROR);
  1783. RemoteStr = LoadMsg( MSG_CONN_UDP_FORADDR );
  1784. if ( RemoteStr == NULL )
  1785. {
  1786. DEBUG_PRINT(("DisplayUdpConnEntry: no message?\n"));
  1787. LocalFree(TypeStr);
  1788. return;
  1789. }
  1790. if (WithOwner)
  1791. {
  1792. ulong Pid = pUdp->ule_owningpid;
  1793. PutMsg( STDOUT, MSG_CONN_ENTRY_EX, TypeStr, LocalStr, RemoteStr, "", Pid );
  1794. }
  1795. else
  1796. {
  1797. PutMsg( STDOUT, MSG_CONN_ENTRY, TypeStr, LocalStr, RemoteStr, "" );
  1798. }
  1799. LocalFree(TypeStr);
  1800. LocalFree(RemoteStr);
  1801. }
  1802. //*****************************************************************************
  1803. //
  1804. // Name: Usage
  1805. //
  1806. // Description: Called when a command line parameter problem is detected, it
  1807. // displays a proper command usage message and exits.
  1808. //
  1809. // WARNING: This routine does not return.
  1810. //
  1811. // Parameters: char *PgmName: pointer to string contain name of program.
  1812. //
  1813. // Returns: Doesn't return.
  1814. //
  1815. // History:
  1816. // 01/04/93 JayPh Created.
  1817. //
  1818. //*****************************************************************************
  1819. void Usage( void )
  1820. {
  1821. PutMsg( STDERR, MSG_USAGE, PgmName );
  1822. exit( 1 );
  1823. }