http://www.net-snmp.org/wiki/index.php/TUT:Simple_Application snmp官方文档**
net-snmp学习笔记
程序开始需要声明几个变量:
snmp_session,里面存储的是调用者与谁交互的信息,对标nta->三方。需要两个,一个用来填充信息,一个是库返回的指针
snmp_pdu 保存我们将要发送到远程主机的所有信息。他将为对方要发回的信息声明一秒钟
这俩都是struct结构体
oid类型 存oid -》比如 oid anOID [10]
variable_list 存储的是想要通过snmp操作的变量,也是结构体
接下来使用init_snmp初始化snmp 库,可以在调用的时候指定文件名,就会自动读取配置文件,默认/etc下
初始化完成,用snmp_sess_init创建一个会话去和nms交互,可以用snmp_sess_init去设置一下会话的属性,就是前面snmp_session结构体
完事用snmp_open去打开会话,打开他之后会返回一个指针,这个指针就用开始定义的snmp_session指针去接收,指向我们应该使用的另一个会话
接下来,我们创建要发送到远程主机的 PDU ,当我们要求提供信息时。示例中这是snmpget程序使用的。它检索用于初始化它的每个 OID 的值。
因此,当我们用我们请求的 oid 填充它。让我们获取此示例的 system.sysDescr.0 变量。可以自己将数字无符号整数值放入我们上面创建的 anOID 数组中。或者用
get_node("sysDescr.0", anOID, &anOID_len); 拿到oid
read_objid("system.sysDescr.0", anOID, &anOID_len); 解析
下来,我们使用snmp_add_null_var将此具有 NULL 值的 oid 添加到 PDU
最后,利用snmp_synch_response,我们可以使用会话指针和 pdu 发送请求,并返回状态和响应,该状态和响应存储在新定位错误的响应 pdu 指针中
最后snmp_sess_close关闭会话
用snmp_shutdown清理snmp库
示例demo:
#include <stdio.h>
#include <stdlib.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
void print_variable(const oid *obj, const size_t obj_len, const netsnmp_variable_list *value)
{
int i;
char buf[1024];
switch(value->type) {
case ASN_INTEGER:
printf("%s = %ld\n",snprint_objid(buf, sizeof(buf), obj, obj_len),*(value->val.integer));
break;
case ASN_OCTET_STR:
printf("%s = %.*s\n",snprint_objid(buf, sizeof(buf), obj, obj_len),value->val_len,value->val.string);
break;
default:
printf("%s = ",snprint_objid(buf, sizeof(buf), obj, obj_len));
for(i=0;i<value->val_len;i++) printf("%02X ",value->val.string[i]);
printf("\n");
break;
}
}
int main(int argc, char ** argv) {
struct snmp_session session, *snmp_sess_pointer;
struct snmp_pdu *pdu;
struct snmp_pdu *response;
oid anOID[MAX_OID_LEN];
size_t anOID_len;
netsnmp_variable_list *vars;
// 初始化SNMP库
init_snmp("snmp_app");
// 初始化会话
snmp_sess_init(&session);
session.peername = argv[1]; // 指定SNMP代理程序的IP地址
session.version = SNMP_VERSION_2c; // 指定SNMP版本
session.community = "public"; // 指定社区字符串
session.community_len = strlen(session.community); // 计算社区字符串长度
// 开启SNMP会话
snmp_sess_pointer = snmp_sess_open(&session);
if (!snmp_sess_pointer) {
snmp_perror("snmp error");
snmp_log(LOG_ERR, "something horrible happened!!!\n");
exit(1);
}
// 准备发送PDU
pdu = snmp_pdu_create(SNMP_MSG_GET); // 创建一个GET请求的PDU
anOID_len = MAX_OID_LEN;
if (read_objid("IF-MIB::ifInOctets.1", anOID, &anOID_len)) { // 解析OID字符串
snmp_perror("read_objid error");
exit(1);
}
snmp_add_null_var(pdu, anOID, anOID_len); // 向PDU添加待查询的OID
// 发送SNMP请求并获取响应
if (snmp_synch_response(snmp_sess_pointer, pdu, &response) == STAT_SUCCESS) {
// 打印接收到的响应结果
for (vars = response->variables; vars; vars = vars->next_variable) {
print_variable(vars->name, vars->name_length, vars);
}
} else {
snmp_perror("snmp error");
}
// 关闭SNMP会话
snmp_sess_close(snmp_sess_pointer);
// 清理SNMP库
snmp_shutdown("snmp_app");
return 0;
}
- 初始化SNMP库:调用
init_snmp()
函数初始化SNMP库(在程序中,传入"snmp_app"
作为库名)。 - 初始化会话:调用
snmp_sess_init()
函数初始化SNMP会话。 - 开启SNMP会话:调用
snmp_sess_open()
函数建立到SNMP代理程序的连接,并返回一个指向SNMP会话的指针,若返回NULL则连接失败。 - 准备发送PDU:使用
snmp_pdu_create()
函数创建一个待发送的PDU(本示例中创建的是一个SNMP GET请求的PDU),然后使用read_objid()
函数解析OID字符串,并调用snmp_add_null_var()
函数向PDU添加待查询的OID。 - 发送SNMP请求并获取响应:使用
snmp_synch_response()
函数向SNMP代理程序发送请求,并获取响应。 - 打印接收到的响应结果:使用
print_variable()
函数打印接收到的SNMP变量值。 - 关闭SNMP会话:调用
snmp_sess_close()
函数关闭到SNMP代理程序的连接。 - 清理SNMP库:调用
snmp_shutdown()
函数清理SNMP库,释放相关资源。