Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennetstat.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS netstat utility 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: apps/utils/net/netstat/netstat.c 00005 * PURPOSE: display IP stack statistics 00006 * COPYRIGHT: Copyright 2005 Ged Murphy <gedmurphy@gmail.com> 00007 */ 00008 /* 00009 * TODO: 00010 * sort function return values. 00011 * implement -b, -o and -v 00012 * clean up GetIpHostName 00013 * command line parser needs more work 00014 */ 00015 00016 #include <windows.h> 00017 #include <winsock2.h> 00018 #include <tchar.h> 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include <iphlpapi.h> 00022 #include "netstat.h" 00023 00024 00025 enum ProtoType {IP, TCP, UDP, ICMP} Protocol; 00026 DWORD Interval; /* time to pause between printing output */ 00027 00028 /* TCP endpoint states */ 00029 TCHAR TcpState[][32] = { 00030 _T("???"), 00031 _T("CLOSED"), 00032 _T("LISTENING"), 00033 _T("SYN_SENT"), 00034 _T("SYN_RCVD"), 00035 _T("ESTABLISHED"), 00036 _T("FIN_WAIT1"), 00037 _T("FIN_WAIT2"), 00038 _T("CLOSE_WAIT"), 00039 _T("CLOSING"), 00040 _T("LAST_ACK"), 00041 _T("TIME_WAIT"), 00042 _T("DELETE_TCB") 00043 }; 00044 00045 00046 /* 00047 * format message string and display output 00048 */ 00049 DWORD DoFormatMessage(DWORD ErrorCode) 00050 { 00051 LPVOID lpMsgBuf; 00052 DWORD RetVal; 00053 00054 if ((RetVal = FormatMessage( 00055 FORMAT_MESSAGE_ALLOCATE_BUFFER | 00056 FORMAT_MESSAGE_FROM_SYSTEM | 00057 FORMAT_MESSAGE_IGNORE_INSERTS, 00058 NULL, 00059 ErrorCode, 00060 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ 00061 (LPTSTR) &lpMsgBuf, 00062 0, 00063 NULL ))) 00064 { 00065 _tprintf(_T("%s"), (LPTSTR)lpMsgBuf); 00066 00067 LocalFree(lpMsgBuf); 00068 /* return number of TCHAR's stored in output buffer 00069 * excluding '\0' - as FormatMessage does*/ 00070 return RetVal; 00071 } 00072 else 00073 return 0; 00074 } 00075 00076 00077 /* 00078 * 00079 * Parse command line parameters and set any options 00080 * 00081 */ 00082 BOOL ParseCmdline(int argc, char* argv[]) 00083 { 00084 INT i; 00085 00086 TCHAR Proto[5]; 00087 00088 if ((argc == 1) || (_istdigit(*argv[1]))) 00089 bNoOptions = TRUE; 00090 00091 /* Parse command line for options we have been given. */ 00092 for (i = 1; i < argc; i++) 00093 { 00094 if ( (argc > 1)&&(argv[i][0] == '-') ) 00095 { 00096 TCHAR c; 00097 00098 while ((c = *++argv[i]) != '\0') 00099 { 00100 switch (tolower(c)) 00101 { 00102 case 'a' : 00103 bDoShowAllCons = TRUE; 00104 break; 00105 case 'b' : 00106 bDoShowProcName = TRUE; 00107 break; 00108 case 'e' : 00109 bDoShowEthStats = TRUE; 00110 break; 00111 case 'n' : 00112 bDoShowNumbers = TRUE; 00113 break; 00114 case 's' : 00115 bDoShowProtoStats = TRUE; 00116 break; 00117 case 'p' : 00118 bDoShowProtoCons = TRUE; 00119 00120 strncpy(Proto, (++argv)[i], sizeof(Proto)); 00121 if (!_tcsicmp( "IP", Proto )) 00122 Protocol = IP; 00123 else if (!_tcsicmp( "ICMP", Proto )) 00124 Protocol = ICMP; 00125 else if (!_tcsicmp( "TCP", Proto )) 00126 Protocol = TCP; 00127 else if (!_tcsicmp( "UDP", Proto )) 00128 Protocol = UDP; 00129 else 00130 { 00131 Usage(); 00132 return EXIT_FAILURE; 00133 } 00134 --i; /* move pointer back down to previous argv */ 00135 break; 00136 case 'r' : 00137 bDoShowRouteTable = TRUE; 00138 break; 00139 case 'v' : 00140 _tprintf(_T("got v\n")); 00141 bDoDispSeqComp = TRUE; 00142 break; 00143 default : 00144 Usage(); 00145 return EXIT_FAILURE; 00146 } 00147 } 00148 } 00149 else if (_istdigit(*argv[i])) 00150 { 00151 if (_stscanf(argv[i], "%lu", &Interval) != EOF) 00152 bLoopOutput = TRUE; 00153 else 00154 return EXIT_FAILURE; 00155 } 00156 // else 00157 // { 00158 // Usage(); 00159 // EXIT_FAILURE; 00160 // } 00161 } 00162 00163 return EXIT_SUCCESS; 00164 } 00165 00166 00167 /* 00168 * Simulate Microsofts netstat utility output 00169 */ 00170 BOOL DisplayOutput() 00171 { 00172 if (bNoOptions) 00173 { 00174 _tprintf(_T("\n Proto Local Address Foreign Address State\n")); 00175 ShowTcpTable(); 00176 return EXIT_SUCCESS; 00177 } 00178 00179 if (bDoShowRouteTable) 00180 { 00181 /* mingw doesn't have lib for _tsystem */ 00182 if (system("route print") == -1) 00183 { 00184 _tprintf(_T("cannot find 'route.exe'\n")); 00185 return EXIT_FAILURE; 00186 } 00187 return EXIT_SUCCESS; 00188 } 00189 00190 if (bDoShowEthStats) 00191 { 00192 ShowEthernetStatistics(); 00193 return EXIT_SUCCESS; 00194 } 00195 00196 if (bDoShowProtoCons) 00197 { 00198 switch (Protocol) 00199 { 00200 case IP : 00201 if (bDoShowProtoStats) 00202 { 00203 ShowIpStatistics(); 00204 return EXIT_SUCCESS; 00205 } 00206 break; 00207 case ICMP : 00208 if (bDoShowProtoStats) 00209 { 00210 ShowIcmpStatistics(); 00211 return EXIT_SUCCESS; 00212 } 00213 break; 00214 case TCP : 00215 if (bDoShowProtoStats) 00216 ShowTcpStatistics(); 00217 _tprintf(_T("\nActive Connections\n")); 00218 _tprintf(_T("\n Proto Local Address Foreign Address State\n")); 00219 ShowTcpTable(); 00220 break; 00221 case UDP : 00222 if (bDoShowProtoStats) 00223 ShowUdpStatistics(); 00224 _tprintf(_T("\nActive Connections\n")); 00225 _tprintf(_T("\n Proto Local Address Foreign Address State\n")); 00226 ShowUdpTable(); 00227 break; 00228 default : 00229 break; 00230 } 00231 } 00232 else if (bDoShowProtoStats) 00233 { 00234 ShowIpStatistics(); 00235 ShowIcmpStatistics(); 00236 ShowTcpStatistics(); 00237 ShowUdpStatistics(); 00238 return EXIT_SUCCESS; 00239 } 00240 else 00241 { 00242 _tprintf(_T("\nActive Connections\n")); 00243 _tprintf(_T("\n Proto Local Address Foreign Address State\n")); 00244 ShowTcpTable(); 00245 if (bDoShowAllCons) 00246 ShowUdpTable(); 00247 } 00248 return EXIT_SUCCESS; 00249 } 00250 00251 00252 00253 00254 VOID ShowIpStatistics() 00255 { 00256 PMIB_IPSTATS pIpStats; 00257 DWORD dwRetVal; 00258 00259 pIpStats = (MIB_IPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IPSTATS)); 00260 00261 if ((dwRetVal = GetIpStatistics(pIpStats)) == NO_ERROR) 00262 { 00263 _tprintf(_T("\nIPv4 Statistics\n\n")); 00264 _tprintf(_T(" %-34s = %lu\n"), _T("Packets Recieved"), pIpStats->dwInReceives); 00265 _tprintf(_T(" %-34s = %lu\n"), _T("Received Header Errors"), pIpStats->dwInHdrErrors); 00266 _tprintf(_T(" %-34s = %lu\n"), _T("Received Address Errors"), pIpStats->dwInAddrErrors); 00267 _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams Forwarded"), pIpStats->dwForwDatagrams); 00268 _tprintf(_T(" %-34s = %lu\n"), _T("Unknown Protocols Recieved"), pIpStats->dwInUnknownProtos); 00269 _tprintf(_T(" %-34s = %lu\n"), _T("Received Packets Discarded"), pIpStats->dwInDiscards); 00270 _tprintf(_T(" %-34s = %lu\n"), _T("Recieved Packets Delivered"), pIpStats->dwInDelivers); 00271 _tprintf(_T(" %-34s = %lu\n"), _T("Output Requests"), pIpStats->dwOutRequests); 00272 _tprintf(_T(" %-34s = %lu\n"), _T("Routing Discards"), pIpStats->dwRoutingDiscards); 00273 _tprintf(_T(" %-34s = %lu\n"), _T("Discarded Output Packets"), pIpStats->dwOutDiscards); 00274 _tprintf(_T(" %-34s = %lu\n"), _T("Output Packets No Route"), pIpStats->dwOutNoRoutes); 00275 _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Required"), pIpStats->dwReasmReqds); 00276 _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Succesful"), pIpStats->dwReasmOks); 00277 _tprintf(_T(" %-34s = %lu\n"), _T("Reassembly Failures"), pIpStats->dwReasmFails); 00278 // _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams succesfully fragmented"), NULL); /* FIXME: what is this one? */ 00279 _tprintf(_T(" %-34s = %lu\n"), _T("Datagrams Failing Fragmentation"), pIpStats->dwFragFails); 00280 _tprintf(_T(" %-34s = %lu\n"), _T("Fragments Created"), pIpStats->dwFragCreates); 00281 } 00282 else 00283 DoFormatMessage(dwRetVal); 00284 00285 HeapFree(GetProcessHeap(), 0, pIpStats); 00286 } 00287 00288 VOID ShowIcmpStatistics() 00289 { 00290 PMIB_ICMP pIcmpStats; 00291 DWORD dwRetVal; 00292 00293 pIcmpStats = (MIB_ICMP*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_ICMP)); 00294 00295 if ((dwRetVal = GetIcmpStatistics(pIcmpStats)) == NO_ERROR) 00296 { 00297 _tprintf(_T("\nICMPv4 Statistics\n\n")); 00298 _tprintf(_T(" Received Sent\n")); 00299 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Messages"), 00300 pIcmpStats->stats.icmpInStats.dwMsgs, pIcmpStats->stats.icmpOutStats.dwMsgs); 00301 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Errors"), 00302 pIcmpStats->stats.icmpInStats.dwErrors, pIcmpStats->stats.icmpOutStats.dwErrors); 00303 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Destination Unreachable"), 00304 pIcmpStats->stats.icmpInStats.dwDestUnreachs, pIcmpStats->stats.icmpOutStats.dwDestUnreachs); 00305 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Time Exceeded"), 00306 pIcmpStats->stats.icmpInStats.dwTimeExcds, pIcmpStats->stats.icmpOutStats.dwTimeExcds); 00307 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Parameter Problems"), 00308 pIcmpStats->stats.icmpInStats.dwParmProbs, pIcmpStats->stats.icmpOutStats.dwParmProbs); 00309 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Source Quenches"), 00310 pIcmpStats->stats.icmpInStats.dwSrcQuenchs, pIcmpStats->stats.icmpOutStats.dwSrcQuenchs); 00311 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Redirects"), 00312 pIcmpStats->stats.icmpInStats.dwRedirects, pIcmpStats->stats.icmpOutStats.dwRedirects); 00313 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Echos"), 00314 pIcmpStats->stats.icmpInStats.dwEchos, pIcmpStats->stats.icmpOutStats.dwEchos); 00315 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Echo Replies"), 00316 pIcmpStats->stats.icmpInStats.dwEchoReps, pIcmpStats->stats.icmpOutStats.dwEchoReps); 00317 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Timestamps"), 00318 pIcmpStats->stats.icmpInStats.dwTimestamps, pIcmpStats->stats.icmpOutStats.dwTimestamps); 00319 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Timestamp Replies"), 00320 pIcmpStats->stats.icmpInStats.dwTimestampReps, pIcmpStats->stats.icmpOutStats.dwTimestampReps); 00321 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Address Masks"), 00322 pIcmpStats->stats.icmpInStats.dwAddrMasks, pIcmpStats->stats.icmpOutStats.dwAddrMasks); 00323 _tprintf(_T(" %-25s %-11lu %lu\n"), _T("Address Mask Replies"), 00324 pIcmpStats->stats.icmpInStats.dwAddrMaskReps, pIcmpStats->stats.icmpOutStats.dwAddrMaskReps); 00325 } 00326 else 00327 DoFormatMessage(dwRetVal); 00328 00329 HeapFree(GetProcessHeap(), 0, pIcmpStats); 00330 00331 } 00332 00333 VOID ShowTcpStatistics() 00334 { 00335 PMIB_TCPSTATS pTcpStats; 00336 DWORD dwRetVal; 00337 00338 pTcpStats = (MIB_TCPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_TCPSTATS)); 00339 00340 if ((dwRetVal = GetTcpStatistics(pTcpStats)) == NO_ERROR) 00341 { 00342 _tprintf(_T("\nTCP Statistics for IPv4\n\n")); 00343 _tprintf(_T(" %-35s = %lu\n"), _T("Active Opens"), pTcpStats->dwActiveOpens); 00344 _tprintf(_T(" %-35s = %lu\n"), _T("Passive Opens"), pTcpStats->dwPassiveOpens); 00345 _tprintf(_T(" %-35s = %lu\n"), _T("Failed Connection Attempts"), pTcpStats->dwAttemptFails); 00346 _tprintf(_T(" %-35s = %lu\n"), _T("Reset Connections"), pTcpStats->dwEstabResets); 00347 _tprintf(_T(" %-35s = %lu\n"), _T("Current Connections"), pTcpStats->dwCurrEstab); 00348 _tprintf(_T(" %-35s = %lu\n"), _T("Segments Recieved"), pTcpStats->dwInSegs); 00349 _tprintf(_T(" %-35s = %lu\n"), _T("Segments Sent"), pTcpStats->dwOutSegs); 00350 _tprintf(_T(" %-35s = %lu\n"), _T("Segments Retransmitted"), pTcpStats->dwRetransSegs); 00351 } 00352 else 00353 DoFormatMessage(dwRetVal); 00354 00355 HeapFree(GetProcessHeap(), 0, pTcpStats); 00356 } 00357 00358 VOID ShowUdpStatistics() 00359 { 00360 PMIB_UDPSTATS pUdpStats; 00361 DWORD dwRetVal; 00362 00363 pUdpStats = (MIB_UDPSTATS*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_UDPSTATS)); 00364 00365 if ((dwRetVal = GetUdpStatistics(pUdpStats)) == NO_ERROR) 00366 { 00367 _tprintf(_T("\nUDP Statistics for IPv4\n\n")); 00368 _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Recieved"), pUdpStats->dwInDatagrams); 00369 _tprintf(_T(" %-21s = %lu\n"), _T("No Ports"), pUdpStats->dwNoPorts); 00370 _tprintf(_T(" %-21s = %lu\n"), _T("Recieve Errors"), pUdpStats->dwInErrors); 00371 _tprintf(_T(" %-21s = %lu\n"), _T("Datagrams Sent"), pUdpStats->dwOutDatagrams); 00372 } 00373 else 00374 DoFormatMessage(dwRetVal); 00375 00376 HeapFree(GetProcessHeap(), 0, pUdpStats); 00377 } 00378 00379 VOID ShowEthernetStatistics() 00380 { 00381 PMIB_IFTABLE pIfTable; 00382 DWORD dwSize = 0; 00383 DWORD dwRetVal = 0; 00384 00385 pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IFTABLE)); 00386 00387 if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) 00388 { 00389 HeapFree(GetProcessHeap(), 0, pIfTable); 00390 pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, dwSize); 00391 00392 if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR) 00393 { 00394 _tprintf(_T("Interface Statistics\n\n")); 00395 _tprintf(_T(" Received Sent\n\n")); 00396 _tprintf(_T("%-20s %14lu %15lu\n"), _T("Bytes"), 00397 pIfTable->table[0].dwInOctets, pIfTable->table[0].dwOutOctets); 00398 _tprintf(_T("%-20s %14lu %15lu\n"), _T("Unicast packets"), 00399 pIfTable->table[0].dwInUcastPkts, pIfTable->table[0].dwOutUcastPkts); 00400 _tprintf(_T("%-20s %14lu %15lu\n"), _T("Non-unicast packets"), 00401 pIfTable->table[0].dwInNUcastPkts, pIfTable->table[0].dwOutNUcastPkts); 00402 _tprintf(_T("%-20s %14lu %15lu\n"), _T("Discards"), 00403 pIfTable->table[0].dwInDiscards, pIfTable->table[0].dwOutDiscards); 00404 _tprintf(_T("%-20s %14lu %15lu\n"), _T("Errors"), 00405 pIfTable->table[0].dwInErrors, pIfTable->table[0].dwOutErrors); 00406 _tprintf(_T("%-20s %14lu\n"), _T("Unknown Protocols"), 00407 pIfTable->table[0].dwInUnknownProtos); 00408 } 00409 else 00410 DoFormatMessage(dwRetVal); 00411 } 00412 HeapFree(GetProcessHeap(), 0, pIfTable); 00413 } 00414 00415 VOID ShowTcpTable() 00416 { 00417 PMIB_TCPTABLE tcpTable; 00418 DWORD error, dwSize; 00419 DWORD i; 00420 CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN]; 00421 CHAR RemoteIp[HOSTNAMELEN], RemotePort[PORTNAMELEN]; 00422 CHAR Host[ADDRESSLEN]; 00423 CHAR Remote[ADDRESSLEN]; 00424 00425 /* Get the table of TCP endpoints */ 00426 dwSize = sizeof (MIB_TCPTABLE); 00427 /* Should also work when we get new connections between 2 GetTcpTable() 00428 * calls: */ 00429 do 00430 { 00431 tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize); 00432 error = GetTcpTable(tcpTable, &dwSize, TRUE); 00433 if ( error != NO_ERROR ) 00434 HeapFree(GetProcessHeap(), 0, tcpTable); 00435 } 00436 while ( error == ERROR_INSUFFICIENT_BUFFER ); 00437 00438 if (error != NO_ERROR) 00439 { 00440 printf("Failed to snapshot TCP endpoints.\n"); 00441 DoFormatMessage(error); 00442 exit(EXIT_FAILURE); 00443 } 00444 00445 /* Dump the TCP table */ 00446 for (i = 0; i < tcpTable->dwNumEntries; i++) 00447 { 00448 /* If we aren't showing all connections, only display established, close wait 00449 * and time wait. This is the default output for netstat */ 00450 if (bDoShowAllCons || (tcpTable->table[i].dwState == MIB_TCP_STATE_ESTAB) 00451 || (tcpTable->table[i].dwState == MIB_TCP_STATE_CLOSE_WAIT) 00452 || (tcpTable->table[i].dwState == MIB_TCP_STATE_TIME_WAIT)) 00453 { 00454 /* I've split this up so it's easier to follow */ 00455 GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN); 00456 GetPortName(tcpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN); 00457 GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr, RemoteIp, HOSTNAMELEN); 00458 GetPortName(tcpTable->table[i].dwRemotePort, "tcp", RemotePort, PORTNAMELEN); 00459 00460 sprintf(Host, "%s:%s", HostIp, HostPort); 00461 sprintf(Remote, "%s:%s", RemoteIp, RemotePort); 00462 00463 _tprintf(_T(" %-6s %-22s %-22s %s\n"), _T("TCP"), 00464 Host, Remote, TcpState[tcpTable->table[i].dwState]); 00465 } 00466 } 00467 HeapFree(GetProcessHeap(), 0, tcpTable); 00468 } 00469 00470 00471 VOID ShowUdpTable() 00472 { 00473 PMIB_UDPTABLE udpTable; 00474 DWORD error, dwSize; 00475 DWORD i; 00476 CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN]; 00477 CHAR Host[ADDRESSLEN]; 00478 00479 /* Get the table of UDP endpoints */ 00480 dwSize = 0; 00481 error = GetUdpTable(NULL, &dwSize, TRUE); 00482 if (error != ERROR_INSUFFICIENT_BUFFER) 00483 { 00484 printf("Failed to snapshot UDP endpoints.\n"); 00485 DoFormatMessage(error); 00486 exit(EXIT_FAILURE); 00487 } 00488 udpTable = (PMIB_UDPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize); 00489 error = GetUdpTable(udpTable, &dwSize, TRUE); 00490 if (error) 00491 { 00492 printf("Failed to snapshot UDP endpoints table.\n"); 00493 DoFormatMessage(error); 00494 HeapFree(GetProcessHeap(), 0, udpTable); 00495 exit(EXIT_FAILURE); 00496 } 00497 00498 /* Dump the UDP table */ 00499 for (i = 0; i < udpTable->dwNumEntries; i++) 00500 { 00501 00502 /* I've split this up so it's easier to follow */ 00503 GetIpHostName(TRUE, udpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN); 00504 GetPortName(udpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN); 00505 00506 sprintf(Host, "%s:%s", HostIp, HostPort); 00507 00508 _tprintf(_T(" %-6s %-22s %-22s\n"), _T("UDP"), Host, _T("*:*")); 00509 } 00510 00511 HeapFree(GetProcessHeap(), 0, udpTable); 00512 } 00513 00514 00515 /* 00516 * Translate port numbers into their text equivalent if there is one 00517 */ 00518 PCHAR 00519 GetPortName(UINT Port, PCSTR Proto, CHAR Name[], INT NameLen) 00520 { 00521 struct servent *pSrvent; 00522 00523 if (bDoShowNumbers) 00524 { 00525 sprintf(Name, "%d", htons((WORD)Port)); 00526 return Name; 00527 } 00528 /* Try to translate to a name */ 00529 if ((pSrvent = getservbyport(Port, Proto))) 00530 strcpy(Name, pSrvent->s_name ); 00531 else 00532 sprintf(Name, "%d", htons((WORD)Port)); 00533 return Name; 00534 } 00535 00536 00537 /* 00538 * convert addresses into dotted decimal or hostname 00539 */ 00540 PCHAR 00541 GetIpHostName(BOOL Local, UINT IpAddr, CHAR Name[], int NameLen) 00542 { 00543 // struct hostent *phostent; 00544 UINT nIpAddr; 00545 00546 /* display dotted decimal */ 00547 nIpAddr = htonl(IpAddr); 00548 if (bDoShowNumbers) { 00549 sprintf(Name, "%d.%d.%d.%d", 00550 (nIpAddr >> 24) & 0xFF, 00551 (nIpAddr >> 16) & 0xFF, 00552 (nIpAddr >> 8) & 0xFF, 00553 (nIpAddr) & 0xFF); 00554 return Name; 00555 } 00556 00557 Name[0] = _T('\0'); 00558 00559 /* try to resolve the name */ 00560 if (!IpAddr) { 00561 if (!Local) { 00562 sprintf(Name, "%d.%d.%d.%d", 00563 (nIpAddr >> 24) & 0xFF, 00564 (nIpAddr >> 16) & 0xFF, 00565 (nIpAddr >> 8) & 0xFF, 00566 (nIpAddr) & 0xFF); 00567 } else { 00568 if (gethostname(Name, NameLen) != 0) 00569 DoFormatMessage(WSAGetLastError()); 00570 } 00571 } else if (IpAddr == 0x0100007f) { 00572 if (Local) { 00573 if (gethostname(Name, NameLen) != 0) 00574 DoFormatMessage(WSAGetLastError()); 00575 } else { 00576 _tcsncpy(Name, _T("localhost"), 10); 00577 } 00578 // } else if (phostent = gethostbyaddr((char*)&ipaddr, sizeof(nipaddr), PF_INET)) { 00579 // strcpy(name, phostent->h_name); 00580 } else { 00581 sprintf(Name, "%d.%d.%d.%d", 00582 ((nIpAddr >> 24) & 0x000000FF), 00583 ((nIpAddr >> 16) & 0x000000FF), 00584 ((nIpAddr >> 8) & 0x000000FF), 00585 ((nIpAddr) & 0x000000FF)); 00586 } 00587 return Name; 00588 } 00589 00590 VOID Usage() 00591 { 00592 _tprintf(_T("\nDisplays current TCP/IP protocol statistics and network connections.\n\n" 00593 "NETSTAT [-a] [-e] [-n] [-s] [-p proto] [-r] [interval]\n\n" 00594 " -a Displays all connections and listening ports.\n" 00595 " -e Displays Ethernet statistics. May be combined with -s\n" 00596 " option\n" 00597 " -n Displays address and port numbers in numeric form.\n" 00598 " -p proto Shows connections for protocol 'proto' TCP or UDP.\n" 00599 " If used with the -s option to display\n" 00600 " per-protocol statistics, 'proto' may be TCP, UDP, or IP.\n" 00601 " -r Displays the current routing table.\n" 00602 " -s Displays per-protocol statistics. By default, Statistics are\n" 00603 " shown for IP, ICMP, TCP and UDP;\n" 00604 " the -p option may be used to specify a subset of the default.\n" 00605 " interval Redisplays selected statistics every 'interval' seconds.\n" 00606 " Press CTRL+C to stop redisplaying. By default netstat will\n" 00607 " print the current information only once.\n")); 00608 } 00609 00610 00611 00612 /* 00613 * 00614 * Parse command line parameters and set any options 00615 * Run display output, looping over set intervals if a number is given 00616 * 00617 */ 00618 int main(int argc, char *argv[]) 00619 { 00620 WSADATA wsaData; 00621 00622 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 00623 { 00624 _tprintf(_T("WSAStartup() failed : %d\n"), WSAGetLastError()); 00625 return -1; 00626 } 00627 00628 if (ParseCmdline(argc, argv)) 00629 return -1; 00630 00631 if (bLoopOutput) 00632 { 00633 while (1) 00634 { 00635 if (DisplayOutput()) 00636 return -1; 00637 Sleep(Interval*1000); 00638 } 00639 } 00640 00641 if (DisplayOutput()) 00642 return -1; 00643 else 00644 return 0; 00645 } Generated on Sun May 27 2012 04:17:15 for ReactOS by
1.7.6.1
|