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

Reply via email to