/*
 * Note: this file originally auto-generated by mib2c using
 * mib2c -c mib2c.container.conf
 */

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

static void     _cache_free(netsnmp_cache * cache, void *magic);
static int      _cache_load(netsnmp_cache * cache, void *vmagic);

/*
 * content of the sctpAssocTable 
 */
static netsnmp_container *sctpAssocTable_container;

/** Initializes the sctpAssocTable module */
void
init_sctpAssocTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_sctpAssocTable();
}

void
shutdown_sctpAssocTable(void)
{
    sctpAssocTable_container_clear(sctpAssocTable_container);
}

/** Initialize the sctpAssocTable table by defining its contents and how it's structured */
void
initialize_table_sctpAssocTable(void)
{
    static oid      sctpAssocTable_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 3 };
    size_t          sctpAssocTable_oid_len =
        OID_LENGTH(sctpAssocTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;
    netsnmp_cache  *cache = NULL;

    reg =
        netsnmp_create_handler_registration("sctpAssocTable",
                                            sctpAssocTable_handler,
                                            sctpAssocTable_oid,
                                            sctpAssocTable_oid_len,
                                            HANDLER_CAN_RWRITE);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpAssocTable\n");
        goto bail;
    }
    /** should a set on a non-existent row create a new one? */
    /** reg->modes |= HANDLER_CAN_NOT_CREATE; */

    container = netsnmp_container_find("sctpAssocTable:table_container");
    if (NULL == container) {
        snmp_log(LOG_ERR, "error creating container for sctpAssocTable\n");
        goto bail;
    }
    sctpAssocTable_container = container;

    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    if (NULL == table_info) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    netsnmp_table_helper_add_indexes(table_info, ASN_UNSIGNED,  /* index: sctpAssocId */
                                     0);
    table_info->min_column = COLUMN_SCTPASSOCREMHOSTNAME;
    table_info->max_column = COLUMN_SCTPASSOCDISCONTINUITYTIME;

    /*************************************************
     *
     * inject container_table helper
     */
    handler = netsnmp_container_table_handler_get(table_info, container,
                                                  TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error allocating table registration for sctpAssocTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */

    /*************************************************
     *
     * inject cache helper
     */
    cache = netsnmp_cache_create(SCTP_TABLES_CACHE_TIMEOUT,     /* timeout in seconds */
                                 _cache_load, _cache_free,
                                 sctpAssocTable_oid,
                                 sctpAssocTable_oid_len);

    if (NULL == cache) {
        snmp_log(LOG_ERR, "error creating cache for sctpAssocTable\n");
        goto bail;
    }
    cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET
        | NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_PRELOAD;
    cache->magic = container;

    handler = netsnmp_cache_handler_get(cache);
    if (NULL == handler) {
        snmp_log(LOG_ERR,
                 "error creating cache handler for sctpAssocTable\n");
        goto bail;
    }

    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting cache handler for sctpAssocTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it */

    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for sctpAssocTable\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

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


    return;                     /* ok */

    /*
     * Some error occurred during registration. Clean up and bail.
     */
  bail:                        /* not ok */

    if (handler)
        netsnmp_handler_free(handler);

    if (cache)
        netsnmp_cache_free(cache);

    if (table_info)
        netsnmp_table_registration_info_free(table_info);

    if (container)
        CONTAINER_FREE(container);

    if (reg)
        netsnmp_handler_registration_free(reg);
}


/** handles requests for the sctpAssocTable table */
int
sctpAssocTable_handler(netsnmp_mib_handler *handler,
                       netsnmp_handler_registration *reginfo,
                       netsnmp_agent_request_info *reqinfo,
                       netsnmp_request_info *requests)
{
    netsnmp_request_info *request;
    netsnmp_table_request_info *table_info;
    sctpAssocTable_entry *table_entry;

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;
            table_entry = (sctpAssocTable_entry *)
                netsnmp_container_table_extract_context(request);
            table_info = netsnmp_extract_table_info(request);
            if ((NULL == table_entry) || (NULL == table_info)) {
                snmp_log(LOG_ERR,
                         "could not extract table entry or info for sctpAssocTable\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_SCTPASSOCREMHOSTNAME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *)
                                         table_entry->sctpAssocRemHostName,
                                         table_entry->sctpAssocRemHostName_len);
                break;
            case COLUMN_SCTPASSOCLOCALPORT:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocLocalPort);
                break;
            case COLUMN_SCTPASSOCREMPORT:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocRemPort);
                break;
            case COLUMN_SCTPASSOCREMPRIMADDRTYPE:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->sctpAssocRemPrimAddrType);
                break;
            case COLUMN_SCTPASSOCREMPRIMADDR:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR,
                                         (u_char *)
                                         table_entry->sctpAssocRemPrimAddr,
                                         table_entry->sctpAssocRemPrimAddr_len);
                break;
            case COLUMN_SCTPASSOCHEARTBEATINTERVAL:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocHeartBeatInterval);
                break;
            case COLUMN_SCTPASSOCSTATE:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER,
                                           table_entry->sctpAssocState);
                break;
            case COLUMN_SCTPASSOCINSTREAMS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocInStreams);
                break;
            case COLUMN_SCTPASSOCOUTSTREAMS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocOutStreams);
                break;
            case COLUMN_SCTPASSOCMAXRETR:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocMaxRetr);
                break;
            case COLUMN_SCTPASSOCPRIMPROCESS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_UNSIGNED,
                                           table_entry->sctpAssocPrimProcess);
                break;
            case COLUMN_SCTPASSOCT1EXPIREDS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocT1expireds);
                break;
            case COLUMN_SCTPASSOCT2EXPIREDS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocT2expireds);
                break;
            case COLUMN_SCTPASSOCRTXCHUNKS:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb, ASN_COUNTER,
                                           table_entry->sctpAssocRtxChunks);
                break;
            case COLUMN_SCTPASSOCSTARTTIME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_TIMETICKS,
                                           table_entry->sctpAssocStartTime);
                break;
            case COLUMN_SCTPASSOCDISCONTINUITYTIME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_TIMETICKS,
                                           table_entry->sctpAssocDiscontinuityTime);
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;
            netsnmp_set_request_error(reqinfo, request,
                                      SNMP_ERR_NOTWRITABLE);
        }
        break;

    case MODE_SET_RESERVE2:
    case MODE_SET_FREE:
    case MODE_SET_ACTION:
    case MODE_SET_UNDO:
    case MODE_SET_COMMIT:
        break;
    }
    return SNMP_ERR_NOERROR;
}

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGMSGTL(("internal:sctpAssocTable:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache for sctpAssocTable_cache_load\n");
        return -1;
    }
    /** should only be called for an invalid or expired cache */
    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    return sctpTables_load();
}                               /* _cache_load */

/**
 * @Internal
 */
/** remove a row from the table */
static void
sctpAssocTable_freeEntry_cb(sctpAssocTable_entry * entry, void *magic)
{

    sctpAssocTable_entry_free(entry);
}

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:sctpAssocTable:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR, "invalid cache in sctpAssocTable_cache_free\n");
        return;
    }
    container = (netsnmp_container *) cache->magic;

    /*
     * empty (but don't free) cache here
     */
    CONTAINER_CLEAR(container, (netsnmp_container_obj_func *)
                    sctpAssocTable_freeEntry_cb, NULL);
}                               /* _cache_free */

sctpAssocTable_entry *
sctpAssocTable_entry_create(void)
{
    sctpAssocTable_entry *entry =
        SNMP_MALLOC_TYPEDEF(sctpAssocTable_entry);
    if (entry != NULL) {
        entry->oid_index.len = SCTP_ASSOC_TABLE_INDEX_SIZE;
        entry->oid_index.oids = entry->oid_tmp;
    }

    return entry;
}

int
sctpAssocTable_entry_update_index(sctpAssocTable_entry * entry)
{
    netsnmp_variable_list var_sctpAssocId;
    int             err = 0;

    /*
     * prepare the value to be converted 
     */
    memset(&var_sctpAssocId, 0, sizeof(var_sctpAssocId));
    var_sctpAssocId.type = ASN_UNSIGNED;
    var_sctpAssocId.next_variable = NULL;
    snmp_set_var_value(&var_sctpAssocId, (u_char *) & entry->sctpAssocId,
                       sizeof(entry->sctpAssocId));

    /*
     * convert it 
     */
    err =
        build_oid_noalloc(entry->oid_index.oids, entry->oid_index.len,
                          &entry->oid_index.len, NULL, 0,
                          &var_sctpAssocId);
    if (err)
        snmp_log(LOG_ERR, "error %d converting index to oid\n", err);

    /*
     * release any memory allocated during the conversion 
     */
    snmp_reset_var_buffers(&var_sctpAssocId);

    return err;
}

void
sctpAssocTable_entry_copy(sctpAssocTable_entry * from,
                          sctpAssocTable_entry * to)
{
    memcpy(to, from, sizeof(sctpAssocTable_entry));
    to->oid_index.oids = to->oid_tmp;
}


void
sctpAssocTable_entry_free(sctpAssocTable_entry * entry)
{
    if (entry != NULL)
        SNMP_FREE(entry);
}

netsnmp_container *
sctpAssocTable_get_container(void)
{
    return sctpAssocTable_container;
}

static void
sctpAssocTable_entry_clear(void *what, void *magic)
{
    sctpAssocTable_entry_free(what);
}

void
sctpAssocTable_container_clear(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, sctpAssocTable_entry_clear, NULL);
}
