(一)编写MIBS
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..128))
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
写完之后将其加入到snmp.conf中(即在conf文件里加mibs +xxx, xxx指的是自己定义的BEGIN名称),如这里的定义的名称是
TEST-DEVICE-MIB。
TEST-DEVICE-MIB DEFINITIONS ::= BEGIN
然后通过命令
snmptranslate -Tp -IR TEST-DEVICE-MIB::Device
Note:Device是自定义Module名称
验证是否成功添加MIB:
+--Device(1)
|
+--boardSlotTable(2)
|
+--boardSlotEntry(1)
| Index: boardSlotID
|
+-- -R-- INTEGER boardSlotID(1)
+-- -R-- INTEGER boardType(2)
+-- -R-- String boardSeriesNumber(3)
| Textual Convention: DisplayString
| Size: 0..128
+-- -R-- EnumVal boardWorkMode(4)
Values: normal(1), abnormal(2), offline(3)
出现这个代表已经成功添加到我们的MIB库里。
使用mib2c工具编译。表格使用mib2c.iterate.conf或mib2c.iterate_access.conf。
mib2c mib2c.iterate.conf TEST-DEVICE-MIB::Device
成功会有提示选择编译选项:
You requested mib2c to be run on the following part of the MIB tree:
OID: Device
numeric translation: .1.3.6.1.4.1.1000.1
number of scalars within: 0
number of tables within: 1
number of notifications within: 0
First, do you want to generate code that is compatible with the
ucd-snmp 4.X line of code, or code for the newer Net-SNMP 5.X code
base (which provides a much greater choice of APIs to pick from):
1) ucd-snmp style code
2) Net-SNMP style code
Select your choice :
根据提示选择即可。
继而生成了对应的.c .h文件。
(二)修改代码
生成的.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"
/** 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 );
netsnmp_inject_handler_before( reg,
netsnmp_get_cache_handler(BOARDSLOTTABLE_TIMEOUT,
boardSlotTable_load, boardSlotTable_free,
boardSlotTable_oid, boardSlotTable_oid_len),
TABLE_ITERATOR_NAME);
/* 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 cache handling - set up linked list from a suitable file */
int
boardSlotTable_load( netsnmp_cache *cache, void *vmagic ) {
FILE *fp;
struct boardSlotTable_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/boardSlotTable", "r" );
if ( !fp ) {
return -1;
}
while ( fgets( buf, STRMAX, fp )) {
this = SNMP_MALLOC_TYPEDEF( struct boardSlotTable_entry );
/* XXX - Unpick 'buf' to extract the individual field values
and then populate the 'this' data structure with them */
this->next = boardSlotTable_head;
boardSlotTable_head = this; /* Iterate helper is fine with unordered lists! */
}
fclose(fp);
return 0; /* OK */
}
void
boardSlotTable_free( netsnmp_cache *cache, void *vmagic ) {
struct boardSlotTable_entry *this, *that;
for ( this = boardSlotTable_head; this; this=that ) {
that = this->next;
SNMP_FREE( this ); /* XXX - release any other internal resources */
}
boardSlotTable_head = NULL;
}
/* 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;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->boardWorkMode);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}
修改后:
/*
* 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"
#define SN_SIZE 64
#define STRMAX 128
struct boardSlotTable_entry {
/*
* Index values
*/
// long boardSlotID;
/*
* Column values
*/
long boardSlotID;
long boardType;
char boardSeriesNumber[SN_SIZE];
size_t boardSeriesNumber_len;
long boardWorkMode;
/*
* Illustrate using a simple linked list
*/
int valid;
struct boardSlotTable_entry *next;
};
struct boardSlotTable_entry *boardSlotTable_head;
struct boardSlotTable_entry *
boardSlotTable_createEntry(long boardSlotID,long boardtype,char *boardSeriesNumber,size_t boardSeriesNumber_len)
{
struct boardSlotTable_entry *entry;
/*
struct boardSlotTable_entry *entry1;
struct boardSlotTable_entry *entry2;
*/
entry = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
entry1 = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
entry2 = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
if (!entry || !entry1 || !entry1)
return NULL;
entry->boardSlotID = boardSlotID;
memcpy(entry->boardSeriesNumber,boardSeriesNumber,strlen(boardSeriesNumber));
entry->boardSeriesNumber_len = boardSeriesNumber_len;
entry->boardType = boardtype;
#if 0
entry1->boardSlotID = 2;
//memcpy( entry1->boardSeriesNumber,"TRY-621-1", strlen("TRY-621-1"));
strcpy(entry1->boardSeriesNumber,"TRY-621-1");
entry1->boardSeriesNumber_len =strlen("TRY-621-1");
entry1->boardType = 1;
entry2->boardSlotID = 3;
//memcpy( entry1->boardSeriesNumber,"TRY-621-2", strlen("TRY-621-2"));
strcpy(entry2->boardSeriesNumber,"TRY-621-2");
entry2->boardSeriesNumber_len =strlen("TRY-621-2");
entry2->boardType = 2;
entry->next = entry1;
entry1->next = entry2;
entry2->next = boardSlotTable_head;
boardSlotTable_head = entry;
#endif
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 */
}
/** 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);
netsnmp_inject_handler_before(reg,
netsnmp_get_cache_handler
(BOARDSLOTTABLE_TIMEOUT,
boardSlotTable_load,
boardSlotTable_free, boardSlotTable_oid,
boardSlotTable_oid_len),
TABLE_ITERATOR_NAME);
/*
* Initialise the contents of the table here
*/
boardSlotTable_createEntry(1,0,"TRY-621-0",strlen("TRY-621-0"));
boardSlotTable_createEntry(2,1,"TRY-621-1",strlen("TRY-621-1"));
boardSlotTable_createEntry(3,2,"TRY-621-2",strlen("TRY-621-2"));
boardSlotTable_createEntry(4,3,"TRY-621-3",strlen("TRY-621-3"));
}
/*
* Example cache handling - set up linked list from a suitable file
*/
int
boardSlotTable_load(netsnmp_cache * cache, void *vmagic)
{
FILE *fp;
struct boardSlotTable_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/boardSlotTable", "r");
if (!fp) {
return -1;
}
while (fgets(buf, STRMAX, fp)) {
this = SNMP_MALLOC_TYPEDEF(struct boardSlotTable_entry);
/*
* XXX - Unpick 'buf' to extract the individual field values
* and then populate the 'this' data structure with them
*/
this->next = boardSlotTable_head;
boardSlotTable_head = this; /* Iterate helper is fine with unordered lists! */
}
fclose(fp);
return 0; /* OK */
}
void
boardSlotTable_free(netsnmp_cache * cache, void *vmagic)
{
struct boardSlotTable_entry *this, *that;
for (this = boardSlotTable_head; this; this = that) {
that = this->next;
SNMP_FREE(this); /* XXX - release any other internal resources */
}
boardSlotTable_head = NULL;
}
/*
* 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;
}
snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
net-snmp-config --compile-subagent xxx xxx.c
table_entry->boardWorkMode); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } } break; } return SNMP_ERR_NOERROR;}
(三)生成子代理
net-snmp-config --compile-subagent xxx xxx.c
xxx自定义生成名称,xxx.c为.c代码名字。
(四)测试
运行snmpd和生成的xxx可执行文件。用snmpwalk遍历节点。
snmpwalk -v2c -c public 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.1.4 = INTEGER: 4
SNMPv2-SMI::enterprises.1000.1.2.1.2.1 = INTEGER: 0
SNMPv2-SMI::enterprises.1000.1.2.1.2.2 = INTEGER: 1
SNMPv2-SMI::enterprises.1000.1.2.1.2.3 = INTEGER: 2
SNMPv2-SMI::enterprises.1000.1.2.1.2.4 = INTEGER: 3
SNMPv2-SMI::enterprises.1000.1.2.1.3.1 = STRING: "TRY-621-0"
SNMPv2-SMI::enterprises.1000.1.2.1.3.2 = STRING: "TRY-621-1"
SNMPv2-SMI::enterprises.1000.1.2.1.3.3 = STRING: "TRY-621-2"
SNMPv2-SMI::enterprises.1000.1.2.1.3.4 = STRING: "TRY-621-3"
SNMPv2-SMI::enterprises.1000.1.2.1.11.1 = INTEGER: 0
SNMPv2-SMI::enterprises.1000.1.2.1.11.2 = INTEGER: 0
SNMPv2-SMI::enterprises.1000.1.2.1.11.3 = INTEGER: 0
SNMPv2-SMI::enterprises.1000.1.2.1.11.4 = INTEGER: 0
End:记录下学习的过程