Chinaunix首页 | 论坛 | 博客
  • 博客访问: 318642
  • 博文数量: 43
  • 博客积分: 1044
  • 博客等级: 准尉
  • 技术积分: 658
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-20 14:56
个人简介

人法地,地法天,天法道,道法自然。

文章分类

全部博文(43)

文章存档

2019年(1)

2013年(3)

2012年(15)

2011年(24)

分类: LINUX

2011-07-12 14:57:25

net-snmp 5.5学习笔记

snmpget动作的学习
net-snmp的两个头文件
#include
#include
以及snmpv3使用的头文件
#include "net-snmp/transform_oids.h"

包含以上头文件后请无视下文中函数上面的头文件。

net-snmp中几个重要的结构体:
  结构体名                             用处
-------------------------------------------------------------
netsnmp_session                在snmp会话中会用到的结构体
netsnmp_pdu                    snmp协议数据单元
netsnmp_variable_list          用于组织snmp协议返回的数据

使用net-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;
/*
* 初始化snmp库
*/
init_snmp("snmpapp");
/*
* 初始化session
*/
snmp_sess_init( &session );                   /* set up defaults */
/* 设置get操作的snmp版本为snmpv1 */
session.version = SNMP_VERSION_1;
   
/* 设置snmp的团体名 */
session.community = "demopublic";
session.community_len = strlen(session.community);
/* 初始化win32的socket,在unix上是空操作 */
SOCK_STARTUP;
/*
* 打开session
*/
ss = snmp_open(&session);                     /* 建立会话 */
/*
* 创建请求的协议数据单元
*   1) 用于取得system.sysDescr.0的值
*/
pdu = snmp_pdu_create(SNMP_MSG_GET);
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
snmp_add_null_var(pdu, anOID, anOID_len);
/*
* 发送请求并接收响应
*/
status = snmp_synch_response(ss, pdu, &response);
/*
* 处理响应
*/
if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) {
     /*
      * SUCCESS: 打印结果
      */
     for(vars = response->variables; vars; vars = vars->next_variable)
       print_variable(vars->name, vars->name_length, vars);
   } else {
     /*
      * FAILURE: 打印错误信息
      */
     if (status == STAT_SUCCESS)
       fprintf(stderr, "Error in packet\nReason: %s\n",
               snmp_errstring(response->errstat));
     else
       snmp_sess_perror("snmpget", ss);
    
}
/*
* 清理工作:
*  1) 释放响应结构体
*  2) 关闭session.
*/
if (response)
   snmp_free_pdu(response);
snmp_close(ss);
/* 清理win32的socket,unix上为空操作 */
SOCK_CLEANUP;

以上用到的函数有:
初始化snmp库:
#include
void init_snmp(const char *);                   用于初始化snmp库

关于session的操作:
#include
void snmp_sess_init(netsnmp_session *);         用于初始化session
netsnmp_session *snmp_open(netsnmp_session *);  打开socket并绑定响应的udp端口,如果返回空,则设置snmp_errno为错误代码
int snmp_close(netsnmp_session *);              关闭输入的session,释放session中申请的内存,抛弃所有未处理的请求,关闭所有socket,返回值为1是表示成功,否则返回0
int snmp_close_sessions(void);                  关闭所有打开的session

关于pdu的操作:
#include
#include
netsnmp_pdu    *snmp_pdu_create(int type);     根据type创建snmp的pdu,一下为type可选值
/*
 * PDU types in SNMPv1, SNMPsec, SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3
 */
#define SNMP_MSG_GET        (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0) /* a0=160 */
#define SNMP_MSG_GETNEXT    (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1) /* a1=161 */
#define SNMP_MSG_RESPONSE   (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2) /* a2=162 */
#define SNMP_MSG_SET        (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3) /* a3=163 */

/*
 * PDU types in SNMPv1 and SNMPsec
 */
#define SNMP_MSG_TRAP       (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4) /* a4=164 */

/*
 * PDU types in SNMPv2p, SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3
 */
#define SNMP_MSG_GETBULK    (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5) /* a5=165 */
#define SNMP_MSG_INFORM     (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6) /* a6=166 */
#define SNMP_MSG_TRAP2      (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7) /* a7=167 */

/*
 * PDU types in SNMPv2u, SNMPv2*, and SNMPv3
 */
#define SNMP_MSG_REPORT     (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x8) /* a8=168 */

/*
 * internal modes that should never be used by the protocol for the
 * pdu type.
 *
 * All modes < 128 are reserved for SET requests.
 */
#define SNMP_MSG_INTERNAL_SET_BEGIN        -1
#define SNMP_MSG_INTERNAL_SET_RESERVE1     0    /* these should match snmp.h */
#define SNMP_MSG_INTERNAL_SET_RESERVE2     1
#define SNMP_MSG_INTERNAL_SET_ACTION       2
#define SNMP_MSG_INTERNAL_SET_COMMIT       3
#define SNMP_MSG_INTERNAL_SET_FREE         4
#define SNMP_MSG_INTERNAL_SET_UNDO         5
#define SNMP_MSG_INTERNAL_SET_MAX          6

#define SNMP_MSG_INTERNAL_CHECK_VALUE           17
#define SNMP_MSG_INTERNAL_ROW_CREATE            18
#define SNMP_MSG_INTERNAL_UNDO_SETUP            19
#define SNMP_MSG_INTERNAL_SET_VALUE             20
#define SNMP_MSG_INTERNAL_CHECK_CONSISTENCY     21
#define SNMP_MSG_INTERNAL_UNDO_SET              22
#define SNMP_MSG_INTERNAL_COMMIT                23
#define SNMP_MSG_INTERNAL_UNDO_COMMIT           24
#define SNMP_MSG_INTERNAL_IRREVERSIBLE_COMMIT   25
#define SNMP_MSG_INTERNAL_UNDO_CLEANUP          26

/*
 * modes > 128 for non sets.
 * Note that 160-168 overlap with SNMP ASN1 pdu types
 */
#define SNMP_MSG_INTERNAL_PRE_REQUEST           128
#define SNMP_MSG_INTERNAL_OBJECT_LOOKUP         129
#define SNMP_MSG_INTERNAL_POST_REQUEST          130
#define SNMP_MSG_INTERNAL_GET_STASH             131


netsnmp_pdu *snmp_clone_pdu(netsnmp_pdu *pdu);
                                                克隆一份pdu
netsnmp_pdu *snmp_fix_pdu(netsnmp_pdu *pdu, int idx);
                                                修复一个接收到的pdu,idx使用创建pdu时的type,修复后需要释放响应pdu
void snmp_free_pdu(netsnmp_pdu *pdu);           释放pdu

设置pud中值的操作:
#include
#include
netsnmp_variable_list *
   snmp_pdu_add_variable(netsnmp_pdu *pdu,
                             const oid * name, size_t name_length,
                             u_char type,
                             const void * value, size_t len);
                                                向pdu中添加一个oid和这个oid的值
netsnmp_variable_list *
   snmp_varlist_add_variable(netsnmp_variable_list ** varlist,
                             const oid * name, size_t name_length,
                             u_char type,
                             const void * value, size_t len);
                                                向netsnmp_variable_list中添加一个oid和这个oid的值
netsnmp_variable_list *
   snmp_add_null_var(netsnmp_pdu *pdu,
                             const oid * name, size_t name_length);
                                                向pdu中添加一个没有值的oid
netsnmp_variable_list *
   snmp_clone_varbind(netsnmp_variable_list * varlist);
                                                克隆结构体


接收和发送snmp的pud有两种方式:同步和异步。同步方式如下:
#include
#include
int snmp_synch_response(netsnmp_session *, netsnmp_pdu *,netsnmp_pdu **);
                                                同步发送请求和接收相应。

异步方式如下:请参考
异步和同步不同之处在于:
/* 异步session中需要设置callback */
session.callback = asynch_response;            /* default callback */
session.callback_magic = hs;

#include
int snmp_send(netsnmp_session *, netsnmp_pdu *);
                                                发送异步请求。成功返回1,错误返回0
int snmp_async_send(netsnmp_session *, netsnmp_pdu *,
                                netsnmp_callback, void *);
                                                发送异步请求。成功返回1,错误返回0。使用参数的callback和data传送到回调函数
int snmp_select_info(int *numfds, fd_set *fdset, struct timeval *timeout,
                     int *block);
                                                返回session打开的fd的fdset。
int snmp_select_info2(int *, netsnmp_large_fd_set *,
                      struct timeval *, int *);
void snmp_read(fd_set *fdset);                  检查fdset是否可读,如果可读就调用callback
void snmp_read2(netsnmp_large_fd_set *);
void snmp_timeout(void);                        select超时返回后可以调用该函数,用于提示用户超时。

其他辅助函数:
/* Output */
void print_variable(const oid * objid, size_t objidlen,
                    const netsnmp_variable_list * variable);
void fprint_variable(FILE * fp,
                     const oid * objid, size_t objidlen,
                     const netsnmp_variable_list * variable);
int snprint_variable(char *buf, size_t buf_len,
                     const oid * objid, size_t objidlen,
                     const netsnmp_variable_list * variable);
void print_value(const oid * objid, size_t objidlen,
                 const netsnmp_variable_list * variable);
void fprint_value(FILE * fp,
                  const oid * objid, size_t objidlen,
                  const netsnmp_variable_list * variable);
int snprint_value(char *buf, size_t buf_len,
                  const oid * objid, size_t objidlen,
                  const netsnmp_variable_list * variable);

/*
 * provided for backwards compatability.  Don't use these functions.
 * See snmp_debug.h and snmp_debug.c instead.
 */
void snmp_set_do_debugging(int);
int  snmp_get_do_debugging(void);

void snmp_sess_error(void *, int *, int *, char **);
void netsnmp_sess_log_error(int priority,
                            const char *prog_string,
                            netsnmp_session * ss);
void snmp_sess_perror(const char *prog_string,
                                 netsnmp_session * ss);
const char *snmp_pdu_type(int type);

/* Searching the MIB Tree */
oid *snmp_parse_oid(const char *, oid *, size_t *);
int read_objid(const char *, oid *, size_t *);
int get_module_node(const char *, const char *, oid *, size_t *);
阅读(9236) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

wangzhezhilu0012014-05-06 15:16:30

曾经搞过网管,好熟悉的代码