I have implemented simple table quite a few times . But I am confused to
implement when the mib contain more than one table and the tables are
nested(means the second table data repeats for each row of first table data,
which I think is very common).
I am using mib2c.iterate.conf to generate the code .
I have extended a hypothetical mib and have used mib2c.iterate.conf to
generate
the code.
Any such nested table implementation for net-snmp . I like to read the code .
Can you point it out ?
I hope , I have to built the memory structure as follows but the generated
code decalres msgVMTable_head as global like the first table messageTable_head.
struct messageTable_entry {
/* Index values */
long messageIndex;
/* Column values */
char messageType[10];
long sentMsgCount;
long errorMsgCount;
long currentMsgID;
/* Illustrate using a simple linked list */
int valid;
struct messageTable_entry *next;
struct msgVMTable_entry *msgVMTable_head;
};
If I declare as above I am struggling to write msgVMTable_createEntry() and
msgVMTable_removeEntry() functions.
I have not understand here . will you please find what's wrong here ?
Thanks
Sujata
/*
* Note: this file originally auto-generated by mib2c using
* : mib2c.iterate.conf 19302 2010-08-13 12:19:42Z dts12 $
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "abcModule.h"
#define STRMAX 256
static void update_stats( unsigned int, void* );
/** Initializes the abcModule module */
void
init_abcModule(void)
{
/* here we initialize all the tables we're planning on supporting */
initialize_table_messageTable();
initialize_table_msgVMTable();
}
/** Initialize the messageTable table by defining its contents and how it's structured */
void
initialize_table_messageTable(void)
{
const oid messageTable_oid[] = {1,3,6,1,4,1,11456,3,3};
const size_t messageTable_oid_len = OID_LENGTH(messageTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
DEBUGMSGTL(("abcModule:init", "initializing table messageTable\n"));
reg = netsnmp_create_handler_registration(
"messageTable", messageTable_handler,
messageTable_oid, messageTable_oid_len,
HANDLER_CAN_RONLY
);
table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
ASN_OCTET_STR,
ASN_INTEGER,
ASN_INTEGER,
ASN_INTEGER, 0);
table_info->min_column = COLUMN_MESSAGETYPE;
table_info->max_column = COLUMN_CURRENTMSGID;
iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = messageTable_get_first_data_point;
iinfo->get_next_data_point = messageTable_get_next_data_point;
iinfo->table_reginfo = table_info;
netsnmp_register_table_iterator( reg, iinfo );
snmp_alarm_register( 5, SA_REPEAT , update_stats, NULL );
/* Initialise the contents of the table here */
}
/* Typical data structure for a row entry */
struct msgVMTable_entry {
/* Index values */
long messageIndex;
long msgVMIndex;
/* Column values */
char msgVMName[10];
long msgVMId;
/* Illustrate using a simple linked list */
int valid;
struct msgVMTable_entry *next;
};
/* Typical data structure for a row entry */
struct messageTable_entry {
/* Index values */
long messageIndex;
/* Column values */
char messageType[10];
long sentMsgCount;
long errorMsgCount;
long currentMsgID;
/* Illustrate using a simple linked list */
int valid;
struct messageTable_entry *next;
//struct msgVMTable_entry *msgVMTable_head;
};
struct messageTable_entry *messageTable_head; //top level Table
struct msgVMTable_entry *msgVMTable_head; // vm table is repeated for each row of messageTable
/* create a new row in the (unsorted) table */
struct messageTable_entry *
messageTable_createEntry(
long messageIndex
) {
struct messageTable_entry *entry;
entry = SNMP_MALLOC_TYPEDEF(struct messageTable_entry);
if (!entry)
return NULL;
entry->messageIndex = messageIndex;
entry->next = messageTable_head;
messageTable_head = entry;
return entry;
}
/* remove a row from the table */
void
messageTable_removeEntry( struct messageTable_entry *entry ) {
struct messageTable_entry *ptr, *prev;
if (!entry)
return; /* Nothing to remove */
for ( ptr = messageTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */
if ( prev == NULL )
messageTable_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 *
messageTable_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 = messageTable_head;
return messageTable_get_next_data_point(my_loop_context, my_data_context,
put_index_data, mydata );
}
netsnmp_variable_list *
messageTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct messageTable_entry *entry = (struct messageTable_entry *)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;
int msg_id, msg_sent, msg_err = 0;
char type[10];
if ( entry ) {
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->messageIndex );
idx = idx->next_variable;
//type = (char*) malloc(11);
//char type1 ='j';
strcpy(type, entry->messageType);
snmp_set_var_value(idx, (u_char *)&type, sizeof(type));
idx = idx->next_variable;
msg_id = entry->currentMsgID;
snmp_set_var_value(idx, (u_char *)&msg_id, sizeof(msg_id));
idx = idx->next_variable;
msg_sent = entry->sentMsgCount;
snmp_set_var_value(idx, (u_char *)&msg_sent, sizeof(msg_sent));
idx = idx->next_variable;
msg_err = entry->errorMsgCount;
snmp_set_var_value(idx, (u_char *)&msg_err, sizeof(msg_err));
*my_data_context = (void *)entry;
*my_loop_context = (void *)entry->next;
return put_index_data;
} else {
return NULL;
}
}
/** handles requests for the messageTable table */
int
messageTable_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 messageTable_entry *table_entry;
DEBUGMSGTL(("abcModule: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 messageTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_MESSAGETYPE:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->messageType,
sizeof(table_entry->messageType));
break;
case COLUMN_SENTMSGCOUNT:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->sentMsgCount);
break;
case COLUMN_ERRORMSGCOUNT:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->errorMsgCount);
break;
case COLUMN_CURRENTMSGID:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->currentMsgID);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}
/** Initialize the msgVMTable table by defining its contents and how it's structured */
void
initialize_table_msgVMTable(void)
{
const oid msgVMTable_oid[] = {1,3,6,1,4,1,11456,3,4};
const size_t msgVMTable_oid_len = OID_LENGTH(msgVMTable_oid);
netsnmp_handler_registration *reg;
netsnmp_iterator_info *iinfo;
netsnmp_table_registration_info *table_info;
DEBUGMSGTL(("abcModule:init", "initializing table msgVMTable\n"));
reg = netsnmp_create_handler_registration(
"msgVMTable", msgVMTable_handler,
msgVMTable_oid, msgVMTable_oid_len,
HANDLER_CAN_RONLY
);
table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
netsnmp_table_helper_add_indexes(table_info,
ASN_INTEGER, /* index: messageIndex */
ASN_OCTET_STR,
ASN_INTEGER, /* index: msgVMIndex */
0);
table_info->min_column = COLUMN_MSGVMNAME;
table_info->max_column = COLUMN_MSGVMID;
iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
iinfo->get_first_data_point = msgVMTable_get_first_data_point;
iinfo->get_next_data_point = msgVMTable_get_next_data_point;
iinfo->table_reginfo = table_info;
netsnmp_register_table_iterator( reg, iinfo );
/* Initialise the contents of the table here */
}
/* create a new row in the (unsorted) table */
struct msgVMTable_entry *
msgVMTable_createEntry(
long messageIndex,
long msgVMIndex
) {
struct msgVMTable_entry *entry;
entry = SNMP_MALLOC_TYPEDEF(struct msgVMTable_entry);
if (!entry)
return NULL;
entry->messageIndex = messageIndex;
entry->msgVMIndex = msgVMIndex;
entry->next = msgVMTable_head;
msgVMTable_head = entry;
return entry;
}
/* remove a row from the table */
void
msgVMTable_removeEntry( struct msgVMTable_entry *entry ) {
struct msgVMTable_entry *ptr, *prev;
if (!entry)
return; /* Nothing to remove */
for ( ptr = msgVMTable_head, prev = NULL;
ptr != NULL;
prev = ptr, ptr = ptr->next ) {
if ( ptr == entry )
break;
}
if ( !ptr )
return; /* Can't find it */
if ( prev == NULL )
msgVMTable_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 *
msgVMTable_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 = msgVMTable_head;
return msgVMTable_get_next_data_point(my_loop_context, my_data_context,
put_index_data, mydata );
}
netsnmp_variable_list *
msgVMTable_get_next_data_point(void **my_loop_context,
void **my_data_context,
netsnmp_variable_list *put_index_data,
netsnmp_iterator_info *mydata)
{
struct msgVMTable_entry *entry = (struct msgVMTable_entry *)*my_loop_context;
netsnmp_variable_list *idx = put_index_data;
char vmName[10];
if ( entry ) {
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->messageIndex );
idx = idx->next_variable;
snmp_set_var_typed_integer( idx, ASN_INTEGER, entry->msgVMIndex );
idx = idx->next_variable;
strcpy(vmName, entry->msgVMName);
snmp_set_var_value(idx, (u_char *)&vmName, sizeof(vmName));
idx = idx->next_variable;
snmp_set_var_value(idx, (u_char *)&entry->msgVMId, sizeof(entry->msgVMId));
*my_data_context = (void *)entry;
*my_loop_context = (void *)entry->next;
return put_index_data;
} else {
return NULL;
}
}
/** handles requests for the msgVMTable table */
int
msgVMTable_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 msgVMTable_entry *table_entry;
DEBUGMSGTL(("abcModule: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 msgVMTable_entry *)
netsnmp_extract_iterator_context(request);
table_info = netsnmp_extract_table_info( request);
switch (table_info->colnum) {
case COLUMN_MSGVMNAME:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR,
table_entry->msgVMName,
sizeof(table_entry->msgVMName));
break;
case COLUMN_MSGVMID:
if ( !table_entry ) {
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHINSTANCE);
continue;
}
snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
table_entry->msgVMId);
break;
default:
netsnmp_set_request_error(reqinfo, request,
SNMP_NOSUCHOBJECT);
break;
}
}
break;
}
return SNMP_ERR_NOERROR;
}
static void
update_stats(unsigned int reg, void * vargs ) {
FILE *fp;
struct messageTable_entry *this;
struct msgVMTable_entry* vmEntry;
char buf[STRMAX];
char type[10];
int index = 0;
int i =0;
int msg_id, msg_sent, msg_err = 0;
memset(type,0x00,10);
fp = fopen( "data1.txt", "r" );
if ( !fp ) {
return ;
}
while ( fgets( buf, STRMAX, fp )) {
this = SNMP_MALLOC_TYPEDEF( struct messageTable_entry );
/* Unpick 'buf' and populate 'this' */
this->messageIndex = index++;
sprintf(type, "%s", strtok(buf, ","));
strcpy(this->messageType, type);
msg_id = atoi(strtok(NULL, ","));
this->currentMsgID = msg_id;
msg_sent = atoi(strtok(NULL, ","));
this->sentMsgCount = msg_sent;
msg_err = atoi(strtok(NULL, ","));
this->errorMsgCount = msg_err;
for (i= 0; i<2; ++i) {
//hard coded values for testing purpose.
vmEntry = SNMP_MALLOC_TYPEDEF( struct msgVMTable_entry );
vmEntry->msgVMIndex= i;
memset(vmEntry->msgVMName,0x00,STRMAX);
sprintf(vmEntry->msgVMName,"VM_%d",i);
vmEntry->msgVMId = 100+i;
// vmEntry->next = msgVMTable_head;
// msgVMTable_head = vmEntry;
}
this->next = messageTable_head;
messageTable_head = this; /* Iterate helper is fine with unordered lists! */
}
fclose(fp);
return ; /* OK */
}
ABC-MIB DEFINITIONS ::= BEGIN
IMPORTS
RowStatus
FROM SNMPv2-TC
OBJECT-GROUP, NOTIFICATION-GROUP
FROM SNMPv2-CONF
enterprises, MODULE-IDENTITY, OBJECT-TYPE, Integer32,
NOTIFICATION-TYPE
FROM SNMPv2-SMI;
abcModule MODULE-IDENTITY
LAST-UPDATED "201002021512Z"
ORGANIZATION "Organization"
CONTACT-INFO "Contact-info"
DESCRIPTION "Description"
REVISION "201002021512Z"
DESCRIPTION "Sample Message"
::= {enterprises 11456}
abc OBJECT IDENTIFIER
::= {abcModule 3}
-- +-abcModule(11456)
-- |
-- +-abc(3)
-- | |
-- | +-messageTable(3)
-- | | |
-- | | +- -R- Integer32 messageIndex(1)
-- | | +- -R- OCTET STRING messageType(2)
-- | | +- -R- Integer32 sentMsgCount(3)
-- | | +- -R- Integer32 errorMsgCount(4)
-- | | +- -R- Integer32 currentMsgID(5)
-- | | |
-- | | +-msgVMTable(2)
-- | | |
-- | | +- -R- Integer32 msgVMIndex(1)
-- | | +- -R- OCTET STRING msgVMName(2)
-- | | +- -R- Integer32 msgVMId(3)
--
-- Message Table
--
messageTable OBJECT-TYPE
SYNTAX SEQUENCE OF MessageEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Table Description"
::= {abc 3}
messageEntry OBJECT-TYPE
SYNTAX MessageEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Row Description"
INDEX {messageIndex}
::= {messageTable 1}
MessageEntry ::= SEQUENCE {
messageIndex Integer32,
messageType OCTET STRING,
sentMsgCount Integer32,
errorMsgCount Integer32,
currentMsgID Integer32
}
messageIndex OBJECT-TYPE
SYNTAX Integer32(1 .. 25)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Message Index"
::= {messageEntry 1}
messageType OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Message Format"
DEFVAL {"AMF"}
::= {messageEntry 2}
sentMsgCount OBJECT-TYPE
SYNTAX Integer32(0..9999)
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Sent messages count"
DEFVAL {0}
::= {messageEntry 3}
errorMsgCount OBJECT-TYPE
SYNTAX Integer32(0..9999)
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Error messages count"
DEFVAL {0}
::= {messageEntry 4}
currentMsgID OBJECT-TYPE
SYNTAX Integer32(0..9999)
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Current message ID"
DEFVAL {0}
::= {messageEntry 5}
--
-- VM
--
msgVMTable OBJECT-TYPE
SYNTAX SEQUENCE OF MsgVMEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Virtual Machine"
::= { abc 4 }
msgVMEntry OBJECT-TYPE
SYNTAX MsgVMEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Virtual Machine"
INDEX { messageIndex, msgVMIndex }
::= { msgVMTable 1 }
MsgVMEntry ::= SEQUENCE {
msgVMIndex Integer32,
msgVMName OCTET STRING,
msgVMId Integer32
}
msgVMIndex OBJECT-TYPE
SYNTAX Integer32(1 .. 25)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "Virtual Machine index"
::= { msgVMEntry 1 }
msgVMName OBJECT-TYPE
SYNTAX OCTET STRING
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Virtual Machine Name"
::= { msgVMEntry 2 }
msgVMId OBJECT-TYPE
SYNTAX Integer32(0..9999)
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Virtual Machine ID"
::= { msgVMEntry 3 }
END
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders