现在的位置: 首页 > 综合 > 正文

linux 下net-snmp简单例子

2018年04月16日 ⁄ 综合 ⁄ 共 9691字 ⁄ 字号 评论关闭

参考原文:http://www.net-snmp.org/wiki/index.php/TUT:Simple_Application



这里我们讨论怎么写个简单的应用。它只是简单的接受来自远程主机的信息。下面是源代码和makefile

 

makefile:



首先,必须安装net-snmp工具,里面包含有代理软件(在被管理的远端主机上相应我们的请求),管理端(在本地接收信息),和我们开发必须的库和头文件。所以在我们的程序中包含以下头文件:

#include <net-snmp/net-snmp-config.h>

#include <net-snmp/net-snmp-includes.h>


下一步,我们考虑到版本问题,我们做一些代码编译的宏定义,不过我们默认是SNMPv3,第3版本比以前的版本复杂,也更安全。

/* change the word "define" to "undef" to try the (insecure) SNMPv1 version */

#define DEMO_USE_SNMP_VERSION_3

#ifdef DEMO_USE_SNMP_VERSION_3

#include "net-snmp/transform_oids.h"

const char *our_v3_passphrase = "The Net-SNMP Demo Password";

#endif

下一步定义主函数:


main() {


第一个我们要声明的变量:


  • struct snmp——session  保存远端主机的信息,我们要声明两个,一个用于填写远端信息,一个用于库返回的指针;

  • strcut  snmp_pdu: 用于我们要发送给远端主机的结构信息,我们也要声明两个,另一个接收返回信息。

  • oid: 一个oid 保存我们希望接收到的信息的位置(远端主机的节点位置)

  • struct variable_list:  保存我们想要通过snmp操作的变量。

struct snmp_session session, *ss;

struct snmp_pdu *pdu;

struct snmp_pdu *response;

oid anOID[MAX_OID_LEN];

size_t anOID_len = MAX_OID_LEN;

struct variable_list *vars;

int status;

初始化化库:

/*

* Initialize the SNMP library

*/

init_snmp("snmpapp");

下一步,我们初始化了一个session描述了我们希望通信的会话信息(包括本版信息,怎么样认证等),完整的session在

net-snmp/snmp_api.h中有原型。这里我们默认用的是第三版。


/*

* Initialize a "session" that defines who we're going to talk to

*/

snmp_sess_init( &session ); /*初始化会话 */

session.peername = "test.net-snmp.org";  /*

/* 设置验证参数 */

#ifdef DEMO_USE_SNMP_VERSION_3

/* 用第三版 */

/* 设置 SNMP version number */

session.version=SNMP_VERSION_3;

/* 设置 SNMPv3用户名*/

session.securityName = strdup("MD5User");

session.securityNameLen = strlen(session.securityName);

/* 设置认证安全等级, 但是不加密*/

session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;

/* 设置认证方法 */

session.securityAuthProto = usmHMACMD5AuthProtocol;

session.securityAuthProtoLen = sizeof(usmHMACMD5AuthProtocol)/sizeof(oid);

session.securityAuthKeyLen = USM_AUTH_KU_LEN;

/* set the authentication key to a MD5 hashed version of our

passphrase "The Net-SNMP Demo Password" (which must be at least 8

characters long) */

if (generate_Ku(session.securityAuthProto,

session.securityAuthProtoLen,

(u_char *) our_v3_passphrase, strlen(our_v3_passphrase),

session.securityAuthKey,

&session.securityAuthKeyLen) != SNMPERR_SUCCESS) {

snmp_perror(argv[0]);

snmp_log(LOG_ERR,

"Error generating Ku from authentication pass phrase. /n");

exit(1);

}

#else /* we'll use the insecure (but simplier) SNMPv1 */

/* set the SNMP version number */

session.version = SNMP_VERSION_1;

/* set the SNMPv1 community name used for authentication */

session.community = "demopublic";

session.community_len = strlen(session.community);

#endif /* SNMPv1 */


在我们建立会话之后,我们要打开它,返回一个指向另一个会话的指针,以后的操作就在返回的会话上完成。

/* windows32 specific initialization (is a noop on unix) */windows32 需要的初始化socket,linux下的不用

SOCK_STARTUP;

/*

* 打开会话

*/

ss = snmp_open(&session); /* 连接会话 */

/*如果打开失败,打印错误原因*/

if (!ss) {

snmp_perror("ack");

snmp_log(LOG_ERR, "something horrible happened!!!/n");

exit(2);

}


下一步,我们创建pdu用于打包我们发送请求的信息,在这里我们建一个SNMP-GET pdu  (是snmpget program用的,也就是管理端用的)

/*

* 创建pdu

*/

下面这段保持原文好点,我翻译的不好

pdu = snmp_pdu_create(SNMP_MSG_GET);

So, let's fill it with our requested oid. Let's get the
system.sysDescr.0 variable for this example. There are numerious ways
you could create the oid in question. You could put in the numerical
unsigned integer values yourself into the anOID array we created above,
or you could use one of the following function calls to do it. We
recommend the first one (get_node), as it is the most powerful and
accepts more types of OIDs.

read_objid(".1.3.6.1.2.1.1.1.0", anOID, &anOID_len);

#if OTHER_METHODS

get_node("sysDescr.0", anOID, &anOID_len);

read_objid("system.sysDescr.0", anOID, &anOID_len);

#endif

So we add this oid, with a NULL value to the PDU using the following
statement: (all oids should be paired with a NULL value for outgoing
requests for information. For an SNMP-SET pdu, we'd put in the value we
wanted to set the oid to).

snmp_add_null_var(pdu, anOID, anOID_len);

通过上面返回的会话指针,发送我们的请求信息pdu,返回一个状态是int型的,还返回一个pdu信息,用pdu指针指向它,它存有我们需要的信息。

/*

* Send the Request out.

*/

status = snmp_synch_response(ss, pdu, &response);


/*先检查信息,假设我们的请求成功返回,如果不是就打印错误信息。*/

if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {

/*

* SUCCESS: Print the result variables

*/

用print_variable()输出pdu的变量到终端。

for(vars = response->variables; vars; vars = vars->next_variable)

print_variable(vars->name, vars->name_length, vars);

Then, for kicks, lets get the information and manipulate it
ourselves (checking to make sure its the type we're expecting (a
string) first):(对获得的信息的操作,检验它的类型)

/* manipulate the information ourselves */

for(vars = response->variables; vars; vars = vars->next_variable) {

int count=1;

if (vars->type == ASN_OCTET_STR) {

char *sp = (char *)malloc(1 + vars->val_len);

memcpy(sp, vars->val.string, vars->val_len);

sp[vars->val_len] = '/0';

printf("value #%d is a string: %s/n", count++, sp);

free(sp);

}

else

printf("value #%d is NOT a string! Ack!/n", count++);

}

/*如果有错误的话,输出错误信息*/

} else {

/*

* FAILURE: print what went wrong!

*/

if (status == STAT_SUCCESS)

fprintf(stderr, "Error in packet/nReason: %s/n",

snmp_errstring(response->errstat));

else

snmp_sess_perror("snmpget", ss);

}


/*最后,要释放资源snmp_free_pdu(),用退出函数snmp_close()安全退出:*/

/*

* Clean up:

* 1) free the response.

* 2) close the session.

*/

if (response)

snmp_free_pdu(response);

snmp_close(ss);

/* windows32 specific cleanup (is a noop on unix) */

SOCK_CLEANUP;

} /* main() */
运行makefile编译:

% make snmpdemoapp

cc -I/usr/local/include -g -c snmpdemoapp.c -o snmpdemoapp.o

cc -o snmpdemoapp snmpdemoapp.o -lsnmp

运行:

% ./snmpdemoapp

system.sysDescr.0 = HP-UX net-snmp B.10.20 A 9000/715

value #1 is a string: HP-UX net-snmp B.10.20 A 9000/715

【上篇】
【下篇】

抱歉!评论已关闭.