【snmp】net-snmp添加自定义MIB(表格)

【snmp】net-snmp添加自定义MIB(表格)

安装net-snmp见:【snmp】centos6.5安装和配置snmp5.7.1

net-snmp添加自定义MIB(标量):【snmp】net-snmp添加自定义MIB(标量)

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 ::= BEGIN

IMPORTS

OBJECT-GROUP

FROM SNMPv2-CONF

enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY

FROM SNMPv2-SMI;

-- 1.3.6.1.4.1.85

myModule MODULE-IDENTITY

LAST-UPDATED "202008071136Z" -- August 07, 2020 at 11:36 GMT

ORGANIZATION

"Organization."

CONTACT-INFO

"Contact-info."

DESCRIPTION

"Description."

::= { enterprises 85 }

--

-- Node definitions

--

-- 1.3.6.1.4.1.85.1

user OBJECT IDENTIFIER ::= { myModule 1 }

-- 1.3.6.1.4.1.85.1.1

userTable OBJECT-TYPE

SYNTAX SEQUENCE OF UserEntry

MAX-ACCESS not-accessible

STATUS current

DESCRIPTION

"Description."

::= { user 1 }

-- 1.3.6.1.4.1.85.1.1.1

userEntry OBJECT-TYPE

SYNTAX UserEntry

MAX-ACCESS not-accessible

STATUS current

DESCRIPTION

"Description."

INDEX { userIdx }

::= { userTable 1 }

UserEntry ::=

SEQUENCE {

userIdx

Integer32,

userName

Integer32,

userAge

Integer32,

userRowStatus

Integer32

}

-- 1.3.6.1.4.1.85.1.1.1.1

userIdx OBJECT-TYPE

SYNTAX Integer32 (1..1000)

MAX-ACCESS read-only

STATUS current

DESCRIPTION

"Description."

::= { userEntry 1 }

-- 1.3.6.1.4.1.85.1.1.1.2

userName OBJECT-TYPE

SYNTAX Integer32

MAX-ACCESS read-create

STATUS current

DESCRIPTION

"Description."

::= { userEntry 2 }

-- 1.3.6.1.4.1.85.1.1.1.3

userAge OBJECT-TYPE

SYNTAX Integer32

MAX-ACCESS read-create

STATUS current

DESCRIPTION

"Description."

::= { userEntry 3 }

-- 1.3.6.1.4.1.85.1.1.1.4

userRowStatus OBJECT-TYPE

SYNTAX Integer32

MAX-ACCESS read-create

STATUS current

DESCRIPTION

"Description."

::= { userEntry 4 }

-- 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

--

View Code

修改后的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 ::= BEGIN

IMPORTS

OBJECT-GROUP

FROM SNMPv2-CONF

enterprises, Integer32, OBJECT-TYPE, MODULE-IDENTITY

FROM SNMPv2-SMI -- 去掉原来的分号

DisplayString, RowStatus -- 增加这一行

FROM SNMPv2-TC; -- 增加这一行

-- 1.3.6.1.4.1.85

myModule MODULE-IDENTITY

LAST-UPDATED "202008071136Z" -- August 07, 2020 at 11:36 GMT

ORGANIZATION

"Organization."

CONTACT-INFO

"Contact-info."

DESCRIPTION

"Description."

::= { enterprises 85 }

--

-- Node definitions

--

-- 1.3.6.1.4.1.85.1

user OBJECT IDENTIFIER ::= { myModule 1 }

-- 1.3.6.1.4.1.85.1.1

userTable OBJECT-TYPE

SYNTAX SEQUENCE OF UserEntry

MAX-ACCESS read-create -- 修改类型为read-create

STATUS current

DESCRIPTION

"Description."

::= { user 1 }

-- 1.3.6.1.4.1.85.1.1.1

userEntry OBJECT-TYPE

SYNTAX UserEntry

MAX-ACCESS read-create -- 修改类型为read-create

STATUS current

DESCRIPTION

"Description."

INDEX { userIdx }

::= { userTable 1 }

UserEntry ::=

SEQUENCE {

userIdx

Integer32,

userName

OCTET STRING,

userAge

Integer32,

userRowStatus

RowStatus -- 修改类型为RowStatus

}

-- 1.3.6.1.4.1.85.1.1.1.1

userIdx OBJECT-TYPE

SYNTAX Integer32 (1..1000)

MAX-ACCESS read-only -- 根据实际业务修改类型

STATUS current

DESCRIPTION

"Description."

::= { userEntry 1 }

-- 1.3.6.1.4.1.85.1.1.1.2

userName OBJECT-TYPE

SYNTAX OCTET STRING

MAX-ACCESS read-write -- 根据实际业务修改类型

STATUS current

DESCRIPTION

"Description."

::= { userEntry 2 }

-- 1.3.6.1.4.1.85.1.1.1.3

userAge OBJECT-TYPE

SYNTAX Integer32

MAX-ACCESS read-write -- 根据实际业务修改类型

STATUS current

DESCRIPTION

"Description."

::= { userEntry 3 }

-- 1.3.6.1.4.1.85.1.1.1.4

userRowStatus OBJECT-TYPE

SYNTAX RowStatus -- 修改为RowStatus

MAX-ACCESS read-create

STATUS current

DESCRIPTION

"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

#include

#include

#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;

else

prev->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;

}

View Code

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

/*

* Note: this file originally auto-generated by mib2c using

* $

*/

#include

#include

#include

#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;

else

prev->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


摩尔庄园在哪买家具
北京市政交通一卡通“玲珑通卡”正式上线:随用随充、熄屏刷卡、无网可刷,全国 300 + 城通用