/*
* PROJECT: ReactOS netstat utility
* LICENSE: GPL - See COPYING in the top level directory
- * FILE: apps/utils/net/netstat/netstat.c
+ * FILE: base/applications/network/netstat/netstat.c
* PURPOSE: display IP stack statistics
* COPYRIGHT: Copyright 2005 Ged Murphy <gedmurphy@gmail.com>
*/
* command line parser needs more work
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+
#define WIN32_NO_STATUS
-#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#define _INC_WINDOWS
#include <winsock2.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <iphlpapi.h>
+#include <conutils.h>
+
#include "netstat.h"
+#include "resource.h"
enum ProtoType {IP, TCP, UDP, ICMP} Protocol;
DWORD Interval; /* time to pause between printing output */
/* TCP endpoint states */
-TCHAR TcpState[][32] = {
- _T("???"),
- _T("CLOSED"),
- _T("LISTENING"),
- _T("SYN_SENT"),
- _T("SYN_RCVD"),
- _T("ESTABLISHED"),
- _T("FIN_WAIT1"),
- _T("FIN_WAIT2"),
- _T("CLOSE_WAIT"),
- _T("CLOSING"),
- _T("LAST_ACK"),
- _T("TIME_WAIT"),
- _T("DELETE_TCB")
+PCWSTR TcpState[] = {
+ L"???",
+ L"CLOSED",
+ L"LISTENING",
+ L"SYN_SENT",
+ L"SYN_RCVD",
+ L"ESTABLISHED",
+ L"FIN_WAIT1",
+ L"FIN_WAIT2",
+ L"CLOSE_WAIT",
+ L"CLOSING",
+ L"LAST_ACK",
+ L"TIME_WAIT",
+ L"DELETE_TCB"
};
/*
* format message string and display output
*/
-DWORD DoFormatMessage(DWORD ErrorCode)
+VOID DoFormatMessage(DWORD ErrorCode)
{
- LPVOID lpMsgBuf;
- DWORD RetVal;
-
- if ((RetVal = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- ErrorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL )))
- {
- _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
+ if (ErrorCode == ERROR_SUCCESS)
+ return;
- LocalFree(lpMsgBuf);
- /* return number of TCHAR's stored in output buffer
- * excluding '\0' - as FormatMessage does*/
- return RetVal;
- }
- else
- return 0;
+ ConMsgPuts(StdErr, FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, ErrorCode, LANG_USER_DEFAULT);
}
/*
* Parse command line parameters and set any options
*
*/
-BOOL ParseCmdline(int argc, char* argv[])
+BOOL ParseCmdline(int argc, wchar_t* argv[])
{
+ LPWSTR Proto;
+ WCHAR c;
INT i;
- TCHAR Proto[5];
-
- if ((argc == 1) || (_istdigit(*argv[1])))
+ if ((argc == 1) || (iswdigit(*argv[1])))
bNoOptions = TRUE;
/* Parse command line for options we have been given. */
for (i = 1; i < argc; i++)
{
- if ( (argc > 1)&&(argv[i][0] == '-') )
+ if ((argc > 1) && (argv[i][0] == L'-' || argv[i][0] == L'/'))
{
- TCHAR c;
-
- while ((c = *++argv[i]) != '\0')
+ while ((c = *++argv[i]) != L'\0')
{
- switch (tolower(c))
+ switch (towlower(c))
{
- case 'a' :
+ case L'a':
bDoShowAllCons = TRUE;
break;
- case 'b' :
+ case L'b':
bDoShowProcName = TRUE;
break;
- case 'e' :
+ case L'e':
bDoShowEthStats = TRUE;
break;
- case 'n' :
+ case L'n':
bDoShowNumbers = TRUE;
break;
- case 's' :
- bDoShowProtoStats = TRUE;
- break;
- case 'p' :
+ case L'p':
bDoShowProtoCons = TRUE;
-
- strncpy(Proto, (++argv)[i], sizeof(Proto));
- if (!_tcsicmp( "IP", Proto ))
+ Proto = argv[i+1];
+ if (!_wcsicmp(L"IP", Proto))
Protocol = IP;
- else if (!_tcsicmp( "ICMP", Proto ))
+ else if (!_wcsicmp(L"ICMP", Proto))
Protocol = ICMP;
- else if (!_tcsicmp( "TCP", Proto ))
+ else if (!_wcsicmp(L"TCP", Proto))
Protocol = TCP;
- else if (!_tcsicmp( "UDP", Proto ))
+ else if (!_wcsicmp(L"UDP", Proto))
Protocol = UDP;
else
{
- Usage();
- return EXIT_FAILURE;
+ ConResPuts(StdOut, IDS_USAGE);
+ return FALSE;
}
- --i; /* move pointer back down to previous argv */
break;
- case 'r' :
+ case L'r':
bDoShowRouteTable = TRUE;
break;
- case 'v' :
- _tprintf(_T("got v\n"));
+ case L's':
+ bDoShowProtoStats = TRUE;
+ break;
+ case L'o':
+ bDoShowProcessId = TRUE;
+ break;
+ case L'v':
+ // FIXME!
+ ConPuts(StdOut, L"got v\n");
bDoDispSeqComp = TRUE;
break;
default :
- Usage();
- return EXIT_FAILURE;
+ ConResPuts(StdOut, IDS_USAGE);
+ return FALSE;
}
}
}
- else if (_istdigit(*argv[i]))
+ else if (iswdigit(*argv[i]) != 0)
{
- if (_stscanf(argv[i], "%lu", &Interval) != EOF)
+ if (swscanf(argv[i], L"%lu", &Interval) != EOF)
bLoopOutput = TRUE;
else
- return EXIT_FAILURE;
+ return FALSE;
}
// else
// {
-// Usage();
-// EXIT_FAILURE;
+// ConResPrintf(StdOut, IDS_USAGE);
+// return FALSE;
// }
}
- return EXIT_SUCCESS;
+ return TRUE;
+}
+
+/*
+ * Display table header
+ */
+VOID DisplayTableHeader(VOID)
+{
+ ConResPuts(StdOut, IDS_DISPLAY_THEADER);
+ if (bDoShowProcessId)
+ ConResPuts(StdOut, IDS_DISPLAY_PROCESS);
+ else
+ ConPuts(StdOut, L"\n");
}
/*
* Simulate Microsofts netstat utility output
*/
-BOOL DisplayOutput()
+BOOL DisplayOutput(VOID)
{
if (bNoOptions)
{
- _tprintf(_T("\n Proto Local Address Foreign Address State\n"));
- ShowTcpTable();
- return EXIT_SUCCESS;
+ DisplayTableHeader();
+ return ShowTcpTable();
}
if (bDoShowRouteTable)
{
- /* mingw doesn't have lib for _tsystem */
- if (system("route print") == -1)
+ if (_wsystem(L"route print") == -1)
{
- _tprintf(_T("cannot find 'route.exe'\n"));
- return EXIT_FAILURE;
+ ConResPuts(StdErr, IDS_ERROR_ROUTE);
+ return FALSE;
}
- return EXIT_SUCCESS;
+ return TRUE;
}
if (bDoShowEthStats)
{
ShowEthernetStatistics();
- return EXIT_SUCCESS;
+ return TRUE;
}
if (bDoShowProtoCons)
{
switch (Protocol)
{
- case IP :
- if (bDoShowProtoStats)
- {
- ShowIpStatistics();
- return EXIT_SUCCESS;
- }
- break;
- case ICMP :
- if (bDoShowProtoStats)
- {
- ShowIcmpStatistics();
- return EXIT_SUCCESS;
- }
- break;
- case TCP :
- if (bDoShowProtoStats)
- ShowTcpStatistics();
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address Foreign Address State\n"));
- ShowTcpTable();
- break;
- case UDP :
- if (bDoShowProtoStats)
- ShowUdpStatistics();
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address Foreign Address State\n"));
- ShowUdpTable();
- break;
- default :
- break;
+ case IP:
+ if (bDoShowProtoStats)
+ ShowIpStatistics();
+ return TRUE;
+ case ICMP:
+ if (bDoShowProtoStats)
+ ShowIcmpStatistics();
+ return TRUE;
+ case TCP:
+ if (bDoShowProtoStats)
+ ShowTcpStatistics();
+ ConResPuts(StdOut, IDS_ACTIVE_CONNECT);
+ DisplayTableHeader();
+ return ShowTcpTable();
+ case UDP:
+ if (bDoShowProtoStats)
+ ShowUdpStatistics();
+ ConResPuts(StdOut, IDS_ACTIVE_CONNECT);
+ DisplayTableHeader();
+ return ShowUdpTable();
+ default:
+ break;
}
}
else if (bDoShowProtoStats)
ShowIcmpStatistics();
ShowTcpStatistics();
ShowUdpStatistics();
- return EXIT_SUCCESS;
+ return TRUE;
}
else
{
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address Foreign Address State\n"));
- ShowTcpTable();
- if (bDoShowAllCons)
+ ConResPuts(StdOut, IDS_ACTIVE_CONNECT);
+ DisplayTableHeader();
+ if (ShowTcpTable() && bDoShowAllCons)
ShowUdpTable();
}
- return EXIT_SUCCESS;
+
+ return TRUE;
}
-VOID ShowIpStatistics()
+VOID ShowIpStatistics(VOID)
{
PMIB_IPSTATS pIpStats;
DWORD dwRetVal;
if ((dwRetVal = GetIpStatistics(pIpStats)) == NO_ERROR)
{
- _tprintf(_T("\nIPv4 Statistics\n\n"));
- _tprintf(_T(" %-34s = %lu\n"), _T("Packets Received"), pIpStats->dwInReceives);
- _tprintf(_T(" %-34s = %lu\n"), _T("Received Header Errors"), pIpStats->dwInHdrErrors);
- _tprintf(_T(" %-34s = %lu\n"), _T("Received Address Errors"), pIpStats->dwInAddrErrors);
- _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams Forwarded"), pIpStats->dwForwDatagrams);
- _tprintf(_T(" %-34s = %lu\n"), _T("Unknown Protocols Received"), pIpStats->dwInUnknownProtos);
- _tprintf(_T(" %-34s = %lu\n"), _T("Received Packets Discarded"), pIpStats->dwInDiscards);
- _tprintf(_T(" %-34s = %lu\n"), _T("Received Packets Delivered"), pIpStats->dwInDelivers);
- _tprintf(_T(" %-34s = %lu\n"), _T("Output Requests"), pIpStats->dwOutRequests);
- _tprintf(_T(" %-34s = %lu\n"), _T("Routing Discards"), pIpStats->dwRoutingDiscards);
- _tprintf(_T(" %-34s = %lu\n"), _T("Discarded Output Packets"), pIpStats->dwOutDiscards);
- _tprintf(_T(" %-34s = %lu\n"), _T("Output Packets No Route"), pIpStats->dwOutNoRoutes);
- _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Required"), pIpStats->dwReasmReqds);
- _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Succesful"), pIpStats->dwReasmOks);
- _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Failures"), pIpStats->dwReasmFails);
- // _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams succesfully fragmented"), NULL); /* FIXME: what is this one? */
- _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams Failing Fragmentation"), pIpStats->dwFragFails);
- _tprintf(_T(" %-34s = %lu\n"), _T("Fragments Created"), pIpStats->dwFragCreates);
+ ConResPuts(StdOut, IDS_IP4_STAT_HEADER);
+ ConResPrintf(StdOut, IDS_IP_PACK_REC, pIpStats->dwInReceives);
+ ConResPrintf(StdOut, IDS_IP_HEAD_REC_ERROR, pIpStats->dwInHdrErrors);
+ ConResPrintf(StdOut, IDS_IP_ADDR_REC_ERROR, pIpStats->dwInAddrErrors);
+ ConResPrintf(StdOut, IDS_IP_DATAG_FWD, pIpStats->dwForwDatagrams);
+ ConResPrintf(StdOut, IDS_IP_UNKNOWN_PRO_REC, pIpStats->dwInUnknownProtos);
+ ConResPrintf(StdOut, IDS_IP_REC_PACK_DISCARD, pIpStats->dwInDiscards);
+ ConResPrintf(StdOut, IDS_IP_REC_PACK_DELIVER, pIpStats->dwInDelivers);
+ ConResPrintf(StdOut, IDS_IP_OUT_REQUEST, pIpStats->dwOutRequests);
+ ConResPrintf(StdOut, IDS_IP_ROUTE_DISCARD, pIpStats->dwRoutingDiscards);
+ ConResPrintf(StdOut, IDS_IP_DISCARD_OUT_PACK, pIpStats->dwOutDiscards);
+ ConResPrintf(StdOut, IDS_IP_OUT_PACKET_NO_ROUTE, pIpStats->dwOutNoRoutes);
+ ConResPrintf(StdOut, IDS_IP_REASSEMBLE_REQUIRED, pIpStats->dwReasmReqds);
+ ConResPrintf(StdOut, IDS_IP_REASSEMBLE_SUCCESS, pIpStats->dwReasmOks);
+ ConResPrintf(StdOut, IDS_IP_REASSEMBLE_FAILURE, pIpStats->dwReasmFails);
+ ConResPrintf(StdOut, IDS_IP_DATAG_FRAG_SUCCESS, pIpStats->dwFragOks);
+ ConResPrintf(StdOut, IDS_IP_DATAG_FRAG_FAILURE, pIpStats->dwFragFails);
+ ConResPrintf(StdOut, IDS_IP_DATAG_FRAG_CREATE, pIpStats->dwFragCreates);
}
else
+ {
DoFormatMessage(dwRetVal);
+ }
HeapFree(GetProcessHeap(), 0, pIpStats);
}
-VOID ShowIcmpStatistics()
+VOID ShowIcmpStatistics(VOID)
{
PMIB_ICMP pIcmpStats;
DWORD dwRetVal;
if ((dwRetVal = GetIcmpStatistics(pIcmpStats)) == NO_ERROR)
{
- _tprintf(_T("\nICMPv4 Statistics\n\n"));
- _tprintf(_T(" Received Sent\n"));
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Messages"),
+ ConResPuts(StdOut, IDS_ICMP4_STAT_HEADER);
+ ConResPuts(StdOut, IDS_ICMP_THEADER);
+ ConResPrintf(StdOut, IDS_ICMP_MSG,
pIcmpStats->stats.icmpInStats.dwMsgs, pIcmpStats->stats.icmpOutStats.dwMsgs);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Errors"),
+ ConResPrintf(StdOut, IDS_ICMP_ERROR,
pIcmpStats->stats.icmpInStats.dwErrors, pIcmpStats->stats.icmpOutStats.dwErrors);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Destination Unreachable"),
+ ConResPrintf(StdOut, IDS_ICMP_DEST_UNREACH,
pIcmpStats->stats.icmpInStats.dwDestUnreachs, pIcmpStats->stats.icmpOutStats.dwDestUnreachs);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Time Exceeded"),
+ ConResPrintf(StdOut, IDS_ICMP_TIME_EXCEED,
pIcmpStats->stats.icmpInStats.dwTimeExcds, pIcmpStats->stats.icmpOutStats.dwTimeExcds);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Parameter Problems"),
+ ConResPrintf(StdOut, IDS_ICMP_PARAM_PROBLEM,
pIcmpStats->stats.icmpInStats.dwParmProbs, pIcmpStats->stats.icmpOutStats.dwParmProbs);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Source Quenches"),
+ ConResPrintf(StdOut, IDS_ICMP_SRC_QUENCHES,
pIcmpStats->stats.icmpInStats.dwSrcQuenchs, pIcmpStats->stats.icmpOutStats.dwSrcQuenchs);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Redirects"),
+ ConResPrintf(StdOut, IDS_ICMP_REDIRECT,
pIcmpStats->stats.icmpInStats.dwRedirects, pIcmpStats->stats.icmpOutStats.dwRedirects);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Echos"),
+ ConResPrintf(StdOut, IDS_ICMP_ECHO,
pIcmpStats->stats.icmpInStats.dwEchos, pIcmpStats->stats.icmpOutStats.dwEchos);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Echo Replies"),
+ ConResPrintf(StdOut, IDS_ICMP_ECHO_REPLY,
pIcmpStats->stats.icmpInStats.dwEchoReps, pIcmpStats->stats.icmpOutStats.dwEchoReps);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Timestamps"),
+ ConResPrintf(StdOut, IDS_ICMP_TIMESTAMP,
pIcmpStats->stats.icmpInStats.dwTimestamps, pIcmpStats->stats.icmpOutStats.dwTimestamps);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Timestamp Replies"),
+ ConResPrintf(StdOut, IDS_ICMP_TIMESTAMP_REPLY,
pIcmpStats->stats.icmpInStats.dwTimestampReps, pIcmpStats->stats.icmpOutStats.dwTimestampReps);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Address Masks"),
+ ConResPrintf(StdOut, IDS_ICMP_ADDRESSS_MASK,
pIcmpStats->stats.icmpInStats.dwAddrMasks, pIcmpStats->stats.icmpOutStats.dwAddrMasks);
- _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Address Mask Replies"),
+ ConResPrintf(StdOut, IDS_ICMP_ADDRESSS_MASK_REPLY,
pIcmpStats->stats.icmpInStats.dwAddrMaskReps, pIcmpStats->stats.icmpOutStats.dwAddrMaskReps);
}
else
+ {
DoFormatMessage(dwRetVal);
+ }
HeapFree(GetProcessHeap(), 0, pIcmpStats);
}
-VOID ShowTcpStatistics()
+VOID ShowTcpStatistics(VOID)
{
- PMIB_TCPSTATS pTcpStats;
+ MIB_TCPSTATS tcpStats;
DWORD dwRetVal;
- pTcpStats = (MIB_TCPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_TCPSTATS));
-
- if ((dwRetVal = GetTcpStatistics(pTcpStats)) == NO_ERROR)
+ if ((dwRetVal = GetTcpStatistics(&tcpStats)) == NO_ERROR)
{
- _tprintf(_T("\nTCP Statistics for IPv4\n\n"));
- _tprintf(_T(" %-35s = %lu\n"), _T("Active Opens"), pTcpStats->dwActiveOpens);
- _tprintf(_T(" %-35s = %lu\n"), _T("Passive Opens"), pTcpStats->dwPassiveOpens);
- _tprintf(_T(" %-35s = %lu\n"), _T("Failed Connection Attempts"), pTcpStats->dwAttemptFails);
- _tprintf(_T(" %-35s = %lu\n"), _T("Reset Connections"), pTcpStats->dwEstabResets);
- _tprintf(_T(" %-35s = %lu\n"), _T("Current Connections"), pTcpStats->dwCurrEstab);
- _tprintf(_T(" %-35s = %lu\n"), _T("Segments Received"), pTcpStats->dwInSegs);
- _tprintf(_T(" %-35s = %lu\n"), _T("Segments Sent"), pTcpStats->dwOutSegs);
- _tprintf(_T(" %-35s = %lu\n"), _T("Segments Retransmitted"), pTcpStats->dwRetransSegs);
+ ConResPuts(StdOut, IDS_TCP4_HEADER);
+ ConResPrintf(StdOut, IDS_TCP_ACTIVE_OPEN, tcpStats.dwActiveOpens);
+ ConResPrintf(StdOut, IDS_TCP_PASS_OPEN, tcpStats.dwPassiveOpens);
+ ConResPrintf(StdOut, IDS_TCP_FAIL_CONNECT, tcpStats.dwAttemptFails);
+ ConResPrintf(StdOut, IDS_TCP_RESET_CONNECT, tcpStats.dwEstabResets);
+ ConResPrintf(StdOut, IDS_TCP_CURRENT_CONNECT, tcpStats.dwCurrEstab);
+ ConResPrintf(StdOut, IDS_TCP_SEG_RECEIVE, tcpStats.dwInSegs);
+ ConResPrintf(StdOut, IDS_TCP_SEG_SENT, tcpStats.dwOutSegs);
+ ConResPrintf(StdOut, IDS_TCP_SEG_RETRANSMIT, tcpStats.dwRetransSegs);
}
else
+ {
DoFormatMessage(dwRetVal);
-
- HeapFree(GetProcessHeap(), 0, pTcpStats);
+ }
}
-VOID ShowUdpStatistics()
+VOID ShowUdpStatistics(VOID)
{
- PMIB_UDPSTATS pUdpStats;
+ MIB_UDPSTATS udpStats;
DWORD dwRetVal;
- pUdpStats = (MIB_UDPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_UDPSTATS));
-
- if ((dwRetVal = GetUdpStatistics(pUdpStats)) == NO_ERROR)
+ if ((dwRetVal = GetUdpStatistics(&udpStats)) == NO_ERROR)
{
- _tprintf(_T("\nUDP Statistics for IPv4\n\n"));
- _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Received"), pUdpStats->dwInDatagrams);
- _tprintf(_T(" %-21s = %lu\n"), _T("No Ports"), pUdpStats->dwNoPorts);
- _tprintf(_T(" %-21s = %lu\n"), _T("Receive Errors"), pUdpStats->dwInErrors);
- _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Sent"), pUdpStats->dwOutDatagrams);
+ ConResPuts(StdOut, IDS_UDP_IP4_HEADER);
+ ConResPrintf(StdOut, IDS_UDP_DATAG_RECEIVE, udpStats.dwInDatagrams);
+ ConResPrintf(StdOut, IDS_UDP_NO_PORT, udpStats.dwNoPorts);
+ ConResPrintf(StdOut, IDS_UDP_RECEIVE_ERROR, udpStats.dwInErrors);
+ ConResPrintf(StdOut, IDS_UDP_DATAG_SEND, udpStats.dwOutDatagrams);
}
else
+ {
DoFormatMessage(dwRetVal);
-
- HeapFree(GetProcessHeap(), 0, pUdpStats);
+ }
}
-VOID ShowEthernetStatistics()
+VOID ShowEthernetStatistics(VOID)
{
PMIB_IFTABLE pIfTable;
DWORD dwSize = 0;
if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR)
{
- _tprintf(_T("Interface Statistics\n\n"));
- _tprintf(_T(" Received Sent\n\n"));
- _tprintf(_T("%-20s %14lu %15lu\n"), _T("Bytes"),
+ ConResPuts(StdOut, IDS_ETHERNET_INTERFACE_STAT);
+ ConResPuts(StdOut, IDS_ETHERNET_THEADER);
+ ConResPrintf(StdOut, IDS_ETHERNET_BYTES,
pIfTable->table[0].dwInOctets, pIfTable->table[0].dwOutOctets);
- _tprintf(_T("%-20s %14lu %15lu\n"), _T("Unicast packets"),
+ ConResPrintf(StdOut, IDS_ETHERNET_UNICAST_PACKET,
pIfTable->table[0].dwInUcastPkts, pIfTable->table[0].dwOutUcastPkts);
- _tprintf(_T("%-20s %14lu %15lu\n"), _T("Non-unicast packets"),
+ ConResPrintf(StdOut, IDS_ETHERNET_NON_UNICAST_PACKET,
pIfTable->table[0].dwInNUcastPkts, pIfTable->table[0].dwOutNUcastPkts);
- _tprintf(_T("%-20s %14lu %15lu\n"), _T("Discards"),
+ ConResPrintf(StdOut, IDS_ETHERNET_DISCARD,
pIfTable->table[0].dwInDiscards, pIfTable->table[0].dwOutDiscards);
- _tprintf(_T("%-20s %14lu %15lu\n"), _T("Errors"),
+ ConResPrintf(StdOut, IDS_ETHERNET_ERROR,
pIfTable->table[0].dwInErrors, pIfTable->table[0].dwOutErrors);
- _tprintf(_T("%-20s %14lu\n"), _T("Unknown Protocols"),
+ ConResPrintf(StdOut, IDS_ETHERNET_UNKNOWN,
pIfTable->table[0].dwInUnknownProtos);
}
else
+ {
DoFormatMessage(dwRetVal);
+ }
}
HeapFree(GetProcessHeap(), 0, pIfTable);
}
-VOID ShowTcpTable()
+BOOL ShowTcpTable(VOID)
{
- PMIB_TCPTABLE tcpTable;
+ PMIB_TCPTABLE_OWNER_PID tcpTable;
DWORD error, dwSize;
DWORD i;
CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
CHAR RemoteIp[HOSTNAMELEN], RemotePort[PORTNAMELEN];
CHAR Host[ADDRESSLEN];
CHAR Remote[ADDRESSLEN];
+ CHAR PID[64];
/* Get the table of TCP endpoints */
- dwSize = sizeof (MIB_TCPTABLE);
+ dwSize = sizeof (MIB_TCPTABLE_OWNER_PID);
/* Should also work when we get new connections between 2 GetTcpTable()
* calls: */
do
{
- tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize);
- error = GetTcpTable(tcpTable, &dwSize, TRUE);
+ tcpTable = (PMIB_TCPTABLE_OWNER_PID) HeapAlloc(GetProcessHeap(), 0, dwSize);
+ error = GetExtendedTcpTable(tcpTable, &dwSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
if ( error != NO_ERROR )
HeapFree(GetProcessHeap(), 0, tcpTable);
}
if (error != NO_ERROR)
{
- printf("Failed to snapshot TCP endpoints.\n");
+ ConResPrintf(StdErr, IDS_ERROR_TCP_SNAPSHOT);
DoFormatMessage(error);
- exit(EXIT_FAILURE);
+ HeapFree(GetProcessHeap(), 0, tcpTable);
+ return FALSE;
}
/* Dump the TCP table */
|| (tcpTable->table[i].dwState == MIB_TCP_STATE_TIME_WAIT))
{
/* I've split this up so it's easier to follow */
- GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN);
- GetPortName(tcpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN);
- GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr, RemoteIp, HOSTNAMELEN);
- GetPortName(tcpTable->table[i].dwRemotePort, "tcp", RemotePort, PORTNAMELEN);
-
+ GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr, HostIp, sizeof(HostIp));
+ GetPortName(tcpTable->table[i].dwLocalPort, "tcp", HostPort, sizeof(HostPort));
sprintf(Host, "%s:%s", HostIp, HostPort);
- sprintf(Remote, "%s:%s", RemoteIp, RemotePort);
- _tprintf(_T(" %-6s %-22s %-22s %s\n"), _T("TCP"),
- Host, Remote, TcpState[tcpTable->table[i].dwState]);
+ if (tcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
+ {
+ sprintf(Remote, "%s:0", HostIp);
+ }
+ else
+ {
+ GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr, RemoteIp, sizeof(RemoteIp));
+ GetPortName(tcpTable->table[i].dwRemotePort, "tcp", RemotePort, sizeof(RemotePort));
+ sprintf(Remote, "%s:%s", RemoteIp, RemotePort);
+ }
+
+ if (bDoShowProcessId)
+ {
+ sprintf(PID, "%ld", tcpTable->table[i].dwOwningPid);
+ }
+ else
+ {
+ PID[0] = 0;
+ }
+
+ ConPrintf(StdOut, L" %-6s %-22S %-22S %-11s %S\n", L"TCP",
+ Host, Remote, TcpState[tcpTable->table[i].dwState], PID);
}
}
+
HeapFree(GetProcessHeap(), 0, tcpTable);
+ return TRUE;
}
-VOID ShowUdpTable()
+BOOL ShowUdpTable(VOID)
{
- PMIB_UDPTABLE udpTable;
+ PMIB_UDPTABLE_OWNER_PID udpTable;
DWORD error, dwSize;
DWORD i;
CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
CHAR Host[ADDRESSLEN];
+ CHAR PID[64];
/* Get the table of UDP endpoints */
dwSize = 0;
- error = GetUdpTable(NULL, &dwSize, TRUE);
+ error = GetExtendedUdpTable(NULL, &dwSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
if (error != ERROR_INSUFFICIENT_BUFFER)
{
- printf("Failed to snapshot UDP endpoints.\n");
+ ConResPuts(StdErr, IDS_ERROR_UDP_ENDPOINT);
DoFormatMessage(error);
- exit(EXIT_FAILURE);
+ return FALSE;
}
- udpTable = (PMIB_UDPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize);
- error = GetUdpTable(udpTable, &dwSize, TRUE);
+ udpTable = (PMIB_UDPTABLE_OWNER_PID) HeapAlloc(GetProcessHeap(), 0, dwSize);
+ error = GetExtendedUdpTable(udpTable, &dwSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
if (error)
{
- printf("Failed to snapshot UDP endpoints table.\n");
+ ConResPuts(StdErr, IDS_ERROR_UDP_ENDPOINT_TABLE);
DoFormatMessage(error);
HeapFree(GetProcessHeap(), 0, udpTable);
- exit(EXIT_FAILURE);
+ return FALSE;
}
/* Dump the UDP table */
{
/* I've split this up so it's easier to follow */
- GetIpHostName(TRUE, udpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN);
- GetPortName(udpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN);
+ GetIpHostName(TRUE, udpTable->table[i].dwLocalAddr, HostIp, sizeof(HostIp));
+ GetPortName(udpTable->table[i].dwLocalPort, "tcp", HostPort, sizeof(HostPort));
sprintf(Host, "%s:%s", HostIp, HostPort);
- _tprintf(_T(" %-6s %-22s %-22s\n"), _T("UDP"), Host, _T("*:*"));
+ if (bDoShowProcessId)
+ {
+ sprintf(PID, "%ld", udpTable->table[i].dwOwningPid);
+ }
+ else
+ {
+ PID[0] = 0;
+ }
+
+ ConPrintf(StdOut, L" %-6s %-22S %-34s %S\n", L"UDP", Host, L"*:*", PID);
}
HeapFree(GetProcessHeap(), 0, udpTable);
+ return TRUE;
}
/*
PCHAR
GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen)
{
- struct servent *pSrvent;
+ struct servent *pServent;
if (bDoShowNumbers)
{
return Name;
}
/* Try to translate to a name */
- if ((pSrvent = getservbyport(Port, Proto)))
- strcpy(Name, pSrvent->s_name );
+ if ((pServent = getservbyport(Port, Proto)))
+ strcpy(Name, pServent->s_name );
else
sprintf(Name, "%d", htons((WORD)Port));
return Name;
* convert addresses into dotted decimal or hostname
*/
PCHAR
-GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen)
+GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], INT NameLen)
{
// struct hostent *phostent;
UINT nIpAddr;
return Name;
}
- Name[0] = _T('\0');
+ Name[0] = '\0';
/* try to resolve the name */
if (!IpAddr) {
if (gethostname(Name, NameLen) != 0)
DoFormatMessage(WSAGetLastError());
} else {
- _tcsncpy(Name, _T("localhost"), 10);
+ strncpy(Name, "localhost", 10);
}
// } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) {
// strcpy(name, phostent->h_name);
return Name;
}
-VOID Usage()
-{
- _tprintf(_T("\nDisplays current TCP/IP protocol statistics and network connections.\n\n"
- "NETSTAT [-a] [-e] [-n] [-s] [-p proto] [-r] [interval]\n\n"
- " -a Displays all connections and listening ports.\n"
- " -e Displays Ethernet statistics. May be combined with -s\n"
- " option\n"
- " -n Displays address and port numbers in numeric form.\n"
- " -p proto Shows connections for protocol 'proto' TCP or UDP.\n"
- " If used with the -s option to display\n"
- " per-protocol statistics, 'proto' may be TCP, UDP, or IP.\n"
- " -r Displays the current routing table.\n"
- " -s Displays per-protocol statistics. By default, Statistics are\n"
- " shown for IP, ICMP, TCP and UDP;\n"
- " the -p option may be used to specify a subset of the default.\n"
- " interval Redisplays selected statistics every 'interval' seconds.\n"
- " Press CTRL+C to stop redisplaying. By default netstat will\n"
- " print the current information only once.\n"));
-}
-
/*
*
* Parse command line parameters and set any options
* Run display output, looping over set intervals if a number is given
*
*/
-int main(int argc, char *argv[])
+int wmain(int argc, wchar_t *argv[])
{
+ BOOL Success;
WSADATA wsaData;
+ /* Initialize the Console Standard Streams */
+ ConInitStdStreams();
+
+ if (!ParseCmdline(argc, argv))
+ return EXIT_FAILURE;
+
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
- _tprintf(_T("WSAStartup() failed : %d\n"), WSAGetLastError());
- return -1;
+ ConResPrintf(StdErr, IDS_ERROR_WSA_START, WSAGetLastError());
+ return EXIT_FAILURE;
}
- if (ParseCmdline(argc, argv))
- return -1;
-
- if (bLoopOutput)
+ Success = DisplayOutput();
+ while (bLoopOutput && Success)
{
- while (1)
- {
- if (DisplayOutput())
- return -1;
- Sleep(Interval*1000);
- }
+ Sleep(Interval*1000);
+ Success = DisplayOutput();
}
- if (DisplayOutput())
- return -1;
- else
- return 0;
+ WSACleanup();
+ return (Success ? EXIT_SUCCESS : EXIT_FAILURE);
}