//++ // // Copyright (C) Microsoft Corporation, 1987 - 1999 // // Module Name: // // netstat.c // // Abstract: // // Queries into network drivers // // Author: // // Anilth - 4-20-1998 // // Environment: // // User mode only. // Contains NT-specific code. // // Revision History: // //-- #include "precomp.h" #include #include "snmputil.h" #include "tcpinfo.h" #include "ipinfo.h" #include "llinfo.h" #define MAX_HOST_NAME_SIZE ( 260) #define MAX_SERVICE_NAME_SIZE ( 200) #define MAX_NUM_DIGITS 30 BOOL NumFlag = FALSE; LPTSTR FormatNumber(DWORD dwNumber); VOID DisplayInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IfEntry *pEntry, IfEntry *ListHead ); //used in DoInterface() HRESULT DoInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); static DWORD GenerateHostNameServiceString( OUT char * pszBuffer, IN OUT int * lpcbBufLen, IN BOOL fNumFlag, IN BOOL fLocalHost, IN const char * pszProtocol, IN ulong uAddress, IN ulong uPort ); void DisplayTcpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, TcpConnEntry *pTcp ); void DisplayUdpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, UdpConnEntry *pUdp ); HRESULT DoConnections( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); void DisplayIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IpEntry *pEntry); //called by DoIp HRESULT DoIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); void DisplayTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, TcpEntry *pEntry ); HRESULT DoTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); VOID DisplayUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, UdpEntry *pEntry ); // called by DoUDP() HRESULT DoUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); void DisplayICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IcmpEntry *pEntry ); HRESULT DoICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ); BOOL NetstatTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) //++ // Description: // This test prints all the stats that netstat outputs // // Arguments: // None. // // Author: // Rajkumar 08/04/98 //-- { HRESULT hr = S_OK; ulong Result; InitializeListHead(&pResults->Netstat.lmsgGlobalOutput); InitializeListHead(&pResults->Netstat.lmsgInterfaceOutput); InitializeListHead(&pResults->Netstat.lmsgConnectionGlobalOutput); InitializeListHead(&pResults->Netstat.lmsgTcpConnectionOutput); InitializeListHead(&pResults->Netstat.lmsgUdpConnectionOutput); InitializeListHead(&pResults->Netstat.lmsgIpOutput); InitializeListHead(&pResults->Netstat.lmsgTcpOutput); InitializeListHead(&pResults->Netstat.lmsgUdpOutput); InitializeListHead(&pResults->Netstat.lmsgIcmpOutput); if (!pParams->fReallyVerbose) return hr; PrintStatusMessage( pParams, 4, IDS_NETSTAT_STATUS_MSG ); // // initialize the snmp interface // Result = InitSnmp(); if( NO_ERROR != Result ) { //IDS_NETSTAT_14401 "Initialization of SNMP failed.\n" AddMessageToListId( &pResults->Netstat.lmsgGlobalOutput, Nd_Quiet, IDS_NETSTAT_14401); return S_FALSE; } // // Show ethernet statistics // hr = DoInterface( pParams, pResults ); // // Show connections // if( S_OK == hr ) hr = DoConnections( pParams, pResults ); // // Display IP statistics // if( S_OK == hr ) hr = DoIP( pParams, pResults ); // // Display TCP statistics // if( S_OK == hr ) hr = DoTCP( pParams, pResults ); // // Display UDP statistics // if( S_OK == hr ) hr = DoUDP( pParams, pResults ); // // Display ICMP statistics // if( S_OK == hr ) hr = DoICMP( pParams, pResults ); pResults->Netstat.hrTestResult = hr; return hr; } //***************************************************************************** // // Name: DisplayInterface // // Description: Display interface statistics. // // Parameters: IfEntry *pEntry: pointer to summary data entry. // ulong VerboseFlag: boolean indicating desire for verbosity. // IfEntry *ListHead: pointer to list of entries. Used if // verbosity desired. // // Returns: void. // // History: // 01/21/94 JayPh Created. // //***************************************************************************** VOID DisplayInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IfEntry *pEntry, IfEntry *ListHead ) { char *TmpStr; IfEntry *pIfList; char PhysAddrStr[32]; //IDS_NETSTAT_14402 "\n\nInterface Statistics\n\n" AddMessageToListId( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14402); //IDS_NETSTAT_14403 " Received Sent\n" AddMessageToListId( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14403); //IDS_NETSTAT_14404 "Unicast Packets %12u %12u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14404, pEntry->Info.if_inoctets, pEntry->Info.if_outoctets ); //IDS_NETSTAT_14405 "Non-unicast packets %12u %12u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14405, pEntry->Info.if_innucastpkts, pEntry->Info.if_outnucastpkts ); //IDS_NETSTAT_14406 "Discards %12u %12u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14406, pEntry->Info.if_indiscards, pEntry->Info.if_outdiscards ); //IDS_NETSTAT_14407 "Errors %12u %12u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14407, pEntry->Info.if_inerrors, pEntry->Info.if_outerrors ); //IDS_NETSTAT_14408 "Unknown protocols %12u %12u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14408, pEntry->Info.if_inunknownprotos ); if ( pParams->fReallyVerbose) { // Also display configuration info // Traverse the list of interfaces, displaying config info pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink, IfEntry, ListEntry ); while ( pIfList != ListHead ) { //IDS_NETSTAT_14409 "\nInterface index = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14409, pIfList->Info.if_index ); //IDS_NETSTAT_14410 "Description = %s\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14410, pIfList->Info.if_descr ); //IDS_NETSTAT_14411 "Type = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14411, pIfList->Info.if_type ); //IDS_NETSTAT_14412 "MTU = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14412, pIfList->Info.if_mtu ); //IDS_NETSTAT_14413 "Speed = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14413, pIfList->Info.if_speed ); sprintf( PhysAddrStr, "%02x-%02X-%02X-%02X-%02X-%02X", pIfList->Info.if_physaddr[0], pIfList->Info.if_physaddr[1], pIfList->Info.if_physaddr[2], pIfList->Info.if_physaddr[3], pIfList->Info.if_physaddr[4], pIfList->Info.if_physaddr[5] ); //IDS_NETSTAT_14414 "Physical Address = %s\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14414, PhysAddrStr ); //IDS_NETSTAT_14415 "Administrative Status = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14415, pIfList->Info.if_adminstatus ); //IDS_NETSTAT_14416 "Operational Status = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14416, pIfList->Info.if_operstatus ); //IDS_NETSTAT_14417 "Last Changed = %u\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14417, pIfList->Info.if_lastchange ); //IDS_NETSTAT_14418 "Output Queue Length = %u\n\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_ReallyVerbose, IDS_NETSTAT_14418, pIfList->Info.if_outqlen ); // Get pointer to next entry in list pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink, IfEntry, ListEntry ); } } } HRESULT DoInterface( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ) //++ // Description: // Displays statistics of current connections //-- { IfEntry *ListHead; IfEntry *pIfList; IfEntry SumOfEntries; ulong Result; // Get the statistics ListHead = (IfEntry *)GetTable( TYPE_IF, &Result ); if ( ListHead == NULL ) { //IDS_NETSTAT_14419 "Getting interface statistics table failed.\n" AddMessageToList( &pResults->Netstat.lmsgInterfaceOutput, Nd_Quiet, IDS_NETSTAT_14419); return S_FALSE; } // Clear the summation structure ZeroMemory( &SumOfEntries, sizeof( IfEntry ) ); // Traverse the list of interfaces, summing the different fields pIfList = CONTAINING_RECORD( ListHead->ListEntry.Flink, IfEntry, ListEntry ); while (pIfList != ListHead) { SumOfEntries.Info.if_inoctets += pIfList->Info.if_inoctets; SumOfEntries.Info.if_inucastpkts += pIfList->Info.if_inucastpkts; SumOfEntries.Info.if_innucastpkts += pIfList->Info.if_innucastpkts; SumOfEntries.Info.if_indiscards += pIfList->Info.if_indiscards; SumOfEntries.Info.if_inerrors += pIfList->Info.if_inerrors; SumOfEntries.Info.if_inunknownprotos += pIfList->Info.if_inunknownprotos; SumOfEntries.Info.if_outoctets += pIfList->Info.if_outoctets; SumOfEntries.Info.if_outucastpkts += pIfList->Info.if_outucastpkts; SumOfEntries.Info.if_outnucastpkts += pIfList->Info.if_outnucastpkts; SumOfEntries.Info.if_outdiscards += pIfList->Info.if_outdiscards; SumOfEntries.Info.if_outerrors += pIfList->Info.if_outerrors; // Get pointer to next entry in list pIfList = CONTAINING_RECORD( pIfList->ListEntry.Flink, IfEntry, ListEntry ); } DisplayInterface( pParams, pResults, &SumOfEntries, ListHead ); // All done with list, free it. FreeTable( (GenericTable *)ListHead ); return S_OK; } //***************************************************************************** // // Name: DisplayTcpConnEntry // // Description: Display information about 1 tcp connection. // // Parameters: TcpConnEntry *pTcp: pointer to a tcp connection structure. // // Returns: void. // // History: // //***************************************************************************** void DisplayTcpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, TcpConnEntry *pTcp ) { char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE]; char RemoteStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE]; DWORD dwErr; int BufLen; int FlagVerbose; if( pTcp->Info.tct_state != TCP_CONN_LISTEN ) FlagVerbose = Nd_Verbose; else FlagVerbose = Nd_ReallyVerbose; //IDS_NETSTAT_14420 "TCP" AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14420); BufLen = sizeof( LocalStr); dwErr = GenerateHostNameServiceString( LocalStr, &BufLen, NumFlag != 0, TRUE, "tcp", pTcp->Info.tct_localaddr, pTcp->Info.tct_localport); ASSERT( dwErr == NO_ERROR); BufLen = sizeof( RemoteStr); dwErr = GenerateHostNameServiceString( RemoteStr, &BufLen, NumFlag != 0, FALSE, "tcp", pTcp->Info.tct_remoteaddr, pTcp->Info.tct_remoteport ); ASSERT( dwErr == NO_ERROR); //IDS_NETSTAT_14421 " %-20s %-40s" AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14421,LocalStr,RemoteStr); switch ( pTcp->Info.tct_state ) { case TCP_CONN_CLOSED: //IDS_NETSTAT_14422 " CLOSED\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14422); break; case TCP_CONN_LISTEN: // Tcpip generates dummy sequential remote ports for // listening connections to avoid getting stuck in snmp. // MohsinA, 12-Feb-97. pTcp->Info.tct_remoteport = 0; //IDS_NETSTAT_14423 " LISTENING\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14423); break; case TCP_CONN_SYN_SENT: //IDS_NETSTAT_14424 " SYN_SENT\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14424); break; case TCP_CONN_SYN_RCVD: //IDS_NETSTAT_14425 " SYN_RECEIVED\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14425); break; case TCP_CONN_ESTAB: //IDS_NETSTAT_14426 " ESTABLISHED\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14426); break; case TCP_CONN_FIN_WAIT1: //IDS_NETSTAT_14427 " FIN_WAIT_1\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14427); break; case TCP_CONN_FIN_WAIT2: //IDS_NETSTAT_14428 " FIN_WAIT_2\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14428); break; case TCP_CONN_CLOSE_WAIT: //IDS_NETSTAT_14429 " CLOSE_WAIT\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14429); break; case TCP_CONN_CLOSING: //IDS_NETSTAT_14430 " CLOSING\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14430); break; case TCP_CONN_LAST_ACK: //IDS_NETSTAT_14431 " LAST_ACK\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14431); break; case TCP_CONN_TIME_WAIT: //IDS_NETSTAT_14432 " TIME_WAIT\n" AddMessageToListId( &pResults->Netstat.lmsgTcpConnectionOutput, FlagVerbose, IDS_NETSTAT_14432); break; default: DEBUG_PRINT(("DisplayTcpConnEntry: State=%d?\n ", pTcp->Info.tct_state )); } } //***************************************************************************** // // Name: DisplayUdpConnEntry // // Description: Display information on 1 udp connection // // Parameters: UdpConnEntry *pUdp: pointer to udp connection structure. // // Returns: void. // // //***************************************************************************** void DisplayUdpConnEntry( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, UdpConnEntry *pUdp ) { char LocalStr[MAX_HOST_NAME_SIZE + MAX_SERVICE_NAME_SIZE]; int BufLen; DWORD dwErr; //IDS_NETSTAT_14433 "UDP" AddMessageToListId( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_ReallyVerbose, IDS_NETSTAT_14433); BufLen = sizeof( LocalStr); dwErr = GenerateHostNameServiceString( LocalStr, &BufLen, NumFlag != 0, TRUE, "udp", pUdp->Info.ue_localaddr, pUdp->Info.ue_localport); ASSERT( dwErr == NO_ERROR); //IDS_NETSTAT_14434 " %-20s %-40s\n" AddMessageToList( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_ReallyVerbose, IDS_NETSTAT_14434,LocalStr, _T("*:*") ); } static DWORD GenerateHostNameServiceString( OUT char * pszBuffer, IN OUT int * lpcbBufLen, IN BOOL fNumFlag, IN BOOL fLocalHost, IN const char * pszProtocol, IN ulong uAddress, IN ulong uPort ) /*++ Description: Generates the : from the address and port information supplied. The result is stored in the pszBuffer passed in. If fLocalHost == TRUE, then the cached local host name is used to improve performance. Arguments: pszBuffer Buffer to store the resulting string. lpcbBufLen pointer to integer containing the count of bytes in Buffer and on return contains the number of bytes written. If the buffer is insufficient, then the required bytes is stored here. fNumFlag generates the output using numbers for host and port number. fLocalHost indicates if we want the service string for local host or remote host. Also for local host, this function generates the local host name without FQDN. pszProtocol specifies the protocol used for the service. uAddress unisgned long address of the service. uPort unsinged long port number. Returns: Win32 error codes. NO_ERROR on success. History: Added this function to avoid FQDNs for local name + abstract the common code used multiple times in old code. Also this function provides local host name caching. --*/ { char LocalBuffer[MAX_HOST_NAME_SIZE]; // to hold dummy output char LocalServiceEntry[MAX_SERVICE_NAME_SIZE]; int BufferLen; char * pszHostName = NULL; // init a pointer. char * pszServiceName = NULL; DWORD dwError = NO_ERROR; struct hostent * pHostEnt; struct servent * pServEnt; uchar * pTmp; // for caching local host name static char s_LocalHostName[MAX_HOST_NAME_SIZE]; static BOOL s_fLocalHostName = FALSE; if ( pszBuffer == NULL) { return ( ERROR_INSUFFICIENT_BUFFER); } *pszBuffer = '\0'; // initialize to null string if ( !fNumFlag) { if ( fLocalHost) { if ( s_fLocalHostName) { pszHostName = s_LocalHostName; // pull from the cache } else { int Result = gethostname( s_LocalHostName, sizeof( s_LocalHostName)); if ( Result == 0) { char * pszFirstDot; // // Cache the copy of local host name now. // Limit the host name to first part of host name. // NO FQDN // s_fLocalHostName = TRUE; pszFirstDot = strchr( s_LocalHostName, '.'); if ( pszFirstDot != NULL) { *pszFirstDot = '\0'; // terminate string } pszHostName = s_LocalHostName; } } // if ( s_fLocalhost) } else { // Remote Host Name. pHostEnt = gethostbyaddr( (uchar *) &uAddress, 4, // IP address is 4 bytes, PF_INET); pszHostName = ( pHostEnt != NULL) ? pHostEnt->h_name: NULL; } pServEnt = getservbyport( htons( ( u_short) uPort), pszProtocol); pszServiceName = ( pServEnt != NULL) ? pServEnt->s_name : NULL; } else { // !fNumFlag pszServiceName = NULL; pszHostName = NULL; } // // Format the data for output. // if ( pszHostName == NULL) { // // Print the IP address itself // uchar * pTmp = ( uchar *) & uAddress; pszHostName = LocalBuffer; sprintf( pszHostName, "%u.%u.%u.%u", pTmp[0], pTmp[1], pTmp[2], pTmp[3]); } // Now pszHostName has the name of the host. if ( pszServiceName == NULL) { pszServiceName = LocalServiceEntry; //IDS_NETSTAT_14436 "%u" sprintf( pszServiceName, "%u", uPort); } // Now pszServiceName has the service name/portnumber BufferLen = strlen( pszHostName) + strlen( pszServiceName) + 2; // 2 bytes extra for ':' and null-character. if ( *lpcbBufLen < BufferLen ) { dwError = ERROR_INSUFFICIENT_BUFFER; } else { sprintf( pszBuffer, "%s:%s", pszHostName, pszServiceName); } *lpcbBufLen = BufferLen; return ( dwError); } // GenerateHostNameServiceString() HRESULT DoConnections( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) //++ // Description: // Displays ethernet statistics // //-- { HRESULT hr = S_OK; TcpConnEntry *pTcpHead; UdpConnEntry *pUdpHead; TcpConnEntry *pTcp; UdpConnEntry *pUdp; ulong Result; //IDS_NETSTAT_14438 "\n\nActive Connections\n" AddMessageToListId( &pResults->Netstat.lmsgConnectionGlobalOutput, Nd_Verbose, IDS_NETSTAT_14438); //IDS_NETSTAT_14439 "\nProto Local Address Foreign Address State\n" AddMessageToListId( &pResults->Netstat.lmsgConnectionGlobalOutput, Nd_Verbose, IDS_NETSTAT_14439); // Get TCP connection table pTcpHead = (TcpConnEntry *)GetTable( TYPE_TCPCONN, &Result ); if ( pTcpHead == NULL ) { //IDS_NETSTAT_14440 "Getting TCP connections failed!\n" AddMessageToList( &pResults->Netstat.lmsgTcpConnectionOutput, Nd_Quiet,IDS_NETSTAT_14440); hr = S_FALSE; } else { // Get pointer to first entry in list pTcp = CONTAINING_RECORD( pTcpHead->ListEntry.Flink, TcpConnEntry, ListEntry ); while (pTcp != pTcpHead) { if ( ( pTcp->Info.tct_state != TCP_CONN_LISTEN ) || (( pTcp->Info.tct_state == TCP_CONN_LISTEN )) ) { // Display the Tcp connection info DisplayTcpConnEntry( pParams, pResults, pTcp ); } // Get the next entry in the table pTcp = CONTAINING_RECORD( pTcp->ListEntry.Flink, TcpConnEntry, ListEntry ); } FreeTable( (GenericTable *)pTcpHead ); } // Get UDP connection table pUdpHead = (UdpConnEntry *)GetTable( TYPE_UDPCONN, &Result ); if ( pUdpHead == NULL ) { //IDS_NETSTAT_14441 "Getting UDP connections failed!\n" AddMessageToList( &pResults->Netstat.lmsgUdpConnectionOutput, Nd_Quiet, IDS_NETSTAT_14441); hr = S_FALSE; } else { // Get pointer to first entry in list pUdp = CONTAINING_RECORD( pUdpHead->ListEntry.Flink, UdpConnEntry, ListEntry ); while (pUdp != pUdpHead) { // Display the Udp connection info DisplayUdpConnEntry( pParams, pResults, pUdp); // Get the next entry in the table pUdp = CONTAINING_RECORD( pUdp->ListEntry.Flink, UdpConnEntry, ListEntry ); } FreeTable( (GenericTable *)pUdpHead ); } return hr; } void DisplayIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IpEntry *pEntry) { //IDS_NETSTAT_14442 "\n\nIP Statistics\n\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14442); //IDS_NETSTAT_14443 "Packets Received = %s\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14443, FormatNumber( pEntry->Info.ipsi_inreceives )); //IDS_NETSTAT_14444 "Received Header Errors = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14444, FormatNumber( pEntry->Info.ipsi_inhdrerrors ) ); //IDS_NETSTAT_14445 "Received Address Errors = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14445, FormatNumber( pEntry->Info.ipsi_inaddrerrors ) ); //IDS_NETSTAT_14446 "Datagrams Forwarded = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14446, FormatNumber( pEntry->Info.ipsi_forwdatagrams ) ); //IDS_NETSTAT_14447 "Unknown Protocols Received = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14447, FormatNumber( pEntry->Info.ipsi_inunknownprotos ) ); //IDS_NETSTAT_14448 "Received Packets Discarded = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14448, FormatNumber( pEntry->Info.ipsi_indiscards ) ); //IDS_NETSTAT_14449 "Received Packets Delivered = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14449, FormatNumber( pEntry->Info.ipsi_indelivers ) ); //IDS_NETSTAT_14450 "Output Requests = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14450, FormatNumber( pEntry->Info.ipsi_outrequests ) ); //IDS_NETSTAT_14451 "Routing Discards = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14451, FormatNumber( pEntry->Info.ipsi_routingdiscards ) ); //IDS_NETSTAT_14452 "Discarded Output Packets = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14452, FormatNumber( pEntry->Info.ipsi_outdiscards ) ); //IDS_NETSTAT_14453 "Output Packet No Route = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14453, FormatNumber( pEntry->Info.ipsi_outnoroutes ) ); //IDS_NETSTAT_14454 "Reassembly Required = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14454, FormatNumber( pEntry->Info.ipsi_reasmreqds ) ); //IDS_NETSTAT_14455 "Reassembly Successful = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14455, FormatNumber( pEntry->Info.ipsi_reasmoks ) ); //IDS_NETSTAT_14456 "Reassembly Failures = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14456, FormatNumber( pEntry->Info.ipsi_reasmfails )); //IDS_NETSTAT_14457 "Datagrams successfully fragmented = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14457, FormatNumber( pEntry->Info.ipsi_fragoks ) ); //IDS_NETSTAT_14458 "Datagrams failing fragmentation = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14458, FormatNumber( pEntry->Info.ipsi_fragfails ) ); //IDS_NETSTAT_14459 "Fragments Created = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14459, FormatNumber( pEntry->Info.ipsi_fragcreates ) ); //IDS_NETSTAT_14460 "Forwarding = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14460, FormatNumber( pEntry->Info.ipsi_forwarding ) ); //IDS_NETSTAT_14461 "Default TTL = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14461, FormatNumber( pEntry->Info.ipsi_defaultttl )); //IDS_NETSTAT_14462 "Reassembly timeout = %u\n" AddMessageToList( &pResults->Netstat.lmsgIpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14462, FormatNumber( pEntry->Info.ipsi_reasmtimeout ) ); } HRESULT DoIP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ) { IpEntry *ListHead; IpEntry *pIpList; ulong Result; // Get the statistics ListHead = (IpEntry *)GetTable( TYPE_IP, &Result ); if ( ListHead == NULL ) { //IDS_NETSTAT_14463 "Getting IP statistics failed.\n" AddMessageToListId( &pResults->Netstat.lmsgIpOutput, Nd_Quiet, IDS_NETSTAT_14463); return S_FALSE; } // Traverse the list of interfaces, summing the different fields pIpList = CONTAINING_RECORD( ListHead->ListEntry.Flink, IpEntry, ListEntry ); DisplayIP( pParams, pResults, pIpList ); // All done with list, free it. FreeTable( (GenericTable *)ListHead ); return S_OK; } HRESULT DoTCP(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) { TcpEntry *ListHead; TcpEntry *pTcpList; ulong Result; // Get the statistics ListHead = (TcpEntry *)GetTable( TYPE_TCP, &Result ); if ( ListHead == NULL ) { //IDS_NETSTAT_14464 "Getting TCP statistics failed.\n" AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_Quiet, IDS_NETSTAT_14464); return S_FALSE; } // Traverse the list, summing the different fields pTcpList = CONTAINING_RECORD( ListHead->ListEntry.Flink, TcpEntry, ListEntry ); DisplayTCP( pParams, pResults, pTcpList ); // All done with list, free it. FreeTable( (GenericTable *)ListHead ); return S_OK; } void DisplayTCP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, TcpEntry *pEntry) { //IDS_NETSTAT_14465 "\n\nTCP Statistics \n\n" AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14465); // FormatNumber( pEntry->Info.ts_activeopens, szNumberBuffer, sizeof(szNumberBuffer)/sizeof(TCHAR), FALSE); //IDS_NETSTAT_14466 "Active Opens = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14466, FormatNumber( pEntry->Info.ts_activeopens ) ); //IDS_NETSTAT_14467 "Passive Opens = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14467, FormatNumber( pEntry->Info.ts_passiveopens ) ); //IDS_NETSTAT_14468 "Failed Connection Attempts = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14468, FormatNumber( pEntry->Info.ts_attemptfails ) ); //IDS_NETSTAT_14469 "Reset Connections = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14469, FormatNumber( pEntry->Info.ts_estabresets ) ); //IDS_NETSTAT_14470 "Current Connections = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14470, FormatNumber( pEntry->Info.ts_currestab ) ); //IDS_NETSTAT_14471 "Received Segments = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14471, FormatNumber( pEntry->Info.ts_insegs ) ); //IDS_NETSTAT_14472 "Segment Sent = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14472, FormatNumber( pEntry->Info.ts_outsegs ) ); //IDS_NETSTAT_14473 "Segment Retransmitted = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14473, FormatNumber( pEntry->Info.ts_retranssegs ) ); //IDS_NETSTAT_14474 "Retransmission Timeout Algorithm = " AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14474); switch ( pEntry->Info.ts_rtoalgorithm ) { case 1: //IDS_NETSTAT_14475 "other\n" AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14475); break; case 2: //IDS_NETSTAT_14476 "constant\n" AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14476); break; case 3: //IDS_NETSTAT_14477 "rsre\n" AddMessageToListId( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14477); break; case 4: //IDS_NETSTAT_14478 "vanj\n " AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14478); break; default: //IDS_NETSTAT_14479 "unknown\n " AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14479, pEntry->Info.ts_rtoalgorithm ); break; } //IDS_NETSTAT_14480 "Minimum Retransmission Timeout = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14480, FormatNumber( pEntry->Info.ts_rtomin ) ); //IDS_NETSTAT_14481 "Maximum Retransmission Timeout = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14481, FormatNumber( pEntry->Info.ts_rtomax ) ); //IDS_NETSTAT_14482 "Maximum Number of Connections = %s\n" AddMessageToList( &pResults->Netstat.lmsgTcpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14482, FormatNumber( pEntry->Info.ts_maxconn ) ); } HRESULT DoUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ) { UdpEntry *ListHead; UdpEntry *pUdpList; ulong Result; // Get the statistics ListHead = (UdpEntry *)GetTable( TYPE_UDP, &Result ); if ( ListHead == NULL ) { //IDS_NETSTAT_14483 "Getting UDP statistics failed.\n" AddMessageToListId( &pResults->Netstat.lmsgUdpOutput, Nd_Quiet, IDS_NETSTAT_14483 ); return S_FALSE; } // Traverse the list of interfaces, summing the different fields pUdpList = CONTAINING_RECORD( ListHead->ListEntry.Flink, UdpEntry, ListEntry ); DisplayUDP( pParams, pResults, pUdpList ); // All done with list, free it. FreeTable( (GenericTable *)ListHead ); return S_OK; } VOID DisplayUDP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, UdpEntry *pEntry) { //IDS_NETSTAT_14484 "\n\nUDP Statistics\n\n" AddMessageToListId( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14484); //IDS_NETSTAT_14485 "Datagrams Received = %s\n" AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14485, FormatNumber( pEntry->Info.us_indatagrams ) ); //IDS_NETSTAT_14486 "No Ports = %s\n" AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14486, FormatNumber(pEntry->Info.us_noports) ); //IDS_NETSTAT_14487 "Receive Errors = %s\n" AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14487, FormatNumber(pEntry->Info.us_inerrors) ); //IDS_NETSTAT_14488 "Datagrams Sent = %s\n" AddMessageToList( &pResults->Netstat.lmsgUdpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14488, FormatNumber(pEntry->Info.us_outdatagrams) ); } HRESULT DoICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults ) { IcmpEntry *ListHead; IcmpEntry *pIcmpList; ulong Result; // Get the statistics ListHead = (IcmpEntry *)GetTable( TYPE_ICMP, &Result ); if ( ListHead == NULL ) { //IDS_NETSTAT_14489 "Getting ICMP statistics failed.\n" AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_Quiet, IDS_NETSTAT_14489); return S_FALSE; } // Traverse the list of interfaces, summing the different fields pIcmpList = CONTAINING_RECORD( ListHead->ListEntry.Flink, IcmpEntry, ListEntry ); DisplayICMP( pParams, pResults, pIcmpList ); // All done with list, free it. FreeTable( (GenericTable *)ListHead ); return S_OK; } void DisplayICMP( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, IcmpEntry *pEntry ) { //IDS_NETSTAT_14490 "\n\nICMP Statistics \n\n" AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14490); //IDS_NETSTAT_14491 "\t\t\t Received Sent\n" AddMessageToListId( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14491); //IDS_NETSTAT_14492 "Messages %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14492, FormatNumber(pEntry->InInfo.icmps_msgs), FormatNumber(pEntry->OutInfo.icmps_msgs) ); //IDS_NETSTAT_14493 "Errors %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14493, FormatNumber(pEntry->InInfo.icmps_errors), FormatNumber(pEntry->OutInfo.icmps_errors) ); //IDS_NETSTAT_14494 "Destination Unreachable %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14494, FormatNumber(pEntry->InInfo.icmps_destunreachs), FormatNumber(pEntry->OutInfo.icmps_destunreachs) ); //IDS_NETSTAT_14495 "Time Exceeded %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14495, FormatNumber(pEntry->InInfo.icmps_timeexcds), FormatNumber(pEntry->OutInfo.icmps_timeexcds) ); //IDS_NETSTAT_14496 "Parameter Problems %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14496, FormatNumber(pEntry->InInfo.icmps_parmprobs), FormatNumber(pEntry->OutInfo.icmps_parmprobs) ); //IDS_NETSTAT_14497 "Source Quenchs %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14497, FormatNumber(pEntry->InInfo.icmps_srcquenchs), FormatNumber(pEntry->OutInfo.icmps_srcquenchs) ); //IDS_NETSTAT_14498 "Redirects %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14498, FormatNumber(pEntry->InInfo.icmps_redirects), FormatNumber(pEntry->OutInfo.icmps_redirects) ); //IDS_NETSTAT_14499 "Echos %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14499, FormatNumber(pEntry->InInfo.icmps_echos), FormatNumber(pEntry->OutInfo.icmps_echos) ); //IDS_NETSTAT_14500 "Echo Replies %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14500, FormatNumber(pEntry->InInfo.icmps_echoreps), FormatNumber(pEntry->OutInfo.icmps_echoreps) ); //IDS_NETSTAT_14501 "Timestamps %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14501, FormatNumber(pEntry->InInfo.icmps_timestamps), FormatNumber(pEntry->OutInfo.icmps_timestamps) ); //IDS_NETSTAT_14502 "Timestamp Replies %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14502, FormatNumber(pEntry->InInfo.icmps_timestampreps), FormatNumber(pEntry->OutInfo.icmps_timestampreps) ); //IDS_NETSTAT_14503 "Address Masks %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14503, FormatNumber(pEntry->InInfo.icmps_addrmasks), FormatNumber(pEntry->OutInfo.icmps_addrmasks) ); //IDS_NETSTAT_14504 "Address Mask Replies %7s %7s\n" AddMessageToList( &pResults->Netstat.lmsgIcmpOutput, Nd_ReallyVerbose, IDS_NETSTAT_14504, FormatNumber(pEntry->InInfo.icmps_addrmaskreps), FormatNumber(pEntry->OutInfo.icmps_addrmaskreps) ); } //---------------------------------------------------------------------------- // Function: FormatNumber // // This function takes an integer and formats a string with the value // represented by the number, grouping digits by powers of one-thousand //---------------------------------------------------------------------------- LPTSTR FormatNumber(DWORD dwNumber) { // assert(cchBuffer > 14); static TCHAR s_szBuffer[MAX_NUM_DIGITS]; BOOL fSigned = TRUE; static TCHAR szNegativeSign[4] = TEXT(""); static TCHAR szThousandsSeparator[4] = TEXT(""); DWORD i, dwLength; TCHAR szDigits[12], pszTemp[20]; TCHAR* pszsrc, *pszdst; // // Retrieve the thousands-separator for the user's locale // if (szThousandsSeparator[0] == TEXT('\0')) { GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandsSeparator, 4 ); } // // If we are formatting a signed value, see if the value is negative // if (fSigned) { if ((INT)dwNumber >= 0) fSigned = FALSE; else { // // The value is negative; retrieve the locale's negative-sign // if (szNegativeSign[0] == TEXT('\0')) { GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SNEGATIVESIGN, szNegativeSign, 4 ); } dwNumber = abs((INT)dwNumber); } } // // Convert the number to a string without thousands-separators // _ltot(dwNumber, szDigits, 10); //padultoa(dwNumber, szDigits, 0); dwLength = lstrlen(szDigits); // // If the length of the string without separators is n, // then the length of the string with separators is n + (n - 1) / 3 // i = dwLength; dwLength += (dwLength - 1) / 3; // // Write the number to the buffer in reverse // pszsrc = szDigits + i - 1; pszdst = pszTemp + dwLength; *pszdst-- = TEXT('\0'); while (TRUE) { if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i--) { *pszdst-- = *pszsrc--; } else { break; } if (i) { *pszdst-- = *szThousandsSeparator; } else { break; } } s_szBuffer[0] = 0; if (fSigned) lstrcat(s_szBuffer, szNegativeSign); lstrcat(s_szBuffer, pszTemp); return s_szBuffer; } void NetstatGlobalPrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults) { if (!pParams->fReallyVerbose) return; if (pParams->fVerbose || !FHrOK(pResults->Netstat.hrTestResult)) { PrintNewLine(pParams, 2); PrintTestTitleResult(pParams, IDS_NETSTAT_LONG, IDS_NETSTAT_SHORT, TRUE, pResults->Netstat.hrTestResult, 0); } PrintMessageList(pParams, &pResults->Netstat.lmsgGlobalOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgInterfaceOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgConnectionGlobalOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgTcpConnectionOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgUdpConnectionOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgIpOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgTcpOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgUdpOutput); PrintMessageList(pParams, &pResults->Netstat.lmsgIcmpOutput); } void NetstatPerInterfacePrint(NETDIAG_PARAMS *pParams, NETDIAG_RESULT *pResults, INTERFACE_RESULT *pInterfaceResults) { if (!pParams->fReallyVerbose) return; } void NetstatCleanup(IN NETDIAG_PARAMS *pParams, IN OUT NETDIAG_RESULT *pResults) { MessageListCleanUp(&pResults->Netstat.lmsgGlobalOutput); MessageListCleanUp(&pResults->Netstat.lmsgInterfaceOutput); MessageListCleanUp(&pResults->Netstat.lmsgConnectionGlobalOutput); MessageListCleanUp(&pResults->Netstat.lmsgTcpConnectionOutput); MessageListCleanUp(&pResults->Netstat.lmsgUdpConnectionOutput); MessageListCleanUp(&pResults->Netstat.lmsgIpOutput); MessageListCleanUp(&pResults->Netstat.lmsgTcpOutput); MessageListCleanUp(&pResults->Netstat.lmsgUdpOutput); MessageListCleanUp(&pResults->Netstat.lmsgIcmpOutput); }