📄 snmp.cpp
字号:
/*************************************************
Copyright (C), 2000-2002, Huayue Co., Ltd.
File name: snmp.cpp
Module: NMS实现模块
Author: 王华东
Version: 1.0
Created on : 2002.11.04
Description: NMS实现模块具体与Agent的接口、实现
一般的MIB变量的查询、设置,Trap由Trap模块实现
目前仅支持单个变量的Set/Get操作
Global function List:
Modify History:
Date: Author: Modification:
1. 2002.12.26 通过代理(Agent+Proxy)与网元相连时,
Proxy经常处于Msg Recv 、Select的Time Out空等中,
导致网管端超时,得不到返回,超时返回包将被丢弃
-》加大网管端超时时间到5S,(不合理,一般为500MS以下)
-》ProxyMsg Recv 、Select 的Time Out降为200MS(原为500MS)
2. 2002.12.27 实现通过网关与一般网元的连接,证明Proxy逻辑正常
Snmp 的收发、操作认为正确,且没有memory leak
3. 2002.01.13 Snmp突然收发不正常、接收不到Snmp Pack Return,
Agent 正常,以前版本居然也不行(某些版本已不可用)
对网关161端口尚可操作、但对网关9500、一般网元操作不行
解决:Agent端错误,网关代理记录NMS端口如下******
gAgent_NeMap[iTemp-1].manage_port = ntohl(from.sin_port);
返回NMS时为******
to.sin_port = htons(gAgent_NeMap[nTemp].manage_port);
去除ntohl,htons即可。
4. 2003.03.15 重大改动
*************************************************/
#include "stdafx.h"
#include "..\..\GUI\nms.h"
#include "Snmp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment (lib , "wsnmp32.lib")
/////////////////////////////////////////////////////////////////////////////
// CSnmp
HSNMP_SESSION CSnmp::m_SessionID=0;
CSnmp::CSnmp()
{
// 参数初始化
m_SnmpStatus = ERR_SNMP_NOT_START ;
/*
* Now Just cReTran/lTimeout is used
*/
m_timeOut = 10000;
m_Retran = 1;
/* 请求服务队列 */
m_SendPos = -1;
hMsgWnd = NULL;
}
/*-----------------------------------------------------------------*/
CSnmp::CSnmp(HWND hWnd)
{
// init Snmp , Start a session
// 参数初始化
m_SnmpStatus = ERR_SNMP_NOT_START ;
/*
* Now Just cReTran/lTimeout is used
*/
m_timeOut = 10000;
m_Retran = 1;
/* 请求服务队列 */
m_SendPos = -1;
for(int i=0 ; i<MAX_SNMP_QUEUE_NUMBER; i++)
{
memset(&gQueryQueue[i] , 0 , sizeof(QueryNMS));
}
hMsgWnd = hWnd;
// attach to a wnd
CreateSnmp(hWnd);
}
/*-----------------------------------------------------------------*/
CSnmp::CSnmp(BOOL bCreate)
{
// init Snmp , Start a session
CSnmp();
/* HWND hWnd;
// Create a Window
/* hWnd = CreateWindow( 0 , pApp->MyWindowName , "SnmpWindow" , WS_POPUP,
100 , 100 , 200 , 100 , NULL , NULL , NULL);
if(hWnd)
{
hMsgWnd = hWnd;
*/
// attach to a wnd
// CreateSnmp(hWnd);
// }
}
/*-----------------------------------------------------------------*/
CSnmp::~CSnmp()
{
SnmpCleanup();
}
/*-----------------------------------------------------------------*/
// Start Snmp Server .
BOOL CSnmp::CreateSnmp(HWND hWnd)
{
smiUINT32 nMajorVersion; // major version number of the
smiUINT32 nMinorVersion; // minor version number of the
smiUINT32 nLevel; // level of SNMP the implementation
smiUINT32 nTranslateMode; // default entity/context translation
smiUINT32 nRetransmitMode; // default retransmission mode
/* Requires the WinSNMP services Init...*/
if( SnmpStartup(&nMajorVersion , &nMinorVersion , &nLevel ,
&nTranslateMode , &nRetransmitMode ) == SNMPAPI_FAILURE)
{
return FALSE;
}
/* The implementation interprets SNMP entity parameters as SNMP transport addresses,
and context parameters as SNMP community strings
*/
if( SnmpSetTranslateMode(SNMPAPI_UNTRANSLATED_V1) == SNMPAPI_FAILURE)
{
return FALSE;
}
/* 设置程序默认将采用重传模式 */
if( SnmpSetRetransmitMode(SNMPAPI_ON) == SNMPAPI_FAILURE)
{
return FALSE;
}
/* Requests WinSNMP to open a session
采用异步通知方式(消息)
*/
m_SessionID = SnmpCreateSession(hWnd , WM_RECVSNMP , NULL , NULL);
if( m_SessionID == SNMPAPI_FAILURE)
{
return FALSE;
}
/* 共享数据保护 */
hInUse = CreateEvent(NULL , TRUE , TRUE , NULL);
if(hInUse == NULL)
{
m_SnmpStatus = ERR_SNMP_START_FAIL;
}
else
{
m_SnmpStatus = ERR_SNMP_START_OK;
}
return TRUE;
}
/*********************************************************
Description: 接收到Agent的Snmp返回,此函数为回调函数
Input :
Out :
*********************************************************/
void CSnmp::OnRecvSnmp(WPARAM wParam , LPARAM lParam)
{
HSNMP_ENTITY srcEntity;
HSNMP_ENTITY dstEntity;
HSNMP_CONTEXT hContext;
HSNMP_PDU hPdu;
HSNMP_VBL hRecvVbl; // handle to the variable bindings list
smiINT PduType;
smiINT32 RequestID; // request_id field of the PDU
smiINT ErrorStatus; // error_status field of the PDU
smiINT ErrorIndex; // error_index field of the PDU
smiOID RecvOid;
smiVALUE RecvSnmpValue;
SnmpReturn snmp_return; // SnmpReturn == AnSwerQuery
int vb_count = 0;
int i;
memset((char*)&snmp_return , 0 , sizeof(SnmpReturn));
/* 接收SNMP Packet */
if( SnmpRecvMsg(m_SessionID ,
&srcEntity ,
&dstEntity ,
&hContext ,
&hPdu
)
== SNMPAPI_FAILURE)
{
ReportError(ERR_SNMP_RECVMSG);
return ;
}
/* Get Pdu Data */
SnmpGetPduData(hPdu , &PduType , &RequestID ,&ErrorStatus , &ErrorIndex , &hRecvVbl);
/*
* Ok ,Agent Report Error , So toss it
*/
if(ErrorStatus != SNMP_ERROR_NOERROR )
{
SnmpFreeVbl(hRecvVbl);
SnmpFreePdu(hPdu);
SnmpFreeEntity(srcEntity);
SnmpFreeEntity(dstEntity);
SnmpFreeContext(hContext);
ReportError(ERR_SNMP_AGENT_REPORT_ERR);
return ;
}
/*
* the variable binding entries in hRecvVbl--vb Binding list
*/
vb_count = SnmpCountVbl(hRecvVbl);
for(i=1; i<=vb_count; i++)
{
/*
* Retrieves a variable name and its associated value
from the variable binding entry specified by the index parameter
*/
SnmpGetVb(hRecvVbl , i , &RecvOid , &RecvSnmpValue);
memset((void*)&snmp_return , 0 , sizeof(SnmpReturn));
/* Agent IP */
SnmpEntityToStr(srcEntity , MAX_IP_LEN , (char*)snmp_return.snmp.target_ip);
/* target_port 没有意义-无法获得 */
snmp_return.snmp.target_port = 0;
/* MIB OID */
SnmpOidToStr( &RecvOid , MAX_DOTTED_OID_SIZE , (char*)snmp_return.snmp.oid);
/* Get/Set Value Type */
snmp_return.snmp.value_type = SNMP_TYPE_INT;//RecvSnmpValue.syntax;
switch(RecvSnmpValue.syntax)
{
case SNMP_SYNTAX_INT:
{
memcpy((void *)snmp_return.snmp.value , (void*)&RecvSnmpValue.value.sNumber , sizeof(smiINT));
}
break;
case SNMP_SYNTAX_UINT32:
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
case SNMP_SYNTAX_TIMETICKS:
{
memcpy((void *)snmp_return.snmp.value , (void*)&RecvSnmpValue.value.uNumber , sizeof(smiUINT32));
}
break;
case SNMP_SYNTAX_CNTR64:
{
memcpy((void *)snmp_return.snmp.value , (void*)&RecvSnmpValue.value.hNumber , sizeof(smiCNTR64));
}
break;
case SNMP_SYNTAX_OCTETS:
{
snmp_return.snmp.value_type = SNMP_TYPE_STRING;
memcpy((void *)snmp_return.snmp.value , (void*)RecvSnmpValue.value.string.ptr , RecvSnmpValue.value.string.len);
}
break;
}
/* Notify Wnd/Thread */
SnmpPacketDispatch(&snmp_return);
}
/*
* Avoid memory leak , Release memory
*/
SnmpFreeVbl(hRecvVbl);
SnmpFreePdu(hPdu);
SnmpFreeEntity(srcEntity);
SnmpFreeEntity(dstEntity);
SnmpFreeContext(hContext);
SnmpFreeDescriptor(SNMP_SYNTAX_OID , (smiLPOPAQUE) &RecvOid);
if(RecvSnmpValue.syntax == SNMP_SYNTAX_OID)
{
SnmpFreeDescriptor( SNMP_SYNTAX_OID, (smiLPOPAQUE) &RecvSnmpValue.value);
}
else if(RecvSnmpValue.syntax == SNMP_SYNTAX_OCTETS)
{
SnmpFreeDescriptor( SNMP_SYNTAX_OCTETS, (smiLPOPAQUE) &RecvSnmpValue.value);
}
else ;
m_SendPos = -1;
/*
* 请求服务队列中还有需要服务的吗?
*/
SendMessage(hMsgWnd , WM_QUERYSNMP , 0 , 0);
}
/*********************************************************
Description: Snmp Get/Set
Input : SendSnmp *(See common.h)
Out : -1 Error
*********************************************************/
int CSnmp::SendSnmpPacket(SendSnmp *SendBuf)
{
PSendSnmp pTemp = (PSendSnmp)SendBuf;
HSNMP_ENTITY dstEntity , srcEntity;
HSNMP_CONTEXT hView;
HSNMP_VBL m_Vb;
HSNMP_PDU m_Pdu;
smiOID m_OID;
smiOCTETS m_ContextName;
smiVALUE smibindValue;
if( (m_SessionID == SNMPAPI_FAILURE) )
{
ReportError(ERR_SNMP_START_FAIL);
return -1;
}
if( (pTemp->action != SNMP_PDU_GET) && (pTemp->action != SNMP_PDU_SET) )
{
ReportError(ERR_SNMP_ERR_ACTION);
return -1;
}
/*
* 以下代码为发送SNMP包作准备 1.3.6.1.2.1.1.1.0
*/
/* ConVert OID to String OID */
SnmpStrToOid((char*)pTemp->oid , &m_OID);
/* Get/Set Community */
m_ContextName.ptr = (unsigned char *)pTemp->community;
m_ContextName.len = lstrlen((char*)pTemp->community);
if( (hView = SnmpStrToContext(m_SessionID,&m_ContextName)) == SNMPAPI_FAILURE)
{
SnmpFreeDescriptor(SNMP_SYNTAX_OID , (smiLPOPAQUE) &m_OID);
ReportError(ERR_SNMP_PREPARE_SEND);
return -1;
}
/* target */
dstEntity = SnmpStrToEntity(m_SessionID , (LPCSTR)pTemp->target_ip);
/**
Window May Use any available port to send the SNMP Packet
and wait in that port to recv the answer
*/
/* Snmp Send Point ---01.13 Any IF In Localhost can ok*/
srcEntity = SnmpStrToEntity(m_SessionID , pApp->SnmpSendIP);
if( (dstEntity == SNMPAPI_FAILURE) || (srcEntity == SNMPAPI_FAILURE) )
{
SnmpFreeDescriptor(SNMP_SYNTAX_OID , (smiLPOPAQUE) &m_OID);
ReportError(ERR_SNMP_PREPARE_SEND);
return -1;
}
/* 设置Agent(网关)接收的端口 */
::SnmpSetPort (dstEntity , pTemp->target_port);
/* 设置重传次数 */
SnmpSetRetry(dstEntity , m_Retran);
/* 设置超时 */
SnmpSetTimeout(dstEntity , m_timeOut/10);
/* 捆绑发送的数据
*/
/* Add 2002.12.21 */
/* if( (m_Vb = SnmpCreateVbl(m_SessionID , &m_OID , NULL)) == SNMPAPI_FAILURE) */
/* Value Type */
smibindValue.syntax = pTemp->value_type;
/* Value Only For Set */
switch(pTemp->value_type)
{
case SNMP_SYNTAX_INT:
{
smibindValue.value.sNumber = atol(pTemp->value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -