前段时间一直在做snmp代理。从一无所知到把项目做完。一些总结写在这里,分享给需要的人。
1. 开发mib文件
mib文件的格式是:起始行;import;从根节点开始,一层层往下,每一层都可在上层找到依赖关系。具体实现可参考安装包内mibs/ NET-SNMP-EXAMPLES-MIB.txt
注:对于可添加删除的表格,则table必须额外添加一项Row Status。用于标识行的添加删除修改。
将设计好的mib文件拷到/usr/local/share/snmp/mibs/
2. 用mib2c工具生成*.c *.h文件
设置环境变量,用对应配置文件生成代码。注意要用root权限。
export MIBS=ALL;
mib2c –c configure mibnode
configure选择:
表格用mib2c.iterate_access.conf或mib2c.iterate.conf
节点用mib2c.scalar.conf
Trap用mib2c.notify.conf
(如果没有生成文件,检查前几步是否正确完成)
(参考安装包内agent/mibgroup/example/ 下的文件完成开发)
3. 修改添加生成的.c文件,完成源代码的编写。
a) 节点方式函数
handle_XXX(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
MODE_GET用于get操作;
MODE_SET_COMMIT用于写操作。从requests->requestvb->val.integer/string获取节点数据。
b) table方式函数说明(mib2c.iterate_access.conf):
initialize_table_xxxTable(void)
模块初始化
xxxTable_handler
表格处理函数句柄
xxxTable_createEntry
传入表格参数,新建一个结构,将各参数依次赋给结构内各项。最后将结构添加在xxxTable_head的前面作为首节点。
xxxTable_removeEntry
此函数可借用mib2c.iterate.conf文件生成的函数。
entry的意思表示是表格的入口,是在mib文件中设置的(index项)。可查看netsnmp_table_helper_add_indexes函数的第二个参数注释。
xxxTable_get_first_data_point
手动创建链表,每个节点包含一行table内容,头结点赋给xxxTable_head。
将xxxTable_head赋给 *my_loop_context。
xxxTable_get_next_data_point
需要填写snmp_set_var_value(idx, (u_char *)xxx, sizeof(xxx))的后两个参数,xxx为index项。
xxxTable_create_data_context(netsnmp_variable_list * index_data, int column)
创建一个结构模板,entry项由index_data传入,如下例:
entry->IPLineID = *(index_data->val.integer); 其他的项随便填。如有RowStatus项,则RowStatus初始化为0。
将创建的结构体添加到xxxTable_head的头结点前面。
本函数在在xxxTable_handler函数中调用,默认生成的模板里第二个参数为空,编译会出错,填入1。
xxxTable_commit_row(void **my_data_context, int new_or_del)
具体的添加修改删除行的操作在这个函数里进行。例:
struct IPLineTable_entry *entry = (IPL_t *)*my_data_context;
switch (entry->RowStatus)
根据entry->RowStatus的不同类型区分不同的操作。
Get_xxx (void *data_context, size_t *ret_len)
获取节点数据内容
Set_xxx (void *data_context, long *val, size_t val_len)
设置节点内容
c) trap函数
发送trap有两种方式,一种是脚本中用snmptrap发送,一种是在程序内用函数发送。发送函数:send_xxxTrap_trap()。
需要填写两个snmp_varlist_add_variable函数。
snmp_varlist_add_variable(&var_list, snmptrap_oid, OID_LENGTH(snmptrap_oid),
ASN_OBJECT_ID, (u_char *)xxxTrap_oid, sizeof(xxxTrap_oid));
snmp_varlist_add_variable(&var_list, yyy_oid, OID_LENGTH(yyy_oid),
ASN_OCTET_STR, string, strlen(string));
xxxTrap_oid是trap节点号,yyy_oid是关联节点号,string即为要发送的字符串。
4. 编译
添加扩展采用动态库方式
生成动态库:
gcc -g -I/root/net-snmp-5.2.2/include/ -c -o example.o example.c
gcc -g -fPIC -shared -o example.so example.o
装载动态库到程序节点
需要配置文件:/etc/snmp/snmpd.conf 中添加
dlmod example /root/snmpdll/ example.so
然后重新启动snmpd程序。