net-snmp扩展table类型的私有mib

时间:2023-02-04 11:19:19


注:本文介绍的是静态编译的方法扩展的私有mib,别的方法请看本人整理的《 net-snmp agent开发(用net-snmp扩展MIB库)

1. 首先创建一个简单的含有table变量的mib文件取名test.mib,后缀名也可以是.txt 实际操作没有区别;

TEST-DEVICE-MIB DEFINITIONS ::= BEGIN

IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, TimeTicks FROM SNMPv2-SMI
DisplayString, FROM SNMPv2-TC
enterprises
FROM RFC1155-SMI;
test OBJECT IDENTIFIER ::= { enterprises 1000 }


Device OBJECT IDENTIFIER ::= { test 1 }

boardSlotTable OBJECT-TYPE
SYNTAX SEQUENCE OF BoardSlotEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION " Fan status description table "
::= { Device 2 }


boardSlotEntry OBJECT-TYPE
SYNTAX BoardSlotEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION " Boad status description table entry "
INDEX { boardSlotID }
::= { boardSlotTable 1}


BoardSlotEntry::=
SEQUENCE {
boardSlotID INTEGER,
boardType INTEGER,
boardSeriesNumber DisplayString,
}

boardSlotID OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION " Slot ID "
::= { boardSlotEntry 1 }

--add enum value
boardType OBJECT-TYPE
SYNTAX INTEGER
MAX-ACCESS read-only
STATUS current
DESCRIPTION " Slot Number "
::= { boardSlotEntry 2 }

boardSeriesNumber OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION " Slot Series Number "
::= { boardSlotEntry 3 }

boardWorkMode OBJECT-TYPE
SYNTAX INTEGER
{
normal (1),
abnormal (2),
offline (3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION " Board Status: normal (1), abnormal (2) and offline (3)"
::= { boardSlotEntry 4 }

END
2. 将创建好的mib文件放入默认中,一般默认目录为/usr/local/net-snmp, 或者放到别的目录中,在配置文件snmpd.conf中增加 mibs +/home//mibs/mytable test.mib,或者直接修改默认的mib路径。

3.使用mib2c -c mib2c.iterate.conf TEST-DEVICE-MIB::boardSlotTable命令生成相应的.c和.h文件,选择1时提供一个缓存来提取数据,一定时间后将更新一次数据,2每次更新,选2生成的代码如下。如果该命令出错(ERROR: You don't have the SNMP perl module installed.  Please obtain
this by getting the latest source release of the net-snmp toolkit from
http://www.net-snmp.org/download/ .  Once you download the source and
unpack it, the perl module is contained in the perl/SNMP directory.
See the README file there for instructions.)请正常make    make install重新安装net-snmp,原因未知。

/*
* 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 "boardSlotTable.h"

/** Initializes the boardSlotTable module */
void
init_boardSlotTable(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_boardSlotTable();
}

# Determine the first/last column names

/** Initialize the boardSlotTable table by defining its contents and how it's structured */
void
initialize_table_boardSlotTable(void)
{
const oid boardSlotTable_oid[] = {1,3,6,1,4,1,1000,1,2};
const size_t boardSlotTable_oid_len = OID_LENGTH(boardSlotTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;

DEBUGMSGTL(("boardSlotTable:init", "initializing table boardSlotTable\n"));

reg = netsnmp_create_handler_registration(
"boardSlotTable", boardSlotTable_handler,
boardSlotTable_oid, boardSlotTable_oid_len,
HANDLER_CAN_RONLY
);

table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: boardSlotID */
0);
table_info->min_column = COLUMN_BOARDSLOTID;
table_info->max_column = COLUMN_BOARDWORKMODE;

iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = boardSlotTable_get_first_data_point;
iinfo->get_next_data_point = boardSlotTable_get_next_data_point;
iinfo->table_reginfo = table_info;

netsnmp_register_table_iterator( reg, iinfo );

/* Initialise the contents of the table here */
}

/* Typical data structure for a row entry */
struct boardSlotTable_entry {
/* Index values */
long boardSlotID;

/* Column values */
long boardSlotID;
long boardType;
char boardSeriesNumber[NNN];
size_t boardSeriesNumber_len;
long boardWorkMode;

/* Illustrate using a simple linked list */
int valid;
struct boardSlotTable_entry *next;
};

struct boardSlotTable_entry *boardSlotTable_head;

/* create a new row in the (unsorted) table */
struct boardSlotTable_entry *
boardSlotTable_createEntry(
long boardSlotID,
) {
struct boardSlotTable_entry *entry;

entry = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
if (!entry)
return NULL;

entry->boardSlotID = boardSlotID;
entry->next = boardSlotTable_head;
boardSlotTable_head = entry;
return entry;
}

/* remove a row from the table */
void
boardSlotTable_removeEntry( struct boardSlotTable_entry *entry ) {
struct boardSlotTable_entry *ptr, *prev;

if (!entry)
return; /* Nothing to remove */

for ( ptr = boardSlotTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */

if ( prev == NULL )
boardSlotTable_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 *
boardSlotTable_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 = boardSlotTable_head;
return boardSlotTable_get_next_data_point(my_loop_context, my_data_context,
put_index_data, mydata );
}

netsnmp_variable_list *
boardSlotTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct boardSlotTable_entry *entry = (struct boardSlotTable_entry *)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;

if ( entry ) {
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->boardSlotID );
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 boardSlotTable table */
int
boardSlotTable_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 boardSlotTable_entry *table_entry;

DEBUGMSGTL(("boardSlotTable: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 boardSlotTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);

switch (table_info->colnum) {
case COLUMN_BOARDSLOTID:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->boardSlotID);
break;
case COLUMN_BOARDTYPE:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->boardType);
break;
case COLUMN_BOARDSERIESNUMBER:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->boardSeriesNumber,
table_entry->boardSeriesNumber_len);
break;
case COLUMN_BOARDWORKMODE:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;

}
return SNMP_ERR_NOERROR;
}
4. 修改后的.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 "boardSlotTable.h"

struct boardSlotTable_entry * boardSlotTable_createEntry(
long boardSlotID,
long boardType,
char boardSeriesNumber[20],
size_t boardSeriesNumber_len
); //ÉùÃ÷һϸú¯Êý
/** Initializes the boardSlotTable module */
void
init_boardSlotTable(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_boardSlotTable();
}

//# Determine the first/last column names

/** Initialize the boardSlotTable table by defining its contents and how it's structured */
void
initialize_table_boardSlotTable(void)
{
const oid boardSlotTable_oid[] = {1,3,6,1,4,1,1000,1,2};
const size_t boardSlotTable_oid_len = OID_LENGTH(boardSlotTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;

DEBUGMSGTL(("boardSlotTable:init", "initializing table boardSlotTable\n"));

reg = netsnmp_create_handler_registration(
"boardSlotTable", boardSlotTable_handler,
boardSlotTable_oid, boardSlotTable_oid_len,
HANDLER_CAN_RONLY
);

table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: boardSlotID */
0);
table_info->min_column = COLUMN_BOARDSLOTID;
table_info->max_column = COLUMN_BOARDSERIESNUMBER;

iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = boardSlotTable_get_first_data_point;
iinfo->get_next_data_point = boardSlotTable_get_next_data_point;
iinfo->table_reginfo = table_info;

netsnmp_register_table_iterator( reg, iinfo );

/* Initialise the contents of the table here */
boardSlotTable_createEntry(1,1,"1 1 1",sizeof("1 1 1"));//µÚÒ»¸öË÷ÒýÖµ¸³Öµ£¬±ØÐëÌí¼Ó
}

/* Typical data structure for a row entry */
struct boardSlotTable_entry {
/* Index values */
long boardSlotID;

/* Column values */
long boardType;
char boardSeriesNumber[20];
size_t boardSeriesNumber_len;

/* Illustrate using a simple linked list */
int valid;
struct boardSlotTable_entry *next;
};

struct boardSlotTable_entry *boardSlotTable_head;

/* create a new row in the (unsorted) table */
struct boardSlotTable_entry *
boardSlotTable_createEntry(
long boardSlotID,
long boardType,
char boardSeriesNumber[20],
size_t boardSeriesNumber_len
) {
struct boardSlotTable_entry *entry1;
struct boardSlotTable_entry *entry2;
struct boardSlotTable_entry *entry3; //ÉùÃ÷Èý¸öË÷Òý£¬ÉùÃ÷¶àµÄ¿ÉÒÔÒÀ´ÎÔö¼Ó

entry1 = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
entry2 = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
entry3 = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);

if (!entry1 || !entry2 || !entry3)
return NULL;

entry1->boardSlotID = boardSlotID;
entry1->boardType = boardType;
memcpy(entry1->boardSeriesNumber, boardSeriesNumber, boardSeriesNumber_len);
entry1->boardSeriesNumber_len = boardSeriesNumber_len;

entry2->boardSlotID = 2;
entry2->boardType = 2;
memcpy(entry2->boardSeriesNumber, "222", sizeof("222"));
entry2->boardSeriesNumber_len = sizeof("222");

entry3->boardSlotID = 3;
entry3->boardType = 3;
memcpy(entry3->boardSeriesNumber, "333", sizeof("333"));
entry3->boardSeriesNumber_len = sizeof("333");

entry1->next = entry2;
entry2->next = entry3;
entry3->next = boardSlotTable_head;
boardSlotTable_head = entry1;
return entry1;
}

/* remove a row from the table */
void
boardSlotTable_removeEntry( struct boardSlotTable_entry *entry ) {
struct boardSlotTable_entry *ptr, *prev;

if (!entry)
return; /* Nothing to remove */

for ( ptr = boardSlotTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */

if ( prev == NULL )
boardSlotTable_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 *
boardSlotTable_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 = boardSlotTable_head;
return boardSlotTable_get_next_data_point(my_loop_context, my_data_context,
put_index_data, mydata );
}

netsnmp_variable_list *
boardSlotTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct boardSlotTable_entry *entry = (struct boardSlotTable_entry *)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;

if ( entry ) {
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->boardSlotID );
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 boardSlotTable table */
int
boardSlotTable_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 boardSlotTable_entry *table_entry;

DEBUGMSGTL(("boardSlotTable: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 boardSlotTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);

switch (table_info->colnum) {
case COLUMN_BOARDSLOTID:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->boardSlotID);
break;
case COLUMN_BOARDTYPE:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->boardType);
break;
case COLUMN_BOARDSERIESNUMBER:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->boardSeriesNumber,
table_entry->boardSeriesNumber_len);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;

}
return SNMP_ERR_NOERROR;
}
5.然后把相应的.c和.h文件添加到net-snmp源码里的 agent/mibgroup路径下,在configure的时候添加   --with-mib-modules="boardSlotTable"选项,如果有多个table,则可以再mibgroup中创建一个文件夹例如testMIB文件夹,然后把相应的.c和.h文件都移到testMIB文件夹下,然后在mibgroup路径下新建一个test.h文件,添加config_require(testMIB/boardSlotTable);依次添加,编译的时候添加configure选项为--weith-mib-modules="test"  则可以一次全部编译;最后make   make install

6.输入命令则可以获取到相应数据

[root@localhost sbin]# snmpwalk -c public -v1 localhost .1.3.6.1.4.1.1000
SNMPv2-SMI::enterprises.1000.1.2.1.1.1 = INTEGER: 1
SNMPv2-SMI::enterprises.1000.1.2.1.1.2 = INTEGER: 2
SNMPv2-SMI::enterprises.1000.1.2.1.1.3 = INTEGER: 3
SNMPv2-SMI::enterprises.1000.1.2.1.2.1 = INTEGER: 1
SNMPv2-SMI::enterprises.1000.1.2.1.2.2 = INTEGER: 2
SNMPv2-SMI::enterprises.1000.1.2.1.2.3 = INTEGER: 3
SNMPv2-SMI::enterprises.1000.1.2.1.3.1 = Hex-STRING: 31 20 31 20 31 00 
SNMPv2-SMI::enterprises.1000.1.2.1.3.2 = Hex-STRING: 32 32 32 00 
SNMPv2-SMI::enterprises.1000.1.2.1.3.3 = Hex-STRING: 33 33 33 00