- 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);