📄 wsnmputil.cpp
字号:
/*
Module Name: wsnmputil.cpp
Abstract:
Command Line utility to query the SNMP agent using WINSNMP API.
--*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <winsock2.h>
#include <winsnmp.h>
#include <snmp.h>
#include <mgmtapi.h>
#include "WSnmpUtil.h"
#include "wsnmputil.h"
#pragma comment( lib, "Ws2_32.lib")
//外部全局变量gVars,记录用户命令等信息
GlobalVars gVars;
//
// abstract: main entry point.
// input arguments:
// argc->number of input arguments
// argv->array of strings ( containing argc number of arguments )
// output: return status.
//
int __cdecl main( int argc, char **argv )
{
//初试化一般参数
PSNMP_MGR_SESSION pSession = NULL;
int nReturn = 0;
BOOL result;
int i = 0;
smiVALUE lvalue;
SNMPAPI_STATUS status;
WSAData wsaData;
//初试化SNMP参数
smiUINT32 nMajorVersion = 0;
smiUINT32 nMinorVersion = 0;
smiUINT32 nLevel = 0;
smiUINT32 nTranslateMode = 0;
smiUINT32 nRetransmitMode = 0;
__try
{
//SNMPAPI_UNTRANSLATED_V1 & SNMPAPI_UNTRANSLATED_V2 require transport address
//and we will use winsock api to get transport address from host names
if ( WSAStartup( 0x202, &wsaData ) != 0 )
{
nReturn = -1;
__leave;
}
// WinSnmp is supported on Windows NT 5.0 or later.
//判断windows NT 的版本
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
GetVersionEx (&osvi);
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
if (osvi.dwMajorVersion <= 4)
{
PrintDbgMessage( "wsnmputil: WinSnmp is supported on Windows NT 5.0 or later ..\n" );
nReturn = -1;
__leave;
}
}
else
{
PrintDbgMessage( "wsnmputil: WinSnmp is supported on Windows NT 5.0 or later ..\n" );
nReturn = -1;
__leave;
}
//接收用户在命令行输入的命令,主要记录在变量gVars中
result = ParseCommandLine( argc, argv );
if ( result == FALSE )
{
nReturn = -1;
__leave;
}
//********************************************************//
//加载SNMP服务
//********************************************************//
// start winsnmp
status = SnmpStartup(
&nMajorVersion, //SNMP主版本号
&nMinorVersion, //SNMP副版本号
&nLevel, //支持的最高操作标准
&nTranslateMode, //默认的上下文传输模式
&nRetransmitMode //默认的重发机制
);
//分两种情况设置传输模式(SNMP1/SNMP2)
if ( !SNMP_FAILURE(status) )
{
if ( gVars.version == FALSE )
SnmpSetTranslateMode( SNMPAPI_UNTRANSLATED_V1 ); //设置传输模式1
else
SnmpSetTranslateMode( SNMPAPI_UNTRANSLATED_V2 ); //设置传输模式2
}
else
{
nReturn = -1;
__leave;
}
//为会话分配内存空间
pSession = ( PSNMP_MGR_SESSION )SnmpUtilMemAlloc( sizeof( SNMP_MGR_SESSION ) );
if ( pSession == NULL )
{
PrintDbgMessage( "wsnmputil: Memory allocation failed ..\n" );
nReturn = -1;
__leave;
}
//*创建一个隐藏的负责监听WinSNMP消息的窗口
if ( !CreateNotificationWindow( pSession ) )
{
PrintDbgMessage( "wsnmputil: Fail to create notification window ..\n" );
nReturn = -1;
__leave;
}
result = OpenWinSNMPSession( pSession );
if ( result == FALSE )
{
PrintDbgMessage( "wsnmputil: Open session failed ..\n" );
nReturn = -1;
__leave;
}
//判断是那个操作Get,GetNext,Set,GetBulk,Walk
switch (gVars.operation)
{
case TRAP:
// WaitForTraps will block in While (ProcessAgentResponse()) loop
// Util user hits Ctrl+C to exit the program
WaitForTraps( pSession );
break;
case WALK:
while ( pSession->nErrorStatus == SNMP_ERROR_NOERROR )
{
if ( ! ( result = CreatePduSendRequest( pSession, NULL ) ) )
break;
if ( gVars.fDone == TRUE )
break;
}
break;
case GET:
case GET_NEXT:
// do create a pdu and send a request.
for( i = 0; i < gVars.oidCount; i++ )
result = CreatePduSendRequest( pSession, NULL );
break;
case GET_BULK:
result = CreatePduSendRequest( pSession, NULL );
break;
case SUB_TREE:
while ( pSession->nErrorStatus == SNMP_ERROR_NOERROR )
{
result = CreatePduSendRequest( pSession, NULL );
// check the return status.
if ( result == FALSE )
break;
// check if we hit the end of the subtree ..
if ( gVars.fDone == TRUE )
break;
}
break;
case SET:
result = FALSE;
gVars.doSet = TRUE;
if ( gVars.pSetValue != NULL )
{
gVars.operation = GET;
result = CreatePduSendRequest( pSession, NULL );
}
if ( result != FALSE )
{
gVars.operation = SET;
// copy the object type. Ex: INT UINT32 etc..
lvalue.syntax = gVars.value.syntax;
ConvertStringToSmiValue( &lvalue );
result = CreatePduSendRequest( pSession, &lvalue );
// check the error status on pSession.
if( pSession->nErrorStatus != 0 )
PrintDbgMessage( "Failed in setting the OID value ..\n" );
else
PrintDbgMessage( "Succeeded in setting the OID value ..\n" );
}
break;
} //end switch
} // end try block
__finally
{
// free memory ..
for( i = 0; i < gVars.oidCount; i++ )
{
if ( gVars.pszOid[ i ] )
SnmpUtilMemFree( gVars.pszOid[ i ] );
}
if ( gVars.pAgentStrAddr )
SnmpUtilMemFree( gVars.pAgentStrAddr );
if ( gVars.pAgentStrAddr != NULL )
SnmpUtilMemFree( gVars.pAgentCommunity );
if ( gVars.pSetValue )
SnmpUtilMemFree( gVars.pSetValue );
if (
( ( lvalue.syntax == SNMP_SYNTAX_OCTETS )
|| ( lvalue.syntax == SNMP_SYNTAX_BITS )
|| ( lvalue.syntax == SNMP_SYNTAX_OPAQUE )
|| ( lvalue.syntax == SNMP_SYNTAX_IPADDR )
|| ( lvalue.syntax == SNMP_SYNTAX_OID ) )
&& lvalue.value.string.ptr )
{
SnmpUtilMemFree (lvalue.value.string.ptr);
}
// close the winsnmp session
CloseWinSNMPSession ( pSession );
if ( pSession ) SnmpUtilMemFree( pSession );
// do SnmpCleanup( )
SnmpCleanup( );
// shut off windows sockets.
WSACleanup( );
} // end finally block
return ( nReturn );
} //end of main()
//建立会话
//
//abstract: open a WinSNMP session
//input : PSNMP_MGR_SESSION pSession
//output: TRUE if successful, FALSE if not.
//
BOOL OpenWinSNMPSession ( PSNMP_MGR_SESSION pSession )
{
smiOCTETS smiCommunity;
if ( pSession == NULL )
return ( FALSE );
//建立会话
// create a remote session
pSession->hSnmpSession = SnmpOpen( pSession->hWnd, WM_SNMP_INCOMING );
if ( SNMP_FAILURE( pSession->hSnmpSession ) )
return ( FALSE );
if ( gVars.pAgentStrAddr != NULL )
{
//创建实体
// create a remote agent entity
pSession->hAgentEntity = SnmpStrToEntity( pSession->hSnmpSession,
inet_ntoa( gVars.agentSockAddr.sin_addr ) );
if ( SNMP_FAILURE( pSession->hAgentEntity ) )
return ( FALSE );
//设置实体的超时时间和重传次数
// attach timeout specified with agent
SnmpSetTimeout( pSession->hAgentEntity, gVars.nTimeOut / 10 );
// attach retries specified with agent
SnmpSetRetry( pSession->hAgentEntity, gVars.nRetries );
// create local manager entity
pSession->hManagerEntity = SnmpStrToEntity(
pSession->hSnmpSession,
DEFAULT_ADDRESS_IP );
if ( SNMP_FAILURE( pSession->hManagerEntity ) )
return ( FALSE );
// attach timeout specified with manager
SnmpSetTimeout( pSession->hManagerEntity, gVars.nTimeOut / 10 );
// attach retries specified with manager
SnmpSetRetry( pSession->hManagerEntity, gVars.nRetries );
} // end of if ( pAgentStrAddr )
// validate pointer
if ( gVars.pAgentCommunity != NULL)
{
// transfer community string
smiCommunity.ptr = (smiLPBYTE)gVars.pAgentCommunity;
smiCommunity.len = gVars.pAgentCommunity ? lstrlen( gVars.pAgentCommunity) : 0;
//创建上下文句柄
// obtain context from community string
pSession->hViewContext = SnmpStrToContext(
pSession->hSnmpSession,
&smiCommunity
);
// validate context handle
if ( SNMP_FAILURE( pSession->hViewContext) )
return ( FALSE );
}
// success
return (TRUE);
} //end of OpenWinSNMP Session
//
// abstarct: close a WinSNMP session
// input : pointer to a SNMP_MGR_SESSION
// output: TRUE if successful, FALSE if not.
//
BOOL CloseWinSNMPSession ( PSNMP_MGR_SESSION pSession )
{
BOOL fOk = TRUE;
SNMPAPI_STATUS status;
// validate session ptr
if ( pSession == NULL )
return FALSE;
// check if window opened
if ( pSession->hWnd != (HWND)NULL )
{
// destroy notification window
fOk = DestroyNotificationWindow( pSession );
}
//释放资源
// close view context
if ( pSession->hViewContext != (HSNMP_CONTEXT) NULL)
{ //释放资源
SnmpFreeContext( pSession->hViewContext );
}
// check if agent entity allocated
if ( pSession->hAgentEntity != (HSNMP_ENTITY)NULL )
{
// close the entity handle
status = SnmpFreeEntity( pSession->hAgentEntity );
// validate status
if ( status == SNMPAPI_FAILURE )
{
// failure
fOk = FALSE;
}
// re-initialize
pSession->hAgentEntity = (HSNMP_ENTITY)NULL;
}
// check if manager entity allocated
if ( pSession->hManagerEntity != (HSNMP_ENTITY)NULL )
{
// close the entity handle
status = SnmpFreeEntity( pSession->hManagerEntity );
// validate status
if ( status == SNMPAPI_FAILURE )
{
// failure
fOk = FALSE;
}
// re-initialize
pSession->hManagerEntity = (HSNMP_ENTITY)NULL;
}
// check if session allocated
if ( pSession->hSnmpSession != (HSNMP_SESSION)NULL )
{
// close the winsnmp session
status = SnmpClose( pSession->hSnmpSession );
// validate status
if ( status == SNMPAPI_FAILURE )
{
// failure
fOk = FALSE;
}
// re-initialize
pSession->hSnmpSession = (HSNMP_SESSION)NULL;
}
return fOk;
} // end of CloseWinSNMPSession
//
// abstarct: create a notification window, which will receive WinSnmp messages.
// The window will remain hidden.
//
// input: pointer to PSNMP_MGR_SESSION
//
// output:
// TRUE if successful in creating the window
// FALSE if not successful in creating the window handle.
//
BOOL CreateNotificationWindow( PSNMP_MGR_SESSION pSession )
{
BOOL fOk;
WNDCLASS wc;
if ( pSession == NULL )
{
return FALSE;
}
// initialize notification window class
wc.lpfnWndProc = (WNDPROC)NotificationWndProc;
wc.lpszClassName = NOTIFICATION_CLASS;
wc.lpszMenuName = NULL;
wc.hInstance = gVars.g_hInst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.cbWndExtra = sizeof(PSNMP_MGR_SESSION);
wc.cbClsExtra = 0;
wc.style = 0; // register class
fOk = RegisterClass(&wc);
if (!fOk)
{
PrintDbgMessage( "snmputil: RegisterClass returned %d.\n", GetLastError() );
return (FALSE);
}
// create notification window
pSession->hWnd = CreateWindow(
NOTIFICATION_CLASS,
"SNMP Util Class", // pointer to window name
WS_OVERLAPPEDWINDOW, // window style
0, // horizontal position of window
0, // vertical position of window
0, // window width
0, // window height
NULL, // handle to parent or owner window
NULL, // handle to menu or child-window identifier
gVars.g_hInst, // handle to application instance
NULL // pointer to window-creation data
);
// validate window handle
if ( pSession->hWnd != NULL )
{
// store pointer to session in window
////陈 SetWindowLongPtr( pSession->hWnd, 0, (INT_PTR)pSession );
// success
fOk = TRUE;
}
else
{
// failure
fOk = FALSE;
}
return fOk;
} // end of CreateNotificationWindow
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -