![冰上的奶牛 冰上的奶牛]()
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_METHODSget_node("sysDescr.0", anOID, &anOID_len);read_objid("system.sysDescr.0", anOID, &anOID_len);#endifsnmp_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 *); 用于初始化sessionnetsnmp_session *snmp_open(netsnmp_session *); 打开socket并绑定响应的udp端口,如果返回空,则设置snmp_errno为错误代码int snmp_close(netsnmp_session *); 关闭输入的session,释放session中申请的内存,抛弃所有未处理的请求,关闭所有socket,返回值为1是表示成功,否则返回0int 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 */#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 131netsnmp_pdu *snmp_clone_pdu(netsnmp_pdu *pdu); 克隆一份pdunetsnmp_pdu *snmp_fix_pdu(netsnmp_pdu *pdu, int idx); 修复一个接收到的pdu,idx使用创建pdu时的type,修复后需要释放响应pduvoid 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中添加一个没有值的oidnetsnmp_variable_list * snmp_clone_varbind(netsnmp_variable_list * varlist); 克隆结构体接收和发送snmp的pud有两种方式:同步和异步。同步方式如下:#include #include int snmp_synch_response(netsnmp_session *, netsnmp_pdu *,netsnmp_pdu **); 同步发送请求和接收相应。异步方式如下:请参考http://www.net-snmp.org/wiki/index.php/TUT:Simple_Async_Application异步和同步不同之处在于:/* 异步session中需要设置callback */session.callback = asynch_response; /* default callback */session.callback_magic = hs;#include int snmp_send(netsnmp_session *, netsnmp_pdu *); 发送异步请求。成功返回1,错误返回0int 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是否可读,如果可读就调用callbackvoid 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 *); 12-21 22:51