/*
 * 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 <openssl/ssl.h>
#include <openssl/x509.h>
#include <net-snmp/library/cert_util.h>
#include "tlstm-mib.h"

#include "snmpTlstmParamsTable.h"

/** XXX - move these to table_data header? */
#define FATE_NEWLY_CREATED    1
#define FATE_NO_CHANGE        0
#define FATE_DELETE_ME        -1

/** **************************************************************************
 *
 * table structures
 *
 */
    /*
     * structure for undo storage and other vars for set processing
     */
 typedef struct snmpTlstmParamsTable_undo_s {
    char  fate;
    char  copied;
    char  is_consistent;
    netsnmp_request_info *req[SNMPTLSTMPARAMSTABLE_MAX_COLUMN + 1];
    /* undo Column space */
    char snmpTlstmParamsClientFingerprint[SNMPTLSTMPARAMSCLIENTFINGERPRINT_MAX_SIZE];
    size_t snmpTlstmParamsClientFingerprint_len;
    char snmpTlstmParamsStorageType;
    char snmpTlstmParamsRowStatus;
 } snmpTlstmParamsTable_undo;

    /*
     * Typical data structure for a row entry
     */
typedef struct snmpTlstmParamsTable_entry_s {
    /* Index values */
    char snmpTargetParamsName[SNMPTARGETPARAMSNAME_MAX_SIZE];
    size_t snmpTargetParamsName_len;

    /* Column values */
    char snmpTlstmParamsClientFingerprint[SNMPTLSTMPARAMSCLIENTFINGERPRINT_MAX_SIZE];
    size_t snmpTlstmParamsClientFingerprint_len;
    char snmpTlstmParamsStorageType;
    char snmpTlstmParamsRowStatus;

    char            hashType;
    char            params_flags;

    /* used during set processing */
     snmpTlstmParamsTable_undo *undo;
} snmpTlstmParamsTable_entry;

static Netsnmp_Node_Handler snmpTlstmParamsTable_handler;
static NetsnmpCacheLoad snmpTlstmParamsTable_load;
static NetsnmpCacheFree snmpTlstmParamsTable_free;

static int _count_handler(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *reqinfo,
                          netsnmp_request_info *requests);
static void _tlstmParams_init_persistence(void);
static void _params_add(snmpTlstmParamsTable_entry *entry);
static void _params_remove(snmpTlstmParamsTable_entry *entry);
static void _params_tweak_storage(snmpTlstmParamsTable_entry *entry);

static uint32_t                _last_changed = 0;
static netsnmp_tdata          *_table_data = NULL;

/*
 * Initialize the snmpTlstmParamsTable table by defining its contents
 * and how it's structured
 */
void
init_snmpTlstmParamsTable(void)
{
    oid reg_oid[] = {SNMP_TLS_TM_BASE,2,2,1,6};
    const size_t reg_oid_len   = OID_LENGTH(reg_oid);
    netsnmp_handler_registration    *reg;
    netsnmp_table_registration_info *table_info;
    netsnmp_cache                   *cache;
    netsnmp_watcher_info            *watcher;

    DEBUGMSGTL(("tlstmParamsTable:init", "initializing table snmpTlstmParamsTable\n"));

    reg = netsnmp_create_handler_registration
        ("snmpTlstmParamsTable", snmpTlstmParamsTable_handler, reg_oid,
         reg_oid_len, HANDLER_CAN_RWRITE);

    _table_data = netsnmp_tdata_create_table( "snmpTlstmParamsTable", 0 );
    if (NULL == _table_data) {
        snmp_log(LOG_ERR,"error creating tdata table for snmpTlstmParamsTable\n");
        return;
    }
    cache = netsnmp_cache_create(SNMPTLSTMPARAMSTABLE_TIMEOUT,
                                  snmpTlstmParamsTable_load,
                                 snmpTlstmParamsTable_free,
                                  reg_oid, reg_oid_len);
    if (NULL == cache) {
        snmp_log(LOG_ERR,"error creating cache for snmpTlstmParamsTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        return;
    }
    cache->magic = (void *)_table_data;
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    if (NULL == table_info) {
        snmp_log(LOG_ERR,"error creating table info for snmpTlstmParamsTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        netsnmp_cache_free(cache);
        return;
    }
    /*
     * populate index types
     */
    netsnmp_table_helper_add_indexes(table_info,
                                     /* index: snmpTargetParamsName */
                                     ASN_PRIV_IMPLIED_OCTET_STR,  0);

    table_info->min_column = SNMPTLSTMPARAMSTABLE_MIN_COLUMN;
    table_info->max_column = SNMPTLSTMPARAMSTABLE_MAX_COLUMN;
    
    netsnmp_tdata_register( reg, _table_data, table_info );
    netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get(cache),
                                   "table_container");

    /*
     * register scalars
     */
    reg_oid[10] = 4;
    reg = netsnmp_create_handler_registration("snmpTlstmParamsCount",
                                              _count_handler, reg_oid,
                                              OID_LENGTH(reg_oid),
                                              HANDLER_CAN_RONLY);
    if (NULL == reg)
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmParamsCount\n");
    else {
        netsnmp_register_scalar(reg);
        if (cache) 
            netsnmp_inject_handler_before(reg,
                                          netsnmp_cache_handler_get(cache),
                                          "snmpTlstmParamsCount");
    }
    
    reg_oid[10] = 5;
    reg = netsnmp_create_handler_registration(
        "snmpTlstmParamsTableLastChanged", NULL, reg_oid,
        OID_LENGTH(reg_oid), HANDLER_CAN_RONLY);
    watcher = netsnmp_create_watcher_info((void*)&_last_changed,
                                          sizeof(_last_changed),
                                          ASN_TIMETICKS,
                                          WATCHER_FIXED_SIZE);
    if ((NULL == reg) || (NULL == watcher))
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmParamsTableLastChanged\n");
    else
        netsnmp_register_watched_scalar(reg, watcher);

    /*
     * Initialise the contents of the table here
     */
    _tlstmParams_init_persistence();
}

/** **************************************************************************
 *
 * utility functions for table structures
 *
 */
/* create a new row in the table */
netsnmp_tdata_row *
snmpTlstmParamsTable_createEntry(netsnmp_tdata *table_data,
                                 char* snmpTargetParamsName,
                                 size_t snmpTargetParamsName_len ) {
    snmpTlstmParamsTable_entry *entry;
    netsnmp_tdata_row *row;

    if ((NULL == snmpTargetParamsName) || (snmpTargetParamsName_len >
                                           sizeof(entry->snmpTargetParamsName)))
        return NULL;

    entry = SNMP_MALLOC_TYPEDEF(snmpTlstmParamsTable_entry);
    if (!entry)
        return NULL;

    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;

    DEBUGMSGT(("tlstmParamsTable:entry:create", "entry %p / row %p\n",
               entry, row));

    DEBUGIF("snmpTlstmParamTable:entry:create") {
        char name[sizeof(entry->snmpTargetParamsName)+1];
        snprintf(name, sizeof(name), "%s", snmpTargetParamsName);
        DEBUGMSGT(("tlstmParamsTable:entry:create",
                   "entry %s %p / row %p\n",
                   name, entry, row));
    }

    /*
     * populate index
     */
    memcpy(entry->snmpTargetParamsName, snmpTargetParamsName,
           snmpTargetParamsName_len);
    entry->snmpTargetParamsName_len = snmpTargetParamsName_len;
    netsnmp_tdata_row_add_index( row, ASN_PRIV_IMPLIED_OCTET_STR,
                                 entry->snmpTargetParamsName,
                                 snmpTargetParamsName_len);

    entry->snmpTlstmParamsClientFingerprint[0] = '\0';
    entry->snmpTlstmParamsClientFingerprint_len = 0;
    entry->snmpTlstmParamsRowStatus = RS_NOTREADY;
    entry->snmpTlstmParamsStorageType = ST_NONVOLATILE;
        
    if (table_data) {
        DEBUGMSGTL(("tlstmParamsTable:row:insert", "row %p\n",
                    row));
        netsnmp_tdata_add_row( table_data, row );
    }
    return row;
}

/* allocate undo resources */
static snmpTlstmParamsTable_undo *
_allocUndo(snmpTlstmParamsTable_entry *entry)
{
    if (!entry)
        return NULL;
    
    entry->undo = SNMP_MALLOC_TYPEDEF(snmpTlstmParamsTable_undo);
    if (!entry->undo)
        return NULL;

    entry->undo->is_consistent = -1; /* don't know */

    /* TODO: allocated any other resources needed */

    return entry->undo;
}

/* free undo resources */
static void
_freeUndo(snmpTlstmParamsTable_entry *entry)
{
    if (!entry || !entry->undo)
        return;

    /* TODO: release any allocated resources */
    SNMP_FREE(entry->undo);
}

/* remove a row from the table */
void
snmpTlstmParamsTable_removeEntry(netsnmp_tdata     *table_data, 
                                 netsnmp_tdata_row *row)
{
    snmpTlstmParamsTable_entry *entry;

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

    entry = (snmpTlstmParamsTable_entry *)row->data;

    DEBUGMSGT(("tlstmParamsTable:entry:delete", "entry %p / row %p\n",
               entry, row));

    if (table_data) {
        DEBUGMSGTL(("tlstmParamsTable:row:remove", "row %p\n", row));
        netsnmp_tdata_remove_and_delete_row( table_data, row );
    }
    else
        netsnmp_tdata_delete_row( row );    

    if (entry && entry->undo)
        _freeUndo(entry);
    SNMP_FREE( entry ); /* TODO - release any other internal resources */
}

/** **************************************************************************
 *
 * handle cache / interactions with snmpTlstmParams container in snmplib
 *
 */
static void
_params_add(snmpTlstmParamsTable_entry *entry)
{
    snmpTlstmParams     *params;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmParamsTable:params:add", "name %s, fp %s\n",
                entry->snmpTargetParamsName, entry->snmpTlstmParamsClientFingerprint));

    params =
        netsnmp_tlstmParams_create(entry->snmpTargetParamsName,
                                   entry->hashType,
                                   entry->snmpTlstmParamsClientFingerprint,
                                   entry->snmpTlstmParamsClientFingerprint_len);
    if (NULL == params)
        return;

    params->flags = TLSTM_PARAMS_FROM_MIB;
    if (entry->snmpTlstmParamsStorageType == ST_NONVOLATILE)
        params->flags |= TLSTM_PARAMS_NONVOLATILE;

    if (netsnmp_tlstmParams_add(params) != 0) {
        netsnmp_tlstmParams_free(params);
    }
}

static void
_params_remove(snmpTlstmParamsTable_entry *entry)
{
    snmpTlstmParams      index, *found;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmParamsTable:params:remove", "name %s\n",
                entry->snmpTargetParamsName));

    index.name = entry->snmpTargetParamsName;
    found = netsnmp_tlstmParams_find(&index);
    if (found) {
        netsnmp_tlstmParams_remove(found);
        netsnmp_tlstmParams_free(found);
    }
    entry->params_flags = 0;
}

static void
_params_tweak_storage(snmpTlstmParamsTable_entry *entry)
{
    snmpTlstmParams     *params, index;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmParamsTable:params:tweak", "name %s, st %d\n",
                entry->snmpTargetParamsName, entry->snmpTlstmParamsStorageType));

    index.name = entry->snmpTargetParamsName;
    params = netsnmp_tlstmParams_find(&index);
    if (NULL == params) {
        DEBUGMSGTL(("tlstmParamsTable:params:tweak",
                    "couldn't find params!\n"));
        return;
    }

    if (entry->snmpTlstmParamsStorageType == ST_NONVOLATILE)
        params->flags |= TLSTM_PARAMS_NONVOLATILE;
    else
        params->flags &= ~TLSTM_PARAMS_NONVOLATILE;
}

static netsnmp_tdata_row *
_entry_from_params(snmpTlstmParams  *params)
{
    netsnmp_tdata_row *row;
    snmpTlstmParamsTable_entry *entry;

    row = snmpTlstmParamsTable_createEntry(NULL, params->name,
                                       strlen(params->name));
    if (NULL == row) {
        snmp_log(LOG_ERR, "can create snmpTlstmParams row entry\n");
        return NULL;
    }
    entry = row->data;

    if (params->flags & TLSTM_PARAMS_FROM_CONFIG)
        entry->snmpTlstmParamsStorageType = ST_PERMANENT;
    else if (! (params->flags & TLSTM_PARAMS_NONVOLATILE))
        entry->snmpTlstmParamsStorageType = ST_VOLATILE;

    entry->snmpTlstmParamsRowStatus = RS_ACTIVE;

    if (params->fingerprint) {
        entry->snmpTlstmParamsClientFingerprint_len = 
            strlen(params->fingerprint);
        if (entry->snmpTlstmParamsClientFingerprint_len >
            sizeof(entry->snmpTlstmParamsClientFingerprint))
            entry->snmpTlstmParamsClientFingerprint_len =
                sizeof(entry->snmpTlstmParamsClientFingerprint) - 1;
        memcpy(entry->snmpTlstmParamsClientFingerprint, params->fingerprint,
               entry->snmpTlstmParamsClientFingerprint_len);
        entry->snmpTlstmParamsClientFingerprint[sizeof(entry->snmpTlstmParamsClientFingerprint) - 1] = 0;
    }
    entry->hashType = params->hashType;
    entry->params_flags = params->flags;

    return row;
}

static int
snmpTlstmParamsTable_load( netsnmp_cache *cache, void *vmagic )
 {
    netsnmp_tdata     *table = (netsnmp_tdata *)vmagic;
    netsnmp_tdata_row *row;
    netsnmp_container *active_params;
    netsnmp_iterator  *itr;
    snmpTlstmParams   *params;
    int                rc = 0;

    active_params = netsnmp_tlstmParams_container();
    if (NULL == active_params)
        return 0;

    DEBUGMSGTL(("tlstmParamsTable:cache:load", "snmpTlstmParams %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(active_params)));
    itr = CONTAINER_ITERATOR(active_params);
    if (NULL == itr) {
        DEBUGMSGTL(("tlstmParamsTable:cache:load",
                    "cant get iterator\n"));
        return -1;
    }

    /*
     * insert rows for active params into tbl container
     */
    params = ITERATOR_FIRST(itr);
    for( ; params; params = ITERATOR_NEXT(itr)) {

        row = _entry_from_params(params);
        if (NULL == row) {
            rc =-1;
            break;
        }
        if (netsnmp_tdata_add_row(table, row) != SNMPERR_SUCCESS) {
            snmpTlstmParamsTable_removeEntry(NULL, row);
            rc = -1;
            break;
        }
    }
    ITERATOR_RELEASE(itr);

    DEBUGMSGTL(("tlstmParamsTable:cache:load", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    return rc;
}

static void
snmpTlstmParamsTable_free( netsnmp_cache *cache, void *vmagic )
{
    netsnmp_tdata            *table = (netsnmp_tdata *)vmagic;
    netsnmp_tdata_row        *row;
    netsnmp_iterator         *tbl_itr;
    snmpTlstmParamsTable_entry   *entry;

    DEBUGMSGTL(("tlstmParamsTable:cache:free", "called, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));

    tbl_itr = CONTAINER_ITERATOR(table->container);
    if (NULL == tbl_itr) {
        DEBUGMSGTL(("tlstmParamsTable:cache:free",
                    "cant get entry iterator\n"));
        return;
    }

    row = ITERATOR_FIRST(tbl_itr);
    for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
        entry = row->data;

        /*
         * remove all active rows (they are in the params container kept
         * by the library). Keep inactive ones for next time.
         */
        if (entry->snmpTlstmParamsRowStatus == RS_ACTIVE) {
            snmpTlstmParamsTable_removeEntry(NULL, row);
            ITERATOR_REMOVE(tbl_itr);
            continue;
        }
    }
    ITERATOR_RELEASE(tbl_itr);

    DEBUGMSGTL(("tlstmParamsTable:cache:free", "done, %" NETSNMP_PRIz "d rows\n",
                CONTAINER_SIZE(table->container)));
}

/** **************************************************************************
 *
 * handles requests for the snmpTlstmParamsTable table
 *
 */
static int
snmpTlstmParamsTable_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request = NULL;
    netsnmp_table_request_info *table_info;
    netsnmp_tdata              *table_data;
    netsnmp_tdata_row          *table_row;
    snmpTlstmParamsTable_entry          *table_entry;
    int                         ret = SNMP_ERR_NOERROR;
    
    DEBUGMSGTL(("tlstmParamsTable:handler", "Processing %s mode (%d) request\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode),
                reqinfo->mode));

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

            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            table_info  =     netsnmp_extract_table_info( request);
            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT: 
            {
                u_char bin[42], *ptr = bin;
                size_t len = sizeof(bin), offset = 1;
                int    rc;
                bin[0] = table_entry->hashType;
                netsnmp_assert(table_entry->hashType != 0);
                rc = netsnmp_hex_to_binary(
                    &ptr, &len, &offset, 0,
                    table_entry->snmpTlstmParamsClientFingerprint, NULL);
                if (1 != rc)
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_GENERR);
                else
                    snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                             bin, offset);
            }
                break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */
            case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE:
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->snmpTlstmParamsStorageType);
                break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */
            case COLUMN_SNMPTLSTMPARAMSROWSTATUS:
                snmp_set_var_typed_integer( request->requestvb, ASN_INTEGER,
                                            table_entry->snmpTlstmParamsRowStatus);
                break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            } /* switch colnum */
        } /* for requests */
        break; /* case MODE_GET */

        /*
         * Write-support
         */
    /** #################################################### RESERVE1 #####
     *
     *   In RESERVE1 we are just checking basic ASN.1 size/type restrictions.
     * You probably don't need to change any of this code. Don't change any
     * of the column values here. Save that for the ACTION phase.
     *
     *   The next phase is RESERVE2 or FREE.
     */
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            table_info  =     netsnmp_extract_table_info( request);

            if ((NULL != table_entry) &&
                (ST_READONLY == table_entry->snmpTlstmParamsStorageType)) {
                ret = SNMP_ERR_NOTWRITABLE;
                break;
            }
            
            /*
             * for each column, allocate any additional resources needed
             * beyond what is in the undo structure.
             */
            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT:
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, ASN_OCTET_STR, sizeof(table_entry->snmpTlstmParamsClientFingerprint));
                /** check len/algorithm MIB requirements */
                if (SNMP_ERR_NOERROR == ret)
                    ret = netsnmp_cert_check_vb_fingerprint(request->requestvb);

                break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */

            case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE:
                ret = netsnmp_check_vb_storagetype(request->requestvb,
                         (table_entry ? table_entry->snmpTlstmParamsStorageType : ST_NONE ));
                break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */

            case COLUMN_SNMPTLSTMPARAMSROWSTATUS:
                ret = netsnmp_check_vb_rowstatus_with_storagetype(request->requestvb,
                         (table_entry ? table_entry->snmpTlstmParamsRowStatus : RS_NONEXISTENT ),
                         (table_entry ? table_entry->snmpTlstmParamsStorageType : ST_NONE));
                break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */
            default:
                ret = SNMP_ERR_NOTWRITABLE;
            } /* switch colnum */

            if ( ret != SNMP_ERR_NOERROR )
                break;
        }/* for requests */
        break; /* case MODE_SET_RESERVE1 */

    /** #################################################### RESERVE2 #####
     *
     *   RESERVE2 is for checking additional restrictions from the MIB.
     * Since these restrictions are often in the description of the object,
     * mib2c can't generate code. It's possible that you need to add
     * additional checks here. However, don't change any of the column
     * values here. Save that for the ACTION phase.
     *
     *   The next phase is ACTION or FREE.
     */
    case MODE_SET_RESERVE2:
        for (request=requests; request; request=request->next) {
            table_entry = (snmpTlstmParamsTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_data = netsnmp_tdata_extract_table(request);
            table_info = netsnmp_extract_table_info( request);
            /*
             * if no table_row, create one
             */
            if ( !table_entry ) {
                table_row = snmpTlstmParamsTable_createEntry
                    (table_data,  (char*)table_info->indexes->val.string, 
                     table_info->indexes->val_len);
                if (!table_row) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                table_entry = table_row->data;
                _allocUndo(table_entry);
                if (table_entry && !table_entry->undo) {
                    snmpTlstmParamsTable_removeEntry(table_data, table_row);
                    table_row = NULL;
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
                table_entry->undo->fate = FATE_NEWLY_CREATED;
                /** associate row with requests */
                netsnmp_insert_tdata_row( request, table_row );
            }
            
            /** allocate undo structure, if needed */
            if(!table_entry->undo) {
                _allocUndo(table_entry);
                if (!table_entry->undo) {
                    ret = SNMP_ERR_RESOURCEUNAVAILABLE;
                    break;
                }
            }
            
            /** don't allow multiple sets of same column */
            if (table_entry->undo->req[table_info->colnum]) {
                DEBUGMSGT(("tlstmParamsTable:reserve2",
                           "multiple sets to col %d in request\n",
                           table_info->colnum));
                ret = SNMP_ERR_INCONSISTENTNAME;
                break;
            }
            table_entry->undo->req[table_info->colnum] = request;
            
            if ( ret != SNMP_ERR_NOERROR )
                break;
        } /* for requests */

        /** make sure rowstatus is used to create rows */
        if ( ret == SNMP_ERR_NOERROR ) {
            for (request = requests; request; request = request->next) {
                if (request->processed)
                    continue;

                table_entry = (snmpTlstmParamsTable_entry *)
                    netsnmp_tdata_extract_entry(request);
                if ((table_entry->undo->fate != FATE_NEWLY_CREATED) ||
                    (table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS]))
                    continue;
                ret = SNMP_ERR_INCONSISTENTNAME;
            break;
            } /* for requests / creation */
        } /* if no error */
        break; /* case MODE_SET_RESERVE2 */

    /** ######################################################## FREE #####
     *
     *   FREE is for cleaning up after a failed request (during either
     * RESERVE1 or RESERVE2). So any allocated resources need to be
     * released.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_FREE:
        /*
         * release undo resources
         * remove any newly created rows
         */
        for (request=requests; request; request=request->next) {
            table_row   =     netsnmp_tdata_extract_row(  request);
            table_data  =  netsnmp_tdata_extract_table(request);
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            
            if ( !table_entry || !table_entry->undo )
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row( request, table_row );

            if (FATE_NEWLY_CREATED == table_entry->undo->fate )
                snmpTlstmParamsTable_removeEntry( table_data, table_row );
            else
                _freeUndo(table_entry);
        }
        break; /* case MODE_SET_FREE */

    /** ###################################################### ACTION #####
     *
     *   In the ACTION phase, we perform any sets that can be undone.
     * (Save anything that can't be undone for the COMMIT phase.)
     *
     *   After individual columns have been done, you should check that the
     * row as a whole is consistent.
     *
     * The next phase is UNDO or COMMIT.
     */
    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            table_info  =     netsnmp_extract_table_info( request);

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT:
            {
                u_char *tmp = (u_char*)table_entry->snmpTlstmParamsClientFingerprint;

                memcpy( table_entry->undo->snmpTlstmParamsClientFingerprint,
                        table_entry->snmpTlstmParamsClientFingerprint,
                        sizeof(table_entry->snmpTlstmParamsClientFingerprint));
                table_entry->undo->snmpTlstmParamsClientFingerprint_len =
                    table_entry->snmpTlstmParamsClientFingerprint_len;

                table_entry->hashType = request->requestvb->val.string[0];
                memset( table_entry->snmpTlstmParamsClientFingerprint, 0,
                        sizeof(table_entry->snmpTlstmParamsClientFingerprint));
                table_entry->snmpTlstmParamsClientFingerprint_len =
                    sizeof(table_entry->snmpTlstmParamsClientFingerprint);
                table_entry->snmpTlstmParamsClientFingerprint_len =
                    netsnmp_binary_to_hex(&tmp, &table_entry->snmpTlstmParamsClientFingerprint_len,
                                          0, &request->requestvb->val.string[1],
                                          request->requestvb->val_len - 1);
                if (0 == table_entry->snmpTlstmParamsClientFingerprint_len)
                    ret = SNMP_ERR_GENERR;
            }
                break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */

            case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE:
                /* save snmpTlstmParamsStorageType value */
                table_entry->undo->snmpTlstmParamsStorageType = table_entry->snmpTlstmParamsStorageType;
                /* get value from varbind */
                table_entry->snmpTlstmParamsStorageType = *request->requestvb->val.integer;
                break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */

            case COLUMN_SNMPTLSTMPARAMSROWSTATUS:
                /* save snmpTlstmParamsRowStatus value */
                table_entry->undo->snmpTlstmParamsRowStatus = table_entry->snmpTlstmParamsRowStatus;
                /* get value from varbind  */
                table_entry->snmpTlstmParamsRowStatus     = *request->requestvb->val.integer;
                break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */
            } /* switch colnum */
            if ( ret != SNMP_ERR_NOERROR )
                break;
        } /* set values for requests */

        if ( ret == SNMP_ERR_NOERROR ) {

            /*
             * All columns now have their final values set. check the
             * internal consistency of each row.
             */
            for (request=requests; request; request=request->next) {
                table_entry = (snmpTlstmParamsTable_entry *)
                    netsnmp_tdata_extract_entry(request);
                table_info  =     netsnmp_extract_table_info( request);
                
                if (table_entry->undo->is_consistent != -1)
                    continue; /* already checked */
                
                /** assume consistency */
                table_entry->undo->is_consistent = 1;
                
                if ((RS_IS_ACTIVE(table_entry->snmpTlstmParamsRowStatus)) &&
                    ((!table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS]) ||
                     (RS_IS_ACTIVE(table_entry->undo->snmpTlstmParamsRowStatus)))) {
                    /*
                     * check mib restrictions on active rows.
                     */
                    if (table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT];
                        ret = SNMP_ERR_INCONSISTENTVALUE; /* per mib */
                    }
                } /* active row */
                else if (RS_IS_GOING_ACTIVE(table_entry->snmpTlstmParamsRowStatus)) {
                    /*
                     * check restrictions for activating a row
                     */
                    /** if going active, inconsistency is fatal */
                    if (!table_entry->undo->is_consistent) {
                        if (FATE_NEWLY_CREATED == table_entry->undo->fate)
                            ret = SNMP_ERR_INCONSISTENTNAME;
                        else
                            ret = SNMP_ERR_INCONSISTENTVALUE;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS];
                    }
                } /* going active */
                else if (RS_DESTROY == table_entry->snmpTlstmParamsRowStatus) {
                    /*
                     * TODO: check restrictions for deleting a row
                     */
                    /** can't delete active row */
                    if (RS_IS_ACTIVE(table_entry->undo->snmpTlstmParamsRowStatus)) {
                        ret = SNMP_ERR_INCONSISTENTVALUE;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS];
                    }
                } /* destroy */
                if ( ret != SNMP_ERR_NOERROR )
                    break;
            } /* consistency for requests */
        } /* if no error */
        break; /* case MODE_SET_ACTION */

    /** ######################################################## UNDO #####
     *
     *   UNDO is for cleaning up any failed requests that went through the
     * ACTION phase.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_UNDO:
        for (request=requests; request; request=request->next) {
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            table_row   =     netsnmp_tdata_extract_row(  request);
            table_data  =     netsnmp_tdata_extract_table(request);
            table_info  =     netsnmp_extract_table_info( request);

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT:
                /* restore snmpTlstmParamsClientFingerprint value */
                memcpy( table_entry->snmpTlstmParamsClientFingerprint,
                        table_entry->undo->snmpTlstmParamsClientFingerprint,
                        sizeof(table_entry->snmpTlstmParamsClientFingerprint));
                table_entry->snmpTlstmParamsClientFingerprint_len =
                    table_entry->undo->snmpTlstmParamsClientFingerprint_len;
                break; /* case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT */

            case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE:
                /* restore snmpTlstmParamsStorageType value */
                table_entry->snmpTlstmParamsStorageType =
                    table_entry->undo->snmpTlstmParamsStorageType;
                break; /* case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE */

                case COLUMN_SNMPTLSTMPARAMSROWSTATUS:
                    /* restore snmpTlstmParamsRowStatus value */
                    table_entry->snmpTlstmParamsRowStatus = table_entry->undo->snmpTlstmParamsRowStatus;
                    break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */
            } /* switch colnum */
        } /* for requests */

        /*
         * release undo data
         * or remove any newly created rows
         */
        for (request=requests; request; request=request->next) {
            table_row   =     netsnmp_tdata_extract_row(  request);
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);
            
            if ( !table_entry || !table_entry->undo )
                continue;

            /** disassociate row with requests */
            netsnmp_remove_tdata_row( request, table_row );
            
            if (FATE_NEWLY_CREATED == table_entry->undo->fate )
                snmpTlstmParamsTable_removeEntry( table_data, table_row );
            else
                _freeUndo(table_entry);
        } /* for requests */
        break; /* case MODE_SET_UNDO */

    /** ###################################################### COMMIT #####
     *
     *   COMMIT is the final success state, when all changes are finalized.
     * There is not recovery state should something faile here.
     *
     *   This the final phase for this path in the state machine.
     */
    case MODE_SET_COMMIT:
        for (request=requests; request; request=request->next) {
            table_row   =     netsnmp_tdata_extract_row(  request);
            table_data  =     netsnmp_tdata_extract_table(request);
            table_info  =     netsnmp_extract_table_info(    request);
            table_entry = (snmpTlstmParamsTable_entry *)
                              netsnmp_tdata_extract_entry(request);

            if (!table_entry || !table_entry->undo)
                continue;
            
            if ((RS_NOTREADY == table_entry->snmpTlstmParamsRowStatus) &&
                table_entry->undo->is_consistent)
                table_entry->snmpTlstmParamsRowStatus = RS_NOTINSERVICE;
            else if ((RS_NOTINSERVICE == table_entry->snmpTlstmParamsRowStatus) &&
                     (0 == table_entry->undo->is_consistent))
                table_entry->snmpTlstmParamsRowStatus = RS_NOTREADY;

            /** release undo data for requests with no rowstatus */
            if (table_entry->undo &&
                !table_entry->undo->req[COLUMN_SNMPTLSTMPARAMSROWSTATUS] != 0) {
                _freeUndo(table_entry);
                
                /** update active addrs */
                if ((0 == table_entry->params_flags) &&
                    (table_entry->snmpTlstmParamsRowStatus == RS_ACTIVE))
                    _params_add(table_entry);
                else if ((0 != table_entry->params_flags) &&
                         (table_entry->snmpTlstmParamsRowStatus == RS_DESTROY))
                    _params_remove(table_entry);
            }

            switch (table_info->colnum) {

            case COLUMN_SNMPTLSTMPARAMSROWSTATUS:
                switch (table_entry->snmpTlstmParamsRowStatus) {
                case RS_CREATEANDGO:
                    /** Fall-through */
                case RS_ACTIVE:
                    table_entry->snmpTlstmParamsRowStatus = RS_ACTIVE;
                    if (0 == table_entry->params_flags)
                        _params_add(table_entry);
                    break;

                case RS_CREATEANDWAIT:
                    /** Fall-through */
                case RS_NOTINSERVICE:
                    /** simply set status based on consistency */
                    if (table_entry->undo->is_consistent)
                        table_entry->snmpTlstmParamsRowStatus = RS_NOTINSERVICE;
                    else
                        table_entry->snmpTlstmParamsRowStatus = RS_NOTREADY;
                    if (0 != table_entry->params_flags)
                        _params_remove(table_entry);
                    break;

                case RS_DESTROY:
                    if (0 != table_entry->params_flags)
                        _params_remove(table_entry);
                    /** disassociate row with requests */
                    netsnmp_remove_tdata_row( request, table_row );
                    snmpTlstmParamsTable_removeEntry(table_data, table_row );
                    table_row = NULL;
                    table_entry = NULL;
                }
                /** release undo data */
                _freeUndo(table_entry);
                break; /* case COLUMN_SNMPTLSTMPARAMSROWSTATUS */

            case COLUMN_SNMPTLSTMPARAMSSTORAGETYPE:
                    if (RS_ACTIVE == table_entry->snmpTlstmParamsRowStatus)
                        _params_tweak_storage(table_entry);
                    break;

            case COLUMN_SNMPTLSTMPARAMSCLIENTFINGERPRINT:
                break;
            } /* switch colnum */
        } /* for requests */

        /** update last changed */
        _last_changed = netsnmp_get_agent_uptime();

        /** set up to save persistent store */
        snmp_store_needed(NULL);

        break; /* case MODE_SET_COMMIT */
    }  /* switch (reqinfo->mode) */
    
    if ( ret != SNMP_ERR_NOERROR )
        netsnmp_set_request_error( reqinfo, request, ret);
    
    return SNMP_ERR_NOERROR;
}


static int
_count_handler(netsnmp_mib_handler *handler,
               netsnmp_handler_registration *reginfo,
               netsnmp_agent_request_info *reqinfo,
               netsnmp_request_info *requests)
{
    int                val;

    if (MODE_GET != reqinfo->mode) {
        snmp_log(LOG_ERR, "bad mode in RO handler");
        return SNMP_ERR_GENERR;
    }

    if (NULL == _table_data->container)
        val = 0;
    else
        val = CONTAINER_SIZE(_table_data->container);

    snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
                             (u_char *) &val, sizeof(val));
   
    if (handler->next && handler->next->access_method)
        return netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
    
    return SNMP_ERR_NOERROR;
}

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/

static int _tlstmParamsTable_save(int majorID, int minorID,
                                  void *serverarg, void *clientarg);
static int _save_params(snmpTlstmParams *params, void *app_type);
static int _save_entry(snmpTlstmParamsTable_entry *entry, void *type);
static void _tlstmParamsTable_row_restore_mib(const char *token, char *buf);

static const char mib_token[] = "snmpTlstmParamsEntry";

/************************************************************
 * *_init_persistence should be called from the main table
 * init routine.
 *
 * If your table depends on rows in another table,
 * you should register your callback after the other table,
 * which should ensure the rows on which you depend are saved
 * (and re-created) before the dependent rows.
 */
void
_tlstmParams_init_persistence(void)
{
    int             rc;

    register_config_handler(NULL, mib_token, _tlstmParamsTable_row_restore_mib,
                            NULL, NULL);
    rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                                SNMP_CALLBACK_STORE_DATA,
                                _tlstmParamsTable_save,
                                _table_data->container);

    if (rc != SNMP_ERR_NOERROR)
        snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
                 "in _tlstmParams_init_persistence\n");
}

static int
_tlstmParamsTable_save(int majorID, int minorID, void *serverarg,
                       void *clientarg)
{
    char            sep[] =
        "##############################################################";
    char            buf[] = "#\n" "# tlstmParams persistent data\n" "#";
    char           *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                                 NETSNMP_DS_LIB_APPTYPE);

    netsnmp_container *active_params = netsnmp_tlstmParams_container();
    netsnmp_tdata_row *row;
    netsnmp_iterator  *tbl_itr, *params_itr;
    snmpTlstmParams   *params;
    snmpTlstmParamsTable_entry *entry;

    if ((CONTAINER_SIZE(active_params) == 0) &&
        (CONTAINER_SIZE(_table_data->container) == 0))
        return SNMPERR_SUCCESS;

    read_config_store((char *) type, sep);
    read_config_store((char *) type, buf);

    /*
     * save active rows from params container
     */
    if (NULL != active_params) {
        params_itr = CONTAINER_ITERATOR(active_params);
        if (NULL == params_itr) {
            DEBUGMSGTL(("tlstmParamsTable:save",
                        "cant get params iterator\n"));
            params = NULL;
        }
        else
            params = ITERATOR_FIRST(params_itr);

        for( ; params; params = ITERATOR_NEXT(params_itr)) {
            /** don't store config rows */
            if ((params->flags & TLSTM_PARAMS_FROM_CONFIG) ||
                ! (params->flags & TLSTM_PARAMS_NONVOLATILE))
                continue;
            _save_params(params, type);
        }
    }
    ITERATOR_RELEASE(params_itr);

    /*
     * save inactive rows from mib
     */
    tbl_itr = CONTAINER_ITERATOR(_table_data->container);
    if (NULL == tbl_itr)
        DEBUGMSGTL(("tlstmParamsTable:save", "cant get table iterator\n"));
    else {
        row = ITERATOR_FIRST(tbl_itr);
        for( ; row; row = ITERATOR_NEXT(tbl_itr)) {
            entry = row->data;

            /*
             * skip all active rows (should be in active_params and thus saved
             * above) and volatile rows.
             */
            if ((entry->snmpTlstmParamsRowStatus == RS_ACTIVE) ||
                (entry->snmpTlstmParamsStorageType != ST_NONVOLATILE))
                continue;

            _save_entry(entry, type);
        }
        ITERATOR_RELEASE(tbl_itr);
    }

    read_config_store((char *) type, sep);
    read_config_store((char *) type, "\n");

    /*
     * never fails 
     */
    return SNMPERR_SUCCESS;
}

/************************************************************
 * _tlstmParamsTable_container_row_save
 */
static int
_save_entry(snmpTlstmParamsTable_entry *entry, void *type)
{
    char   buf[SNMP_MAXBUF_SMALL], *hashType;

    hashType = se_find_label_in_slist("cert_hash_alg", entry->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 entry->hashType);
        return SNMP_ERR_GENERR;
    }

    /*
     * build the line
     */
    netsnmp_assert(0 == entry->snmpTargetParamsName[
                       entry->snmpTargetParamsName_len]);
    netsnmp_assert(0 == entry->snmpTlstmParamsClientFingerprint[
                       entry->snmpTlstmParamsClientFingerprint_len]);
    snprintf(buf, sizeof(buf), "%s %s %s %s %d", mib_token,
             entry->snmpTargetParamsName, hashType,
             entry->snmpTlstmParamsClientFingerprint,
             entry->snmpTlstmParamsRowStatus);
    buf[sizeof(buf)-1] = 0;

    read_config_store(type, buf);
    DEBUGMSGTL(("tlstmParamsTable:row:save", "saving entry '%s'\n", buf));

    return SNMP_ERR_NOERROR;
}

static int
_save_params(snmpTlstmParams *params, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType;

    if (NULL == params)
        return SNMP_ERR_GENERR;

    hashType = se_find_label_in_slist("cert_hash_alg", params->hashType);
    if (NULL == hashType) {
        snmp_log(LOG_ERR, "skipping entry unknown hash type %d\n",
                 params->hashType);
        return SNMP_ERR_GENERR;
    }
    snprintf(buf, sizeof(buf), "%s %s --%s %s %d", mib_token, params->name,
             hashType, params->fingerprint, RS_ACTIVE);

    DEBUGMSGTL(("tlstmParamsTable:params:save", "saving params '%s'\n",
                buf));
    read_config_store(app_type, buf);

    return SNMP_ERR_NOERROR;
}

static void
_tlstmParamsTable_row_restore_mib(const char *token, char *buf)
{
    u_char                 rowStatus;
    snmpTlstmParams       *params;

    /** need somewhere to save rows */
    netsnmp_assert(_table_data && _table_data->container); 

    params = netsnmp_tlstmParams_restore_common(&buf);
    if (NULL == params)
        return;

    if (NULL == buf) {
        config_perror("incomplete line");
        return;
    }
    rowStatus = atoi(buf);

    /*
     * if row is active, add it to the params container so it is available
     * for use. Do not add it to the table, since it will be added
     * during cache_load.
     */
    if (RS_ACTIVE == rowStatus) {
        params->flags = TLSTM_PARAMS_FROM_MIB | TLSTM_PARAMS_NONVOLATILE;

        if (netsnmp_tlstmParams_add(params) != 0)
            netsnmp_tlstmParams_free(params);
    }
    else {
        netsnmp_tdata_row     *row;
        snmpTlstmParamsTable_entry  *entry;

        row = snmpTlstmParamsTable_createEntry(_table_data, params->name,
                                               strlen(params->name));
        if (!row)
            return;

        entry = row->data;
        
        entry->hashType = params->hashType;
        strlcpy(entry->snmpTlstmParamsClientFingerprint, params->fingerprint,
                sizeof(entry->snmpTlstmParamsClientFingerprint));
        entry->snmpTlstmParamsClientFingerprint_len =
            strlen(entry->snmpTlstmParamsClientFingerprint);
        entry->snmpTlstmParamsStorageType = ST_NONVOLATILE;
        entry->snmpTlstmParamsRowStatus = rowStatus;
        netsnmp_tlstmParams_free(params);
    }
}
