X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=base%2Fapplications%2Fnetwork%2Fnetstat%2Fnetstat.c;h=97a843b143dc3f5d35e0d113771da4ba0da50118;hp=20818c425350104268605553280fde2a07aad8c1;hb=af0d1d2f98749ed382ab7e718b91a9f11fd8a073;hpb=eae27787e5ab44c69661672bc501ce6bba6ec4e5 diff --git a/base/applications/network/netstat/netstat.c b/base/applications/network/netstat/netstat.c index 20818c42535..97a843b143d 100644 --- a/base/applications/network/netstat/netstat.c +++ b/base/applications/network/netstat/netstat.c @@ -1,7 +1,7 @@ /* * 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 */ @@ -13,67 +13,52 @@ * command line parser needs more work */ +#include +#include +#include + #define WIN32_NO_STATUS -#include #include #include #define _INC_WINDOWS #include -#include -#include -#include #include +#include + #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); } /* @@ -81,153 +66,155 @@ DWORD DoFormatMessage(DWORD ErrorCode) * 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 (bDoShowAllCons ? ShowUdpTable() : TRUE); + default: + break; } } else if (bDoShowProtoStats) @@ -236,20 +223,20 @@ BOOL DisplayOutput() 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; @@ -258,32 +245,34 @@ VOID ShowIpStatistics() 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; @@ -292,89 +281,87 @@ VOID ShowIcmpStatistics() 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; @@ -389,45 +376,48 @@ VOID ShowEthernetStatistics() 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); } @@ -435,9 +425,10 @@ VOID ShowTcpTable() 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 */ @@ -450,46 +441,65 @@ VOID ShowTcpTable() || (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 */ @@ -497,15 +507,25 @@ VOID ShowUdpTable() { /* 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, "udp", 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; } /* @@ -514,7 +534,7 @@ VOID ShowUdpTable() PCHAR GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen) { - struct servent *pSrvent; + struct servent *pServent; if (bDoShowNumbers) { @@ -522,8 +542,8 @@ GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen) 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; @@ -533,7 +553,7 @@ GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen) * 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; @@ -549,7 +569,7 @@ GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen) return Name; } - Name[0] = _T('\0'); + Name[0] = '\0'; /* try to resolve the name */ if (!IpAddr) { @@ -568,7 +588,7 @@ GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen) 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); @@ -582,57 +602,36 @@ GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen) 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); }