⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netstatp.c

📁 netstat源代码
💻 C
字号:
//------------------------------------------------------------
//
// Netstatp
//
// Copyright (C) 1998-2002 Mark Russinovich
// Sysinternals
// www.sysinternals.com
//
// This program implements a subset of the Netstat program's
// functionality. Specifically, it enumerates and displays
// information about all UDP and TCP endpoints.
//
//------------------------------------------------------------
#include "windows.h"
#include "stdio.h"
#include "winsock.h"
#include "iprtrmib.h"
#include "tlhelp32.h"
#include "iphlpapi.h"
#include "netstatp.h"

//
// APIs that we link against dynamically in case they aren't 
// present on the system we're running on.
//
DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(
  PMIB_TCPEXTABLE *pTcpTable,  // buffer for the connection table
  BOOL bOrder,               // sort the table?
  HANDLE heap,
  DWORD zero,
  DWORD flags
);

DWORD (WINAPI *pAllocateAndGetUdpExTableFromStack)(
  PMIB_UDPEXTABLE *pTcpTable,  // buffer for the connection table
  BOOL bOrder,               // sort the table?
  HANDLE heap,
  DWORD zero,
  DWORD flags
);

HANDLE (WINAPI *pCreateToolhelp32Snapshot)(
  DWORD dwFlags,       
  DWORD th32ProcessID  
);

BOOL (WINAPI *pProcess32First)(
  HANDLE hSnapshot,      
  LPPROCESSENTRY32 lppe  
);

BOOL (WINAPI *pProcess32Next)(
  HANDLE hSnapshot,      
  LPPROCESSENTRY32 lppe  
);


//
// Possible TCP endpoint states
//
static char TcpState[][32] = {
	"???",
	"CLOSED",
	"LISTENING",
	"SYN_SENT",
	"SYN_RCVD",
	"ESTABLISHED",
	"FIN_WAIT1",
	"FIN_WAIT2",
	"CLOSE_WAIT",
	"CLOSING",
	"LAST_ACK",
	"TIME_WAIT",
	"DELETE_TCB"
};


//--------------------------------------------------------------------
//
// PrintError
// 
// Translates a Win32 error into a text equivalent
//
//--------------------------------------------------------------------
VOID
PrintError( 
	DWORD ErrorCode 
	)
{
	LPVOID lpMsgBuf;
 
	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
					NULL, ErrorCode, 
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					(LPTSTR) &lpMsgBuf, 0, NULL );
	printf("%s\n", lpMsgBuf );
	LocalFree( lpMsgBuf );
}

//------------------------------------------------------------
//
// GetPortName
//
// Translate port numbers into their text equivalent if 
// there is one
//
//------------------------------------------------------------
PCHAR
GetPortName( 
	DWORD Flags,
	UINT port, 
	PCHAR proto, 
	PCHAR name, 
	int namelen 
	) 
{
	struct servent *psrvent;

	if( Flags & FLAG_SHOW_NUMBERS ) {

		sprintf( name, "%d", htons( (WORD) port));
		return name;
	} 

	//
	// Try to translate to a name
	//
	if( psrvent = getservbyport( port, proto )) {

		strcpy( name, psrvent->s_name );

	} else {
	
		sprintf( name, "%d", htons( (WORD) port));
	}		
	return name;
}


//------------------------------------------------------------
//
// GetIpHostName
//
// Translate IP addresses into their name-resolved form
// if possible.
//
//------------------------------------------------------------
PCHAR
GetIpHostName( 
	DWORD Flags,
	BOOL local, 
	UINT ipaddr, 
	PCHAR name, 
	int namelen 
	) 
{
	struct hostent			*phostent;
	UINT					nipaddr;

	//
	// Does the user want raw numbers?
	//
	nipaddr = htonl( ipaddr );
	if( Flags & FLAG_SHOW_NUMBERS ) {

		sprintf( name, "%d.%d.%d.%d", 
			(nipaddr >> 24) & 0xFF,
			(nipaddr >> 16) & 0xFF,
			(nipaddr >> 8) & 0xFF,
			(nipaddr) & 0xFF);
		return name;
	}

	//
	// Try to translate to a name
	//
	if( !ipaddr  ) {

		if( !local ) {

			sprintf( name, "%d.%d.%d.%d", 
				(nipaddr >> 24) & 0xFF,
				(nipaddr >> 16) & 0xFF,
				(nipaddr >> 8) & 0xFF,
				(nipaddr) & 0xFF);

		} else {

			gethostname(name, namelen);
		}

	} else if( ipaddr == 0x0100007f ) {

		if( local ) {

			gethostname(name, namelen);
		} else {

			strcpy( name, "localhost" );
		}

	} else if( phostent = gethostbyaddr( (char *) &ipaddr,
		sizeof( nipaddr ), PF_INET )) {

		strcpy( name, phostent->h_name );

	} else {

		sprintf( name, "%d.%d.%d.%d", 
			(nipaddr >> 24) & 0xFF,
			(nipaddr >> 16) & 0xFF,
			(nipaddr >> 8) & 0xFF,
			(nipaddr) & 0xFF);
	}
	return name;
}


//------------------------------------------------------------
//
// ProcessPidToName
//
// Translates a PID to a name.
//
//------------------------------------------------------------
PCHAR
ProcessPidToName(
	HANDLE hProcessSnap,
	DWORD ProcessId,
	PCHAR ProcessName
	)
{
	PROCESSENTRY32 processEntry;

	strcpy( ProcessName, "???" );
	if( !pProcess32First( hProcessSnap, &processEntry )) {

		return ProcessName;
	}
	do {

		if( processEntry.th32ProcessID == ProcessId ) {

			strcpy( ProcessName, processEntry.szExeFile );
			return ProcessName;
		}

	} while( pProcess32Next( hProcessSnap, &processEntry ));

	return ProcessName;
}


//------------------------------------------------------------
//
// ExApisArePresent
//
// Determines if Ex APIs (the XP version) are present, and
// if so, gets the function entry points.
//
//------------------------------------------------------------
BOOLEAN
ExApisArePresent(
	VOID
	)
{
	pAllocateAndGetTcpExTableFromStack = (PVOID) GetProcAddress( LoadLibrary( "iphlpapi.dll"), 
				"AllocateAndGetTcpExTableFromStack" );
	if( !pAllocateAndGetTcpExTableFromStack ) return FALSE;

	pAllocateAndGetUdpExTableFromStack = (PVOID) GetProcAddress( LoadLibrary( "iphlpapi.dll"), 
				"AllocateAndGetUdpExTableFromStack" );
	if( !pAllocateAndGetUdpExTableFromStack ) return FALSE;

	pCreateToolhelp32Snapshot = (PVOID) GetProcAddress( GetModuleHandle( "kernel32.dll" ),
				"CreateToolhelp32Snapshot" );
	if( !pCreateToolhelp32Snapshot ) return FALSE;

	pProcess32First = (PVOID) GetProcAddress( GetModuleHandle( "kernel32.dll" ),
				"Process32First" );
	if( !pProcess32First ) return FALSE;

	pProcess32Next = (PVOID) GetProcAddress( GetModuleHandle( "kernel32.dll" ),
				"Process32Next" );
	if( !pProcess32Next ) return FALSE;
	return TRUE;
}

//--------------------------------------------------------------------
//
// Usage
//
//--------------------------------------------------------------------
BOOLEAN 
Usage( 
	VOID
	)
{
	printf("Netstatp lists process endpoints.\n" );
	printf("\nUsage: netstatp [-a] [-n]\n" );
	printf("     -a    Displays all connections and listening ports.\n");
	printf("     -n    Displays addresses and port numbers in numerical form.\n");
	printf("\n");
	return FALSE;
}

//--------------------------------------------------------------------
//
// GetOptions
// 
// Parses the command line arguments.
//
//--------------------------------------------------------------------
BOOLEAN 
GetOptions( 
	int argc, 
	char *argv[],
	BOOLEAN ExPresent,
	PDWORD Flags
	)
{
	int			i, j;
	BOOLEAN		skipArgument;

	*Flags = 0;
	for(i = 1; i < argc; i++) {

		skipArgument = FALSE;
		switch( argv[i][0] ) {

		case '-':
		case '/':

			j = 1;
			while( argv[i][j] ) {

				switch( toupper( argv[i][j] )) {

				case 'A':
					*Flags |= FLAG_ALL_ENDPOINTS;
					break;

				case 'N':
					*Flags |= FLAG_SHOW_NUMBERS;
					break;
				default:

					return Usage();
				}
				if( skipArgument ) break;
				j++;
			}
			break;

		default:
	
			return Usage();
		}
	}
	return TRUE;
}


//------------------------------------------------------------
//
// Main
//
// Do it all. 
//
//------------------------------------------------------------
int 
main( 
	int argc, 
	char *argv[] 
	)
{
	DWORD		error, dwSize;
	WORD		wVersionRequested;
	WSADATA		wsaData;
	HANDLE		hProcessSnap;
	PMIB_TCPEXTABLE tcpExTable;
	PMIB_TCPTABLE tcpTable;
	PMIB_UDPEXTABLE udpExTable;
	PMIB_UDPTABLE udpTable;
	BOOLEAN		exPresent;
	DWORD		i, flags;
	CHAR		processName[MAX_PATH];
	CHAR		localname[HOSTNAMELEN], remotename[HOSTNAMELEN];
	CHAR		remoteport[PORTNAMELEN], localport[PORTNAMELEN];
	CHAR		localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN];

	//
	// Print banner
	//
	printf("\nNetstatp v2.0 - TCP/IP endpoint lister\n");
	printf("by Mark Russinovich\n");
	printf("Sysinternals - www.sysinternals.com\n\n");

	// 
	// Check for NT
	//
	if( GetVersion() >= 0x80000000 ) {

		printf("%s requres Windows NT/2K/XP.\n\n", argv[0]);
		return -1;
	}

	//
	// Initialize winsock
	//
	wVersionRequested = MAKEWORD( 1, 1 );
	if( WSAStartup(  wVersionRequested, &wsaData ) ) {

		printf("Could not initialize Winsock.\n");
		return -1;
	}

	//
	// Get options
	//
	exPresent = ExApisArePresent();
	if( !GetOptions( argc, argv, exPresent, &flags )) {

		return -1;
	}

	//
	// Determine if extended query is available (it's only present
	// on XP and higher).
	//
	if( exPresent ) {

		//
		// Get the tables of TCP and UDP endpoints with process IDs
		//
		error = pAllocateAndGetTcpExTableFromStack( &tcpExTable, TRUE, GetProcessHeap(), 2, 2 );
		if( error ) {

			printf("Failed to snapshot TCP endpoints.\n");
			PrintError( error );
			return -1;
		}
		error = pAllocateAndGetUdpExTableFromStack( &udpExTable, TRUE, GetProcessHeap(), 2, 2 );
		if( error ) {

			printf("Failed to snapshot UDP endpoints.\n");
			PrintError( error );
			return -1;
		}

		//
		// Get a process snapshot. Note that we won't be guaranteed to 
		// exactly match a PID against a process name because a process could have exited 
		// and the PID gotten reused between our endpoint and process snapshots.
		//
		hProcessSnap = pCreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
		if( hProcessSnap == INVALID_HANDLE_VALUE ) {

			printf("Failed to take process snapshot. Process names will not be shown.\n\n");
		}

		//
		// Dump the TCP table
		//
		for( i = 0; i < tcpExTable->dwNumEntries; i++ ) {

			if( flags & FLAG_ALL_ENDPOINTS ||
				tcpExTable->table[i].dwState == MIB_TCP_STATE_ESTAB ) {

				sprintf( localaddr, "%s:%s", 
					GetIpHostName( flags, TRUE, tcpExTable->table[i].dwLocalAddr, localname, HOSTNAMELEN), 
					GetPortName( flags, tcpExTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN ));

				sprintf( remoteaddr, "%s:%s",
					GetIpHostName( flags, FALSE, tcpExTable->table[i].dwRemoteAddr, remotename, HOSTNAMELEN), 
					tcpExTable->table[i].dwRemoteAddr ? 
						GetPortName( flags, tcpExTable->table[i].dwRemotePort, "tcp", remoteport, PORTNAMELEN ):
						"0" );

				printf("%-5s %s:%d\n      State:   %s\n", "[TCP]", 
					ProcessPidToName( hProcessSnap, tcpExTable->table[i].dwProcessId, processName ),
					tcpExTable->table[i].dwProcessId,
					TcpState[ tcpExTable->table[i].dwState ] );
				printf("      Local:   %s\n      Remote:  %s\n",
					localaddr, remoteaddr );
			}
		}

		//
		// Dump the UDP table
		//
		if( flags & FLAG_ALL_ENDPOINTS ) {

			for( i = 0; i < udpExTable->dwNumEntries; i++ ) {

				sprintf( localaddr, "%s:%s", 
					GetIpHostName( flags, TRUE, udpExTable->table[i].dwLocalAddr, localname, HOSTNAMELEN), 
					GetPortName( flags, udpExTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN ));

				printf("%-5s %s:%d\n", "[UDP]", 
					ProcessPidToName( hProcessSnap, udpExTable->table[i].dwProcessId, processName ),
					udpExTable->table[i].dwProcessId );
				printf("      Local:   %s\n      Remote:  %s\n",
					localaddr, "*.*.*.*:*" );
			}
		}

	} else {

		//
		// Get the table of TCP endpoints
		//
		dwSize = 0;
		error = GetTcpTable( NULL, &dwSize, TRUE );
		if( error != ERROR_INSUFFICIENT_BUFFER ) {

			printf("Failed to snapshot TCP endpoints.\n");
			PrintError( error );
			return -1;
		}
		tcpTable = (PMIB_TCPTABLE) malloc( dwSize );
		error = GetTcpTable( tcpTable, &dwSize, TRUE );
		if( error ) {

			printf("Failed to snapshot TCP endpoints.\n");
			PrintError( error );
			return -1;
		}

		//
		// Get the table of UDP endpoints
		//
		dwSize = 0;
		error = GetUdpTable( NULL, &dwSize, TRUE );
		if( error != ERROR_INSUFFICIENT_BUFFER ) {

			printf("Failed to snapshot UDP endpoints.\n");
			PrintError( error );
			return -1;
		}
		udpTable = (PMIB_UDPTABLE) malloc( dwSize );
		error = GetUdpTable( udpTable, &dwSize, TRUE );
		if( error ) {

			printf("Failed to snapshot UDP endpoints.\n");
			PrintError( error );
			return -1;
		}

		//
		// Dump the TCP table
		//
		for( i = 0; i < tcpTable->dwNumEntries; i++ ) {

			if( flags & FLAG_ALL_ENDPOINTS ||
				tcpTable->table[i].dwState == MIB_TCP_STATE_ESTAB ) {

				sprintf( localaddr, "%s:%s", 
					GetIpHostName( flags, TRUE, tcpTable->table[i].dwLocalAddr, localname, HOSTNAMELEN), 
					GetPortName(  flags, tcpTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN ));

				sprintf( remoteaddr, "%s:%s",
					GetIpHostName( flags, FALSE, tcpTable->table[i].dwRemoteAddr, remotename, HOSTNAMELEN), 
					tcpTable->table[i].dwRemoteAddr ? 
						GetPortName( flags, tcpTable->table[i].dwRemotePort, "tcp", remoteport, PORTNAMELEN ):
						"0" );

				printf("%4s\tState:   %s\n", "[TCP]", 
					TcpState[ tcpTable->table[i].dwState ] );
				printf("       Local:   %s\n       Remote:  %s\n",
					localaddr, remoteaddr );
			}
		}

		//
		// Dump the UDP table
		//
		if( flags & FLAG_ALL_ENDPOINTS ) {

			for( i = 0; i < udpTable->dwNumEntries; i++ ) {

				sprintf( localaddr, "%s:%s", 
					GetIpHostName( flags, TRUE, udpTable->table[i].dwLocalAddr, localname, HOSTNAMELEN), 
					GetPortName(  flags, udpTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN ));

				printf("%4s", "[UDP]");
				printf("       Local:   %s\n       Remote:  %s\n",
					localaddr, "*.*.*.*:*" );
			}
		}
	}	
	printf("\n");
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -