/*
 * table_container.c
 * $Id$
 */

#include <net-snmp/net-snmp-config.h>

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

#include <net-snmp/agent/table_container.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/agent/table.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/snmp_assert.h>

/*
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN        -1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1     0 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2     1 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION       2 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT       3 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE         4 
 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO         5 
 */

/*
 * PRIVATE structure for holding important info for each table.
 */
typedef struct container_table_data_s {

   /** registration info for the table */
    netsnmp_table_registration_info *tblreg_info;

   /** container for the table rows */
   netsnmp_container          *table;

    /*
     * mutex_type                lock;
     */

   /* what type of key do we want? */
   char            key_type;

} container_table_data;

/** @defgroup table_container table_container
 *  Helps you implement a table when data can be found via a netsnmp_container.
 *  @ingroup table
 *
 *  The table_container handler is used (automatically) in conjuntion
 *  with the @link table table@endlink handler.
 *
 *  This handler will use the index information provided by
 *  the @link table @endlink handler to find the row needed to process
 *  the request.
 *
 *  The container must use one of 3 key types. It is the sub-handler's
 *  responsibility to ensure that the container and key type match (unless
 *  neither is specified, in which case a default will be used.)
 *
 *  The current key types are:
 *
 *    TABLE_CONTAINER_KEY_NETSNMP_INDEX
 *        The container should do comparisons based on a key that may be cast
 *        to a netsnmp index (netsnmp_index *). This index contains only the
 *        index portion of the OID, not the entire OID.
 *
 *    TABLE_CONTAINER_KEY_VARBIND_INDEX
 *        The container should do comparisons based on a key that may be cast
 *        to a netsnmp variable list (netsnmp_variable_list *). This variable
 *        list will contain one varbind for each index component.
 *
 *    TABLE_CONTAINER_KEY_VARBIND_RAW    (NOTE: unimplemented)
 *        While not yet implemented, future plans include passing the request
 *        varbind with the full OID to a container.
 *
 *  If a key type is not specified at registration time, the default key type
 *  of TABLE_CONTAINER_KEY_NETSNMP_INDEX will be used. If a container is
 *  provided, or the handler name is aliased to a container type, the container
 *  must use a netsnmp index.
 *
 *  If no container is provided, a lookup will be made based on the
 *  sub-handler's name, or if that isn't found, "table_container". The 
 *  table_container key type will be netsnmp_index.
 *
 *  The container must, at a minimum, implement find and find_next. If a NULL
 *  key is passed to the container, it must return the first item, if any.
 *  All containers provided by net-snmp fulfil this requirement.
 *
 *  This handler will only register to process 'data lookup' modes. In
 *  traditional net-snmp modes, that is any GET-like mode (GET, GET-NEXT,
 *  GET-BULK) or the first phase of a SET (RESERVE1). In the new baby-steps
 *  mode, DATA_LOOKUP is it's own mode, and is a pre-cursor to other modes.
 *
 *  When called, the handler will call the appropriate container method
 *  with the appropriate key type. If a row was not found, the result depends
 *  on the mode.
 *
 *  GET Processing
 *    An exact match must be found. If one is not, the error NOSUCHINSTANCE
 *    is set.
 *
 *  GET-NEXT / GET-BULK
 *    If no row is found, the column number will be increased (using any
 *    valid_columns structure that may have been provided), and the first row
 *    will be retrieved. If no first row is found, the processed flag will be
 *    set, so that the sub-handler can skip any processing related to the
 *    request. The agent will notice this unsatisfied request, and attempt to
 *    pass it to the next appropriate handler.
 *
 *  SET
 *    If the hander did not register with the HANDLER_CAN_NOT_CREATE flag
 *    set in the registration modes, it is assumed that this is a row
 *    creation request and a NULL row is added to the request's data list.
 *    The sub-handler is responsbile for dealing with any row creation
 *    contraints and inserting any newly created rows into the container
 *    and the request's data list.
 *
 *  If a row is found, it will be inserted into
 *  the request's data list. The sub-handler may retrieve it by calling
 *      netsnmp_container_table_extract_context(request); *
 *  NOTE NOTE NOTE:
 *
 *  This helper and it's API are still being tested and are subject to change.
 *
 * @{
 */

static int
_container_table_handler(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests);

static void *
_find_next_row(netsnmp_container *c,
               netsnmp_table_request_info *tblreq,
               void * key);

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * PUBLIC Registration functions                                      *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/

/* ==================================
 *
 * Container Table API: Table maintenance
 *
 * ================================== */

container_table_data *
netsnmp_tcontainer_create_table( const char *name,
                                 netsnmp_container *container, long flags )
{
    container_table_data *table;

    table = SNMP_MALLOC_TYPEDEF(container_table_data);
    if (!table)
        return NULL;
    if (container)
        table->table = container;
    else {
        table->table = netsnmp_container_find("table_container");
        if (!table->table) {
            SNMP_FREE(table);
            return NULL;
        }
    }

    if (flags)
        table->key_type = (char)(flags & 0x03);  /* Use lowest two bits */
    else
        table->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX;

    if (!table->table->compare)
         table->table->compare  = netsnmp_compare_netsnmp_index;
    if (!table->table->ncompare)
         table->table->ncompare = netsnmp_ncompare_netsnmp_index;

    return table;
}

void
netsnmp_tcontainer_delete_table( container_table_data *table )
{
    if (!table)
       return;

    if (table->table)
       CONTAINER_FREE(table->table);
    
    SNMP_FREE(table);
    return;
}

    /*
     * The various standalone row operation routines
     *    (create/clone/copy/delete)
     * will be specific to a particular table,
     *    so can't be implemented here.
     */

int
netsnmp_tcontainer_add_row( container_table_data *table, netsnmp_index *row )
{
    if (!table || !table->table || !row)
        return -1;
    CONTAINER_INSERT( table->table, row );
    return 0;
}

netsnmp_index *
netsnmp_tcontainer_remove_row( container_table_data *table, netsnmp_index *row )
{
    if (!table || !table->table || !row)
        return NULL;
    CONTAINER_REMOVE( table->table, row );
    return NULL;
}

int
netsnmp_tcontainer_replace_row( container_table_data *table,
                                netsnmp_index *old_row, netsnmp_index *new_row )
{
    if (!table || !table->table || !old_row || !new_row)
        return -1;
    netsnmp_tcontainer_remove_row( table, old_row );
    netsnmp_tcontainer_add_row(    table, new_row );
    return 0;
}

    /* netsnmp_tcontainer_remove_delete_row() will be table-specific too */


/* ==================================
 *
 * Container Table API: MIB maintenance
 *
 * ================================== */

/** returns a netsnmp_mib_handler object for the table_container helper */
netsnmp_mib_handler *
netsnmp_container_table_handler_get(netsnmp_table_registration_info *tabreg,
                                    netsnmp_container *container, char key_type)
{
    container_table_data *tad;
    netsnmp_mib_handler *handler;

    if (NULL == tabreg) {
        snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n");
        return NULL;
    }

    tad = SNMP_MALLOC_TYPEDEF(container_table_data);
    handler = netsnmp_create_handler("table_container",
                                     _container_table_handler);
    if((NULL == tad) || (NULL == handler)) {
        if(tad) free(tad); /* SNMP_FREE wasted on locals */
        if(handler) free(handler); /* SNMP_FREE wasted on locals */
        snmp_log(LOG_ERR,
                 "malloc failure in netsnmp_container_table_register\n");
        return NULL;
    }

    tad->tblreg_info = tabreg;  /* we need it too, but it really is not ours */
    if(key_type)
        tad->key_type = key_type;
    else
        tad->key_type = TABLE_CONTAINER_KEY_NETSNMP_INDEX;

    if(NULL == container)
        container = netsnmp_container_find("table_container");
    tad->table = container;

    if (NULL==container->compare)
        container->compare = netsnmp_compare_netsnmp_index;
    if (NULL==container->ncompare)
        container->ncompare = netsnmp_ncompare_netsnmp_index;
    
    handler->myvoid = (void*)tad;
    handler->flags |= MIB_HANDLER_AUTO_NEXT;
    
    return handler;
}

int
netsnmp_container_table_register(netsnmp_handler_registration *reginfo,
                                 netsnmp_table_registration_info *tabreg,
                                 netsnmp_container *container, char key_type )
{
    netsnmp_mib_handler *handler;

    if ((NULL == reginfo) || (NULL == reginfo->handler) || (NULL == tabreg)) {
        snmp_log(LOG_ERR, "bad param in netsnmp_container_table_register\n");
        return SNMPERR_GENERR;
    }

    if (NULL==container)
        container = netsnmp_container_find(reginfo->handlerName);

    handler = netsnmp_container_table_handler_get(tabreg, container, key_type);
    netsnmp_inject_handler(reginfo, handler );

    return netsnmp_register_table(reginfo, tabreg);
}

int
netsnmp_container_table_unregister(netsnmp_handler_registration *reginfo)
{
    container_table_data *tad;

    if (!reginfo)
        return MIB_UNREGISTRATION_FAILED;
    tad = (container_table_data *)
        netsnmp_find_handler_data_by_name(reginfo, "table_container");
    if (tad) {
        CONTAINER_FREE( tad->table );
        tad->table = NULL;
        free(tad);
        reginfo->handler->myvoid = NULL;
    }
    return netsnmp_unregister_table( reginfo );
}

/** retrieve the container used by the table_container helper */
netsnmp_container*
netsnmp_container_table_container_extract(netsnmp_request_info *request)
{
    return (netsnmp_container *)
         netsnmp_request_get_list_data(request, TABLE_CONTAINER_CONTAINER);
}

#ifndef NETSNMP_USE_INLINE
/** find the context data used by the table_container helper */
void *
netsnmp_container_table_row_extract(netsnmp_request_info *request)
{
    /*
     * NOTE: this function must match in table_container.c and table_container.h.
     *       if you change one, change them both!
     */
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
}
/** find the context data used by the table_container helper */
void *
netsnmp_container_table_extract_context(netsnmp_request_info *request)
{
    /*
     * NOTE: this function must match in table_container.c and table_container.h.
     *       if you change one, change them both!
     */
    return netsnmp_request_get_list_data(request, TABLE_CONTAINER_ROW);
}
#endif /* inline */

/** inserts a newly created table_container entry into a request list */
void
netsnmp_container_table_row_insert(netsnmp_request_info *request,
                                   netsnmp_index        *row)
{
    netsnmp_request_info       *req;
    netsnmp_table_request_info *table_info = NULL;
    netsnmp_variable_list      *this_index = NULL;
    netsnmp_variable_list      *that_index = NULL;
    oid      base_oid[] = {0, 0};	/* Make sure index OIDs are legal! */
    oid      this_oid[MAX_OID_LEN];
    oid      that_oid[MAX_OID_LEN];
    size_t   this_oid_len, that_oid_len;

    if (!request)
        return;

    /*
     * We'll add the new row information to any request
     * structure with the same index values as the request
     * passed in (which includes that one!).
     *
     * So construct an OID based on these index values.
     */

    table_info = netsnmp_extract_table_info(request);
    this_index = table_info->indexes;
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
                      base_oid, 2, this_index);

    /*
     * We need to look through the whole of the request list
     * (as received by the current handler), as there's no
     * guarantee that this routine will be called by the first
     * varbind that refers to this row.
     *   In particular, a RowStatus controlled row creation
     * may easily occur later in the variable list.
     *
     * So first, we rewind to the head of the list....
     */
    for (req=request; req->prev; req=req->prev)
        ;

    /*
     * ... and then start looking for matching indexes
     * (by constructing OIDs from these index values)
     */
    for (; req; req=req->next) {
        if (req->processed) 
            continue;
        
        table_info = netsnmp_extract_table_info(req);
        that_index = table_info->indexes;
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
                          base_oid, 2, that_index);
      
        /*
         * This request has the same index values,
         * so add the newly-created row information.
         */
        if (snmp_oid_compare(this_oid, this_oid_len,
                             that_oid, that_oid_len) == 0) {
            netsnmp_request_add_list_data(req,
                netsnmp_create_data_list(TABLE_CONTAINER_ROW, row, NULL));
        }
    }
}

/** removes a table_container entry from a request list */
void
netsnmp_container_table_row_remove(netsnmp_request_info *request,
                                   netsnmp_index        *row)
{
    netsnmp_request_info       *req;
    netsnmp_table_request_info *table_info = NULL;
    netsnmp_variable_list      *this_index = NULL;
    netsnmp_variable_list      *that_index = NULL;
    oid      base_oid[] = {0, 0};	/* Make sure index OIDs are legal! */
    oid      this_oid[MAX_OID_LEN];
    oid      that_oid[MAX_OID_LEN];
    size_t   this_oid_len, that_oid_len;

    if (!request)
        return;

    /*
     * We'll add the new row information to any request
     * structure with the same index values as the request
     * passed in (which includes that one!).
     *
     * So construct an OID based on these index values.
     */

    table_info = netsnmp_extract_table_info(request);
    this_index = table_info->indexes;
    build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
                      base_oid, 2, this_index);

    /*
     * We need to look through the whole of the request list
     * (as received by the current handler), as there's no
     * guarantee that this routine will be called by the first
     * varbind that refers to this row.
     *   In particular, a RowStatus controlled row creation
     * may easily occur later in the variable list.
     *
     * So first, we rewind to the head of the list....
     */
    for (req=request; req->prev; req=req->prev)
        ;

    /*
     * ... and then start looking for matching indexes
     * (by constructing OIDs from these index values)
     */
    for (; req; req=req->next) {
        if (req->processed) 
            continue;
        
        table_info = netsnmp_extract_table_info(req);
        that_index = table_info->indexes;
        build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
                          base_oid, 2, that_index);
      
        /*
         * This request has the same index values,
         * so add the newly-created row information.
         */
        if (snmp_oid_compare(this_oid, this_oid_len,
                             that_oid, that_oid_len) == 0) {
            netsnmp_request_remove_list_data(req, TABLE_CONTAINER_ROW);
        }
    }
}

/** @cond */
/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * DATA LOOKUP functions                                              *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
NETSNMP_STATIC_INLINE void
_set_key( container_table_data * tad, netsnmp_request_info *request,
          netsnmp_table_request_info *tblreq_info,
          void **key, netsnmp_index *index )
{
    if (TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {
        index->oids = tblreq_info->index_oid;
        index->len = tblreq_info->index_oid_len;
        *key = index;
    }
    else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {
        *key = tblreq_info->indexes;
    }
#if 0
    else if (TABLE_CONTAINER_KEY_VARBIND_RAW == tad->key_type) {
        *key = request->requestvb;
    }
#endif
    else
        *key = NULL;
}


NETSNMP_STATIC_INLINE void
_data_lookup(netsnmp_handler_registration *reginfo,
            netsnmp_agent_request_info *agtreq_info,
            netsnmp_request_info *request, container_table_data * tad)
{
    netsnmp_index *row = NULL;
    netsnmp_table_request_info *tblreq_info;
    netsnmp_variable_list *var;
    netsnmp_index index;
    void *key;

    var = request->requestvb;

    DEBUGIF("table_container") {
        DEBUGMSGTL(("table_container", "  data_lookup oid:"));
        DEBUGMSGOID(("table_container", var->name, var->name_length));
        DEBUGMSG(("table_container", "\n"));
    }

    /*
     * Get pointer to the table information for this request. This
     * information was saved by table_helper_handler.
     */
    tblreq_info = netsnmp_extract_table_info(request);
    /** the table_helper_handler should enforce column boundaries. */
    netsnmp_assert((NULL != tblreq_info) &&
                   (tblreq_info->colnum <= tad->tblreg_info->max_column));
    
    if ((agtreq_info->mode == MODE_GETNEXT) ||
        (agtreq_info->mode == MODE_GETBULK)) {
        /*
         * find the row. This will automatically move to the next
         * column, if necessary.
         */
        _set_key( tad, request, tblreq_info, &key, &index );
        row = (netsnmp_index*)_find_next_row(tad->table, tblreq_info, key);
        if (row) {
            /*
             * update indexes in tblreq_info (index & varbind),
             * then update request varbind oid
             */
            if(TABLE_CONTAINER_KEY_NETSNMP_INDEX == tad->key_type) {
                tblreq_info->index_oid_len = row->len;
                memcpy(tblreq_info->index_oid, row->oids,
                       row->len * sizeof(oid));
                netsnmp_update_variable_list_from_index(tblreq_info);
            }
            else if (TABLE_CONTAINER_KEY_VARBIND_INDEX == tad->key_type) {
                /** xxx-rks: shouldn't tblreq_info->indexes be updated
                    before we call this?? */
                netsnmp_update_indexes_from_variable_list(tblreq_info);
            }

            if (TABLE_CONTAINER_KEY_VARBIND_RAW != tad->key_type) {
                netsnmp_table_build_oid_from_index(reginfo, request,
                                                   tblreq_info);
            }
        }
        else {
            /*
             * no results found. Flag the request so lower handlers will
             * ignore it, but it is not an error - getnext will move
             * on to another handler to process this request.
             */
            netsnmp_set_request_error(agtreq_info, request, SNMP_ENDOFMIBVIEW);
            DEBUGMSGTL(("table_container", "no row found\n"));
        }
    } /** GETNEXT/GETBULK */
    else {

        _set_key( tad, request, tblreq_info, &key, &index );
        row = (netsnmp_index*)CONTAINER_FIND(tad->table, key);
        if (NULL == row) {
            /*
             * not results found. For a get, that is an error
             */
            DEBUGMSGTL(("table_container", "no row found\n"));
            if((agtreq_info->mode != MODE_SET_RESERVE1) || /* get */
               (reginfo->modes & HANDLER_CAN_NOT_CREATE)) { /* no create */
                netsnmp_set_request_error(agtreq_info, request,
                                          SNMP_NOSUCHINSTANCE);
            }
        }
    } /** GET/SET */
    
    /*
     * save the data and table in the request.
     */
    if (SNMP_ENDOFMIBVIEW != request->requestvb->type) {
        if (NULL != row)
            netsnmp_request_add_list_data(request,
                                          netsnmp_create_data_list
                                          (TABLE_CONTAINER_ROW,
                                           row, NULL));
        netsnmp_request_add_list_data(request,
                                      netsnmp_create_data_list
                                      (TABLE_CONTAINER_CONTAINER,
                                       tad->table, NULL));
    }
}

/**********************************************************************
 **********************************************************************
 *                                                                    *
 *                                                                    *
 * netsnmp_table_container_helper_handler()                           *
 *                                                                    *
 *                                                                    *
 **********************************************************************
 **********************************************************************/
static int
_container_table_handler(netsnmp_mib_handler *handler,
                         netsnmp_handler_registration *reginfo,
                         netsnmp_agent_request_info *agtreq_info,
                         netsnmp_request_info *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    int             oldmode, need_processing = 0;
    container_table_data *tad;

    /** sanity checks */
    netsnmp_assert((NULL != handler) && (NULL != handler->myvoid));
    netsnmp_assert((NULL != reginfo) && (NULL != agtreq_info));

    DEBUGMSGTL(("table_container", "Mode %s, Got request:\n",
                se_find_label_in_slist("agent_mode",agtreq_info->mode)));

    /*
     * First off, get our pointer from the handler. This
     * lets us get to the table registration information we
     * saved in get_table_container_handler(), as well as the
     * container where the actual table data is stored.
     */
    tad = (container_table_data *)handler->myvoid;

    /*
     * only do data lookup for first pass
     *
     * xxx-rks: this should really be handled up one level. we should
     * be able to say what modes we want to be called for during table
     * registration.
     */
    oldmode = agtreq_info->mode;
    if(MODE_IS_GET(oldmode) || (MODE_SET_RESERVE1 == oldmode)) {
        netsnmp_request_info *curr_request;
        /*
         * Loop through each of the requests, and
         * try to find the appropriate row from the container.
         */
        for (curr_request = requests; curr_request; curr_request = curr_request->next) {
            /*
             * skip anything that doesn't need processing.
             */
            if (curr_request->processed != 0) {
                DEBUGMSGTL(("table_container", "already processed\n"));
                continue;
            }
            
            /*
             * find data for this request
             */
            _data_lookup(reginfo, agtreq_info, curr_request, tad);

            if(curr_request->processed)
                continue;

            ++need_processing;
        } /** for ( ... requests ... ) */
    }
    
    /*
     * send GET instead of GETNEXT to sub-handlers
     * xxx-rks: again, this should be handled further up.
     */
    if ((oldmode == MODE_GETNEXT) && (handler->next)) {
        /*
         * tell agent handlder not to auto call next handler
         */
        handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;

        /*
         * if we found rows to process, pretend to be a get request
         * and call handler below us.
         */
        if(need_processing > 0) {
            agtreq_info->mode = MODE_GET;
            rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info,
                                           requests);
            if (rc != SNMP_ERR_NOERROR) {
                DEBUGMSGTL(("table_container",
                            "next handler returned %d\n", rc));
            }

            agtreq_info->mode = oldmode; /* restore saved mode */
        }
    }

    return rc;
}
/** @endcond */


/* ==================================
 *
 * Container Table API: Row operations
 *
 * ================================== */

static void *
_find_next_row(netsnmp_container *c,
               netsnmp_table_request_info *tblreq,
               void * key)
{
    void *row = NULL;

    if (!c || !tblreq || !tblreq->reg_info ) {
        snmp_log(LOG_ERR,"_find_next_row param error\n");
        return NULL;
    }

    /*
     * table helper should have made sure we aren't below our minimum column
     */
    netsnmp_assert(tblreq->colnum >= tblreq->reg_info->min_column);

    /*
     * if no indexes then use first row.
     */
    if(tblreq->number_indexes == 0) {
        row = CONTAINER_FIRST(c);
    } else {

        if(NULL == key) {
            netsnmp_index index;
            index.oids = tblreq->index_oid;
            index.len = tblreq->index_oid_len;
            row = CONTAINER_NEXT(c, &index);
        }
        else
            row = CONTAINER_NEXT(c, key);

        /*
         * we don't have a row, but we might be at the end of a
         * column, so try the next column.
         */
        if (NULL == row) {
            /*
             * don't set tblreq next_col unless we know there is one,
             * so we don't mess up table handler sparse table processing.
             */
            oid next_col = netsnmp_table_next_column(tblreq);
            if (0 != next_col) {
                tblreq->colnum = next_col;
                row = CONTAINER_FIRST(c);
            }
        }
    }
    
    return row;
}

/**
 * deprecated, backwards compatability only
 *
 * expected impact to remove: none
 *  - used between helpers, shouldn't have been used by end users
 *
 * replacement: none
 *  - never should have been a public method in the first place
 */
netsnmp_index *
netsnmp_table_index_find_next_row(netsnmp_container *c,
                                  netsnmp_table_request_info *tblreq)
{
    return (netsnmp_index*)_find_next_row(c, tblreq, NULL );
}

/* ==================================
 *
 * Container Table API: Index operations
 *
 * ================================== */

/** @} */
