如何解决使用 net-snmp lib 接收 SNMP V3 陷阱的 C++ 源代码
使用 net-snmp lib,我必须编写一个简单的应用程序“SNMP 管理器”来接收 UDP 端口 162 上的陷阱。我遵循了“snmptrapd.c”中的源代码,但我无法在回调函数中获取陷阱我的应用程序。在我的源文件中,当我遇到陷阱(snmpV2 或 snmpv3)时,我永远无法进入回调函数“snmpInputWrapper”。但是我注意到 UDP 端口在应用程序启动时正确打开。我该如何解决?提前致谢。
================ 文件陷阱.h
#ifndef TRAP_H
#define TRAP_H
#include <QDebug>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
/* change the word "define" to "undef" to try the (insecure) SNMPv1 version */
//#define USE_SNMP_VERSION_3
#define authProtocolSha 0
#define authProtocoMd5 1
#define privProtocolAes 0
#define privProtocolDes 1
#define SUCCESS 0
#define Failed -1
/* values for type field in get_req_state */
#define ALARM_GET_REQ 1
#define EVENT_GET_REQ 2
#define DEFAULT_RETRIES 5
class Trap
{
public:
Trap();
~Trap();
private:
#ifdef USE_SNMP_VERSION_3
const char *userV3 = "pippo";
const char *authPassphraseV3 = "authPwd";
const char *privPassphraseV3 = "privPwd";
int securityLevelV3 = SNMP_SEC_LEVEL_AUTHPRIV;
int authProtocol = 0;
int privProtocol = 1;
#else
QString communityName = "public";
#endif
netsnmp_transport *transport = NULL;
QString remoteHost = "xxx.xxx.xxx.xxx";
QString cfgFileLbl = "snmpCfg";
static int snmpInputWrapper(int operation,netsnmp_session *ss,int reqId,struct snmp_pdu *pdu,void *magic); /* callback */
int snmpInput(int operation,void *magic);
struct getReqState {
int type;
void *info;
};
netsnmp_session ss; /* snmp session to fill with information */
netsnmp_session *snmpSession; /* pointer of snmp session returned by the library */
int createSession(netsnmp_transport *transport);
int openSession();
void closeSession();
};
#endif // TRAP_H
================ 文件trap.cpp
#include "trap.h"
//Global callback object
Trap *globalTrap;
Trap::Trap() {
globalTrap = this;
int status = SUCCESS;
/* initialize the SNMP library */
init_snmp(cfgFileLbl.tolatin1().data());
const char* application = "snmptrap";
const char* portNumber = "162";
transport = netsnmp_transport_open_server(application,portNumber);
if(transport != NULL) {
createSession(transport);
if(status != SUCCESS) {
qDebug() << "error making new snmp session";
return;
}
status = openSession();
if(status != SUCCESS) {
qDebug() << "error opening new snmp session";
}
}
else
qDebug() << "error openning snmp transport for snmp trap";
}
int Trap::snmpInput(int operation,void *magic) {
int status = SUCCESS;
struct getReqState *state = (struct getReqState*)magic;
if (operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
if (pdu->command == SNMP_MSG_GET) {
if (state->type == EVENT_GET_REQ) {
/* this is just the ack to our inform pdu */
return status;
}
}
} else if(operation == NETSNMP_CALLBACK_OP_TIMED_OUT) {
if (state->type == ALARM_GET_REQ) {
/* need a mechanism to replace obsolete SNMPv2p alarm */
}
}
/* Todo */
return status;
}
int Trap::snmpInputWrapper(int operation,void *magic) {
int status = SUCCESS;
/* call the non-static member */
if(globalTrap) {
Trap *myCb = (TraP*)globalTrap;
status = myCb->snmpInput(operation,ss,reqId,pdu,magic);
}
return status;
}
int Trap::createSession(netsnmp_transport *transport) {
/* set up the authentication parameters for talking to the server */
int status = SUCCESS;
/* initialize a "session" that defines who we're going to talk to */
snmp_sess_init(&ss); /* set up defaults */
ss.peername = strdup(remoteHost.tolatin1().data()); /* Original code had NULL here */
/* set up the authentication parameters for talking to the server */
#ifdef USE_SNMP_VERSION_3
/* use SNMPv3 to talk to the experimental server */
ss.version=SNMP_VERSION_3; /* set the SNMP version number */
ss.securityName = strdup(userV3); /* set the SNMPv3 user name */
ss.securityNameLen = strlen(ss.securityName);
ss.securityLevel = securityLevelV3; /* set the security level to authenticated,but not encrypted */
if(authProtocol == authProtocolSha) {
ss.securityAuthProto = usmHMACSHA1AuthProtocol; /* set the authentication algorithm */
ss.securityAuthProtoLen = sizeof(usmHMACSHA1AuthProtocol)/sizeof(oid);
}
else {
ss.securityAuthProto = usmHMACMD5AuthProtocol; /* set the authentication algorithm */
ss.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);
}
ss.securityAuthKeyLen = USM_AUTH_KU_LEN;
/* set the authentication key which must be at least 8 characters long */
if(generate_Ku(ss.securityAuthProto,ss.securityAuthProtoLen,(u_char *) authPassphraseV3,strlen(authPassphraseV3),ss.securityAuthKey,&ss.securityAuthKeyLen) != SNMPERR_SUCCESS) {
const char* error;
snmp_perror(error); /* populate error variable */
qDebug() << "error generating Ku from authentication pass phrase: " << error;
status = Failed;
return status;
}
if(privProtocol == privProtocolAes) {
ss.securityPrivProto = usmAESPrivProtocol; /* set the privacy algorithm */
ss.securityPrivProtoLen = sizeof(usmAESPrivProtocol)/sizeof(oid);
}
else {
ss.securityPrivProto = usmDESPrivProtocol; /* set the privacy algorithm */
ss.securityPrivProtoLen = sizeof(usmDESPrivProtocol)/sizeof(oid);
}
ss.securityPrivKeyLen = USM_PRIV_KU_LEN;
if(generate_Ku(ss.securityAuthProto,(u_char *) privPassphraseV3,strlen(privPassphraseV3),ss.securityPrivKey,&ss.securityPrivKeyLen) != SNMPERR_SUCCESS) {
const char* error;
snmp_perror(error); /* populate error variable */
qDebug() << "error generating Ku from authentication pass phrase: " << error;
status = Failed;
return status;
}
#else /* we'll use the insecure (but simplier) SNMPv1 */
ss.version = SNMP_VERSION_1 /* SNMP_VERSION_2c */; /* set the SNMP version number */
ss.community = (unsigned char*)communityName.tolatin1().data(); /* set the SNMPv1 community name used for authentication */
ss.community_len = strlen((const char*)ss.community);
ss.authenticator = NULL;
ss.isAuthoritative = SNMP_SESS_UNKNowNAUTH;
//ss.retries = SNMP_DEFAULT_RETRIES;
//ss.timeout = SNMP_DEFAULT_TIMEOUT;
#endif
/* define callback function to get traps */
ss.callback = snmpInputWrapper;
ss.callback_magic = (void*)transport;
}
int Trap::openSession() {
/* open the session */
int status = SUCCESS;
SOCK_STARTUP;
snmpSession = snmp_open(&ss); /* establish the session */
if(!snmpSession) {
qDebug() << "error opening snmp session";
snmp_sess_perror("ack",&ss);
SOCK_CLEANUP;
status = Failed;
}
return status;
}
void Trap::closeSession() {
snmp_close(snmpSession); /* close active session for the current host */
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。