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

📄 snmp.cpp

📁 我们的网管程序的后台软件,主要是网络方面的内容.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************
	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 + -