- Implement -r Calling route.exe for output
authorGed Murphy <gedmurphy@reactos.org>
Fri, 14 Oct 2005 21:35:03 +0000 (21:35 +0000)
committerGed Murphy <gedmurphy@reactos.org>
Fri, 14 Oct 2005 21:35:03 +0000 (21:35 +0000)
- 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

svn path=/trunk/; revision=18459

reactos/apps/utils/net/netstat/netstat.c
reactos/apps/utils/net/netstat/netstat.h

index f726561..3b8c5e9 100644 (file)
 
 /*
  * 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 */
@@ -70,6 +66,37 @@ TCHAR TcpState[][32] = {
 };
 
 
+/*
+ * 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 @@ BOOL ParseCmdline(int argc, char* argv[])
                         (--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 @@ BOOL ParseCmdline(int argc, char* argv[])
     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 @@ BOOL DisplayOutput()
         return EXIT_SUCCESS;
     }
 
-    if (bDoShowEthStats)
-    {
-        ShowEthernetStatistics();
-        return EXIT_SUCCESS;
-    }
-
     if (bDoShowRouteTable)
     {
         if (system("route print") == -1)
@@ -187,150 +207,70 @@ BOOL DisplayOutput()
             _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()
@@ -490,8 +430,12 @@ VOID ShowTcpTable()
     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 @@ VOID ShowTcpTable()
         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 @@ VOID ShowUdpTable()
     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 @@ VOID ShowUdpTable()
         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;
-    }
-    // Try to translate to a name
-    if ((psrvent = getservbyport(port, proto))) {
-        strcpy(name, psrvent->s_name );
-    } else {
-        sprintf(name, "%d", htons((WORD)port));
+    if (bDoShowNumbers)
+    {
+        sprintf(Name, "%d", htons((WORD)Port));
+        return Name;
     }
-    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 @@ GetPortName(UINT port, PCHAR proto, PCHAR name, int namelen)
 // 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()
index 44afceb..728d154 100644 (file)
@@ -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 ShowUdpStatistics(VOID);
 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);