> 技术文档 > mib2c --生成标量数据对应c文件

mib2c --生成标量数据对应c文件

 env MIBS=\"+/root/.snmp/mibs/TEST-MODULE.MIB\" mib2c TEST-MODULE::testModule

在ubuntu终端输入上面的指令前 确保 MIB文件已经拷贝到了对应的目录 另外确保mib2c工具已经安装了 前面Ubuntu安装snmp的两种方式 通过apt安装的时候会已经安装了mib2c工具

回车后提示:

这里询问我们选择那种类型的代码分格 我们后面 需要用net-snmp所以这里选择2

这里检查到我们的MIb树中包含标量和表格对象,这里自动生成的net-snmp分格的处理器不能同生成两种分格代码 需要分开生成 然后在合并 ,我们先生成标量类型的选择1

这里提示我们可以选择选择标量 API 风格还是魔法绑定整数变量 

选择标量 API 风格(mib2c.scalar.conf)
自定义数据处理:需要手动实现标量值的获取/设置逻辑(如从硬件传感器读取数据或写入配置)。
复杂业务逻辑:标量值与其他系统组件(如数据库、外部 API)交互时需额外处理。
灵活性要求高:需完全控制标量对象的行为(如验证输入、触发事件)

代码框架:

 static int handle_myScalar(netsnmp_mib_handler *handler, ...) { switch (reqinfo->mode) { case MODE_GET:  // 自定义获取逻辑(如读取系统时间)  snmp_set_var_typed_value(...);  break; case MODE_SET:  // 自定义设置逻辑(如写入配置文件)  break; } return SNMP_ERR_NOERROR; }

魔法绑定整数变量(mib2c.int_watch.conf)适用 
简单监控需求:标量值直接映射到内存中的整数变量(如计数器、状态标志)。
无需复杂逻辑:只需自动同步变量值与 SNMP 标量,无需额外处理。
快速原型开发:快速测试或临时监控某个整数值。

生成代码:自动创建变量与标量的绑定,例如

 static int myScalar_value = 0; // 内存中的变量 netsnmp_register_scalar(..., &myScalar_value);

这里我们选择1

询问是否需要为notifications生成代码 这里我们选择n 如果选择y的话会覆盖前面的标量代码

最终生成的.c文件 有中文注释修改的地方就是后面我们需要调整的地方

/* * Note: this file originally auto-generated by mib2c * using mib2c.scalar.conf */#include #include #include #include \"testModule.h\"/** Initializes the testModule module */voidinit_testModule(void){ const oid objtype1_oid[] = { 1,3,6,1,4,1,2,1,1 }; const oid objtype2_oid[] = { 1,3,6,1,4,1,2,1,2 }; DEBUGMSGTL((\"testModule\", \"Initializing\\n\")); netsnmp_register_scalar( netsnmp_create_handler_registration(\"objtype1\", handle_objtype1, objtype1_oid, OID_LENGTH(objtype1_oid), HANDLER_CAN_RWRITE )); netsnmp_register_scalar( netsnmp_create_handler_registration(\"objtype2\", handle_objtype2, objtype2_oid, OID_LENGTH(objtype2_oid), HANDLER_CAN_RWRITE ));}inthandle_objtype1(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests){ int ret; /* We are never called for a GETNEXT if it\'s registered as a \"instance\", as it\'s \"magically\" handled for us. */ /* a instance handler also only hands us one request at a time, so we don\'t need to loop over a list of requests; we\'ll only get one. */ switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,  /* XXX: a pointer to the scalar\'s data */,  /* XXX: the length of the data in bytes */); // snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, // \"test\", //定义的变量名称buff // strlen(\"test\") //buff的长度 // ); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: /* or you could use netsnmp_check_vb_type_and_size instead */ ret = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, requests, ret ); } break; case MODE_SET_RESERVE2: /* XXX malloc \"undo\" storage buffer */ if (/* XXX if malloc, or whatever, failed: */) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } break; case MODE_SET_FREE: /* XXX: free resources allocated in RESERVE1 and/or  RESERVE2. Something failed somewhere, and the states  below won\'t be called. */ break; case MODE_SET_ACTION: /* XXX: perform the value change here */ if (/* XXX: error? */) { netsnmp_set_request_error(reqinfo, requests, /* some error */); } break; case MODE_SET_COMMIT: // static char buff[256]=\"\"; // /* XXX: delete temporary storage */ // memcpy(buff,requests->requestvb->buf,requests->requestvb->val_len); // 赋值 // buff[requests->requestvb->val_len] =\'\\0\'; //字符串结束符 if (/* XXX: error? */) { /* try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_COMMITFAILED); } break; case MODE_SET_UNDO: /* XXX: UNDO and return to previous value for the object */ if (/* XXX: error? */) { /* try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } break; default: /* we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, \"unknown mode (%d) in handle_objtype1\\n\", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR;}inthandle_objtype2(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests){ int ret; /* We are never called for a GETNEXT if it\'s registered as a \"instance\", as it\'s \"magically\" handled for us. */ /* a instance handler also only hands us one request at a time, so we don\'t need to loop over a list of requests; we\'ll only get one. */ switch(reqinfo->mode) { case MODE_GET: snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,  /* XXX: a pointer to the scalar\'s data */,  /* XXX: the length of the data in bytes */); break; /* * SET REQUEST * * multiple states in the transaction. See: * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg */ case MODE_SET_RESERVE1: /* or you could use netsnmp_check_vb_type_and_size instead */ ret = netsnmp_check_vb_type(requests->requestvb, ASN_INTEGER); if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, requests, ret ); } break; case MODE_SET_RESERVE2: /* XXX malloc \"undo\" storage buffer */ if (/* XXX if malloc, or whatever, failed: */) { netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_RESOURCEUNAVAILABLE); } break; case MODE_SET_FREE: /* XXX: free resources allocated in RESERVE1 and/or  RESERVE2. Something failed somewhere, and the states  below won\'t be called. */ break; case MODE_SET_ACTION: /* XXX: perform the value change here */ if (/* XXX: error? */) { netsnmp_set_request_error(reqinfo, requests, /* some error */); } break; case MODE_SET_COMMIT: /* XXX: delete temporary storage */ if (/* XXX: error? */) { /* try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_COMMITFAILED); } break; case MODE_SET_UNDO: /* XXX: UNDO and return to previous value for the object */ if (/* XXX: error? */) { /* try _really_really_ hard to never get to this point */ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_UNDOFAILED); } break; default: /* we should never get here, so this is a really bad error */ snmp_log(LOG_ERR, \"unknown mode (%d) in handle_objtype2\\n\", reqinfo->mode ); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR;}