在 C 中使用 net-snmp 库处理来自 SNMP 代理的响应时收到 SIGSEGV
SIGSEGV received when processing response from SNMP agent using net-snmp library in C
我正在开发一个使用 net-snmp 的网络应用程序,通过在 C 中编写 snmp 管理器来从 snmp 代理获取信息。我的代码应该可以工作,但每次我处理来自 net-snmp 库的变量结构时,我都会收到SIGSEGV,我真的不知道为什么。如果有人知道为什么 and/or 如何使我的代码工作,请告诉我。 (我正在使用 CodeBlocks 16.01 IDE 进行开发,如果有帮助的话)
感谢您的帮助。
PS : 我使用的是 net-snmp 版本 5.7.2.1+dfsg-1.
PPS : 我的电脑支持 Debian Jessie (8.6.0)。
PPPS : 第一次在论坛发帖寻求帮助,请多多关照。
来源:
/* Include zone, some may not be useful in this application but I used them for testings */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <string.h>
/* function prototypes */
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu);
/* Main program */
int main(void)
{
netsnmp_session session, *ss;
netsnmp_pdu *pdu;
netsnmp_pdu *response;
oid anOID[MAX_OID_LEN];
size_t anOID_len;
int status;
long int *buf[256];
/* Variables init */
status = 0;
response = 0;
/* SNMP init */
init_snmp("test");
/* Session init */
snmp_sess_init(&session);
session.peername = "192.168.50.29";
/* SNMP session version */
session.version = SNMP_VERSION_1;
/* SNMP session community */
session.community = "public";
session.community_len = strlen(session.community);
/* Session open */
SOCK_STARTUP;
ss = snmp_open(&session);
if (!ss)
{
snmp_perror("ack");
exit(2);
}
/* Create PDU */
pdu = snmp_pdu_create(SNMP_MSG_GET);
/* Get OID */
get_node("sysDescr.0", anOID, &anOID_len);
snmp_add_null_var(pdu, anOID, anOID_len);
/* Send PDU request and stock response in &response */
status = snmp_synch_response(ss, pdu, &response);
/* Response processing */
print_result(status, ss, response);
if(response)
{
snmp_free_pdu(response);
}
/* Closing */
snmp_close(ss);
SOCK_CLEANUP;
return (0);
}
/* Response processing program, where the error I get is */
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu)
{
char buf[1024];
struct variable_list *vp;
int ix;
struct timeval now;
struct timezone tz;
struct tm *tm;
/* Get the hour */
gettimeofday(&now, &tz);
tm = localtime(&now.tv_sec);
printf("Heure = %.2d:%.2d:%.2d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
/* Print SNMP response */
switch (status)
{
/* If no error in snmp_synch_response(); */
case STAT_SUCCESS :
{
vp = pdu->variables;
/* If no error in response */
if (pdu->errstat == SNMP_ERR_NOERROR)
{
while(vp) //Possibly error here, but not the point of this question
{
/* The error I get is here : everytime I manipulate the vp structure I get the SIGSEGV signal */
snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
printf("%s: %s\n", sp->peername, buf);
vp = vp->next_variable;
}
return 0;
}
/* If error in response */
else
{
for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++)
{
if (vp)
{
snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
}
else
{
strcpy(buf, "(none)");
}
printf("%s: %s: %s\n",sp->peername, buf, snmp_errstring(pdu->errstat));
}
return -1;
}
}break;
/* If timeout in snmp_synch_response(); */
case STAT_TIMEOUT :
{
fprintf(stdout, "%s: Timeout\n", sp->peername);
return -1;
}break;
/* If error snmp_synch_response(); */
case STAT_ERROR :
{
snmp_perror(sp->peername);
return -1;
}break;
default :
{
return -1;
}
}
}
我回答我自己的问题是因为我发现我的代码有什么问题。
SNMP版本错误,我问的代理用的是SNMPv2c,不是SNMPv1。
OID 错误(而不是给出它的名字,给出它的标识符效果更好):为了知道给哪个我使用 OiDViEW 软件来解析我用于测试的代理的 MIB并选择其中之一 (OID)。
为了使代码正常工作,我将 get_node("sysDescr.0", anOID, &anOID_len);
替换为 snmp_parse_oid(".1.3.6.1.2.1.1.5.0", anOID, &anOID_len);
,将 session.version = SNMP_VERSION_1;
替换为 session.version = SNMP_VERSION_2c;
经过这些更改后,代码可以正常工作。
我正在开发一个使用 net-snmp 的网络应用程序,通过在 C 中编写 snmp 管理器来从 snmp 代理获取信息。我的代码应该可以工作,但每次我处理来自 net-snmp 库的变量结构时,我都会收到SIGSEGV,我真的不知道为什么。如果有人知道为什么 and/or 如何使我的代码工作,请告诉我。 (我正在使用 CodeBlocks 16.01 IDE 进行开发,如果有帮助的话)
感谢您的帮助。
PS : 我使用的是 net-snmp 版本 5.7.2.1+dfsg-1.
PPS : 我的电脑支持 Debian Jessie (8.6.0)。
PPPS : 第一次在论坛发帖寻求帮助,请多多关照。
来源:
/* Include zone, some may not be useful in this application but I used them for testings */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <string.h>
/* function prototypes */
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu);
/* Main program */
int main(void)
{
netsnmp_session session, *ss;
netsnmp_pdu *pdu;
netsnmp_pdu *response;
oid anOID[MAX_OID_LEN];
size_t anOID_len;
int status;
long int *buf[256];
/* Variables init */
status = 0;
response = 0;
/* SNMP init */
init_snmp("test");
/* Session init */
snmp_sess_init(&session);
session.peername = "192.168.50.29";
/* SNMP session version */
session.version = SNMP_VERSION_1;
/* SNMP session community */
session.community = "public";
session.community_len = strlen(session.community);
/* Session open */
SOCK_STARTUP;
ss = snmp_open(&session);
if (!ss)
{
snmp_perror("ack");
exit(2);
}
/* Create PDU */
pdu = snmp_pdu_create(SNMP_MSG_GET);
/* Get OID */
get_node("sysDescr.0", anOID, &anOID_len);
snmp_add_null_var(pdu, anOID, anOID_len);
/* Send PDU request and stock response in &response */
status = snmp_synch_response(ss, pdu, &response);
/* Response processing */
print_result(status, ss, response);
if(response)
{
snmp_free_pdu(response);
}
/* Closing */
snmp_close(ss);
SOCK_CLEANUP;
return (0);
}
/* Response processing program, where the error I get is */
int print_result(int status, struct snmp_session *sp, struct snmp_pdu *pdu)
{
char buf[1024];
struct variable_list *vp;
int ix;
struct timeval now;
struct timezone tz;
struct tm *tm;
/* Get the hour */
gettimeofday(&now, &tz);
tm = localtime(&now.tv_sec);
printf("Heure = %.2d:%.2d:%.2d\n", tm->tm_hour, tm->tm_min, tm->tm_sec);
/* Print SNMP response */
switch (status)
{
/* If no error in snmp_synch_response(); */
case STAT_SUCCESS :
{
vp = pdu->variables;
/* If no error in response */
if (pdu->errstat == SNMP_ERR_NOERROR)
{
while(vp) //Possibly error here, but not the point of this question
{
/* The error I get is here : everytime I manipulate the vp structure I get the SIGSEGV signal */
snprint_variable(buf, sizeof(buf), vp->name, vp->name_length, vp);
printf("%s: %s\n", sp->peername, buf);
vp = vp->next_variable;
}
return 0;
}
/* If error in response */
else
{
for (ix = 1; vp && ix != pdu->errindex; vp = vp->next_variable, ix++)
{
if (vp)
{
snprint_objid(buf, sizeof(buf), vp->name, vp->name_length);
}
else
{
strcpy(buf, "(none)");
}
printf("%s: %s: %s\n",sp->peername, buf, snmp_errstring(pdu->errstat));
}
return -1;
}
}break;
/* If timeout in snmp_synch_response(); */
case STAT_TIMEOUT :
{
fprintf(stdout, "%s: Timeout\n", sp->peername);
return -1;
}break;
/* If error snmp_synch_response(); */
case STAT_ERROR :
{
snmp_perror(sp->peername);
return -1;
}break;
default :
{
return -1;
}
}
}
我回答我自己的问题是因为我发现我的代码有什么问题。
SNMP版本错误,我问的代理用的是SNMPv2c,不是SNMPv1。
OID 错误(而不是给出它的名字,给出它的标识符效果更好):为了知道给哪个我使用 OiDViEW 软件来解析我用于测试的代理的 MIB并选择其中之一 (OID)。
为了使代码正常工作,我将 get_node("sysDescr.0", anOID, &anOID_len);
替换为 snmp_parse_oid(".1.3.6.1.2.1.1.5.0", anOID, &anOID_len);
,将 session.version = SNMP_VERSION_1;
替换为 session.version = SNMP_VERSION_2c;
经过这些更改后,代码可以正常工作。