From: Ged Murphy Date: Fri, 14 Oct 2005 21:35:03 +0000 (+0000) Subject: - Implement -r Calling route.exe for output X-Git-Tag: backups/ros-branch-0_2_9@19949~1389 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=901449fbf784a151913006dd16580192454af1f5 - 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 svn path=/trunk/; revision=18459 --- diff --git a/reactos/apps/utils/net/netstat/netstat.c b/reactos/apps/utils/net/netstat/netstat.c index f7265612dc7..3b8c5e91d5b 100644 --- a/reactos/apps/utils/net/netstat/netstat.c +++ b/reactos/apps/utils/net/netstat/netstat.c @@ -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 #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() diff --git a/reactos/apps/utils/net/netstat/netstat.h b/reactos/apps/utils/net/netstat/netstat.h index 44afceb1bdf..728d154f5cd 100644 --- a/reactos/apps/utils/net/netstat/netstat.h +++ b/reactos/apps/utils/net/netstat/netstat.h @@ -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);