Hi All,

In my table implementation, I am creating a row inside the
"xxx_get_first_data_point" function using "xxx_createEntry"
till it reaches the maximum allowed count, as the row creation
needs to be dynamic. But I don't know the correct way to free
these allocated rows.

The function "xxx_free_loop_context_at_end" is not getting called
even if it is given in the function pointer like this,
"iinfo->free_loop_context_at_end = xxx_free_loop_context_at_end".
But "xxx_free_data_context" will gets called if it is given in
"iinfo->free_data_context = xxx_free_data_context_at_end".

Even this "xxx_free_data_context_at_end" doesn't help, as it is
called on every time "xxx_get_next_data_point" returns NULL.
On a "snmpwalk" the "net-snmp handler" is called in a column
wise order, so traversal through same row happens multiple times
for each column value and "xxx_get_next_data_point" returns NULL
on each occasion. So I am getting only the first column values
for each row after "snmpwalk". This is because after the traversal
for first column the entire row gets freed.

If anybody knows the solution for this please reply back. Please
find the source code and "snmpwalk" output below for the reference.

Best Regards,
Sreenath


SOURCE CODE
===========

/*
 * Note: this file originally auto-generated by mib2c using
 *  : mib2c.iterate.conf,v 1.4 2004/10/14 19:48:52 slozovsk Exp $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "dot1xPaePortTable.h"

struct dot1xPaePortTable_entry *dot1xPaePortTable_head = NULL;
static int rowCount = 0;

/** Initializes the dot1xPaePortTable module */
void
init_dot1xPaePortTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting
     */
    initialize_table_dot1xPaePortTable();
}

/** Initialize the dot1xPaePortTable table by defining its contents and how
it's
 * structured */
void
initialize_table_dot1xPaePortTable(void)
{
    static oid      dot1xPaePortTable_oid[] =
        { 1, 0, 8802, 1, 1, 1, 1, 1, 2 };
    size_t          dot1xPaePortTable_oid_len =
        OID_LENGTH(dot1xPaePortTable_oid);
    netsnmp_handler_registration *reg;
    netsnmp_iterator_info *iinfo;
    netsnmp_table_registration_info *table_info;

    reg =
        netsnmp_create_handler_registration("dot1xPaePortTable",
                                            dot1xPaePortTable_handler,
                                            dot1xPaePortTable_oid,
                                            dot1xPaePortTable_oid_len,
                                            HANDLER_CAN_RWRITE);

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,   /* index:
                                     dot1xPaePortNumber */
                                     0);
    table_info->min_column = 2;
    table_info->max_column = 5;

    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
    iinfo->get_first_data_point = dot1xPaePortTable_get_first_data_point;
    iinfo->get_next_data_point = dot1xPaePortTable_get_next_data_point;
    iinfo->table_reginfo = table_info;

    iinfo->free_loop_context = NULL;
    iinfo->free_data_context = dot1xPaePortTable_free_loop_context_at_end;
    iinfo->free_loop_context_at_end =
dot1xPaePortTable_free_loop_context_at_end;

    netsnmp_register_table_iterator(reg, iinfo);

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


/*
 * create a new row in the (unsorted) table
 */
struct dot1xPaePortTable_entry *
dot1xPaePortTable_createEntry(long dot1xPaePortNumber)
{
    struct dot1xPaePortTable_entry *entry = NULL;

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

    entry->dot1xPaePortNumber = dot1xPaePortNumber;
    entry->valid = 1;
    entry->next = dot1xPaePortTable_head;
    dot1xPaePortTable_head = entry;

    return entry;
}

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

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

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

    if (prev == NULL)
        dot1xPaePortTable_head = ptr->next;
    else
        prev->next = ptr->next;

    SNMP_FREE(entry);           /* XXX - release any other internal
resources */
}

void
dot1xPaePortTable_free_loop_context_at_end(void *my_loop_context,

netsnmp_iterator_info *iinfo)
{
    struct dot1xPaePortTable_entry *ptr;

    ptr = (struct dot1xPaePortTable_entry *) my_loop_context;

    dot1xPaePortTable_removeEntry(ptr);
}

/*
 * Example iterator hook routines - using 'get_next' to do most of the work
 */
netsnmp_variable_list *
dot1xPaePortTable_get_first_data_point(void **my_loop_context,
                                                           void
**my_data_context,

netsnmp_variable_list *
                                                           put_index_data,

netsnmp_iterator_info *mydata)
{
    netsnmp_variable_list * ret_val = NULL;

   if (rowCount < MAX_ROW_COUNT)
        dot1xPaePortTable_createEntry(++rowCount);

    *my_loop_context = dot1xPaePortTable_head;
    ret_val = dot1xPaePortTable_get_next_data_point(my_loop_context,
                                                    my_data_context,
                                                    put_index_data, mydata);
    return ret_val;
}

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

    if (NULL != entry) {
        snmp_set_var_value(idx, (u_char *)&(entry->dot1xPaePortNumber),
                           sizeof(entry->dot1xPaePortNumber));

        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 dot1xPaePortTable table */
int
dot1xPaePortTable_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 dot1xPaePortTable_entry *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed != 0) {
                continue;
            }

            table_entry = (struct dot1xPaePortTable_entry *)
                netsnmp_extract_iterator_context(request);
            if (table_entry == NULL) {
                continue;
            }

            table_info = netsnmp_extract_table_info(request);
            if (table_info == NULL) {
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_DOT1XPAEPORTPROTOCOLVERSION:
                table_entry->dot1xPaePortProtocolVersion = 1;

                snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                         (u_char *)&(table_entry->
                                         dot1xPaePortProtocolVersion),
                                         sizeof(table_entry->

dot1xPaePortProtocolVersion));
                break;
            case COLUMN_DOT1XPAEPORTCAPABILITIES:
                table_entry->dot1xPaePortCapabilities = 2;

                snmp_set_var_typed_value(request->requestvb, ASN_BIT_STR,
                                         (u_char *)&(table_entry->
                                         dot1xPaePortCapabilities),
                                         sizeof(table_entry->
                                                dot1xPaePortCapabilities));
                break;
            case COLUMN_DOT1XPAEPORTINITIALIZE:
                table_entry->dot1xPaePortInitialize = 3;

                snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char *)&(table_entry->
                                         dot1xPaePortInitialize),
                                         sizeof(table_entry->
                                                dot1xPaePortInitialize));
                break;
            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
                table_entry->dot1xPaePortReauthenticate = 4;

                snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char *)&(table_entry->
                                         dot1xPaePortReauthenticate),
                                         sizeof(table_entry->

dot1xPaePortReauthenticate));
                break;
            }
        }
        break;

        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        #if 0
        for (request = requests; request; request = request->next) {
            table_entry = (struct dot1xPaePortTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_DOT1XPAEPORTINITIALIZE:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                /*
                 * Also may need to check size/value
                 */
                break;
            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                /*
                 * Also may need to check size/value
                 */
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                return SNMP_ERR_NOTWRITABLE;
            }
        }
        #endif
        break;

    case MODE_SET_RESERVE2:
        break;

    case MODE_SET_FREE:
        break;

    case MODE_SET_ACTION:
        #if 0
        for (request = requests; request; request = request->next) {
            table_entry = (struct dot1xPaePortTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_DOT1XPAEPORTINITIALIZE:
                /*
                 * Need to save old 'table_entry->dot1xPaePortInitialize'
value.
                 * May need to use 'memcpy'
                 */
                table_entry->old_dot1xPaePortInitialize =
                    table_entry->dot1xPaePortInitialize;
                table_entry->dot1xPaePortInitialize =
                    request->requestvb->val.integer;
                break;
            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
                /*
                 * Need to save old
'table_entry->dot1xPaePortReauthenticate'
                 * value.
                 * May need to use 'memcpy'
                 */
                table_entry->old_dot1xPaePortReauthenticate =
                    table_entry->dot1xPaePortReauthenticate;
                table_entry->dot1xPaePortReauthenticate =
                    request->requestvb->val.integer;
                break;
            }
        }
        #endif
        break;

    case MODE_SET_UNDO:
        #if 0
        for (request = requests; request; request = request->next) {
            table_entry = (struct dot1xPaePortTable_entry *)
                netsnmp_extract_iterator_context(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_DOT1XPAEPORTINITIALIZE:
                /*
                 * Need to restore old 'table_entry->dot1xPaePortInitialize'
                 * value.
                 * May need to use 'memcpy'
                 */
                table_entry->dot1xPaePortInitialize =
                    table_entry->old_dot1xPaePortInitialize;
                break;
            case COLUMN_DOT1XPAEPORTREAUTHENTICATE:
                /*
                 * Need to restore old
'table_entry->dot1xPaePortReauthenticate'
                 * value.
                 * May need to use 'memcpy'
                 */
                table_entry->dot1xPaePortReauthenticate =
                    table_entry->old_dot1xPaePortReauthenticate;
                break;
            }
        }
        #endif
        break;

    case MODE_SET_COMMIT:
        break;
    }

    return SNMP_ERR_NOERROR;
}


"snmpwalk" OUTPUT
=================
iso.0.8802.1.1.1.1.1.2.1.2.1 = Gauge32: 11
iso.0.8802.1.1.1.1.1.2.1.2.2 = Gauge32: 21
iso.0.8802.1.1.1.1.1.2.1.2.3 = Gauge32: 31
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Net-snmp-users mailing list
Net-snmp-users@lists.sourceforge.net
Please see the following page to unsubscribe or change other options:
https://lists.sourceforge.net/lists/listinfo/net-snmp-users

Reply via email to