设计MIB文件mytableTest-MIB.txt:
myTestTable DEFINITIONS ::= BEGIN
IMPORTS
OBJECT-GROUP, MODULE-COMPLIANCE, NOTIFICATION-GROUP
FROM SNMPv2-CONF
enterprises, Integer32, Unsigned32, OBJECT-TYPE, MODULE-IDENTITY,
NOTIFICATION-TYPE
FROM SNMPv2-SMI
DisplayString
FROM SNMPv2-TC
dell-OID-three
FROM dellRX-MIB;
-- 1.3.6.1.4.1.10000
myTable-MIB MODULE-IDENTITY
LAST-UPDATED "201412151450Z"
ORGANIZATION
"Actiontec Shenzhen team Surpas"
CONTACT-INFO
"Surpas HC(editor)
Email: <[email protected]>"
DESCRIPTION
"For Dell project MIB pdmGeneral."
::= { enterprises 10000 }
--testID OBJECT IDENTIFIER ::= { pdmGeneral 2 }
--1.3.6.1.4.1.10000.1
testTableRoot OBJECT IDENTIFIER ::= { myTable-MIB 1 }
--1.3.6.1.4.1.10000.1.1
tcTable OBJECT-TYPE
SYNTAX SEQUENCE OF TcEntry
MAX-ACCESS not-accessible
STATUS current
::= { testTableRoot 1 }
--1.3.6.1.4.1.10000.1.1.1
tcEntry OBJECT-TYPE
SYNTAX TcEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Information about a particular current UDP endpoint."
INDEX { tcIndex }--很重要,snmpwalk时的节点号。
::= { tcTable 1 }
TcEntry ::= SEQUENCE {
tcIndex Interger32
tcString DisplayString (SIZE (0..100)),
tcinteger Integer32
}
--1.3.6.1.4.1.10000.1.1.1.1
tcIndex OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The address type of accepted."
DEFVAL { "xxx table Index xxx!" }
::= { tcEntry 1 }
--1.3.6.1.4.1.10000.1.1.1.2
tcString OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..100))
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The address type of accepted."
DEFVAL { "xxx table row string1 xxx!" }
::= { tcEntry 2 }
--1.3.6.1.4.1.10000.1.1.1.3
tcInteger OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The address type of accepted."
DEFVAL { 6543 }
::= { tcEntry 3 }
END
将MIB文件mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs并且在目录/usr/local/etc/snmp:/usr/local/share/snmp:/usr/local/lib/snmp:/home/actiontec/.snmp:/var/net-snmp添加snmp.conf文件,添加内容:
#mibs +/home/actiontec/.snmp/mibs/xxx.txt
mibs +/home/actiontec/.snmp/mibs/mytableTest-MIB.txt
使用snmptranslate -Tp -IR myTestTable::testTableRoot(前提mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs下)或者用snmptranslate -Tp -IR testTableRoot(mytableTest-MIB.txt放到MIB search path: /home/actiontec/.snmp/mibs:/usr/local/share/snmp/mibs并且在目录/usr/local/etc/snmp:/usr/local/share/snmp:/usr/local/lib/snmp:/home/actiontec/.snmp:/var/net-snmp添加snmp.conf文件添加内容mibs +/home/actiontec/.snmp/mibs/mytableTest-MIB.txt)查看有无错误。
+--testTableRoot(1)
|
+--tcTable(1)
|
+--tcEntry(1)
| Index: tcIndex
|
+-- ---- Integer32 tcIndex(1)
+-- -RW- String tcString(2)
| Textual Convention: DisplayString
| Size: 0..100
+-- -RW- Integer32 tcInteger(3)
生成代码mib2c -c mib2c.iterate.conf myTestTable::testTableRoot或者mib2c -c mib2c.iterate.conf testTableRoot
选择1时提供一个缓存来提取数据,一定时间后将更新一次数据,2每次更新
编译代码net-snmp-config --compile-subagent Test testTableRoot.c,设计是否有误
将testTableRoot.c和头文件放到agent/mibgroup/newdir中。建立文件agent/mibgroup/newdir.h添加内容:config_require(newdir/testTableRoot);用于./configure时用。
testTableRoot.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 "testTableRoot.h"
#define MY_ERROR_FILE "/home/actiontec/install-dir/net-snmp/errdir/errtablefile.txt"
/** Initializes the testTableRoot module */
void
init_testTableRoot(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_tcTable();
}
// # Determine the first/last column names
/** Initialize the tcTable table by defining its contents and how it's structured */
void
initialize_table_tcTable(void)
{
const oid tcTable_oid[] = {1,3,6,1,4,1,10000,1,1};
const size_t tcTable_oid_len = OID_LENGTH(tcTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
DEBUGMSGTL(("testTableRoot:init", "initializing table tcTable\n"));
reg = netsnmp_create_handler_registration(
"tcTable", tcTable_handler,
tcTable_oid, tcTable_oid_len,
HANDLER_CAN_RWRITE
);
table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: tcIndex */
0);
table_info->min_column = COLUMN_TCSTRING;
table_info->max_column = COLUMN_TCINTEGER;
iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = tcTable_get_first_data_point;
iinfo->get_next_data_point = tcTable_get_next_data_point;
iinfo->table_reginfo = table_info;
netsnmp_register_table_iterator( reg, iinfo );
tcTable_createEntry(1, "xiaolongxxxwo", sizeof("xiaolongxxxwo"), 556);
//这句话很重要,必须创建一个表对象才可以访问他
/* Initialise the contents of the table here */
}
/* Typical data structure for a row entry */
struct tcTable_entry {
/* Index values */
long tcIndex;
/* Column values */
char tcString[64];
size_t tcString_len;
char old_tcString[64];
size_t old_tcString_len;
long tcInteger;
long old_tcInteger;
/* Illustrate using a simple linked list */
int valid;
struct tcTable_entry *next;
};
struct tcTable_entry *tcTable_head;
/* create a new row in the (unsorted) table */
struct tcTable_entry *
tcTable_createEntry(
long tcIndex,
char* tcString,
size_t tcString_len,
long tcInteger
) {
struct tcTable_entry *entry;
struct tcTable_entry *entryNext;
entry = SNMP_MALLOC_TYPEDEF(struct tcTable_entry);
entryNext = SNMP_MALLOC_TYPEDEF(struct tcTable_entry);
if (!entry)
return NULL;
//胡乱添加的,这里设计了1,2节点,一会看效果就知道作用了
entry->tcIndex = tcIndex;
memcpy(entry->tcString, tcString, tcString_len);
entry->tcString_len = tcString_len;
entry->tcInteger = tcInteger;
entryNext->tcIndex = 2;
memcpy(entryNext->tcString, "abcdefg", sizeof("abcdefg"));
entryNext->tcString_len = sizeof("abcdefg");
entryNext->tcInteger = 321;
entry->next = entryNext;
entryNext->next = tcTable_head;
tcTable_head = entry;
return entry;
}
/* remove a row from the table */
void
tcTable_removeEntry( struct tcTable_entry *entry ) {
struct tcTable_entry *ptr, *prev;
if (!entry)
return; /* Nothing to remove */
for ( ptr = tcTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */
if ( prev == NULL )
tcTable_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 *
tcTable_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 = tcTable_head;
return tcTable_get_next_data_point(my_loop_context, my_data_context,
put_index_data, mydata );
}
netsnmp_variable_list *
tcTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct tcTable_entry *entry = (struct tcTable_entry *)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;
if ( entry ) {
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->tcIndex );
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 tcTable table */
int
tcTable_handler(
netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests) {
int ret;
netsnmp_request_info *request;
netsnmp_table_request_info *table_info;
struct tcTable_entry *table_entry;
FILE *fd;
DEBUGMSGTL(("myTable_MIB:handler", "Processing request (%d)\n", reqinfo->mode));
fd = fopen(MY_ERROR_FILE, "ar");
if(fd>0)
{
fprintf(fd, "surpas:%s,%d,mode=%d!\n", __FILE__, __LINE__, reqinfo->mode);
fclose(fd);
}
switch (reqinfo->mode) {
/*
* Read-support (also covers GetNext requests)
*/
case MODE_GET:
for (request=requests; request; request=request->next) {
table_entry = (struct tcTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_TCSTRING:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->tcString,
table_entry->tcString_len);
break;
case COLUMN_TCINTEGER:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->tcInteger);
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 tcTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_TCSTRING:
/* or possibly 'netsnmp_check_vb_type_and_size' */
ret = netsnmp_check_vb_type_and_max_size(
request->requestvb, ASN_OCTET_STR, sizeof(table_entry->tcString));
if ( ret != SNMP_ERR_NOERROR ) {
netsnmp_set_request_error( reqinfo, request, ret );
return SNMP_ERR_NOERROR;
}
break;
case COLUMN_TCINTEGER:
/* 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;
default:
netsnmp_set_request_error( reqinfo, request,
SNMP_ERR_NOTWRITABLE );
return SNMP_ERR_NOERROR;
}
}
break;
case MODE_SET_RESERVE2:
break;
case MODE_SET_FREE:
break;
case MODE_SET_ACTION:
for (request=requests; request; request=request->next) {
table_entry = (struct tcTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
//here change our own configure
switch (table_info->colnum) {
case COLUMN_TCSTRING:
memcpy( table_entry->old_tcString,
table_entry->tcString,
sizeof(table_entry->tcString));
table_entry->old_tcString_len =
table_entry->tcString_len;
memset( table_entry->tcString, 0,
sizeof(table_entry->tcString));
memcpy( table_entry->tcString,
request->requestvb->val.string,
request->requestvb->val_len);
table_entry->tcString_len =
request->requestvb->val_len;
break;
case COLUMN_TCINTEGER:
table_entry->old_tcInteger = table_entry->tcInteger;
table_entry->tcInteger = *request->requestvb->val.integer;
break;
}
}
break;
case MODE_SET_UNDO:
for (request=requests; request; request=request->next) {
table_entry = (struct tcTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_TCSTRING:
memcpy( table_entry->tcString,
table_entry->old_tcString,
sizeof(table_entry->tcString));
memset( table_entry->old_tcString, 0,
sizeof(table_entry->tcString));
table_entry->tcString_len =
table_entry->old_tcString_len;
break;
case COLUMN_TCINTEGER:
table_entry->tcInteger = table_entry->old_tcInteger;
table_entry->old_tcInteger = 0;
break;
}
}
break;
case MODE_SET_COMMIT:
break;
}
return SNMP_ERR_NOERROR;
}
我们先看下7的效果,在create里面可以添加列表的:
myTestTable::tcString.1 = STRING: xiaolongxxxwo.
myTestTable::tcString.2 = STRING: abcdefg.
myTestTable::tcInteger.1 = INTEGER: 556
myTestTable::tcInteger.2 = INTEGER: 321
SNMPv2-SMI::enterprises.10000.1.1.1.2.1 = Hex-STRING: 78 69 61 6F 6C 6F 6E 67 78 78 78 77 6F 00
SNMPv2-SMI::enterprises.10000.1.1.1.2.2 = Hex-STRING: 61 62 63 64 65 66 67 00
SNMPv2-SMI::enterprises.10000.1.1.1.3.1 = INTEGER: 556
SNMPv2-SMI::enterprises.10000.1.1.1.3.2 = INTEGER: 321
完成了,先进行编译:./configure --with-default-snmp-version="3" --with-sys-contact="@@no.where" --with-sys-location="Unknown" --with-logfile="/var/log/snmpd.log" --with-persistent-directory="/var/net-snmp" --with-mib-modules="newdir" --enable-mini-agent(mini版)
makesudo make install