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
32 #define MAX_RESLEN 4000
35 // Possible TCP endpoint states
37 static char TcpState
[][32] = {
53 VOID
PrintError(DWORD ErrorCode
)
57 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
58 NULL
, ErrorCode
, MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
59 (LPTSTR
)&lpMsgBuf
, 0, NULL
);
60 printf("%s\n", (TCHAR
*)lpMsgBuf
);
65 static void ShowTcpStatistics()
67 MIB_TCPSTATS TcpStatsMIB
;
68 GetTcpStatistics(&TcpStatsMIB
);
70 _tprintf(_T("TCP/IP Statistics\t\n"));
71 _tprintf(_T(" time-out algorithm:\t\t%lu\n"), TcpStatsMIB
.dwRtoAlgorithm
);
72 _tprintf(_T(" minimum time-out:\t\t%lu\n"), TcpStatsMIB
.dwRtoMin
);
73 _tprintf(_T(" maximum time-out:\t\t%lu\n"), TcpStatsMIB
.dwRtoMax
);
74 _tprintf(_T(" maximum connections:\t\t%lu\n"), TcpStatsMIB
.dwMaxConn
);
75 _tprintf(_T(" active opens:\t\t\t%lu\n"), TcpStatsMIB
.dwActiveOpens
);
76 _tprintf(_T(" passive opens:\t\t\t%lu\n"), TcpStatsMIB
.dwPassiveOpens
);
77 _tprintf(_T(" failed attempts:\t\t%lu\n"), TcpStatsMIB
.dwAttemptFails
);
78 _tprintf(_T(" established connections reset:\t%lu\n"), TcpStatsMIB
.dwEstabResets
);
79 _tprintf(_T(" established connections:\t%lu\n"), TcpStatsMIB
.dwCurrEstab
);
80 _tprintf(_T(" segments received:\t\t%lu\n"), TcpStatsMIB
.dwInSegs
);
81 _tprintf(_T(" segment sent:\t\t\t%lu\n"), TcpStatsMIB
.dwOutSegs
);
82 _tprintf(_T(" segments retransmitted:\t\t%lu\n"), TcpStatsMIB
.dwRetransSegs
);
83 _tprintf(_T(" incoming errors:\t\t%lu\n"), TcpStatsMIB
.dwInErrs
);
84 _tprintf(_T(" outgoing resets:\t\t%lu\n"), TcpStatsMIB
.dwOutRsts
);
85 _tprintf(_T(" cumulative connections:\t\t%lu\n"), TcpStatsMIB
.dwNumConns
);
88 static void ShowUdpStatistics()
90 MIB_UDPSTATS UDPStatsMIB
;
91 GetUdpStatistics(&UDPStatsMIB
);
93 _tprintf(_T("UDP Statistics\t\n"));
94 _tprintf(_T(" received datagrams:\t\t\t%lu\n"), UDPStatsMIB
.dwInDatagrams
);
95 _tprintf(_T(" datagrams for which no port exists:\t%lu\n"), UDPStatsMIB
.dwNoPorts
);
96 _tprintf(_T(" errors on received datagrams:\t\t%lu\n"), UDPStatsMIB
.dwInErrors
);
97 _tprintf(_T(" sent datagrams:\t\t\t\t%lu\n"), UDPStatsMIB
.dwOutDatagrams
);
98 _tprintf(_T(" number of entries in listener table:\t%lu\n"), UDPStatsMIB
.dwNumAddrs
);
101 static void ShowIpStatistics()
103 MIB_IPSTATS IPStatsMIB
;
104 GetIpStatistics(&IPStatsMIB
);
106 _tprintf(_T("IP Statistics\t\n"));
107 _tprintf(_T(" IP forwarding enabled or disabled:\t%lu\n"), IPStatsMIB
.dwForwarding
);
108 _tprintf(_T(" default time-to-live:\t\t\t%lu\n"), IPStatsMIB
.dwDefaultTTL
);
109 _tprintf(_T(" datagrams received:\t\t\t%lu\n"), IPStatsMIB
.dwInReceives
);
110 _tprintf(_T(" received header errors:\t\t\t%lu\n"), IPStatsMIB
.dwInHdrErrors
);
111 _tprintf(_T(" received address errors:\t\t%lu\n"), IPStatsMIB
.dwInAddrErrors
);
112 _tprintf(_T(" datagrams forwarded:\t\t\t%lu\n"), IPStatsMIB
.dwForwDatagrams
);
113 _tprintf(_T(" datagrams with unknown protocol:\t%lu\n"), IPStatsMIB
.dwInUnknownProtos
);
114 _tprintf(_T(" received datagrams discarded:\t\t%lu\n"), IPStatsMIB
.dwInDiscards
);
115 _tprintf(_T(" received datagrams delivered:\t\t%lu\n"), IPStatsMIB
.dwInDelivers
);
116 _tprintf(_T(" sent datagrams discarded:\t\t%lu\n"), IPStatsMIB
.dwOutDiscards
);
117 _tprintf(_T(" datagrams for which no route exists:\t%lu\n"), IPStatsMIB
.dwOutNoRoutes
);
118 _tprintf(_T(" datagrams for which frags didn't arrive:%lu\n"), IPStatsMIB
.dwReasmTimeout
);
119 _tprintf(_T(" datagrams requiring reassembly:\t\t%lu\n"), IPStatsMIB
.dwReasmReqds
);
120 _tprintf(_T(" successful reassemblies:\t\t%lu\n"), IPStatsMIB
.dwReasmOks
);
121 _tprintf(_T(" failed reassemblies:\t\t\t%lu\n"), IPStatsMIB
.dwReasmFails
);
122 _tprintf(_T(" successful fragmentations:\t\t%lu\n"), IPStatsMIB
.dwFragOks
);
123 _tprintf(_T(" failed fragmentations:\t\t\t%lu\n"), IPStatsMIB
.dwFragFails
);
124 _tprintf(_T(" datagrams fragmented:\t\t\t%lu\n"), IPStatsMIB
.dwFragCreates
);
125 _tprintf(_T(" number of interfaces on computer:\t%lu\n"), IPStatsMIB
.dwNumIf
);
126 _tprintf(_T(" number of IP address on computer:\t%lu\n"), IPStatsMIB
.dwNumAddr
);
127 _tprintf(_T(" number of routes in routing table:\t%lu\n"), IPStatsMIB
.dwNumRoutes
);
130 static void ShowNetworkParams()
132 FIXED_INFO
* FixedInfo
;
133 IP_ADDR_STRING
* pIPAddr
;
137 _tprintf(_T("Network Parameters\t\n"));
139 FixedInfo
= (FIXED_INFO
*)GlobalAlloc(GPTR
, sizeof(FIXED_INFO
));
140 ulOutBufLen
= sizeof(FIXED_INFO
);
141 if (ERROR_BUFFER_OVERFLOW
== GetNetworkParams(FixedInfo
, &ulOutBufLen
)) {
142 GlobalFree(FixedInfo
);
143 FixedInfo
=(FIXED_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
145 if ((dwRetVal
= GetNetworkParams(FixedInfo
, &ulOutBufLen
))) {
146 _tprintf(_T("Call to GetNetworkParams failed. Return Value: 0x%08lx\n"), dwRetVal
);
148 printf(" Host Name: %s", FixedInfo
->HostName
);
149 printf("\n Domain Name: %s", FixedInfo
->DomainName
);
150 printf("\n DNS Servers:\t%s\n", FixedInfo
->DnsServerList
.IpAddress
.String
);
151 pIPAddr
= FixedInfo
->DnsServerList
.Next
;
153 printf("\t\t\t%s\n", pIPAddr
->IpAddress
.String
);
154 pIPAddr
= pIPAddr
->Next
;
159 static void ShowAdapterInfo()
161 IP_ADAPTER_INFO
* pAdaptorInfo
;
165 _tprintf(_T("\nAdaptor Information\t\n"));
166 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, sizeof(IP_ADAPTER_INFO
));
167 ulOutBufLen
= sizeof(IP_ADAPTER_INFO
);
169 if (ERROR_BUFFER_OVERFLOW
== GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
)) {
170 GlobalFree(pAdaptorInfo
);
171 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
173 if ((dwRetVal
= GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
))) {
174 _tprintf(_T("Call to GetAdaptersInfo failed. Return Value: 0x%08lx\n"), dwRetVal
);
176 while (pAdaptorInfo
) {
177 printf(" AdapterName: %s\n", pAdaptorInfo
->AdapterName
);
178 printf(" Description: %s\n", pAdaptorInfo
->Description
);
179 pAdaptorInfo
= pAdaptorInfo
->Next
;
189 } AsnObjectIdentifier;
191 VOID SnmpUtilPrintAsnAny(AsnAny* pAny); // pointer to value to print
192 VOID SnmpUtilPrintOid(AsnObjectIdentifier* Oid); // object identifier to print
200 pCache
= (BYTE
*)SnmpUtilMemAlloc(nBytes
);
201 if (pCache
!= NULL
) {
202 AsnObjectIdentifier
* pOidSrc
= NULL
;
203 AsnObjectIdentifier AsnObId
;
204 if (SnmpUtilOidCpy(&AsnObId
, pOidSrc
)) {
208 SnmpUtilOidFree(&AsnObId
);
210 SnmpUtilMemFree(pCache
);
212 _tprintf(_T("ERROR: call to SnmpUtilMemAlloc() failed\n"));
216 // Maximum string lengths for ASCII ip address and port names
218 #define HOSTNAMELEN 256
219 #define PORTNAMELEN 256
220 #define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN
225 #define FLAG_SHOW_ALL_ENDPOINTS 1
226 #define FLAG_SHOW_ETH_STATS 2
227 #define FLAG_SHOW_NUMBERS 3
228 #define FLAG_SHOW_PROT_CONNECTIONS 4
229 #define FLAG_SHOW_ROUTE_TABLE 5
230 #define FLAG_SHOW_PROT_STATS 6
231 #define FLAG_SHOW_INTERVAL 7
234 // Undocumented extended information structures available only on XP and higher
237 DWORD dwState
; // state of the connection
238 DWORD dwLocalAddr
; // address on local computer
239 DWORD dwLocalPort
; // port number on local computer
240 DWORD dwRemoteAddr
; // address on remote computer
241 DWORD dwRemotePort
; // port number on remote computer
243 } MIB_TCPEXROW
, *PMIB_TCPEXROW
;
247 MIB_TCPEXROW table
[ANY_SIZE
];
248 } MIB_TCPEXTABLE
, *PMIB_TCPEXTABLE
;
251 DWORD dwLocalAddr
; // address on local computer
252 DWORD dwLocalPort
; // port number on local computer
254 } MIB_UDPEXROW
, *PMIB_UDPEXROW
;
258 MIB_UDPEXROW table
[ANY_SIZE
];
259 } MIB_UDPEXTABLE
, *PMIB_UDPEXTABLE
;
265 // Translate port numbers into their text equivalent if there is one
268 GetPortName(DWORD Flags
, UINT port
, PCHAR proto
, PCHAR name
, int namelen
)
270 struct servent
*psrvent
;
272 if (Flags
& FLAG_SHOW_NUMBERS
) {
273 sprintf(name
, "%d", htons((WORD
)port
));
276 // Try to translate to a name
277 if ((psrvent
= getservbyport(port
, proto
))) {
278 strcpy(name
, psrvent
->s_name
);
280 sprintf(name
, "%d", htons((WORD
)port
));
289 // Translate IP addresses into their name-resolved form if possible.
292 GetIpHostName(DWORD Flags
, BOOL local
, UINT ipaddr
, PCHAR name
, int namelen
)
294 // struct hostent *phostent;
297 // Does the user want raw numbers?
298 nipaddr
= htonl(ipaddr
);
299 if (Flags
& FLAG_SHOW_NUMBERS
) {
300 sprintf(name
, "%d.%d.%d.%d",
301 (nipaddr
>> 24) & 0xFF,
302 (nipaddr
>> 16) & 0xFF,
303 (nipaddr
>> 8) & 0xFF,
310 // Try to translate to a name
313 sprintf(name
, "%d.%d.%d.%d",
314 (nipaddr
>> 24) & 0xFF,
315 (nipaddr
>> 16) & 0xFF,
316 (nipaddr
>> 8) & 0xFF,
319 //gethostname(name, namelen);
321 } else if (ipaddr
== 0x0100007f) {
323 //gethostname(name, namelen);
325 strcpy(name
, "localhost");
327 // } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) {
328 // strcpy(name, phostent->h_name);
333 i1
= (nipaddr
>> 24) & 0x000000FF;
334 i2
= (nipaddr
>> 16) & 0x000000FF;
335 i3
= (nipaddr
>> 8) & 0x000000FF;
336 i4
= (nipaddr
) & 0x000000FF;
343 sprintf(name
, "%d.%d.%d.%d", i1
,i2
,i3
,i4
);
345 sprintf(name
, "%d.%d.%d.%d",
346 ((nipaddr
>> 24) & 0x000000FF),
347 ((nipaddr
>> 16) & 0x000000FF),
348 ((nipaddr
>> 8) & 0x000000FF),
349 ((nipaddr
) & 0x000000FF));
357 TCHAR buffer
[MAX_RESLEN
];
359 LoadString(GetModuleHandle(NULL
), IDS_APP_USAGE
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]));
360 _fputts(buffer
, stderr
);
367 // Parses the command line arguments.
370 GetOptions(int argc
, char *argv
[], PDWORD pFlags
)
373 BOOLEAN skipArgument
;
376 for (i
= 1; i
< argc
; i
++) {
377 skipArgument
= FALSE
;
378 switch (argv
[i
][0]) {
383 switch (toupper(argv
[i
][j
])) {
385 *pFlags
|= FLAG_SHOW_ALL_ENDPOINTS
;
388 *pFlags
|= FLAG_SHOW_ETH_STATS
;
391 *pFlags
|= FLAG_SHOW_NUMBERS
;
394 *pFlags
|= FLAG_SHOW_PROT_CONNECTIONS
;
397 *pFlags
|= FLAG_SHOW_ROUTE_TABLE
;
400 *pFlags
|= FLAG_SHOW_PROT_STATS
;
405 if (skipArgument
) break;
410 *pFlags
|= FLAG_SHOW_INTERVAL
;
421 CHAR localname
[HOSTNAMELEN
], remotename
[HOSTNAMELEN
];
422 CHAR remoteport
[PORTNAMELEN
], localport
[PORTNAMELEN
];
423 CHAR localaddr
[ADDRESSLEN
], remoteaddr
[ADDRESSLEN
];
425 int main(int argc
, char *argv
[])
427 PMIB_TCPTABLE tcpTable
;
428 PMIB_UDPTABLE udpTable
;
433 if (!GetOptions(argc
, argv
, &flags
)) {
436 // Get the table of TCP endpoints
438 error
= GetTcpTable(NULL
, &dwSize
, TRUE
);
439 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
440 printf("Failed to snapshot TCP endpoints.\n");
444 tcpTable
= (PMIB_TCPTABLE
)malloc(dwSize
);
445 error
= GetTcpTable(tcpTable
, &dwSize
, TRUE
);
447 printf("Failed to snapshot TCP endpoints table.\n");
452 // Get the table of UDP endpoints
454 error
= GetUdpTable(NULL
, &dwSize
, TRUE
);
455 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
456 printf("Failed to snapshot UDP endpoints.\n");
460 udpTable
= (PMIB_UDPTABLE
)malloc(dwSize
);
461 error
= GetUdpTable(udpTable
, &dwSize
, TRUE
);
463 printf("Failed to snapshot UDP endpoints table.\n");
468 // Dump the TCP table
469 for (i
= 0; i
< tcpTable
->dwNumEntries
; i
++) {
470 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
||
471 tcpTable
->table
[i
].dwState
== MIB_TCP_STATE_ESTAB
) {
472 sprintf(localaddr
, "%s:%s",
473 GetIpHostName(flags
, TRUE
, tcpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
474 GetPortName(flags
, tcpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
475 sprintf(remoteaddr
, "%s:%s",
476 GetIpHostName(flags
, FALSE
, tcpTable
->table
[i
].dwRemoteAddr
, remotename
, HOSTNAMELEN
),
477 tcpTable
->table
[i
].dwRemoteAddr
?
478 GetPortName(flags
, tcpTable
->table
[i
].dwRemotePort
, "tcp", remoteport
, PORTNAMELEN
):
480 printf("%4s\tState: %s\n", "[TCP]", TcpState
[tcpTable
->table
[i
].dwState
]);
481 printf(" Local: %s\n Remote: %s\n", localaddr
, remoteaddr
);
484 // Dump the UDP table
485 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
) {
486 for (i
= 0; i
< udpTable
->dwNumEntries
; i
++) {
487 sprintf(localaddr
, "%s:%s",
488 GetIpHostName(flags
, TRUE
, udpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
489 GetPortName(flags
, udpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
490 printf("%4s", "[UDP]");
491 printf(" Local: %s\n Remote: %s\n", localaddr
, "*.*.*.*:*");
501 int main(int argc
, char *argv
[])
508 _tprintf(_T("\nActive Connections\n\n")\
509 _T(" Proto Local Address Foreign Address State\n\n"));