用模板mib2c.iterate.conf生成表过程 1. 写mib 库文件 bvcom-AD988-MIB.txt 2.复制mib库文件到/usr/local/share/snmp/mibs/ 3.加载mib库(修改snmp.conf文件) cat /usr/local/share/snmp/snmp.conf mibs +bvcom-AD988-MIB.txt 4. 检查mib是否正常加载 snmptranslate -IR -Tp vsDevice 5. 查看mib2c支持的模板 border@debian:/work/border/snmp/example-demon$ ls /usr/local/share/snmp/ mib2c.access_functions.conf mib2c.create-dataset.conf mib2c.scalar.conf mib2c.array-user.conf mib2c-data mib2c.table_data.conf mib2c.check_values.conf mib2c.genhtml.conf mibs mib2c.check_values_local.conf mib2c.int_watch.conf snmp.conf mib2c.column_defines.conf mib2c.iterate_access.conf snmp.conf~ mib2c.column_enums.conf mib2c.iterate.conf snmpconf-data mib2c.column_storage.conf mib2c.mfd.conf snmpd.conf mib2c.conf mib2c.notify.conf snmp_perl.pl mib2c.container.conf mib2c.old-api.conf snmp_perl_trapd.pl 6. 通过模板生成.c 和 .h 文件() border@debian:/work/border/snmp/example-demon$ mib2c -c mib2c.iterate.conf vsDevice 7. 通过 snmp_agent_api 编写守护程序 AD988DM.c #include #include #include #include #include "vsDevice.h" static int keep_running; RETSIGTYPE stop_server(int a) { keep_running = 0; } int main (int argc, char **argv) { int agentx_subagent=0; /* change this if you want to be a SNMP master agent */ int background = 0; /* change this if you want to run in the background */ int syslog = 0; /* change this if you want to use syslog */ /* print log errors to syslog or stderr */ if (syslog) snmp_enable_calllog(); else snmp_enable_stderrlog(); /* we're an agentx subagent? */ if (agentx_subagent) { /* make us a agentx client. */ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); } /* run in background, if requested */ if (background && netsnmp_daemonize(1, !syslog)) exit(1); /* Initialize tcpip, if necessary */ SOCK_STARTUP; /* Initialize the agent library */ init_agent("AD988DM"); // 配置文件名 /* Initialize our mib code here */ printf("Before init ViewScenes \n"); init_vsDevice(); // 加载节点信息 printf("End init ViewScenes \n"); /* initialize vacm/usm access control */ if (!agentx_subagent) { void init_vacm_vars(); void init_usmUser(); } /* Example-demon will be used to read example-demon.conf files. */ init_snmp("AD988DM"); /* If we're going to be a snmp master agent, initial the ports */ if (!agentx_subagent) init_master_agent(); /* open the port to listen on (defaults to udp:161) */ printf("---------------------\n"); /* In case we recevie a request to stop (kill -TERM or kill -INT) */ keep_running = 1; signal(SIGTERM, stop_server); signal(SIGINT, stop_server); snmp_log(LOG_INFO,"AD988DM is up and running.\n"); /* your main loop here... */ while(keep_running) { /* if you use select(), see snmp_select_info() in snmp_api(3) */ /* --- OR --- */ agent_check_and_process(1); /* 0 == don't block */ } /* at shutdown time */ snmp_shutdown("AD988DM"); SOCK_CLEANUP; return 0; } 8. 编写Makefile文件,应用于编译。主要是make时候用到。 # # Warning: you may need more libraries than are included here on the # build line. The agent frequently needs various libraries in order # to compile pieces of it, but is OS dependent and we can't list all # the combinations here. Instead, look at the libraries that were # used when linking the snmpd master agent and copy those to this # file. # CC=gcc OBJS2=AD988DM.o vsDevice.o TARGETS=AD988DM CFLAGS=-I. `net-snmp-config --cflags` BUILDLIBS=`net-snmp-config --libs` BUILDAGENTLIBS=`net-snmp-config --agent-libs` # shared library flags (assumes gcc) DLFLAGS=-fPIC -shared all: $(TARGETS) AD988DM: $(OBJS2) $(CC) -o AD988DM $(OBJS2) $(BUILDAGENTLIBS) clean: rm $(OBJS2) $(OBJS2) $(TARGETS) 9. 编写配置文件AD988DM.conf 并copy到 ~./snmp目录下。 ############################################################################### # Access Control ############################################################################### # sec.name source community com2sec local localhost public com2sec mynetwork 192.168.0.0/24 public #### # Second, map the security names into group names: # sec.model sec.name group MyRWGroup v1 local group MyRWGroup v2c local group MyRWGroup usm local group MyROGroup v1 mynetwork group MyROGroup v2c mynetwork group MyROGroup usm mynetwork #### # Third, create a view for us to let the groups have rights to: # incl/excl subtree mask view all included .1 80 #### # Finally, grant the 2 groups access to the 1 view with different # write permissions: # context sec.model sec.level match read write notif access MyROGroup "" any noauth exact all none none access MyRWGroup "" any noauth exact all all none agentaddress 161; 10.修改vsDevice.c(这是最重要一步,举其中的一个表为例,其他类推) /** Initializes the vsDevice module */ void init_vsDevice(void) { /* here we initialize all the tables we're planning on supporting */ initialize_table_vsDevTypeTable(); initialize_table_vsDeviceTable(); initialize_table_vsDevElementTable(); } // # Determine the first/last column names /* Typical data structure for a row entry */ struct vsDevTypeTable_entry { /* Index values */ long vsDevTypeIndex; /* Column values */ // long vsDevTypeIndex; char vsDevTypeName[30]; size_t vsDevTypeName_len; long vsDevTypeNum; /* Illustrate using a simple linked list */ int valid; struct vsDevTypeTable_entry *next; }; struct vsDevTypeTable_entry *vsDevTypeTable_head; /* create a new row in the (unsorted) table */ struct vsDevTypeTable_entry * vsDevTypeTable_createEntry( long vsDevTypeIndex, ///////////////////////////////////////////////////////添加的部分 char *vsDevTypeName, long vsDevTypeNum ///////////////////////////////////////////////////// ) { struct vsDevTypeTable_entry *entry; entry = SNMP_MALLOC_TYPEDEF(struct vsDevTypeTable_entry); if (!entry) return NULL; entry->vsDevTypeIndex = vsDevTypeIndex; ////////////////////////////////////////////////////添加的部分 strcpy((u_char*)entry->vsDevTypeName,vsDevTypeName); entry->vsDevTypeNum = vsDevTypeNum; //////////////////////////////////////////////////// entry->next = vsDevTypeTable_head; vsDevTypeTable_head = entry; return entry; } /** Initialize the vsDevTypeTable table by defining its contents and how it's structured */ void initialize_table_vsDevTypeTable(void) { static oid vsDevTypeTable_oid[] = {1,3,6,1,4,1,500000,9,3,1,2}; size_t vsDevTypeTable_oid_len = OID_LENGTH(vsDevTypeTable_oid); netsnmp_handler_registration *reg; netsnmp_iterator_info *iinfo; netsnmp_table_registration_info *table_info; reg = netsnmp_create_handler_registration( "vsDevTypeTable", vsDevTypeTable_handler, vsDevTypeTable_oid, vsDevTypeTable_oid_len, HANDLER_CAN_RONLY ); table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info ); netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, /* index: vsDevTypeIndex */ 0); table_info->min_column = COLUMN_VSDEVTYPEINDEX; table_info->max_column = COLUMN_VSDEVTYPENUM; iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info ); iinfo->get_first_data_point = vsDevTypeTable_get_first_data_point; iinfo->get_next_data_point = vsDevTypeTable_get_next_data_point; iinfo->table_reginfo = table_info; netsnmp_register_table_iterator( reg, iinfo ); /* Initialise the contents of the table here */ vsDevTypeTable_createEntry(1, "sunligang", 24);//添加的部分 } /* remove a row from the table */ void vsDevTypeTable_removeEntry( struct vsDevTypeTable_entry *entry ) { struct vsDevTypeTable_entry *ptr, *prev; if (!entry) return; /* Nothing to remove */ for ( ptr = vsDevTypeTable_head, prev = NULL; ptr != NULL; prev = ptr, ptr = ptr->next ) { if ( ptr == entry ) break; } if ( !ptr ) return; /* Can't find it */ if ( prev == NULL ) vsDevTypeTable_head = ptr->next; else prev->next = ptr->next; SNMP_FREE( entry ); /* XXX - release any other internal resources */ } /* Example iterator hook routines - using 'get_next' to do most of the work */ netsnmp_variable_list * vsDevTypeTable_get_first_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { *my_loop_context = vsDevTypeTable_head; return vsDevTypeTable_get_next_data_point(my_loop_context, my_data_context, put_index_data, mydata ); } netsnmp_variable_list * vsDevTypeTable_get_next_data_point(void **my_loop_context, void **my_data_context, netsnmp_variable_list *put_index_data, netsnmp_iterator_info *mydata) { struct vsDevTypeTable_entry *entry = (struct vsDevTypeTable_entry *)*my_loop_context; netsnmp_variable_list *idx = put_index_data; if ( entry ) { snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->vsDevTypeIndex ); idx = idx->next_variable; *my_data_context = (void *)entry; *my_loop_context = (void *)entry->next; return put_index_data; } else { return NULL; } } /** handles requests for the vsDevTypeTable table */ int vsDevTypeTable_handler( netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; struct vsDevTypeTable_entry *table_entry; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request=requests; request; request=request->next) { table_entry = (struct vsDevTypeTable_entry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info( request); switch (table_info->colnum) { case COLUMN_VSDEVTYPEINDEX: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, table_entry->vsDevTypeIndex); break; case COLUMN_VSDEVTYPENAME: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR, (u_char*)table_entry->vsDevTypeName, strlen(table_entry->vsDevTypeName));//添加的部分,最后一个变量是长度,需要修改 break; case COLUMN_VSDEVTYPENUM: if ( !table_entry ) { netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); continue; } snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER, table_entry->vsDevTypeNum); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } } break; } return SNMP_ERR_NOERROR; } /*以上是第一个表的内容,已经成功取得*/ 操作如下: 1.slg@slg-desktop:~/snmpan/slg/AD988DM/doc$ snmpwalk -v 2c -c public localhost vsDevTypeTable bvcom-AD988-MIB::vsDevTypeIndex.1 = INTEGER: 1 bvcom-AD988-MIB::vsDevTypeName.1 = STRING: "sunligang" bvcom-AD988-MIB::vsDevTypeNum.1 = INTEGER: 24 2.slg@slg-desktop:~/snmpan/slg/AD988DM/doc$ snmpwalk -v 2c -c public localhost vsDevice bvcom-AD988-MIB::vsDevTypeIndex.1 = INTEGER: 1 bvcom-AD988-MIB::vsDevTypeName.1 = STRING: "sunligang" bvcom-AD988-MIB::vsDevTypeNum.1 = INTEGER: 24 bvcom-AD988-MIB::vsDevTypeIndex.1 = INTEGER: 1 bvcom-AD988-MIB::vsDeviceIndex.1 = INTEGER: 2 bvcom-AD988-MIB::vsDeviceName.1 = STRING: "sunligang" bvcom-AD988-MIB::vsDeviceStatusVal.1 = INTEGER: 22 bvcom-AD988-MIB::vsDeviceStatus.1 = STRING: "bvcom" bvcom-AD988-MIB::vsDevTypeIndex.1 = INTEGER: 1 bvcom-AD988-MIB::vsDeviceIndex.1 = INTEGER: 2 bvcom-AD988-MIB::vsDeviceElementIndex.1 = INTEGER: 3 bvcom-AD988-MIB::vsDeviceElementName.1 = STRING: "sunligang" bvcom-AD988-MIB::vsDeviceElementStatusVal.1 = INTEGER: 24 bvcom-AD988-MIB::vsDeviceElementStatus.1 = STRING: "zhangcl" bvcom-AD988-MIB::vsDeviceElementStatus.1 = No mo 3.6 代码的合并 在实现整个mib时,只需把简单变量的初始化函数和表实现的初始化函数合并。在这里简单变量的初始化函数为:void init_foxmail。把表的初始化函数void initialize_table_ExampleTable放到init_foxmail内部 ,再将init_foxmail作为主函数的初始化函数,修改相关头文件的引用,代码的简单合并就完成了。最后以主函数建立工程编译全部文件。 实现v3: 在配置文件中添加: rwuser bvcomslg createUser bvcomslg MD5 "bvcomslg" DES 运行结果: slg@slg-desktop:~/snmpan/slg/AD988DM$ snmpget -v3 -l authPriv -u bvcomslg -A bvcomslg -X bvcomslg localhost vsDevTypeName.2 bvcom-AD988-MIB::vsDevTypeName.2 = STRING: "sunligang" slg@slg-desktop:~/snmpan/slg/AD988DM$ snmpwalk -v3 -l authPriv -u bvcomslg -A bvcomslg -X bvcomslg localhost vsDevice bvcom-AD988-MIB::vsDevTypeNumber.0 = INTEGER: 0 bvcom-AD988-MIB::vsDevTypeIndex.2 = INTEGER: 2 bvcom-AD988-MIB::vsDevTypeName.2 = STRING: "sunligang" bvcom-AD988-MIB::vsDevTypeNum.2 = INTEGER: 24 bvcom-AD988-MIB::vsDeviceNumber.0 = INTEGER: 0 bvcom-AD988-MIB::vsDevTypeIndex.2 = INTEGER: 2 bvcom-AD988-MIB::vsDeviceIndex.2 = INTEGER: 2 bvcom-AD988-MIB::vsDeviceName.2 = STRING: "sunligang"