/*
 * Note: this file originally auto-generated by mib2c using
 *  $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.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 "snmpTlstmAddrTable.h"

netsnmp_feature_require(table_tdata)
netsnmp_feature_require(tlstmaddr_container)
netsnmp_feature_require(table_tdata_delete_table)
netsnmp_feature_require(table_tdata_extract_table)
netsnmp_feature_require(table_tdata_remove_row)
#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(check_vb_storagetype)
netsnmp_feature_require(check_vb_type_and_max_size)
netsnmp_feature_require(table_tdata_insert_row)
#endif /* NETSNMP_NO_WRITE_SUPPORT */

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

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
    /*
     * structure for undo storage and other vars for set processing 
     */
typedef struct tlstmAddrTable_undo_s {
    char            fate;
    char            copied;
    char            is_consistent;
    netsnmp_request_info *req[TLSTMADDRTABLE_MAX_COLUMN + 1];
    /*
     * undo Column space 
     */
    char       tlstmAddrServerFingerprint[TLSTMADDRSERVERFINGERPRINT_MAX_SIZE];
    size_t          tlstmAddrServerFingerprint_len;
    char            tlstmAddrServerIdentity[TLSTMADDRSERVERIDENTITY_MAX_SIZE];
    size_t          tlstmAddrServerIdentity_len;
    char            tlstmAddrStorageType;
    char            tlstmAddrRowStatus;
    char            hashType;
} tlstmAddrTable_undo;

    /*
     * Typical data structure for a row entry 
     */
typedef struct tlstmAddrTable_entry_s {
    /*
     * Index values 
     */
    char            snmpTargetAddrName[SNMPTARGETADDRNAME_MAX_SIZE];
    size_t          snmpTargetAddrName_len;

    /*
     * Column values 
     */
    char        tlstmAddrServerFingerprint[TLSTMADDRSERVERFINGERPRINT_MAX_SIZE];
    size_t          tlstmAddrServerFingerprint_len;
    char            tlstmAddrServerIdentity[TLSTMADDRSERVERIDENTITY_MAX_SIZE];
    size_t          tlstmAddrServerIdentity_len;
    char            tlstmAddrStorageType;
    char            tlstmAddrRowStatus;
    char            hashType;

    /*
     * used during set processing 
     */
    tlstmAddrTable_undo *undo;

    /*
     * user data
     */
    struct netsnmp_cert_s   *cert;
    char                     addr_flags;

} tlstmAddrTable_entry;

netsnmp_tdata_row *tlstmAddrTable_createEntry(netsnmp_tdata * table_data,
                                              char *snmpTargetAddrName,
                                              size_t snmpTargetAddrName_len);
void tlstmAddrTable_removeEntry(netsnmp_tdata * table_data,
                                netsnmp_tdata_row * row);

static Netsnmp_Node_Handler tlstmAddrTable_handler;
static int _cache_load(netsnmp_cache *cache, netsnmp_tdata *table);
static void _cache_free(netsnmp_cache *cache, netsnmp_tdata *table);
static uint32_t _last_changed = 0;
static int _count_handler(netsnmp_mib_handler *handler,
                          netsnmp_handler_registration *reginfo,
                          netsnmp_agent_request_info *reqinfo,
                          netsnmp_request_info *requests);

static void _tlstmAddr_init_persistence(void);
static void _addrs_add(tlstmAddrTable_entry *entry);
static void _addrs_remove(tlstmAddrTable_entry *entry);
static void _addr_tweak_storage(tlstmAddrTable_entry *entry);
static netsnmp_tdata  *_table_data = NULL;

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/** Initializes the tlstmAddrTable module */
void
init_snmpTlstmAddrTable(void)
{
    oid             reg_oid[] = { SNMP_TLS_TM_ADDR_TABLE };
    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(("tlstmAddrTable:init",
                "initializing table tlstmAddrTable\n"));

    reg =
        netsnmp_create_handler_registration("tlstmAddrTable",
                                            tlstmAddrTable_handler,
                                            reg_oid, reg_oid_len,
                                            HANDLER_CAN_RWRITE);

    _table_data = netsnmp_tdata_create_table("tlstmAddrTable", 0);
    if (NULL == _table_data) {
        snmp_log(LOG_ERR, "error creating tdata table for tlstmAddrTable\n");
        return;
    }
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR, "error creating table info for tlstmAddrTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        return;
    }

    /*
     * cache init
     */
    cache = netsnmp_cache_create(30, (NetsnmpCacheLoad*)_cache_load,
                                 (NetsnmpCacheFree*)_cache_free,
                                 reg_oid, reg_oid_len);
    if (NULL == cache) {
        snmp_log(LOG_ERR,"error creating cache for tlstmCertToTSNTable\n");
        netsnmp_tdata_delete_table(_table_data);
        _table_data = NULL;
        return;
    }
    cache->magic = (void *)_table_data;
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    /*
     * populate index types
     */
    netsnmp_table_helper_add_indexes(table_info,
                                     /* index: snmpTargetAddrName */
                                     ASN_PRIV_IMPLIED_OCTET_STR, 
                                     0);

    table_info->min_column = TLSTMADDRTABLE_MIN_COLUMN;
    table_info->max_column = TLSTMADDRTABLE_MAX_COLUMN;

    netsnmp_tdata_register(reg, _table_data, table_info);

    if (cache) 
        netsnmp_inject_handler_before( reg, netsnmp_cache_handler_get(cache),
                                       "table_container");

    /*
     * register scalars
     */
    reg_oid[10] = 7;
    reg = netsnmp_create_handler_registration("snmpTlstmAddrCount",
                                              _count_handler, reg_oid,
                                              OID_LENGTH(reg_oid),
                                              HANDLER_CAN_RONLY);
    if (NULL == reg)
        snmp_log(LOG_ERR,
                 "could not create handler for snmpTlstmAddrCount\n");
    else {
        netsnmp_register_scalar(reg);
        if (cache) 
            netsnmp_inject_handler_before(reg,
                                          netsnmp_cache_handler_get(cache),
                                          "snmpTlstmAddrCount");
    }
    
    reg_oid[10] = 8;
    reg = netsnmp_create_handler_registration(
        "snmpTlstmAddrTableLastChanged", 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 snmpTlstmAddrTableLastChanged\n");
    else
        netsnmp_register_watched_scalar2(reg, watcher);

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

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/*
 * create a new row in the table 
 */
netsnmp_tdata_row *
tlstmAddrTable_createEntry(netsnmp_tdata * table_data,
                           char *snmpTargetAddrName,
                           size_t snmpTargetAddrName_len)
{
    tlstmAddrTable_entry *entry;
    netsnmp_tdata_row *row;

    if (snmpTargetAddrName_len > sizeof(entry->snmpTargetAddrName))
        return NULL;

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

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

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

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

    /*
     * defaults
     */
    entry->tlstmAddrServerFingerprint[0] = '\0';
    entry->tlstmAddrServerFingerprint_len = 0;
    entry->hashType = 0;
    entry->tlstmAddrServerIdentity[0] = '\0';
    entry->tlstmAddrServerIdentity_len = 0;
    entry->tlstmAddrStorageType = ST_NONVOLATILE;
    entry->tlstmAddrRowStatus = RS_NOTREADY;

    if (table_data) {
        DEBUGMSGTL(("tlstmAddrTable:row:insert", "row %p\n",row));
        netsnmp_tdata_add_row(table_data, row);
    }
    return row;
}

/*
 * allocate undo resources 
 */
static tlstmAddrTable_undo *
_allocUndo(tlstmAddrTable_entry * entry)
{
    if (!entry)
        return NULL;

    entry->undo = SNMP_MALLOC_TYPEDEF(tlstmAddrTable_undo);
    if (!entry->undo)
        return NULL;

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

    return entry->undo;
}

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

    SNMP_FREE(entry->undo);
}

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

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

    entry = (tlstmAddrTable_entry *) row->data;

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

    DEBUGIF("tlstmAddrTable:entry:delete") {
        char name[sizeof(entry->snmpTargetAddrName)+1];
        snprintf(name, sizeof(name), "%s", entry->snmpTargetAddrName);
        DEBUGMSGT(("tlstmAddrTable:entry:delete", "entry %s %p / row %p\n",
                   name, entry, row));
    }
    if (entry && entry->undo)
        _freeUndo(entry);
    SNMP_FREE(entry);
}


/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
/** handles requests for the tlstmAddrTable table */
static int
tlstmAddrTable_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;
    tlstmAddrTable_entry *table_entry;
    int             ret = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("tlstmAddrTable:handler", "Processing mode %s (%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 = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);
            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
            {
                u_char bin[42], *ptr = bin;
                size_t len = sizeof(bin), offset = 1;
                int    rc;

                if ((table_entry->hashType == 0) ||
                    (table_entry->tlstmAddrServerFingerprint_len ==0))
                    offset = 0;
                else {
                    bin[0] = table_entry->hashType;
                    rc = netsnmp_hex_to_binary(
                        &ptr, &len, &offset, 0,
                        table_entry->tlstmAddrServerFingerprint, NULL);
                    if (1 != rc)
                        ret = SNMP_ERR_GENERR;
                }
                if (ret == SNMP_ERR_NOERROR)
                    snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                             bin, offset);
            }
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                snmp_set_var_typed_value
                    (request->requestvb, ASN_OCTET_STR,
                     (u_char *) table_entry->tlstmAddrServerIdentity,
                     table_entry->tlstmAddrServerIdentity_len);
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->tlstmAddrStorageType);
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->tlstmAddrRowStatus);
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            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 = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);

            if ((NULL != table_entry) &&
                (ST_READONLY == table_entry->tlstmAddrStorageType)) {
                ret = SNMP_ERR_NOTWRITABLE;
                break;
            }

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(table_entry->tlstmAddrServerFingerprint));
                /** check len/algorithm MIB requirements */
                if (ret == SNMP_ERR_NOERROR)
                    ret = netsnmp_cert_check_vb_fingerprint(request->requestvb);
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                ret = netsnmp_check_vb_type_and_max_size
                    (request->requestvb, ASN_OCTET_STR,
                     sizeof(table_entry->tlstmAddrServerIdentity));
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                ret = netsnmp_check_vb_storagetype
                    (request->requestvb,
                     (table_entry ?
                      table_entry->tlstmAddrStorageType : ST_NONE));
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                ret = netsnmp_check_vb_rowstatus_with_storagetype
                    (request->requestvb,
                     (table_entry ?
                      table_entry->tlstmAddrRowStatus : RS_NONEXISTENT),
                     (table_entry ?
                      table_entry->tlstmAddrStorageType : ST_NONE));
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            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 = (tlstmAddrTable_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 = tlstmAddrTable_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) {
                    tlstmAddrTable_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(("tlstmAddrTable: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 = (tlstmAddrTable_entry *)
                    netsnmp_tdata_extract_entry(request);
                if ((table_entry->undo->fate != FATE_NEWLY_CREATED) ||
                    (table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS]))
                    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 =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;

            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)
                tlstmAddrTable_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 = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);
            table_info = netsnmp_extract_table_info(request);

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

                memcpy(table_entry->undo->tlstmAddrServerFingerprint,
                       table_entry->tlstmAddrServerFingerprint,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->undo->tlstmAddrServerFingerprint_len =
                    table_entry->tlstmAddrServerFingerprint_len;
                table_entry->undo->hashType = table_entry->hashType;

                table_entry->hashType = request->requestvb->val.string[0];
                table_entry->tlstmAddrServerFingerprint_len =
                    sizeof(table_entry->tlstmAddrServerFingerprint);
                memset(table_entry->tlstmAddrServerFingerprint, 0,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->tlstmAddrServerFingerprint_len =
                    netsnmp_binary_to_hex(&tmp, &table_entry->tlstmAddrServerFingerprint_len,
                                          0, &request->requestvb->val.string[1],
                                          request->requestvb->val_len - 1);
                if (0 == table_entry->tlstmAddrServerFingerprint_len)
                    ret = SNMP_ERR_GENERR;
            }
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                memcpy(table_entry->undo->tlstmAddrServerIdentity,
                       table_entry->tlstmAddrServerIdentity,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                table_entry->undo->tlstmAddrServerIdentity_len =
                    table_entry->tlstmAddrServerIdentity_len;
                memset(table_entry->tlstmAddrServerIdentity, 0,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                memcpy(table_entry->tlstmAddrServerIdentity,
                       request->requestvb->val.string,
                       request->requestvb->val_len);
                table_entry->tlstmAddrServerIdentity_len =
                    request->requestvb->val_len;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                table_entry->undo->tlstmAddrStorageType =
                    table_entry->tlstmAddrStorageType;
                table_entry->tlstmAddrStorageType =
                    *request->requestvb->val.integer;
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                table_entry->undo->tlstmAddrRowStatus =
                    table_entry->tlstmAddrRowStatus;
                table_entry->tlstmAddrRowStatus =
                    *request->requestvb->val.integer;
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            }                   /* 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 = (tlstmAddrTable_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;

                /*
                 * per mib, can't have empty fingerprint and wildcard id
                 */
                if ( (0 == table_entry->tlstmAddrServerFingerprint_len) &&
                     (1 == table_entry->tlstmAddrServerIdentity_len) &&
                     ('*' == table_entry->tlstmAddrServerIdentity[0]) ) {
                    DEBUGMSGTL(("tlstmAddrTable", "fingerprint must not "
                                "be empty for wildcard (*) identity\n"));
                    table_entry->undo->is_consistent = 0;
                }
                
                if ((RS_IS_ACTIVE(table_entry->tlstmAddrRowStatus)) &&
                    ((!table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS]) ||
                     (RS_IS_ACTIVE(table_entry->undo->tlstmAddrRowStatus)))) {
                    /*
                     * check mib restrictions on active rows.
                     */
                    if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT];
                    }
                    else if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERIDENTITY]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSERVERIDENTITY];
                    }
                    else if (table_entry->undo->req[COLUMN_SNMPTLSTMADDRSTORAGETYPE]) {
                        table_entry->undo->is_consistent = 0;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRSTORAGETYPE];
                    }
                    
                    if (!table_entry->undo->is_consistent)
                        ret = SNMP_ERR_INCONSISTENTVALUE; /* per mib */
                } /* active row */
                else if (RS_IS_GOING_ACTIVE
                         (table_entry->tlstmAddrRowStatus)) {
                    /** 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_SNMPTLSTMADDRROWSTATUS];
                    }
                } /* going active */
                else if (RS_DESTROY == table_entry->tlstmAddrRowStatus) {
                    /** can't delete active row */
                    if (RS_IS_ACTIVE(table_entry->undo->tlstmAddrRowStatus)) {
                        ret = SNMP_ERR_INCONSISTENTVALUE;
                        request = table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS];
                    }
                }               /* 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_row = netsnmp_tdata_extract_row(request);
            table_entry =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;
            table_data = netsnmp_tdata_extract_table(request);
            table_info = netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                /*
                 * restore tlstmAddrServerFingerprint value 
                 */
                memcpy(table_entry->tlstmAddrServerFingerprint,
                       table_entry->undo->tlstmAddrServerFingerprint,
                       sizeof(table_entry->tlstmAddrServerFingerprint));
                table_entry->tlstmAddrServerFingerprint_len =
                    table_entry->undo->tlstmAddrServerFingerprint_len;
                table_entry->hashType = table_entry->undo->hashType;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT */
            case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                /*
                 * restore tlstmAddrServerIdentity value 
                 */
                memcpy(table_entry->tlstmAddrServerIdentity,
                       table_entry->undo->tlstmAddrServerIdentity,
                       sizeof(table_entry->tlstmAddrServerIdentity));
                table_entry->tlstmAddrServerIdentity_len =
                    table_entry->undo->tlstmAddrServerIdentity_len;
                break;          /* case COLUMN_SNMPTLSTMADDRSERVERIDENTITY */
            case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                /*
                 * restore tlstmAddrStorageType value 
                 */
                table_entry->tlstmAddrStorageType =
                    table_entry->undo->tlstmAddrStorageType;
                break;          /* case COLUMN_SNMPTLSTMADDRSTORAGETYPE */
            case COLUMN_SNMPTLSTMADDRROWSTATUS:
                /*
                 * restore tlstmAddrRowStatus value 
                 */
                table_entry->tlstmAddrRowStatus =
                    table_entry->undo->tlstmAddrRowStatus;
                break;          /* case COLUMN_SNMPTLSTMADDRROWSTATUS */
            }                   /* 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 =
                (tlstmAddrTable_entry *) table_row ? table_row->
                data : NULL;

            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)
                tlstmAddrTable_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 = (tlstmAddrTable_entry *)
                netsnmp_tdata_extract_entry(request);

            if (!table_entry || !table_entry->undo)
                continue;

            if ((RS_NOTREADY == table_entry->tlstmAddrRowStatus) &&
                table_entry->undo->is_consistent)
                table_entry->tlstmAddrRowStatus = RS_NOTINSERVICE;
            else if ((RS_NOTINSERVICE == table_entry->tlstmAddrRowStatus) &&
                     (0 == table_entry->undo->is_consistent))
                table_entry->tlstmAddrRowStatus = RS_NOTREADY;

            /** release undo data for requests with no rowstatus */
            if (table_entry->undo &&
                !table_entry->undo->req[COLUMN_SNMPTLSTMADDRROWSTATUS] != 0) {

                _freeUndo(table_entry);

                /** update active addrs */
                if ((0 == table_entry->addr_flags) &&
                    (table_entry->tlstmAddrRowStatus == RS_ACTIVE))
                    _addrs_add(table_entry);
                else if ((0 != table_entry->addr_flags) &&
                         (table_entry->tlstmAddrRowStatus == RS_DESTROY))
                    _addrs_remove(table_entry);
            }

            switch (table_info->colnum) {
                case COLUMN_SNMPTLSTMADDRROWSTATUS:
                    switch (table_entry->tlstmAddrRowStatus) {
                    case RS_CREATEANDGO:
                    /** Fall-through */
                    case RS_ACTIVE:
                        table_entry->tlstmAddrRowStatus = RS_ACTIVE;
                        if (0 == table_entry->addr_flags)
                            _addrs_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->tlstmAddrRowStatus =
                                RS_NOTINSERVICE;
                        else
                            table_entry->tlstmAddrRowStatus = RS_NOTREADY;
                        if (0 != table_entry->addr_flags)
                            _addrs_remove(table_entry);
                        break;

                    case RS_DESTROY:
                        if (0 != table_entry->addr_flags)
                            _addrs_remove(table_entry);
                        /** disassociate row with requests */
                        netsnmp_remove_tdata_row(request, table_row);
                        tlstmAddrTable_removeEntry(table_data, table_row);
                        table_row = NULL;
                        table_entry = NULL;
                    }
                    /** release undo data */
                    _freeUndo(table_entry);
                    break;      /* case COLUMN_SNMPTLSTMADDRROWSTATUS */

                case COLUMN_SNMPTLSTMADDRSTORAGETYPE:
                    if (RS_ACTIVE == table_entry->tlstmAddrRowStatus)
                        _addr_tweak_storage(table_entry);
                    break;

                case COLUMN_SNMPTLSTMADDRSERVERFINGERPRINT:
                case COLUMN_SNMPTLSTMADDRSERVERIDENTITY:
                    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;
}

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/
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) || (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;
}

/** **************************************************************************
 *
 * handle cache / interactions with tlstmAddr container in snmplib
 *
 ** *************************************************************************/
static void
_addrs_add(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr     *addr;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addrs:add", "name %s, fp %s\n",
                entry->snmpTargetAddrName, entry->tlstmAddrServerFingerprint));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    addr = netsnmp_tlstmAddr_create(entry->snmpTargetAddrName);
    if (NULL == addr)
        return;

    if (entry->tlstmAddrServerFingerprint_len)
        addr->fingerprint = strdup(entry->tlstmAddrServerFingerprint);
    if (entry->tlstmAddrServerIdentity_len)
        addr->identity = strdup(entry->tlstmAddrServerIdentity);
    addr->hashType = entry->hashType;

    addr->flags = TLSTM_ADDR_FROM_MIB;
    if (entry->tlstmAddrStorageType == ST_NONVOLATILE)
        addr->flags |= TLSTM_ADDR_NONVOLATILE;

    if (CONTAINER_INSERT(addrs, addr) != 0) {
        netsnmp_tlstmAddr_free(addr);
        snmp_log(LOG_ERR, "could not insert new tlstm addr");
    }
}

static void
_addrs_remove(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr      addr;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addr:remove", "name %s, fp %s\n",
                entry->snmpTargetAddrName, entry->tlstmAddrServerFingerprint));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    addr.name = entry->snmpTargetAddrName;
    if (CONTAINER_REMOVE(addrs, &addr) != 0) {
        snmp_log(LOG_ERR, "could not remove tlstm addr");
    }
    entry->addr_flags = 0;
}

static void
_addr_tweak_storage(tlstmAddrTable_entry *entry)
{
    netsnmp_container *addrs;
    snmpTlstmAddr     *addr, index;

    if (NULL == entry)
        return;

    DEBUGMSGTL(("tlstmAddrTable:addr:tweak", "name %s, st %d\n",
                entry->snmpTargetAddrName, entry->tlstmAddrStorageType));

    /** get current active addrs */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return;

    index.name = entry->snmpTargetAddrName;
    addr = CONTAINER_FIND(addrs, &index);
    if (NULL == addr) {
        DEBUGMSGTL(("tlstmAddrTable:addr:tweak", "couldn't find addr!\n"));
        return;
    }

    if (entry->tlstmAddrStorageType == ST_NONVOLATILE)
        addr->flags |= TLSTM_ADDR_NONVOLATILE;
    else
        addr->flags &= ~TLSTM_ADDR_NONVOLATILE;
}

static netsnmp_tdata_row *
_entry_from_addr(snmpTlstmAddr  *addr)
{
    netsnmp_tdata_row *row;
    tlstmAddrTable_entry *entry;

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

    if (addr->flags & TLSTM_ADDR_FROM_CONFIG)
        entry->tlstmAddrStorageType = ST_PERMANENT;
    else if (! (addr->flags & TLSTM_ADDR_NONVOLATILE))
        entry->tlstmAddrStorageType = ST_VOLATILE;

    entry->tlstmAddrRowStatus = RS_ACTIVE;

    if (addr->fingerprint) {
        entry->tlstmAddrServerFingerprint_len = strlen(addr->fingerprint);
        if (entry->tlstmAddrServerFingerprint_len >
            sizeof(entry->tlstmAddrServerFingerprint))
            entry->tlstmAddrServerFingerprint_len =
                sizeof(entry->tlstmAddrServerFingerprint) - 1;
        memcpy(entry->tlstmAddrServerFingerprint, addr->fingerprint,
               entry->tlstmAddrServerFingerprint_len);
        entry->tlstmAddrServerFingerprint[sizeof(entry->tlstmAddrServerFingerprint) - 1] = 0;
    }

    if (addr->identity) {
        entry->tlstmAddrServerIdentity_len = strlen(addr->identity);
        if (entry->tlstmAddrServerIdentity_len >
            sizeof(entry->tlstmAddrServerIdentity))
            entry->tlstmAddrServerIdentity_len =
                sizeof(entry->tlstmAddrServerIdentity) - 1;
        memcpy(entry->tlstmAddrServerIdentity, addr->identity,
               entry->tlstmAddrServerIdentity_len);
        entry->tlstmAddrServerIdentity[sizeof(entry->tlstmAddrServerIdentity) - 1] = 0;
    }

    entry->hashType = addr->hashType;
    entry->addr_flags = addr->flags;

    return row;
}

static int
_cache_load(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_container *addrs;
    netsnmp_iterator  *itr;
    snmpTlstmAddr     *addr;
    netsnmp_tdata_row *row;
    int                rc = 0;

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

    /** get current active rows */
    addrs = netsnmp_tlstmAddr_container();
    if (NULL == addrs)
        return 0;

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

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

        row = _entry_from_addr(addr);
        if (NULL == row) {
            rc =-1;
            break;
        }

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

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

    return rc;
}

static void
_cache_free(netsnmp_cache *cache, netsnmp_tdata *table)
{
    netsnmp_tdata_row *row;
    netsnmp_iterator   *tbl_itr;
    tlstmAddrTable_entry   *entry;

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

    tbl_itr = CONTAINER_ITERATOR(table->container);
    if (NULL == tbl_itr) {
        DEBUGMSGTL(("tlstmAddrTable: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 addrs container kept
         * by the library). Keep inactive ones for next time.
         */
        if (entry->tlstmAddrRowStatus == RS_ACTIVE) {
            tlstmAddrTable_removeEntry(NULL, row);
            ITERATOR_REMOVE(tbl_itr);
            continue;
        }
    }
    ITERATOR_RELEASE(tbl_itr);

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

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

static int  _tlstmAddrTable_save_rows(int majorID, int minorID,
                                                void *serverarg,
                                                void *clientarg);
static void _tlstmAddrTable_row_restore_mib(const char *token,
                                                       char *buf);
static const char mib_token[] = "snmpTlstmAddrEntry";

/************************************************************
 * *_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.
 */
static void
_tlstmAddr_init_persistence(void)
{
    int             rc;

    if (NULL == _table_data) {
        snmp_log(LOG_ERR, "no table data for tlstmAddr persistence!\n");
        return;
    }

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

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

static int
_save_entry(tlstmAddrTable_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->snmpTargetAddrName[
                       entry->snmpTargetAddrName_len]);
    netsnmp_assert(0 == entry->tlstmAddrServerFingerprint[
                       entry->tlstmAddrServerFingerprint_len]);
    snprintf(buf, sizeof(buf), "%s %s --%s %s %s %d", mib_token,
             entry->snmpTargetAddrName, hashType,
             entry->tlstmAddrServerFingerprint,
             entry->tlstmAddrServerIdentity,
             entry->tlstmAddrRowStatus);
    buf[sizeof(buf)-1] = 0;

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

    return SNMP_ERR_NOERROR;
}

static int
_save_addrs(snmpTlstmAddr *addrs, void *app_type)
{
    char buf[SNMP_MAXBUF_SMALL], *hashType;

    if (NULL == addrs)
        return SNMP_ERR_GENERR;

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

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

    return SNMP_ERR_NOERROR;
}

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

    netsnmp_container *mib_addrs = (netsnmp_container *) clientarg;
    netsnmp_container *active_addrs = netsnmp_tlstmAddr_container();
    netsnmp_iterator  *tbl_itr, *addrs_itr = NULL;
    netsnmp_tdata_row *row;
    snmpTlstmAddr     *addr;
    tlstmAddrTable_entry *entry;

    if (((NULL == mib_addrs) || (CONTAINER_SIZE(mib_addrs) == 0)) &&
        ((NULL == active_addrs) || (CONTAINER_SIZE(active_addrs) == 0)))
        return SNMPERR_SUCCESS;

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

    /*
     * save active rows from addr container
     */
    if (NULL != active_addrs) {
        addrs_itr = CONTAINER_ITERATOR(active_addrs);
        if (NULL == addrs_itr) {
            DEBUGMSGTL(("tlstmAddrTable:save", "cant get addrs iterator\n"));
            addr = NULL;
        }
        else
            addr = ITERATOR_FIRST(addrs_itr);

        for( ; addr; addr = ITERATOR_NEXT(addrs_itr)) {
            /** don't store config rows */
            if ((addr->flags & TLSTM_ADDR_FROM_CONFIG) ||
                ! (addr->flags & TLSTM_ADDR_NONVOLATILE))
                continue;
            _save_addrs(addr, type);
        }
    }
    ITERATOR_RELEASE(addrs_itr);

    /*
     * save inactive rows from mib
     */
    tbl_itr = CONTAINER_ITERATOR(mib_addrs);
    if (NULL == tbl_itr)
        DEBUGMSGTL(("tlstmAddrTable: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_addrs and thus saved
             * above) and volatile rows.
             */
            if ((entry->tlstmAddrRowStatus == RS_ACTIVE) ||
                (entry->tlstmAddrStorageType != 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;
}

static void
_tlstmAddrTable_row_restore_mib(const char *token, char *buf)
{
    char                   name[SNMPADMINLENGTH + 1], id[SNMPADMINLENGTH + 1],
                           fingerprint[SNMPTLSFINGERPRINT_MAX_LEN + 1];
    size_t                 name_len = sizeof(name), id_len = sizeof(id),
                           fp_len = sizeof(fingerprint);
    u_char                 hashType, rowStatus;
    int                    rc;

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

    rc = netsnmp_tlstmAddr_restore_common(&buf, name, &name_len, id, &id_len,
                                          fingerprint, &fp_len, &hashType);
    if (rc < 0)
        return;

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

    /*
     * if row is active, add it to the addrs 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) {
        snmpTlstmAddr *addr;

        addr = netsnmp_tlstmAddr_create(name);
        if (!addr)
            return;

        if (fp_len)
            addr->fingerprint = strdup(fingerprint);
        if (id_len)
            addr->identity = strdup(id);
        addr->hashType = hashType;
        addr->flags = TLSTM_ADDR_FROM_MIB | TLSTM_ADDR_NONVOLATILE;

        netsnmp_tlstmAddr_add(addr);
    }
    else {
        netsnmp_tdata_row     *row;
        tlstmAddrTable_entry  *entry;

        row = tlstmAddrTable_createEntry(_table_data, name, name_len);
        if (!row)
            return;

        entry = row->data;
        
        entry->hashType = hashType;
        memcpy(entry->tlstmAddrServerFingerprint,fingerprint, fp_len);
        entry->tlstmAddrServerFingerprint_len = fp_len;
        memcpy(entry->tlstmAddrServerIdentity, id, id_len);
        entry->tlstmAddrServerIdentity_len = id_len;
        entry->tlstmAddrStorageType = ST_NONVOLATILE;
        entry->tlstmAddrRowStatus = rowStatus;
    }
}
