您的位置:首页 > 理论基础 > 计算机网络

通过SNMP实现Netstat

2004-07-27 13:54 381 查看
#include "windows.h"
#include "stdio.h"
#include "snmp.h"
#include "winsock.h"
#define HOSTNAMELEN 256
#define PORTNAMELEN 256
#define ADDRESSLEN HOSTNAMELEN+PORTNAMELEN
//定义TCP连接链表结构
typedef struct _tcpinfo {
 struct _tcpinfo  *prev;
 struct _tcpinfo  *next;
 UINT    state;
 UINT    localip;
 UINT    localport;
 UINT    remoteip;
 UINT    remoteport;
} TCPINFO, *PTCPINFO;
// 定义获取SNMP扩展库中SnmpExtensionInit函数的指针pSnmpExtensionInit
BOOL (__stdcall *pSnmpExtensionInit)(
    IN  DWORD               dwTimeZeroReference,
    OUT HANDLE              *hPollForTrapEvent,
    OUT AsnObjectIdentifier *supportedView);
// 定义获取SNMP扩展库中SnmpExtensionQuery函数的指针pSnmpExtensionQuery
BOOL (__stdcall *pSnmpExtensionQuery)(
    IN BYTE                   requestType,
    IN OUT RFC1157VarBindList *variableBindings,
    OUT AsnInteger            *errorStatus,
    OUT AsnInteger            *errorIndex);
// 定义TCP连接时可能出现的状态:
static char TcpState[][32] = {
 "???",
 "CLOSED",
 "LISTENING",
 "SYN_SENT",
 "SEN_RECEIVED",
 "ESTABLISHED",
 "FIN_WAIT",
 "FIN_WAIT2",
 "CLOSE_WAIT",
 "CLOSING",
 "LAST_ACK",
 "TIME_WAIT"
};
 
TCPINFO  TcpInfoTable;
// 定义获取端口号文本值的函数
char *GetPortName( UINT port, char *proto, char *name, int namelen )
{
 struct servent *psrvent;
 if( psrvent = getservbyport( htons( (USHORT) port ), proto )) {
  strcpy( name, psrvent->s_name );
 } else {
  sprintf(name, "%d", port);
 }  
 return name;
}
// 定义转换IP地址显示格式的函数,用于获得主机名
char *GetIpHostName( BOOL local, UINT ipaddr, char *name, int namelen )
{
 struct hostent   *phostent;
 UINT     nipaddr;
 nipaddr = htonl( ipaddr );
 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;
}
// 定义装入SNMP扩展库,同时导出所需的SNMP接口函数的 LoadInetMibEntryPoints函数
BOOLEAN LoadInetMibEntryPoints()
{
 HINSTANCE hInetLib;
 if( !(hInetLib = LoadLibrary( "inetmib1.dll" ))) {
  return FALSE;
 }
 if( !(pSnmpExtensionInit = (void *) GetProcAddress( hInetLib,
   "SnmpExtensionInit" )) ) {
  return FALSE;
 }
 if( !(pSnmpExtensionQuery = (void *) GetProcAddress( hInetLib,
   "SnmpExtensionQuery" )) ) {
  return FALSE;
 }
 
 return TRUE;
}

int main( int argc, char *argv[] )
{
 HANDLE     hTrapEvent;
 AsnObjectIdentifier  hIdentifier;
 RFC1157VarBindList  bindList;
 RFC1157VarBind   bindEntry;
 UINT     tcpidentifiers[] = { 1,3,6,1,2,1,6,13,1,1};
 UINT     udpidentifiers[] = { 1,3,6,1,2,1,7,5,1,1};
 AsnInteger    errorStatus, errorIndex;
 TCPINFO     *currentEntry, *newEntry;
 UINT     currentIndex;
 WORD     wVersionRequested;
 WSADATA     wsaData;
 char     localname[HOSTNAMELEN], remotename[HOSTNAMELEN];
 char     remoteport[PORTNAMELEN], localport[PORTNAMELEN];
 char     localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN];
 wVersionRequested = MAKEWORD( 1, 1 );
 if( WSAStartup(  wVersionRequested, &wsaData ) ) {
  printf("Could not initialize Winsock./n");
  return 1;
 }
 if( !LoadInetMibEntryPoints()) {
  printf("Could not load extension DLL./n");
  return 1;
 }
 if( !pSnmpExtensionInit( GetCurrentTime(), &hTrapEvent, &hIdentifier )) {
  printf("Could not initialize extension DLL./n");
  return 1;
 }
 bindEntry.name.idLength = 0xA;
 bindEntry.name.ids = tcpidentifiers;
 bindList.list = &bindEntry;
 bindList.len  = 1;
 TcpInfoTable.prev = &TcpInfoTable;
 TcpInfoTable.next = &TcpInfoTable;
 currentIndex = 1;
 currentEntry = &TcpInfoTable;
 while(1) {
  if( !pSnmpExtensionQuery( ASN_RFC1157_GETNEXTREQUEST,
   &bindList, &errorStatus, &errorIndex )) {
   return 1;
  }
  if( bindEntry.name.idLength < 0xA ) break;
  if( currentIndex != bindEntry.name.ids[9] ) {
   currentEntry = TcpInfoTable.next;
   currentIndex = bindEntry.name.ids[9];
  }
  switch( bindEntry.name.ids[9] ) {
  case 1:
   
   newEntry = (TCPINFO *) malloc( sizeof(TCPINFO ));
   newEntry->prev = currentEntry;
   newEntry->next = &TcpInfoTable;
   currentEntry->next = newEntry;
   currentEntry = newEntry;
   currentEntry->state = bindEntry.value.asnValue.number;
   break;
  case 2:
   currentEntry->localip =
    *(UINT *) bindEntry.value.asnValue.address.stream;
   currentEntry = currentEntry->next;
   break;
  case 3:
   
   currentEntry->localport =
    bindEntry.value.asnValue.number;
   currentEntry = currentEntry->next;
   break;
  case 4:
   currentEntry->remoteip =
    *(UINT *) bindEntry.value.asnValue.address.stream;
   currentEntry = currentEntry->next;
   break;
  case 5:
   currentEntry->remoteport =
    bindEntry.value.asnValue.number;
   currentEntry = currentEntry->next;
   break;
  }
 }
 
 printf("%7s %-30s %-30s %s/n", "Proto", "Local", "Remote", "State" );
 currentEntry = TcpInfoTable.next;
 while( currentEntry != &TcpInfoTable ) {
  sprintf( localaddr, "%s:%s",
   GetIpHostName( TRUE, currentEntry->localip, localname, HOSTNAMELEN),
   GetPortName( currentEntry->localport, "tcp", localport, PORTNAMELEN ));
  sprintf( remoteaddr, "%s:%s",
   GetIpHostName( FALSE, currentEntry->remoteip, remotename, HOSTNAMELEN),
   currentEntry->remoteip ?
    GetPortName( currentEntry->remoteport, "tcp", remoteport, PORTNAMELEN ):
    "0" );
  printf("%7s %-30s %-30s %s/n", "TCP",
   localaddr, remoteaddr,
   TcpState[currentEntry->state]);
  
  currentEntry = currentEntry->next;
 }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息