snmp 表格支持增删改查操作,比标量节点多了增删操作,那么为了实现增删操作,可以向表格增加一个RowStatus行状态类型的列,通过设置状态值对表格进行控制。

RowStatus状态值

状态 说明
active(1) 表明状态行是可用的
notInService(2) 表明行存在但不可用
notReady (3) 表明行存在,但因为缺少必要的信息而不能用
createAndGo (4) 由管理者设置,表明希望创建一个行并设置该行的状态列对象为active
createAndWait(5) 由管理者设置,表明希望创建一个行,但不可用,从上面的代码看到,是被设置为了notInService
destroy(6) 删除行

一、编写mib文件

使用MIB Builder生成MIB文件见:【snmp】使用MIB Builder生成MIB文件

注意

1、要有一个index索引节点,但是这个索引的名称不能为"index",为"index"会报错,我这里索引名称是为"userIdx"

2、一般会设置最后一列为RowStatus列,实际使用时除了RowStatus对应的节点需要设置read-create,其他节点可以随便设置,但是在MIB Builder工具中设置了一列为read-create,其他列(除索引列)也要设置为read-create,否则会报错,因此请将表的各个节点均设置为read-create类型,后面我们再修改生成的MIB文件

生成的UserTable-MIB.my文件内容如下:

--
-- UserTable-MIB.my
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0  Build 88
-- Thursday, August 06, 2020 at 14:12:31
--UserTable-MIB DEFINITIONS ::= BEGINIMPORTSOBJECT-GROUP           FROM SNMPv2-CONF            enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY            FROM SNMPv2-SMI;-- 1.3.6.1.4.1.85myModule MODULE-IDENTITY LAST-UPDATED "202008071136Z"        -- August 07, 2020 at 11:36 GMTORGANIZATION "Organization."CONTACT-INFO "Contact-info."DESCRIPTION "Description."::= { enterprises 85 }--
-- Node definitions
---- 1.3.6.1.4.1.85.1user OBJECT IDENTIFIER ::= { myModule 1 }-- 1.3.6.1.4.1.85.1.1userTable OBJECT-TYPESYNTAX SEQUENCE OF UserEntryMAX-ACCESS not-accessibleSTATUS currentDESCRIPTION"Description."::= { user 1 }-- 1.3.6.1.4.1.85.1.1.1userEntry OBJECT-TYPESYNTAX UserEntryMAX-ACCESS not-accessibleSTATUS currentDESCRIPTION"Description."INDEX { userIdx }::= { userTable 1 }UserEntry ::=SEQUENCE { userIdxInteger32,userNameInteger32,userAgeInteger32,userRowStatusInteger32}-- 1.3.6.1.4.1.85.1.1.1.1userIdx OBJECT-TYPESYNTAX Integer32 (1..1000)MAX-ACCESS read-onlySTATUS currentDESCRIPTION"Description."::= { userEntry 1 }-- 1.3.6.1.4.1.85.1.1.1.2userName OBJECT-TYPESYNTAX Integer32MAX-ACCESS read-createSTATUS currentDESCRIPTION"Description."::= { userEntry 2 }-- 1.3.6.1.4.1.85.1.1.1.3userAge OBJECT-TYPESYNTAX Integer32MAX-ACCESS read-createSTATUS currentDESCRIPTION"Description."::= { userEntry 3 }-- 1.3.6.1.4.1.85.1.1.1.4userRowStatus OBJECT-TYPESYNTAX Integer32MAX-ACCESS read-createSTATUS currentDESCRIPTION"Description."::= { userEntry 4 }-- 1.3.6.1.4.1.85.1.3userGroup OBJECT-GROUPOBJECTS { userIdx, userName, userAge, userRowStatus }STATUS currentDESCRIPTION "Description."::= { user 3 }END--
-- UserTable-MIB.my
--

修改后的MIB文件,有中文注释是修改的地方:

-- UserTable-MIB.my
-- MIB generated by MG-SOFT Visual MIB Builder Version 6.0  Build 88
-- Thursday, August 06, 2020 at 14:12:31
--UserTable-MIB DEFINITIONS ::= BEGINIMPORTSOBJECT-GROUP           FROM SNMPv2-CONF            enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY            FROM SNMPv2-SMI      -- 去掉原来的分号DisplayString, RowStatus -- 增加这一行FROM SNMPv2-TC;      -- 增加这一行-- 1.3.6.1.4.1.85myModule MODULE-IDENTITY LAST-UPDATED "202008071136Z"       -- August 07, 2020 at 11:36 GMTORGANIZATION "Organization."CONTACT-INFO "Contact-info."DESCRIPTION "Description."::= { enterprises 85 }--
-- Node definitions
---- 1.3.6.1.4.1.85.1user OBJECT IDENTIFIER ::= { myModule 1 }-- 1.3.6.1.4.1.85.1.1userTable OBJECT-TYPESYNTAX SEQUENCE OF UserEntryMAX-ACCESS read-create  -- 修改类型为read-createSTATUS currentDESCRIPTION"Description."::= { user 1 }-- 1.3.6.1.4.1.85.1.1.1userEntry OBJECT-TYPESYNTAX UserEntryMAX-ACCESS read-create  -- 修改类型为read-createSTATUS currentDESCRIPTION"Description."INDEX { userIdx }::= { userTable 1 }UserEntry ::=SEQUENCE { userIdxInteger32,userNameOCTET STRING,userAgeInteger32,userRowStatusRowStatus      -- 修改类型为RowStatus}-- 1.3.6.1.4.1.85.1.1.1.1userIdx OBJECT-TYPESYNTAX Integer32 (1..1000)MAX-ACCESS read-only   -- 根据实际业务修改类型STATUS currentDESCRIPTION"Description."::= { userEntry 1 }-- 1.3.6.1.4.1.85.1.1.1.2userName OBJECT-TYPESYNTAX OCTET STRINGMAX-ACCESS read-write  -- 根据实际业务修改类型STATUS currentDESCRIPTION"Description."::= { userEntry 2 }-- 1.3.6.1.4.1.85.1.1.1.3userAge OBJECT-TYPESYNTAX Integer32MAX-ACCESS read-write  -- 根据实际业务修改类型STATUS currentDESCRIPTION"Description."::= { userEntry 3 }-- 1.3.6.1.4.1.85.1.1.1.4userRowStatus OBJECT-TYPESYNTAX RowStatus       -- 修改为RowStatusMAX-ACCESS read-createSTATUS currentDESCRIPTION"Description."::= { userEntry 4 }-- OBJECT-GROUP可以不要-- 1.3.6.1.4.1.85.1.3-- userGroup OBJECT-GROUP--  OBJECTS { userIdx, userName, userAge, userRowStatus }-- STATUS current--    DESCRIPTION --      "Description."--  ::= { user 3 }END--
-- UserTable-MIB.my
--

二、使用mib2c命令生成.c和.h文件

上传UserTable-MIB.my到linux机器的/usr/local/snmp/share/snmp/mibs目录下

1、使用如下命令查看文件格式是否正确

/usr/local/snmp/bin/snmptranslate -Tp -IR UserTable-MIB::myModule

可以看到userRowStatus节点(也就是RowStatus列)所支持的状态值

2、执行如下命令生成表格文件

env MIBS="+/usr/local/snmp/share/snmp/mibs/UserTable-MIB.my" /usr/local/snmp/bin/mib2c -c mib2c.iterate.conf UserTable-MIB::myModule

以上命令执行完后会生成myModule.h和myModule.c文件

生成的原代码(myModule.c文件):

/** Note: this file originally auto-generated by mib2c using*  $*/#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "myModule.h"/** Initializes the myModule module */
void
init_myModule(void)
{/** here we initialize all the tables we're planning on supporting */initialize_table_userTable();
}# Determine the first/last column names/** Initialize the userTable table by defining its contents and how it's structured */
void
initialize_table_userTable(void)
{const oid       userTable_oid[] = { 1, 3, 6, 1, 4, 1, 85, 1, 1 };const size_t    userTable_oid_len = OID_LENGTH(userTable_oid);netsnmp_handler_registration *reg;netsnmp_iterator_info *iinfo;netsnmp_table_registration_info *table_info;DEBUGMSGTL(("myModule:init", "initializing table userTable\n"));reg =netsnmp_create_handler_registration("userTable", userTable_handler,userTable_oid,userTable_oid_len,HANDLER_CAN_RWRITE);table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: userIdx */0);table_info->min_column = COLUMN_USERIDX;table_info->max_column = COLUMN_USERROWSTATUS;iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);iinfo->get_first_data_point = userTable_get_first_data_point;iinfo->get_next_data_point = userTable_get_next_data_point;iinfo->table_reginfo = table_info;netsnmp_register_table_iterator(reg, iinfo);netsnmp_inject_handler_before(reg,netsnmp_get_cache_handler(USERTABLE_TIMEOUT, userTable_load,userTable_free, userTable_oid,userTable_oid_len),TABLE_ITERATOR_NAME);/** Initialise the contents of the table here */
}/** Typical data structure for a row entry */
struct userTable_entry {/** Index values */long            userIdx;/** Column values */long            userIdx;char            userName[NNN];size_t          userName_len;char            old_userName[NNN];size_t          old_userName_len;long            userAge;long            old_userAge;long            userRowStatus;/** Illustrate using a simple linked list */int             valid;struct userTable_entry *next;
};struct userTable_entry *userTable_head;/** create a new row in the (unsorted) table */
struct userTable_entry *
userTable_createEntry(long userIdx,)
{struct userTable_entry *entry;entry = SNMP_MALLOC_TYPEDEF(struct userTable_entry);if (!entry)return NULL;entry->userIdx = userIdx;entry->next = userTable_head;userTable_head = entry;return entry;
}/** remove a row from the table */
void
userTable_removeEntry(struct userTable_entry *entry)
{struct userTable_entry *ptr, *prev;if (!entry)return;                 /* Nothing to remove */for (ptr = userTable_head, prev = NULL;ptr != NULL; prev = ptr, ptr = ptr->next) {if (ptr == entry)break;}if (!ptr)return;                 /* Can't find it */if (prev == NULL)userTable_head = ptr->next;elseprev->next = ptr->next;SNMP_FREE(entry);           /* XXX - release any other internal resources */
}/** Example cache handling - set up linked list from a suitable file */
int
userTable_load(netsnmp_cache * cache, void *vmagic)
{FILE           *fp;struct userTable_entry *this;char            buf[STRMAX];/** The basic load routine template assumes that the data to* be reported is held in a file - with one row of the file* for each row of the table.* If your data is available via a different API, you* should amend this initial block (and the control of the* 'while' loop) accordingly.* 'XXX' marks where the template is incomplete and* code will definitely need to be added. */fp = fopen("/data/for/userTable", "r");if (!fp) {return -1;}while (fgets(buf, STRMAX, fp)) {this = SNMP_MALLOC_TYPEDEF(struct userTable_entry);/** XXX - Unpick 'buf' to extract the individual field values* and then populate the 'this' data structure with them */this->next = userTable_head;userTable_head = this;  /* Iterate helper is fine with unordered lists! */}fclose(fp);return 0;                   /* OK */
}void
userTable_free(netsnmp_cache * cache, void *vmagic)
{struct userTable_entry *this, *that;for (this = userTable_head; this; this = that) {that = this->next;SNMP_FREE(this);        /* XXX - release any other internal resources */}userTable_head = NULL;
}/** Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
userTable_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 = userTable_head;return userTable_get_next_data_point(my_loop_context, my_data_context,put_index_data, mydata);
}netsnmp_variable_list *
userTable_get_next_data_point(void **my_loop_context,void **my_data_context,netsnmp_variable_list * put_index_data,netsnmp_iterator_info *mydata)
{struct userTable_entry *entry =(struct userTable_entry *) *my_loop_context;netsnmp_variable_list *idx = put_index_data;if (entry) {snmp_set_var_typed_integer(idx, ASN_INTEGER, entry->userIdx);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 userTable table */
int
userTable_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 userTable_entry *table_entry;DEBUGMSGTL(("myModule:handler", "Processing request (%d)\n",reqinfo->mode));switch (reqinfo->mode) {/** Read-support (also covers GetNext requests)*/case MODE_GET:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERIDX:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userIdx);break;case COLUMN_USERNAME:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,table_entry->userName,table_entry->userName_len);break;case COLUMN_USERAGE:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userAge);break;case COLUMN_USERROWSTATUS:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userRowStatus);break;default:netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHOBJECT);break;}}break;/** Write-support*/case MODE_SET_RESERVE1:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:/** or possibly 'netsnmp_check_vb_type_and_size' */ret =netsnmp_check_vb_type_and_max_size(request->requestvb,ASN_OCTET_STR,sizeof(table_entry->userName));if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;case COLUMN_USERAGE:/** or possibly 'netsnmp_check_vb_int_range' */ret = netsnmp_check_vb_int(request->requestvb);if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;case COLUMN_USERROWSTATUS:ret = netsnmp_check_vb_rowstatus(request->requestvb,(table_entry ? RS_ACTIVE :RS_NONEXISTENT));if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;default:netsnmp_set_request_error(reqinfo, request,SNMP_ERR_NOTWRITABLE);return SNMP_ERR_NOERROR;}}break;case MODE_SET_RESERVE2:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:table_row =userTable_createEntry(,*table_info->indexes->val.integer);if (table_row) {netsnmp_insert_iterator_context(request,table_row);} else {netsnmp_set_request_error(reqinfo, request,SNMP_ERR_RESOURCEUNAVAILABLE);return SNMP_ERR_NOERROR;}}}}break;case MODE_SET_FREE:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:if (table_entry && !table_entry->valid) {userTable_removeEntry(table_data, table_row);}}}}break;case MODE_SET_ACTION:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:memcpy(table_entry->old_userName,table_entry->userName,sizeof(table_entry->userName));table_entry->old_userName_len = table_entry->userName_len;memset(table_entry->userName, 0,sizeof(table_entry->userName));memcpy(table_entry->userName,request->requestvb->val.string,request->requestvb->val_len);table_entry->userName_len = request->requestvb->val_len;break;case COLUMN_USERAGE:table_entry->old_userAge = table_entry->userAge;table_entry->userAge = *request->requestvb->val.integer;break;}}/** Check the internal consistency of an active row */for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_ACTIVE:case RS_CREATEANDGO:if ( /* XXX */ ) {netsnmp_set_request_error(reqinfo, request,SNMP_ERR_INCONSISTENTVALUE);return SNMP_ERR_NOERROR;}}}}break;case MODE_SET_UNDO:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:memcpy(table_entry->userName,table_entry->old_userName,sizeof(table_entry->userName));memset(table_entry->old_userName, 0,sizeof(table_entry->userName));table_entry->userName_len = table_entry->old_userName_len;break;case COLUMN_USERAGE:table_entry->userAge = table_entry->old_userAge;table_entry->old_userAge = 0;break;case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:if (table_entry && !table_entry->valid) {userTable_removeEntry(table_data, table_row);}}break;}}break;case MODE_SET_COMMIT:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:table_entry->valid = 1;/** Fall-through */case RS_ACTIVE:table_entry->userRowStatus = RS_ACTIVE;break;case RS_CREATEANDWAIT:table_entry->valid = 1;/** Fall-through */case RS_NOTINSERVICE:table_entry->userRowStatus = RS_NOTINSERVICE;break;case RS_DESTROY:userTable_removeEntry(table_data, table_row);}}}break;}return SNMP_ERR_NOERROR;
}

需要对myModule.c文件进行修改,修改后的文件如下(有中文注释的地方就是修改的地方):

/** Note: this file originally auto-generated by mib2c using*  $*/#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "myModule.h"/** Initializes the myModule module */
void
init_myModule(void)
{/** here we initialize all the tables we're planning on supporting */initialize_table_userTable();
}// 注释下面这行
// # Determine the first/last column names/** Initialize the userTable table by defining its contents and how it's structured */
void
initialize_table_userTable(void)
{const oid       userTable_oid[] = { 1, 3, 6, 1, 4, 1, 85, 1, 1 };const size_t    userTable_oid_len = OID_LENGTH(userTable_oid);netsnmp_handler_registration *reg;netsnmp_iterator_info *iinfo;netsnmp_table_registration_info *table_info;DEBUGMSGTL(("myModule:init", "initializing table userTable\n"));reg =netsnmp_create_handler_registration("userTable", userTable_handler,userTable_oid,userTable_oid_len,HANDLER_CAN_RWRITE);table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index: userIdx */0);table_info->min_column = COLUMN_USERIDX;table_info->max_column = COLUMN_USERROWSTATUS;iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);iinfo->get_first_data_point = userTable_get_first_data_point;iinfo->get_next_data_point = userTable_get_next_data_point;iinfo->table_reginfo = table_info;netsnmp_register_table_iterator(reg, iinfo);netsnmp_inject_handler_before(reg,netsnmp_get_cache_handler(USERTABLE_TIMEOUT, userTable_load,userTable_free, userTable_oid,userTable_oid_len),TABLE_ITERATOR_NAME);/** Initialise the contents of the table here */
}#define NNN 256 //定义这个宏,下面这个结构体用到/** Typical data structure for a row entry */
struct userTable_entry {/** Index values */long            userIdx;/** Column values */// long            userIdx; //注释掉,上面已经定义了char            userName[NNN];size_t          userName_len;char            old_userName[NNN];size_t          old_userName_len;long            userAge;long            old_userAge;long            userRowStatus;/** Illustrate using a simple linked list */int             valid;struct userTable_entry *next;
};struct userTable_entry *userTable_head;/** create a new row in the (unsorted) table */
//补全这个函数的参数,其实就是表格中那四列的内容
//这个函数就是添加一行数据的函数,RowStatus列不传也可以,程序内部会自动处理
struct userTable_entry *
userTable_createEntry(long userIdx,char *userName ,size_t userName_len,long userAge)
{struct userTable_entry *entry;entry = SNMP_MALLOC_TYPEDEF(struct userTable_entry);if (!entry)return NULL;entry->userIdx = userIdx;snprintf(entry->userName, sizeof(entry->userName), "%s", userName); //将userName数据赋给结构体entry->userName_len = userName_len; //将userName_len数据赋给结构体entry->userAge = userAge; //将userAge数据赋值给结构体entry->next = userTable_head;userTable_head = entry;return entry;
}/** remove a row from the table */
void
userTable_removeEntry(struct userTable_entry *entry)
{struct userTable_entry *ptr, *prev;if (!entry)return;                 /* Nothing to remove */for (ptr = userTable_head, prev = NULL;ptr != NULL; prev = ptr, ptr = ptr->next) {if (ptr == entry)break;}if (!ptr)return;                 /* Can't find it */if (prev == NULL)userTable_head = ptr->next;elseprev->next = ptr->next;SNMP_FREE(entry);           /* XXX - release any other internal resources */
}#define STRMAX 1024 //定义宏
/** Example cache handling - set up linked list from a suitable file */
int
userTable_load(netsnmp_cache * cache, void *vmagic)
{FILE           *fp;struct userTable_entry *this;char            buf[STRMAX];/** The basic load routine template assumes that the data to* be reported is held in a file - with one row of the file* for each row of the table.* If your data is available via a different API, you* should amend this initial block (and the control of the* 'while' loop) accordingly.* 'XXX' marks where the template is incomplete and* code will definitely need to be added. */fp = fopen("/data/for/userTable", "r");if (!fp) {return -1;}while (fgets(buf, STRMAX, fp)) {this = SNMP_MALLOC_TYPEDEF(struct userTable_entry);/** XXX - Unpick 'buf' to extract the individual field values* and then populate the 'this' data structure with them */this->next = userTable_head;userTable_head = this;  /* Iterate helper is fine with unordered lists! */}fclose(fp);return 0;                   /* OK */
}void
userTable_free(netsnmp_cache * cache, void *vmagic)
{struct userTable_entry *this, *that;for (this = userTable_head; this; this = that) {that = this->next;SNMP_FREE(this);        /* XXX - release any other internal resources */}userTable_head = NULL;
}/** Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
userTable_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 = userTable_head;return userTable_get_next_data_point(my_loop_context, my_data_context,put_index_data, mydata);
}netsnmp_variable_list *
userTable_get_next_data_point(void **my_loop_context,void **my_data_context,netsnmp_variable_list * put_index_data,netsnmp_iterator_info *mydata)
{struct userTable_entry *entry =(struct userTable_entry *) *my_loop_context;netsnmp_variable_list *idx = put_index_data;if (entry) {snmp_set_var_typed_integer(idx, ASN_INTEGER, entry->userIdx);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 userTable table */
int
userTable_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 userTable_entry *table_entry;struct userTable_entry *table_row; //这个变量未定义int ret; //变量未定义DEBUGMSGTL(("myModule:handler", "Processing request (%d)\n",reqinfo->mode));switch (reqinfo->mode) {/** Read-support (also covers GetNext requests)*/case MODE_GET:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERIDX:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userIdx);break;case COLUMN_USERNAME:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,table_entry->userName,table_entry->userName_len);break;case COLUMN_USERAGE:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userAge);break;case COLUMN_USERROWSTATUS:if (!table_entry) {netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHINSTANCE);continue;}snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,table_entry->userRowStatus);break;default:netsnmp_set_request_error(reqinfo, request,SNMP_NOSUCHOBJECT);break;}}break;/** Write-support*/case MODE_SET_RESERVE1:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:/** or possibly 'netsnmp_check_vb_type_and_size' */ret =netsnmp_check_vb_type_and_max_size(request->requestvb,ASN_OCTET_STR,sizeof(table_entry->userName));if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;case COLUMN_USERAGE:/** or possibly 'netsnmp_check_vb_int_range' */ret = netsnmp_check_vb_int(request->requestvb);if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;case COLUMN_USERROWSTATUS:ret = netsnmp_check_vb_rowstatus(request->requestvb,(table_entry ? RS_ACTIVE :RS_NONEXISTENT));if (ret != SNMP_ERR_NOERROR) {netsnmp_set_request_error(reqinfo, request, ret);return SNMP_ERR_NOERROR;}break;default:netsnmp_set_request_error(reqinfo, request,SNMP_ERR_NOTWRITABLE);return SNMP_ERR_NOERROR;}}break;case MODE_SET_RESERVE2:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:table_row =userTable_createEntry(*table_info->indexes->val.integer,"",0,0); //补全,这里是创建一个新的行if (table_row) {netsnmp_insert_iterator_context(request,table_row);} else {netsnmp_set_request_error(reqinfo, request,SNMP_ERR_RESOURCEUNAVAILABLE);return SNMP_ERR_NOERROR;}}}}break;case MODE_SET_FREE:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:if (table_entry && !table_entry->valid) {userTable_removeEntry(table_row); //多传了table_data参数,删除}}}}break;case MODE_SET_ACTION:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:memcpy(table_entry->old_userName,table_entry->userName,sizeof(table_entry->userName));table_entry->old_userName_len = table_entry->userName_len;memset(table_entry->userName, 0,sizeof(table_entry->userName));memcpy(table_entry->userName,request->requestvb->val.string,request->requestvb->val_len);table_entry->userName_len = request->requestvb->val_len;break;case COLUMN_USERAGE:table_entry->old_userAge = table_entry->userAge;table_entry->userAge = *request->requestvb->val.integer;break;}}/** Check the internal consistency of an active row */for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_ACTIVE:case RS_CREATEANDGO:if ( 0/* 出错条件 */ ) {netsnmp_set_request_error(reqinfo, request,SNMP_ERR_INCONSISTENTVALUE);return SNMP_ERR_NOERROR;}}}}break;case MODE_SET_UNDO:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERNAME:memcpy(table_entry->userName,table_entry->old_userName,sizeof(table_entry->userName));memset(table_entry->old_userName, 0,sizeof(table_entry->userName));table_entry->userName_len = table_entry->old_userName_len;break;case COLUMN_USERAGE:table_entry->userAge = table_entry->old_userAge;table_entry->old_userAge = 0;break;case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:case RS_CREATEANDWAIT:if (table_entry && !table_entry->valid) {userTable_removeEntry(table_row); //多传了table_data参数,删除}}break;}}break;case MODE_SET_COMMIT:for (request = requests; request; request = request->next) {table_entry = (struct userTable_entry *)netsnmp_extract_iterator_context(request);table_info = netsnmp_extract_table_info(request);switch (table_info->colnum) {case COLUMN_USERROWSTATUS:switch (*request->requestvb->val.integer) {case RS_CREATEANDGO:table_entry->valid = 1;/** Fall-through */case RS_ACTIVE:table_entry->userRowStatus = RS_ACTIVE;break;case RS_CREATEANDWAIT:table_entry->valid = 1;/** Fall-through */case RS_NOTINSERVICE:table_entry->userRowStatus = RS_NOTINSERVICE;break;case RS_DESTROY:userTable_removeEntry(table_entry); //修改table_row为table_entry,否则删除行不成功, 多传了table_data参数,删除}}}break;}return SNMP_ERR_NOERROR;
}

三、载入自定义的MIB库
1、将myModule.h 和修改后的myModule.c文件复制到linux机器的net-snmp-5.7.1/agent/mibgroup/目录下


2、如果snmp服务在运行,停止snmp服务

3、在/root/net-snmp-5.7.1目录下依次执行下面3个命令编译安装

./configure --prefix=/usr/local/snmp --with-mib-modules=“myModule”

make && make install

四、测试

1、执行/usr/local/snmp/sbin/snmpd -c /usr/local/snmp/etc/snmpd.conf 命令启动snmp服务

2、执行/usr/local/snmp/bin/snmpwalk -v 2c -c public localhost 1.3.6.1.4.1.85.1.1查看表格内容,可以看到表里什么都没有

3、添加第一行数据:/usr/local/snmp/bin/snmpset -v 2c -c public localhost 1.3.6.1.4.1.85.1.1.1.4.1 i 4

这个命令表示对表的第一行的第三列设置值为4,因为第三列为RowStatus类型,所以系统会创建这一行

(表中原本是没有第一行的,只要对第一行的RowStatus列写入4就可以创建这一行)

4、修改第一行数据中的userName字段:/usr/local/snmp/bin/snmpset -v 2c -c public localhost 1.3.6.1.4.1.85.1.1.1.2.1 s harara


5、修改第一行数据中的userAge字段:/usr/local/snmp/bin/snmpset -v 2c -c public localhost 1.3.6.1.4.1.85.1.1.1.3.1 i 24

6、删除第1行,对第1行的第4列写入6即可:/usr/local/snmp/bin/snmpset -v 2c -c public localhost 1.3.6.1.4.1.85.1.1.1.4.1 i 6

【snmp】net-snmp添加自定义MIB(表格)相关推荐

  1. 添加自定义MIB的三种方法

    我所知道的添加自定义MIB的方法有三种 1.静态加载,将生成的.c和.h文件加入到相应的位置,重新编译snmp库,优点是不需要修改配置文件,缺点是每次添加都得重新编译: 2.动态加载,将生成的.c和. ...

  2. mysql snmp agent_WebNMS SNMP Micro Agent for MySQL - MySQL Management Console

    主页 > SNMP Micro Agent for MySQL WebNMS SNMP Micro Agent for MySQL™ MySQL数据库服务器是世界上应用最普遍的开放式源码数据库. ...

  3. SNMP介绍, OID及MIB库

    1 SNMP概览 1.1 SNMP的基本知识介绍 简单网络管理协议(SNMP-Simple Network Management Protocol)是一个与网络设备交互的简单方法.该规范是由IETF在 ...

  4. linux下的SNMP设置(snmp get/set/trap)

    本文不讲解snmp理论知识,只讲解在linux下环境的配置.(方便服务器SNMP测试) 以rhel8为例: 1.NetSnmp 工具安装 Linux 安装 netsnmp 采用在线安装的方式(确保测试 ...

  5. 串口服务器支持SNMP,支持SNMP的串口服务器——上海卓岚

    支持SNMP协议的串口服务器 发布时间:2013-05-22 作者:上海卓岚 浏览量:4284 1.为什么串口服务器需要SNMP SNMP是简单网管协议的简称.SNMP协议由于其可扩展性好,简单易用, ...

  6. 服务器安装snmp协议,snmp协议在windows下的安装与配置

    SNMP(Simple Network Management Protocol,简单网络管理协议,对于服务器运维,服务器管理来说这个协议是必不可少的,小编从网络上发现一些关于snmp协议在window ...

  7. 基于SNMP的MIB库访问实现的研究

    蔡国森 (北京工商大学  计算机学院) 摘要  SNMP是用于网络管理/代理之间的请求/应答协议.管理信息库(MIB)定义了由代理者维护的各种变量,它们由管理者来进行存取操作,从而实现具体的网络管理. ...

  8. [转]基于SNMP的MIB库访问实现的研究

    蔡国森 (北京工商大学 计算机学院) 摘要 SNMP是用于网络管理/代理之间的请求/应答协议.管理信息库(MIB)定义了由代理者维护的各种变量,它们由管理者来进行存取操作,从而实现具体的网络管理.本文 ...

  9. SNMP、MIB、OID概念的理解

    为什么80%的码农都做不了架构师?>>>    1.1. SNMP概览 SNMP的基本知识介绍 简单网络管理协议(SNMP-Simple Network Management Pro ...

最新文章

  1. dSploitzANTI渗透教程之HTTP服务重定向地址
  2. 操作系统课设--具有优先级的线程调度
  3. 课时 30:理解 RuntimeClass 与使用多容器运行时(贾之光)
  4. python中类中属性和方法的具体定义方法和使用
  5. java 调用.net webservice axis2_java利用axis2调用.net写的webservice,传递自定义的实体类参数...
  6. IntelliJ IDEA forMac 如何生成项目的javadoc(API文档)
  7. 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别
  8. python读取图像并相加_python给图像加上mask,并提取mask区域实例
  9. python随机猜数字游戏_Python小游戏——猜数字教程(random库教程)
  10. Apache Solr solrconfig.xml 中文说明
  11. OCR证件识别及其衍生产品介绍
  12. baocms7.0版本一元云购报错Call-time pass-by-reference has been removed处理办法
  13. 2020幻影围棋 第三天围棋规则模块(一)
  14. 树莓派开箱+上手python小游戏
  15. HP M132snw 打印机如何在换路由器的时候更换整个局域网配置?
  16. MySQL、SQL Server、Hive对时间格式化
  17. 单片机 stm32 差分升级 增量升级算法源码
  18. 我多想时光都可以典当,你回来带我赎回过往
  19. 程序员敲诈老板,或面临37年监禁
  20. DRV8870/A4950/AT8870(3.6A单通道刷式直流电机驱动IC)

热门文章

  1. Rime Squirrel 鼠须管输入法配置详解
  2. 杭电操作系统实验二---linux内核模块编译(完整实验报告)
  3. win11 centos7 NAT配置 及无法连接目标主机或响应超时
  4. H5视差滑屏,Swiper的Parallax属性
  5. PE-CE路由协议(OSPF)
  6. 基于JAVA软件测试过程管理计算机毕业设计源码+数据库+lw文档+系统+部署
  7. 头部企业走入无人区,国产数智化厂商挑大梁
  8. Delphi Excel 操作大全【CreateOleObject( 'Excel.Application' )】
  9. kindeditor 加载 html,kindeditor配置
  10. Java线程池ThreadPool详解