2 * netstat - display IP stack statistics.
4 * This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
6 * Robert Dickenson <robd@reactos.org>, August 15, 2002.
9 // Extensive reference made and use of source to netstatp by:
10 // Copyright (C) 1998-2002 Mark Russinovich
11 // www.sysinternals.com
36 #define MAX_RESLEN 4000
39 // Possible TCP endpoint states
41 static char TcpState
[][32] = {
57 VOID
PrintError(DWORD ErrorCode
)
61 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
62 NULL
, ErrorCode
, MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
63 (LPTSTR
)&lpMsgBuf
, 0, NULL
);
64 printf("%s\n", lpMsgBuf
);
68 static void ShowTcpStatistics()
70 MIB_TCPSTATS TcpStatsMIB
;
71 GetTcpStatistics(&TcpStatsMIB
);
73 _tprintf(_T("TCP/IP Statistics\t\n"));
74 _tprintf(_T(" time-out algorithm:\t\t%d\n"), TcpStatsMIB
.dwRtoAlgorithm
);
75 _tprintf(_T(" minimum time-out:\t\t%d\n"), TcpStatsMIB
.dwRtoMin
);
76 _tprintf(_T(" maximum time-out:\t\t%d\n"), TcpStatsMIB
.dwRtoMax
);
77 _tprintf(_T(" maximum connections:\t\t%d\n"), TcpStatsMIB
.dwMaxConn
);
78 _tprintf(_T(" active opens:\t\t\t%d\n"), TcpStatsMIB
.dwActiveOpens
);
79 _tprintf(_T(" passive opens:\t\t\t%d\n"), TcpStatsMIB
.dwPassiveOpens
);
80 _tprintf(_T(" failed attempts:\t\t%d\n"), TcpStatsMIB
.dwAttemptFails
);
81 _tprintf(_T(" established connections reset:\t%d\n"), TcpStatsMIB
.dwEstabResets
);
82 _tprintf(_T(" established connections:\t%d\n"), TcpStatsMIB
.dwCurrEstab
);
83 _tprintf(_T(" segments received:\t\t%d\n"), TcpStatsMIB
.dwInSegs
);
84 _tprintf(_T(" segment sent:\t\t\t%d\n"), TcpStatsMIB
.dwOutSegs
);
85 _tprintf(_T(" segments retransmitted:\t\t%d\n"), TcpStatsMIB
.dwRetransSegs
);
86 _tprintf(_T(" incoming errors:\t\t%d\n"), TcpStatsMIB
.dwInErrs
);
87 _tprintf(_T(" outgoing resets:\t\t%d\n"), TcpStatsMIB
.dwOutRsts
);
88 _tprintf(_T(" cumulative connections:\t\t%d\n"), TcpStatsMIB
.dwNumConns
);
91 static void ShowUdpStatistics()
93 MIB_UDPSTATS UDPStatsMIB
;
94 GetUdpStatistics(&UDPStatsMIB
);
96 _tprintf(_T("UDP Statistics\t\n"));
97 _tprintf(_T(" received datagrams:\t\t\t%d\n"), UDPStatsMIB
.dwInDatagrams
);
98 _tprintf(_T(" datagrams for which no port exists:\t%d\n"), UDPStatsMIB
.dwNoPorts
);
99 _tprintf(_T(" errors on received datagrams:\t\t%d\n"), UDPStatsMIB
.dwInErrors
);
100 _tprintf(_T(" sent datagrams:\t\t\t\t%d\n"), UDPStatsMIB
.dwOutDatagrams
);
101 _tprintf(_T(" number of entries in listener table:\t%d\n"), UDPStatsMIB
.dwNumAddrs
);
104 static void ShowIpStatistics()
106 MIB_IPSTATS IPStatsMIB
;
107 GetIpStatistics(&IPStatsMIB
);
109 _tprintf(_T("IP Statistics\t\n"));
110 _tprintf(_T(" IP forwarding enabled or disabled:\t%d\n"), IPStatsMIB
.dwForwarding
);
111 _tprintf(_T(" default time-to-live:\t\t\t%d\n"), IPStatsMIB
.dwDefaultTTL
);
112 _tprintf(_T(" datagrams received:\t\t\t%d\n"), IPStatsMIB
.dwInReceives
);
113 _tprintf(_T(" received header errors:\t\t\t%d\n"), IPStatsMIB
.dwInHdrErrors
);
114 _tprintf(_T(" received address errors:\t\t%d\n"), IPStatsMIB
.dwInAddrErrors
);
115 _tprintf(_T(" datagrams forwarded:\t\t\t%d\n"), IPStatsMIB
.dwForwDatagrams
);
116 _tprintf(_T(" datagrams with unknown protocol:\t%d\n"), IPStatsMIB
.dwInUnknownProtos
);
117 _tprintf(_T(" received datagrams discarded:\t\t%d\n"), IPStatsMIB
.dwInDiscards
);
118 _tprintf(_T(" received datagrams delivered:\t\t%d\n"), IPStatsMIB
.dwInDelivers
);
119 _tprintf(_T(" sent datagrams discarded:\t\t%d\n"), IPStatsMIB
.dwOutDiscards
);
120 _tprintf(_T(" datagrams for which no route exists:\t%d\n"), IPStatsMIB
.dwOutNoRoutes
);
121 _tprintf(_T(" datagrams for which frags didn't arrive:%d\n"), IPStatsMIB
.dwReasmTimeout
);
122 _tprintf(_T(" datagrams requiring reassembly:\t\t%d\n"), IPStatsMIB
.dwReasmReqds
);
123 _tprintf(_T(" successful reassemblies:\t\t%d\n"), IPStatsMIB
.dwReasmOks
);
124 _tprintf(_T(" failed reassemblies:\t\t\t%d\n"), IPStatsMIB
.dwReasmFails
);
125 _tprintf(_T(" successful fragmentations:\t\t%d\n"), IPStatsMIB
.dwFragOks
);
126 _tprintf(_T(" failed fragmentations:\t\t\t%d\n"), IPStatsMIB
.dwFragFails
);
127 _tprintf(_T(" datagrams fragmented:\t\t\t%d\n"), IPStatsMIB
.dwFragCreates
);
128 _tprintf(_T(" number of interfaces on computer:\t%d\n"), IPStatsMIB
.dwNumIf
);
129 _tprintf(_T(" number of IP address on computer:\t%d\n"), IPStatsMIB
.dwNumAddr
);
130 _tprintf(_T(" number of routes in routing table:\t%d\n"), IPStatsMIB
.dwNumRoutes
);
133 static void ShowNetworkParams()
135 FIXED_INFO
* FixedInfo
;
136 IP_ADDR_STRING
* pIPAddr
;
140 _tprintf(_T("Network Parameters\t\n"));
142 FixedInfo
= (FIXED_INFO
*)GlobalAlloc(GPTR
, sizeof(FIXED_INFO
));
143 ulOutBufLen
= sizeof(FIXED_INFO
);
144 if (ERROR_BUFFER_OVERFLOW
== GetNetworkParams(FixedInfo
, &ulOutBufLen
)) {
145 GlobalFree(FixedInfo
);
146 FixedInfo
=(FIXED_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
148 if (dwRetVal
= GetNetworkParams(FixedInfo
, &ulOutBufLen
)) {
149 _tprintf(_T("Call to GetNetworkParams failed. Return Value: %08x\n"), dwRetVal
);
151 printf(" Host Name: %s", FixedInfo
->HostName
);
152 printf("\n Domain Name: %s", FixedInfo
->DomainName
);
153 printf("\n DNS Servers:\t%s\n", FixedInfo
->DnsServerList
.IpAddress
.String
);
154 pIPAddr
= FixedInfo
->DnsServerList
.Next
;
156 printf("\t\t\t%s\n", pIPAddr
->IpAddress
.String
);
157 pIPAddr
= pIPAddr
->Next
;
162 static void ShowAdapterInfo()
164 IP_ADAPTER_INFO
* pAdaptorInfo
;
168 _tprintf(_T("\nAdaptor Information\t\n"));
169 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, sizeof(IP_ADAPTER_INFO
));
170 ulOutBufLen
= sizeof(IP_ADAPTER_INFO
);
172 if (ERROR_BUFFER_OVERFLOW
== GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
)) {
173 GlobalFree(pAdaptorInfo
);
174 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
176 if (dwRetVal
= GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
)) {
177 _tprintf(_T("Call to GetAdaptersInfo failed. Return Value: %08x\n"), dwRetVal
);
179 while (pAdaptorInfo
) {
180 printf(" AdapterName: %s\n", pAdaptorInfo
->AdapterName
);
181 printf(" Description: %s\n", pAdaptorInfo
->Description
);
182 pAdaptorInfo
= pAdaptorInfo
->Next
;
191 } AsnObjectIdentifier;
193 VOID SnmpUtilPrintAsnAny(AsnAny* pAny); // pointer to value to print
194 VOID SnmpUtilPrintOid(AsnObjectIdentifier* Oid); // object identifier to print
202 pCache
= (BYTE
*)SnmpUtilMemAlloc(nBytes
);
203 if (pCache
!= NULL
) {
204 AsnObjectIdentifier
* pOidSrc
= NULL
;
205 AsnObjectIdentifier AsnObId
;
206 if (SnmpUtilOidCpy(&AsnObId
, pOidSrc
)) {
210 SnmpUtilOidFree(&AsnObId
);
212 SnmpUtilMemFree(pCache
);
214 _tprintf(_T("ERROR: call to SnmpUtilMemAlloc() failed\n"));
218 // Maximum string lengths for ASCII ip address and port names
220 #define HOSTNAMELEN 256
221 #define PORTNAMELEN 256
222 #define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN
227 #define FLAG_SHOW_ALL_ENDPOINTS 1
228 #define FLAG_SHOW_ETH_STATS 2
229 #define FLAG_SHOW_NUMBERS 3
230 #define FLAG_SHOW_PROT_CONNECTIONS 4
231 #define FLAG_SHOW_ROUTE_TABLE 5
232 #define FLAG_SHOW_PROT_STATS 6
233 #define FLAG_SHOW_INTERVAL 7
236 // Undocumented extended information structures available only on XP and higher
239 DWORD dwState
; // state of the connection
240 DWORD dwLocalAddr
; // address on local computer
241 DWORD dwLocalPort
; // port number on local computer
242 DWORD dwRemoteAddr
; // address on remote computer
243 DWORD dwRemotePort
; // port number on remote computer
245 } MIB_TCPEXROW
, *PMIB_TCPEXROW
;
249 MIB_TCPEXROW table
[ANY_SIZE
];
250 } MIB_TCPEXTABLE
, *PMIB_TCPEXTABLE
;
253 DWORD dwLocalAddr
; // address on local computer
254 DWORD dwLocalPort
; // port number on local computer
256 } MIB_UDPEXROW
, *PMIB_UDPEXROW
;
260 MIB_UDPEXROW table
[ANY_SIZE
];
261 } MIB_UDPEXTABLE
, *PMIB_UDPEXTABLE
;
267 // Translate port numbers into their text equivalent if there is one
270 GetPortName(DWORD Flags
, UINT port
, PCHAR proto
, PCHAR name
, int namelen
)
272 struct servent
*psrvent
;
274 if (Flags
& FLAG_SHOW_NUMBERS
) {
275 sprintf(name
, "%d", htons((WORD
)port
));
278 // Try to translate to a name
279 if (psrvent
= getservbyport(port
, proto
)) {
280 strcpy(name
, psrvent
->s_name
);
282 sprintf(name
, "%d", htons((WORD
)port
));
291 // Translate IP addresses into their name-resolved form if possible.
294 GetIpHostName(DWORD Flags
, BOOL local
, UINT ipaddr
, PCHAR name
, int namelen
)
296 // struct hostent *phostent;
299 // Does the user want raw numbers?
300 nipaddr
= htonl(ipaddr
);
301 if (Flags
& FLAG_SHOW_NUMBERS
) {
302 sprintf(name
, "%d.%d.%d.%d",
303 (nipaddr
>> 24) & 0xFF,
304 (nipaddr
>> 16) & 0xFF,
305 (nipaddr
>> 8) & 0xFF,
312 // Try to translate to a name
315 sprintf(name
, "%d.%d.%d.%d",
316 (nipaddr
>> 24) & 0xFF,
317 (nipaddr
>> 16) & 0xFF,
318 (nipaddr
>> 8) & 0xFF,
321 //gethostname(name, namelen);
323 } else if (ipaddr
== 0x0100007f) {
325 //gethostname(name, namelen);
327 strcpy(name
, "localhost");
329 // } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) {
330 // strcpy(name, phostent->h_name);
335 i1
= (nipaddr
>> 24) & 0x000000FF;
336 i2
= (nipaddr
>> 16) & 0x000000FF;
337 i3
= (nipaddr
>> 8) & 0x000000FF;
338 i4
= (nipaddr
) & 0x000000FF;
345 sprintf(name
, "%d.%d.%d.%d", i1
,i2
,i3
,i4
);
347 sprintf(name
, "%d.%d.%d.%d",
348 ((nipaddr
>> 24) & 0x000000FF),
349 ((nipaddr
>> 16) & 0x000000FF),
350 ((nipaddr
>> 8) & 0x000000FF),
351 ((nipaddr
) & 0x000000FF));
359 TCHAR buffer
[MAX_RESLEN
];
361 int length
= LoadString(GetModuleHandle(NULL
), IDS_APP_USAGE
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]));
362 _fputts(buffer
, stderr
);
369 // Parses the command line arguments.
372 GetOptions(int argc
, char *argv
[], PDWORD pFlags
)
375 BOOLEAN skipArgument
;
378 for (i
= 1; i
< argc
; i
++) {
379 skipArgument
= FALSE
;
380 switch (argv
[i
][0]) {
385 switch (toupper(argv
[i
][j
])) {
387 *pFlags
|= FLAG_SHOW_ALL_ENDPOINTS
;
390 *pFlags
|= FLAG_SHOW_ETH_STATS
;
393 *pFlags
|= FLAG_SHOW_NUMBERS
;
396 *pFlags
|= FLAG_SHOW_PROT_CONNECTIONS
;
399 *pFlags
|= FLAG_SHOW_ROUTE_TABLE
;
402 *pFlags
|= FLAG_SHOW_PROT_STATS
;
407 if (skipArgument
) break;
412 *pFlags
|= FLAG_SHOW_INTERVAL
;
423 CHAR localname
[HOSTNAMELEN
], remotename
[HOSTNAMELEN
];
424 CHAR remoteport
[PORTNAMELEN
], localport
[PORTNAMELEN
];
425 CHAR localaddr
[ADDRESSLEN
], remoteaddr
[ADDRESSLEN
];
427 int main(int argc
, char *argv
[])
429 PMIB_TCPTABLE tcpTable
;
430 PMIB_UDPTABLE udpTable
;
435 if (!GetOptions(argc
, argv
, &flags
)) {
438 // Get the table of TCP endpoints
440 error
= GetTcpTable(NULL
, &dwSize
, TRUE
);
441 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
442 printf("Failed to snapshot TCP endpoints.\n");
446 tcpTable
= (PMIB_TCPTABLE
)malloc(dwSize
);
447 error
= GetTcpTable(tcpTable
, &dwSize
, TRUE
);
449 printf("Failed to snapshot TCP endpoints table.\n");
454 // Get the table of UDP endpoints
456 error
= GetUdpTable(NULL
, &dwSize
, TRUE
);
457 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
458 printf("Failed to snapshot UDP endpoints.\n");
462 udpTable
= (PMIB_UDPTABLE
)malloc(dwSize
);
463 error
= GetUdpTable(udpTable
, &dwSize
, TRUE
);
465 printf("Failed to snapshot UDP endpoints table.\n");
470 // Dump the TCP table
471 for (i
= 0; i
< tcpTable
->dwNumEntries
; i
++) {
472 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
||
473 tcpTable
->table
[i
].dwState
== MIB_TCP_STATE_ESTAB
) {
474 sprintf(localaddr
, "%s:%s",
475 GetIpHostName(flags
, TRUE
, tcpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
476 GetPortName(flags
, tcpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
477 sprintf(remoteaddr
, "%s:%s",
478 GetIpHostName(flags
, FALSE
, tcpTable
->table
[i
].dwRemoteAddr
, remotename
, HOSTNAMELEN
),
479 tcpTable
->table
[i
].dwRemoteAddr
?
480 GetPortName(flags
, tcpTable
->table
[i
].dwRemotePort
, "tcp", remoteport
, PORTNAMELEN
):
482 printf("%4s\tState: %s\n", "[TCP]", TcpState
[tcpTable
->table
[i
].dwState
]);
483 printf(" Local: %s\n Remote: %s\n", localaddr
, remoteaddr
);
486 // Dump the UDP table
487 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
) {
488 for (i
= 0; i
< udpTable
->dwNumEntries
; i
++) {
489 sprintf(localaddr
, "%s:%s",
490 GetIpHostName(flags
, TRUE
, udpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
491 GetPortName(flags
, udpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
492 printf("%4s", "[UDP]");
493 printf(" Local: %s\n Remote: %s\n", localaddr
, "*.*.*.*:*");
503 int main(int argc
, char *argv
[])
510 _tprintf(_T("\nActive Connections\n\n")\
511 _T(" Proto Local Address Foreign Address State\n\n"));