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
31 #define MAX_RESLEN 4000
34 // Possible TCP endpoint states
36 static char TcpState
[][32] = {
52 VOID
PrintError(DWORD ErrorCode
)
56 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
57 NULL
, ErrorCode
, MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
58 (LPTSTR
)&lpMsgBuf
, 0, NULL
);
59 printf("%s\n", lpMsgBuf
);
63 static void ShowTcpStatistics()
65 MIB_TCPSTATS TcpStatsMIB
;
66 GetTcpStatistics(&TcpStatsMIB
);
68 _tprintf(_T("TCP/IP Statistics\t\n"));
69 _tprintf(_T(" time-out algorithm:\t\t%d\n"), TcpStatsMIB
.dwRtoAlgorithm
);
70 _tprintf(_T(" minimum time-out:\t\t%d\n"), TcpStatsMIB
.dwRtoMin
);
71 _tprintf(_T(" maximum time-out:\t\t%d\n"), TcpStatsMIB
.dwRtoMax
);
72 _tprintf(_T(" maximum connections:\t\t%d\n"), TcpStatsMIB
.dwMaxConn
);
73 _tprintf(_T(" active opens:\t\t\t%d\n"), TcpStatsMIB
.dwActiveOpens
);
74 _tprintf(_T(" passive opens:\t\t\t%d\n"), TcpStatsMIB
.dwPassiveOpens
);
75 _tprintf(_T(" failed attempts:\t\t%d\n"), TcpStatsMIB
.dwAttemptFails
);
76 _tprintf(_T(" established connections reset:\t%d\n"), TcpStatsMIB
.dwEstabResets
);
77 _tprintf(_T(" established connections:\t%d\n"), TcpStatsMIB
.dwCurrEstab
);
78 _tprintf(_T(" segments received:\t\t%d\n"), TcpStatsMIB
.dwInSegs
);
79 _tprintf(_T(" segment sent:\t\t\t%d\n"), TcpStatsMIB
.dwOutSegs
);
80 _tprintf(_T(" segments retransmitted:\t\t%d\n"), TcpStatsMIB
.dwRetransSegs
);
81 _tprintf(_T(" incoming errors:\t\t%d\n"), TcpStatsMIB
.dwInErrs
);
82 _tprintf(_T(" outgoing resets:\t\t%d\n"), TcpStatsMIB
.dwOutRsts
);
83 _tprintf(_T(" cumulative connections:\t\t%d\n"), TcpStatsMIB
.dwNumConns
);
86 static void ShowUdpStatistics()
88 MIB_UDPSTATS UDPStatsMIB
;
89 GetUdpStatistics(&UDPStatsMIB
);
91 _tprintf(_T("UDP Statistics\t\n"));
92 _tprintf(_T(" received datagrams:\t\t\t%d\n"), UDPStatsMIB
.dwInDatagrams
);
93 _tprintf(_T(" datagrams for which no port exists:\t%d\n"), UDPStatsMIB
.dwNoPorts
);
94 _tprintf(_T(" errors on received datagrams:\t\t%d\n"), UDPStatsMIB
.dwInErrors
);
95 _tprintf(_T(" sent datagrams:\t\t\t\t%d\n"), UDPStatsMIB
.dwOutDatagrams
);
96 _tprintf(_T(" number of entries in listener table:\t%d\n"), UDPStatsMIB
.dwNumAddrs
);
99 static void ShowIpStatistics()
101 MIB_IPSTATS IPStatsMIB
;
102 GetIpStatistics(&IPStatsMIB
);
104 _tprintf(_T("IP Statistics\t\n"));
105 _tprintf(_T(" IP forwarding enabled or disabled:\t%d\n"), IPStatsMIB
.dwForwarding
);
106 _tprintf(_T(" default time-to-live:\t\t\t%d\n"), IPStatsMIB
.dwDefaultTTL
);
107 _tprintf(_T(" datagrams received:\t\t\t%d\n"), IPStatsMIB
.dwInReceives
);
108 _tprintf(_T(" received header errors:\t\t\t%d\n"), IPStatsMIB
.dwInHdrErrors
);
109 _tprintf(_T(" received address errors:\t\t%d\n"), IPStatsMIB
.dwInAddrErrors
);
110 _tprintf(_T(" datagrams forwarded:\t\t\t%d\n"), IPStatsMIB
.dwForwDatagrams
);
111 _tprintf(_T(" datagrams with unknown protocol:\t%d\n"), IPStatsMIB
.dwInUnknownProtos
);
112 _tprintf(_T(" received datagrams discarded:\t\t%d\n"), IPStatsMIB
.dwInDiscards
);
113 _tprintf(_T(" received datagrams delivered:\t\t%d\n"), IPStatsMIB
.dwInDelivers
);
114 _tprintf(_T(" sent datagrams discarded:\t\t%d\n"), IPStatsMIB
.dwOutDiscards
);
115 _tprintf(_T(" datagrams for which no route exists:\t%d\n"), IPStatsMIB
.dwOutNoRoutes
);
116 _tprintf(_T(" datagrams for which frags didn't arrive:%d\n"), IPStatsMIB
.dwReasmTimeout
);
117 _tprintf(_T(" datagrams requiring reassembly:\t\t%d\n"), IPStatsMIB
.dwReasmReqds
);
118 _tprintf(_T(" successful reassemblies:\t\t%d\n"), IPStatsMIB
.dwReasmOks
);
119 _tprintf(_T(" failed reassemblies:\t\t\t%d\n"), IPStatsMIB
.dwReasmFails
);
120 _tprintf(_T(" successful fragmentations:\t\t%d\n"), IPStatsMIB
.dwFragOks
);
121 _tprintf(_T(" failed fragmentations:\t\t\t%d\n"), IPStatsMIB
.dwFragFails
);
122 _tprintf(_T(" datagrams fragmented:\t\t\t%d\n"), IPStatsMIB
.dwFragCreates
);
123 _tprintf(_T(" number of interfaces on computer:\t%d\n"), IPStatsMIB
.dwNumIf
);
124 _tprintf(_T(" number of IP address on computer:\t%d\n"), IPStatsMIB
.dwNumAddr
);
125 _tprintf(_T(" number of routes in routing table:\t%d\n"), IPStatsMIB
.dwNumRoutes
);
128 static void ShowNetworkParams()
130 FIXED_INFO
* FixedInfo
;
131 IP_ADDR_STRING
* pIPAddr
;
135 _tprintf(_T("Network Parameters\t\n"));
137 FixedInfo
= (FIXED_INFO
*)GlobalAlloc(GPTR
, sizeof(FIXED_INFO
));
138 ulOutBufLen
= sizeof(FIXED_INFO
);
139 if (ERROR_BUFFER_OVERFLOW
== GetNetworkParams(FixedInfo
, &ulOutBufLen
)) {
140 GlobalFree(FixedInfo
);
141 FixedInfo
=(FIXED_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
143 if (dwRetVal
= GetNetworkParams(FixedInfo
, &ulOutBufLen
)) {
144 _tprintf(_T("Call to GetNetworkParams failed. Return Value: %08x\n"), dwRetVal
);
146 printf(" Host Name: %s", FixedInfo
->HostName
);
147 printf("\n Domain Name: %s", FixedInfo
->DomainName
);
148 printf("\n DNS Servers:\t%s\n", FixedInfo
->DnsServerList
.IpAddress
.String
);
149 pIPAddr
= FixedInfo
->DnsServerList
.Next
;
151 printf("\t\t\t%s\n", pIPAddr
->IpAddress
.String
);
152 pIPAddr
= pIPAddr
->Next
;
157 static void ShowAdapterInfo()
159 IP_ADAPTER_INFO
* pAdaptorInfo
;
163 _tprintf(_T("\nAdaptor Information\t\n"));
164 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, sizeof(IP_ADAPTER_INFO
));
165 ulOutBufLen
= sizeof(IP_ADAPTER_INFO
);
167 if (ERROR_BUFFER_OVERFLOW
== GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
)) {
168 GlobalFree(pAdaptorInfo
);
169 pAdaptorInfo
= (IP_ADAPTER_INFO
*)GlobalAlloc(GPTR
, ulOutBufLen
);
171 if (dwRetVal
= GetAdaptersInfo(pAdaptorInfo
, &ulOutBufLen
)) {
172 _tprintf(_T("Call to GetAdaptersInfo failed. Return Value: %08x\n"), dwRetVal
);
174 while (pAdaptorInfo
) {
175 printf(" AdapterName: %s\n", pAdaptorInfo
->AdapterName
);
176 printf(" Description: %s\n", pAdaptorInfo
->Description
);
177 pAdaptorInfo
= pAdaptorInfo
->Next
;
186 } AsnObjectIdentifier;
188 VOID SnmpUtilPrintAsnAny(AsnAny* pAny); // pointer to value to print
189 VOID SnmpUtilPrintOid(AsnObjectIdentifier* Oid); // object identifier to print
197 pCache
= (BYTE
*)SnmpUtilMemAlloc(nBytes
);
198 if (pCache
!= NULL
) {
199 AsnObjectIdentifier
* pOidSrc
= NULL
;
200 AsnObjectIdentifier AsnObId
;
201 if (SnmpUtilOidCpy(&AsnObId
, pOidSrc
)) {
205 SnmpUtilOidFree(&AsnObId
);
207 SnmpUtilMemFree(pCache
);
209 _tprintf(_T("ERROR: call to SnmpUtilMemAlloc() failed\n"));
213 // Maximum string lengths for ASCII ip address and port names
215 #define HOSTNAMELEN 256
216 #define PORTNAMELEN 256
217 #define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN
222 #define FLAG_SHOW_ALL_ENDPOINTS 1
223 #define FLAG_SHOW_ETH_STATS 2
224 #define FLAG_SHOW_NUMBERS 3
225 #define FLAG_SHOW_PROT_CONNECTIONS 4
226 #define FLAG_SHOW_ROUTE_TABLE 5
227 #define FLAG_SHOW_PROT_STATS 6
228 #define FLAG_SHOW_INTERVAL 7
231 // Undocumented extended information structures available only on XP and higher
234 DWORD dwState
; // state of the connection
235 DWORD dwLocalAddr
; // address on local computer
236 DWORD dwLocalPort
; // port number on local computer
237 DWORD dwRemoteAddr
; // address on remote computer
238 DWORD dwRemotePort
; // port number on remote computer
240 } MIB_TCPEXROW
, *PMIB_TCPEXROW
;
244 MIB_TCPEXROW table
[ANY_SIZE
];
245 } MIB_TCPEXTABLE
, *PMIB_TCPEXTABLE
;
248 DWORD dwLocalAddr
; // address on local computer
249 DWORD dwLocalPort
; // port number on local computer
251 } MIB_UDPEXROW
, *PMIB_UDPEXROW
;
255 MIB_UDPEXROW table
[ANY_SIZE
];
256 } MIB_UDPEXTABLE
, *PMIB_UDPEXTABLE
;
262 // Translate port numbers into their text equivalent if there is one
265 GetPortName(DWORD Flags
, UINT port
, PCHAR proto
, PCHAR name
, int namelen
)
267 struct servent
*psrvent
;
269 if (Flags
& FLAG_SHOW_NUMBERS
) {
270 sprintf(name
, "%d", htons((WORD
)port
));
273 // Try to translate to a name
274 if (psrvent
= getservbyport(port
, proto
)) {
275 strcpy(name
, psrvent
->s_name
);
277 sprintf(name
, "%d", htons((WORD
)port
));
286 // Translate IP addresses into their name-resolved form if possible.
289 GetIpHostName(DWORD Flags
, BOOL local
, UINT ipaddr
, PCHAR name
, int namelen
)
291 // struct hostent *phostent;
294 // Does the user want raw numbers?
295 nipaddr
= htonl(ipaddr
);
296 if (Flags
& FLAG_SHOW_NUMBERS
) {
297 sprintf(name
, "%d.%d.%d.%d",
298 (nipaddr
>> 24) & 0xFF,
299 (nipaddr
>> 16) & 0xFF,
300 (nipaddr
>> 8) & 0xFF,
307 // Try to translate to a name
310 sprintf(name
, "%d.%d.%d.%d",
311 (nipaddr
>> 24) & 0xFF,
312 (nipaddr
>> 16) & 0xFF,
313 (nipaddr
>> 8) & 0xFF,
316 //gethostname(name, namelen);
318 } else if (ipaddr
== 0x0100007f) {
320 //gethostname(name, namelen);
322 strcpy(name
, "localhost");
324 // } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) {
325 // strcpy(name, phostent->h_name);
330 i1
= (nipaddr
>> 24) & 0x000000FF;
331 i2
= (nipaddr
>> 16) & 0x000000FF;
332 i3
= (nipaddr
>> 8) & 0x000000FF;
333 i4
= (nipaddr
) & 0x000000FF;
340 sprintf(name
, "%d.%d.%d.%d", i1
,i2
,i3
,i4
);
342 sprintf(name
, "%d.%d.%d.%d",
343 ((nipaddr
>> 24) & 0x000000FF),
344 ((nipaddr
>> 16) & 0x000000FF),
345 ((nipaddr
>> 8) & 0x000000FF),
346 ((nipaddr
) & 0x000000FF));
354 TCHAR buffer
[MAX_RESLEN
];
356 int length
= LoadString(GetModuleHandle(NULL
), IDS_APP_USAGE
, buffer
, sizeof(buffer
)/sizeof(buffer
[0]));
357 _fputts(buffer
, stderr
);
364 // Parses the command line arguments.
367 GetOptions(int argc
, char *argv
[], PDWORD pFlags
)
370 BOOLEAN skipArgument
;
373 for (i
= 1; i
< argc
; i
++) {
374 skipArgument
= FALSE
;
375 switch (argv
[i
][0]) {
380 switch (toupper(argv
[i
][j
])) {
382 *pFlags
|= FLAG_SHOW_ALL_ENDPOINTS
;
385 *pFlags
|= FLAG_SHOW_ETH_STATS
;
388 *pFlags
|= FLAG_SHOW_NUMBERS
;
391 *pFlags
|= FLAG_SHOW_PROT_CONNECTIONS
;
394 *pFlags
|= FLAG_SHOW_ROUTE_TABLE
;
397 *pFlags
|= FLAG_SHOW_PROT_STATS
;
402 if (skipArgument
) break;
407 *pFlags
|= FLAG_SHOW_INTERVAL
;
418 CHAR localname
[HOSTNAMELEN
], remotename
[HOSTNAMELEN
];
419 CHAR remoteport
[PORTNAMELEN
], localport
[PORTNAMELEN
];
420 CHAR localaddr
[ADDRESSLEN
], remoteaddr
[ADDRESSLEN
];
422 int main(int argc
, char *argv
[])
424 PMIB_TCPTABLE tcpTable
;
425 PMIB_UDPTABLE udpTable
;
430 if (!GetOptions(argc
, argv
, &flags
)) {
433 // Get the table of TCP endpoints
435 error
= GetTcpTable(NULL
, &dwSize
, TRUE
);
436 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
437 printf("Failed to snapshot TCP endpoints.\n");
441 tcpTable
= (PMIB_TCPTABLE
)malloc(dwSize
);
442 error
= GetTcpTable(tcpTable
, &dwSize
, TRUE
);
444 printf("Failed to snapshot TCP endpoints table.\n");
449 // Get the table of UDP endpoints
451 error
= GetUdpTable(NULL
, &dwSize
, TRUE
);
452 if (error
!= ERROR_INSUFFICIENT_BUFFER
) {
453 printf("Failed to snapshot UDP endpoints.\n");
457 udpTable
= (PMIB_UDPTABLE
)malloc(dwSize
);
458 error
= GetUdpTable(udpTable
, &dwSize
, TRUE
);
460 printf("Failed to snapshot UDP endpoints table.\n");
465 // Dump the TCP table
466 for (i
= 0; i
< tcpTable
->dwNumEntries
; i
++) {
467 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
||
468 tcpTable
->table
[i
].dwState
== MIB_TCP_STATE_ESTAB
) {
469 sprintf(localaddr
, "%s:%s",
470 GetIpHostName(flags
, TRUE
, tcpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
471 GetPortName(flags
, tcpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
472 sprintf(remoteaddr
, "%s:%s",
473 GetIpHostName(flags
, FALSE
, tcpTable
->table
[i
].dwRemoteAddr
, remotename
, HOSTNAMELEN
),
474 tcpTable
->table
[i
].dwRemoteAddr
?
475 GetPortName(flags
, tcpTable
->table
[i
].dwRemotePort
, "tcp", remoteport
, PORTNAMELEN
):
477 printf("%4s\tState: %s\n", "[TCP]", TcpState
[tcpTable
->table
[i
].dwState
]);
478 printf(" Local: %s\n Remote: %s\n", localaddr
, remoteaddr
);
481 // Dump the UDP table
482 if (flags
& FLAG_SHOW_ALL_ENDPOINTS
) {
483 for (i
= 0; i
< udpTable
->dwNumEntries
; i
++) {
484 sprintf(localaddr
, "%s:%s",
485 GetIpHostName(flags
, TRUE
, udpTable
->table
[i
].dwLocalAddr
, localname
, HOSTNAMELEN
),
486 GetPortName(flags
, udpTable
->table
[i
].dwLocalPort
, "tcp", localport
, PORTNAMELEN
));
487 printf("%4s", "[UDP]");
488 printf(" Local: %s\n Remote: %s\n", localaddr
, "*.*.*.*:*");
498 int main(int argc
, char *argv
[])
505 _tprintf(_T("\nActive Connections\n\n")\
506 _T(" Proto Local Address Foreign Address State\n\n"));