- Implement -r Calling route.exe for output
- Rewrote DisplayOutput so simulates the MS netstat tool better and is
now readable
- Fix ShowTcpTable to show correct endpoints on default, and expand it a
little so it's easier to follow
- expand ShowUdpTable in the same manner
- Cleaner formatting in GetPortName
Modified: trunk/reactos/apps/utils/net/netstat/netstat.c
Modified: trunk/reactos/apps/utils/net/netstat/netstat.h
_____
Modified: trunk/reactos/apps/utils/net/netstat/netstat.c
--- trunk/reactos/apps/utils/net/netstat/netstat.c 2005-10-14
20:19:23 UTC (rev 18458)
+++ trunk/reactos/apps/utils/net/netstat/netstat.c 2005-10-14
21:35:03 UTC (rev 18459)
@@ -31,10 +31,9 @@
/*
* TODO:
- * rewrite DisplayOutput
- * sort function return values. BOOL is crap
+ * sort function return values.
* implement -b, -o and -v
- * clean up GetPortName and GetIpHostName
+ * clean up GetIpHostName
* command line parser needs more work
*/
@@ -45,9 +44,6 @@
#include <iphlpapi.h>
#include "netstat.h"
-CHAR localname[HOSTNAMELEN], remotename[HOSTNAMELEN];
-CHAR remoteport[PORTNAMELEN], localport[PORTNAMELEN];
-CHAR localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN];
enum ProtoType {IP, TCP, UDP, ICMP} Protocol;
DWORD Interval; /* time to pause between printing output */
@@ -71,6 +67,37 @@
/*
+ * format message string and display output
+ */
+DWORD 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);
+
+ LocalFree(lpMsgBuf);
+ /* return number of TCHAR's stored in output buffer
+ * excluding '\0' - as FormatMessage does*/
+ return RetVal;
+ }
+ else
+ return 0;
+}
+
+
+/*
*
* Parse command line parameters and set any options
*
@@ -132,7 +159,7 @@
(--argv)[i]; /* move pointer back down to
previous argv */
break;
case 'r' :
- bDoShowRouteTable = FALSE;
+ bDoShowRouteTable = TRUE;
break;
case 'v' :
_tprintf(_T("got v\n"));
@@ -159,12 +186,11 @@
return EXIT_SUCCESS;
}
-/* Simulate Microsofts netstat utility output. It's a bit
- * ugly and over nested, but it is a fairly acurate simulation
- * It was easier for testing, I'll rewrite it later with flags
- * For now, it works*/
+
+/*
+ * Simulate Microsofts netstat utility output
+ */
BOOL DisplayOutput()
-// FIXME: This whole function needs rewriting
{
if (bNoOptions)
{
@@ -173,12 +199,6 @@
return EXIT_SUCCESS;
}
- if (bDoShowEthStats)
- {
- ShowEthernetStatistics();
- return EXIT_SUCCESS;
- }
-
if (bDoShowRouteTable)
{
if (system("route print") == -1)
@@ -187,152 +207,72 @@
_tprintf(_T("cannot find 'route.exe'\n"));
return EXIT_FAILURE;
}
+ return EXIT_SUCCESS;
}
- /* output connections: -a */
- if (bDoShowAllCons)
+ if (bDoShowEthStats)
{
- /* filter out certain protocols: -p */
- if (bDoShowProtoCons)
- {
- /* do we want to list the stats: -s */
- if (bDoShowProtoStats)
- {
- switch (Protocol)
- {
- case IP :
- ShowIpStatistics();
- break;
- case ICMP :
- ShowIcmpStatistics();
- break;
- case TCP :
- ShowTcpStatistics();
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
- ShowTcpTable();
- break;
- case UDP :
- ShowUdpStatistics();
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
- ShowUdpTable();
- break;
- default :
- break;
- }
- return EXIT_SUCCESS;
- }
- else
- {
- switch (Protocol)
- {
- case IP :
- break;
- case ICMP :
- ShowIcmpStatistics();
- break;
- case TCP :
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
- ShowTcpTable();
- break;
- case UDP :
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
- ShowUdpTable();
- break;
- default :
- break;
- }
- return EXIT_SUCCESS;
- }
-
- }
- else
- {
- _tprintf(_T("\nActive Connections\n"));
- _tprintf(_T("\n Proto Local Address Foreign
Address State\n"));
- ShowTcpTable();
- ShowUdpTable();
- return EXIT_SUCCESS;
- }
+ ShowEthernetStatistics();
+ return EXIT_SUCCESS;
}
- /* do we want to list the stats: -s */
- if (bDoShowProtoStats)
+ if (bDoShowProtoCons)
{
- if (bDoShowProtoCons) // -p
+ switch (Protocol)
{
- /* show individual protocols only */
- switch (Protocol)
- {
case IP :
- ShowIpStatistics();
+ if (bDoShowProtoStats)
+ {
+ ShowIpStatistics();
+ return EXIT_SUCCESS;
+ }
break;
case ICMP :
- ShowIcmpStatistics();
+ if (bDoShowProtoStats)
+ {
+ ShowIcmpStatistics();
+ return EXIT_SUCCESS;
+ }
break;
case TCP :
- ShowTcpStatistics();
+ if (bDoShowProtoStats)
+ ShowTcpStatistics();
_tprintf(_T("\nActive Connections\n"));
_tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
ShowTcpTable();
break;
case UDP :
- ShowUdpStatistics();
+ if (bDoShowProtoStats)
+ ShowUdpStatistics();
_tprintf(_T("\nActive Connections\n"));
_tprintf(_T("\n Proto Local Address
Foreign Address State\n"));
ShowUdpTable();
break;
default :
break;
- }
- return EXIT_SUCCESS;
}
- else
- {
- /* list the lot */
- ShowIpStatistics();
- ShowIcmpStatistics();
- ShowTcpStatistics();
- ShowUdpStatistics();
- return EXIT_SUCCESS;
- }
}
+ else if (bDoShowProtoStats)
+ {
+ ShowIpStatistics();
+ ShowIcmpStatistics();
+ ShowTcpStatistics();
+ ShowUdpStatistics();
+ return EXIT_SUCCESS;
+ }
+ else //if (bDoShowAllCons)
+ {
+ _tprintf(_T("\nActive Connections\n"));
+ _tprintf(_T("\n Proto Local Address Foreign Address
State\n"));
+ ShowTcpTable();
+ ShowUdpTable();
+ }
return EXIT_SUCCESS;
}
-/* format message string and display output */
-DWORD 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);
- LocalFree(lpMsgBuf);
- /* return number of TCHAR's stored in output buffer
- * excluding '\0' - as FormatMessage does*/
- return RetVal;
- }
- else
- return 0;
-}
-
-
VOID ShowIpStatistics()
{
PMIB_IPSTATS pIpStats;
@@ -490,8 +430,12 @@
PMIB_TCPTABLE tcpTable;
DWORD error, dwSize;
DWORD i;
+ CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
+ CHAR RemoteIp[HOSTNAMELEN], RemotePort[PORTNAMELEN];
+ CHAR Host[ADDRESSLEN];
+ CHAR Remote[ADDRESSLEN];
- // Get the table of TCP endpoints
+ /* Get the table of TCP endpoints */
dwSize = 0;
error = GetTcpTable(NULL, &dwSize, TRUE);
if (error != ERROR_INSUFFICIENT_BUFFER)
@@ -509,21 +453,26 @@
exit(EXIT_FAILURE);
}
- // Dump the TCP table
+ /* Dump the TCP table */
for (i = 0; i < tcpTable->dwNumEntries; i++)
{
- if (bDoShowAllCons || (tcpTable->table[i].dwState ==
- MIB_TCP_STATE_ESTAB))
+ /* If we aren't showing all connections, only display
established, close wait
+ * and time wait. This is the default output for netstat */
+ if (bDoShowAllCons || (tcpTable->table[i].dwState ==
MIB_TCP_STATE_ESTAB)
+ || (tcpTable->table[i].dwState ==
MIB_TCP_STATE_CLOSE_WAIT)
+ || (tcpTable->table[i].dwState ==
MIB_TCP_STATE_TIME_WAIT))
{
- sprintf(localaddr, "%s:%s",
- GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr,
localname, HOSTNAMELEN),
- GetPortName(tcpTable->table[i].dwLocalPort, "tcp",
localport, PORTNAMELEN));
- sprintf(remoteaddr, "%s:%s",
- GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr,
remotename, HOSTNAMELEN),
- tcpTable->table[i].dwRemoteAddr ?
- GetPortName(tcpTable->table[i].dwRemotePort, "tcp",
remoteport, PORTNAMELEN):
- "0");
- _tprintf(_T(" %-6s %-22s %-22s %s\n"), _T("TCP"),
localaddr, remoteaddr, TcpState[tcpTable->table[i].dwState]);
+ /* 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);
+
+ 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]);
}
}
}
@@ -534,8 +483,10 @@
PMIB_UDPTABLE udpTable;
DWORD error, dwSize;
DWORD i;
+ CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
+ CHAR Host[ADDRESSLEN];
- // Get the table of UDP endpoints
+ /* Get the table of UDP endpoints */
dwSize = 0;
error = GetUdpTable(NULL, &dwSize, TRUE);
if (error != ERROR_INSUFFICIENT_BUFFER)
@@ -553,38 +504,40 @@
exit(EXIT_FAILURE);
}
- // Dump the UDP table
+ /* Dump the UDP table */
for (i = 0; i < udpTable->dwNumEntries; i++)
{
- sprintf(localaddr, "%s:%s",
- GetIpHostName(TRUE, udpTable->table[i].dwLocalAddr,
localname, HOSTNAMELEN),
- GetPortName(udpTable->table[i].dwLocalPort, "tcp",
localport, PORTNAMELEN));
- _tprintf(_T(" %-6s %-22s %-22s\n"), _T("UDP"), localaddr,
_T(":*:"));
+
+ /* 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);
+
+ sprintf(Host, "%s:%s", HostIp, HostPort);
+
+ _tprintf(_T(" %-6s %-22s %-22s\n"), _T("UDP"), Host,
_T(":*:"));
}
}
-//
-// GetPortName
-//
-// Translate port numbers into their text equivalent if there is one
-//
+/*
+ * Translate port numbers into their text equivalent if there is one
+ */
PCHAR
-GetPortName(UINT port, PCHAR proto, PCHAR name, int namelen)
+GetPortName(UINT Port, PCHAR Proto, CHAR Name[], INT NameLen)
{
- struct servent *psrvent;
+ struct servent *pSrvent;
- if (bDoShowNumbers) {
- sprintf(name, "%d", htons((WORD)port));
- return name;
+ if (bDoShowNumbers)
+ {
+ sprintf(Name, "%d", htons((WORD)Port));
+ return Name;
}
- // Try to translate to a name
- if ((psrvent = getservbyport(port, proto))) {
- strcpy(name, psrvent->s_name );
- } else {
- sprintf(name, "%d", htons((WORD)port));
- }
- return name;
+ /* Try to translate to a name */
+ if ((pSrvent = getservbyport(Port, Proto)))
+ strcpy(Name, pSrvent->s_name );
+ else
+ sprintf(Name, "%d", htons((WORD)Port));
+ return Name;
}
@@ -594,51 +547,51 @@
// Translate IP addresses into their name-resolved form if possible.
//
PCHAR
-GetIpHostName(BOOL local, UINT ipaddr, PCHAR name, int namelen)
+GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen)
{
// struct hostent *phostent;
- UINT nipaddr;
+ UINT nIpAddr;
// Does the user want raw numbers?
- nipaddr = htonl(ipaddr);
+ nIpAddr = htonl(IpAddr);
if (bDoShowNumbers) {
- sprintf(name, "%d.%d.%d.%d",
- (nipaddr >> 24) & 0xFF,
- (nipaddr >> 16) & 0xFF,
- (nipaddr >> 8) & 0xFF,
- (nipaddr) & 0xFF);
- return name;
+ sprintf(Name, "%d.%d.%d.%d",
+ (nIpAddr >> 24) & 0xFF,
+ (nIpAddr >> 16) & 0xFF,
+ (nIpAddr >> 8) & 0xFF,
+ (nIpAddr) & 0xFF);
+ return Name;
}
- name[0] = _T('\0');
+ Name[0] = L'\0';
// Try to translate to a name
- if (!ipaddr) {
- if (!local) {
- sprintf(name, "%d.%d.%d.%d",
- (nipaddr >> 24) & 0xFF,
- (nipaddr >> 16) & 0xFF,
- (nipaddr >> 8) & 0xFF,
- (nipaddr) & 0xFF);
+ if (!IpAddr) {
+ if (!Local) {
+ sprintf(Name, "%d.%d.%d.%d",
+ (nIpAddr >> 24) & 0xFF,
+ (nIpAddr >> 16) & 0xFF,
+ (nIpAddr >> 8) & 0xFF,
+ (nIpAddr) & 0xFF);
} else {
//gethostname(name, namelen);
}
- } else if (ipaddr == 0x0100007f) {
- if (local) {
+ } else if (IpAddr == 0x0100007f) {
+ if (Local) {
//gethostname(name, namelen);
} else {
- strcpy(name, "localhost");
+ strcpy(Name, "localhost");
}
// } else if (phostent = gethostbyaddr((char*)&ipaddr,
sizeof(nipaddr), PF_INET)) {
// strcpy(name, phostent->h_name);
} else {
- sprintf(name, "%d.%d.%d.%d",
- ((nipaddr >> 24) & 0x000000FF),
- ((nipaddr >> 16) & 0x000000FF),
- ((nipaddr >> 8) & 0x000000FF),
- ((nipaddr) & 0x000000FF));
+ sprintf(Name, "%d.%d.%d.%d",
+ ((nIpAddr >> 24) & 0x000000FF),
+ ((nIpAddr >> 16) & 0x000000FF),
+ ((nIpAddr >> 8) & 0x000000FF),
+ ((nIpAddr) & 0x000000FF));
}
- return name;
+ return Name;
}
VOID Usage()
_____
Modified: trunk/reactos/apps/utils/net/netstat/netstat.h
--- trunk/reactos/apps/utils/net/netstat/netstat.h 2005-10-14
20:19:23 UTC (rev 18458)
+++ trunk/reactos/apps/utils/net/netstat/netstat.h 2005-10-14
21:35:03 UTC (rev 18459)
@@ -1,6 +1,5 @@
-// Maximum string lengths for ASCII ip address and port names
-//
+/* Maximum string lengths for ASCII ip address and port names */
#define HOSTNAMELEN 256
#define PORTNAMELEN 256
#define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN
@@ -55,7 +54,7 @@
VOID ShowEthernetStatistics(VOID);
VOID ShowTcpTable(VOID);
VOID ShowUdpTable(VOID);
-PCHAR GetPortName(UINT port, PCHAR proto, PCHAR name, int namelen);
-PCHAR GetIpHostName(BOOL local, UINT ipaddr, PCHAR name, int namelen);
+PCHAR GetPortName(UINT Port, PCHAR Proto, CHAR Name[PORTNAMELEN], INT
NameLen);
+PCHAR GetIpHostName(BOOL local, UINT ipaddr, CHAR name[HOSTNAMELEN],
int namelen);
VOID Usage(VOID);