/*
 * 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 <net-snmp/agent/table_container.h>
#include "sctpAssocLocalAddrTable.h"

/*
 * content of the sctpAssocLocalAddrTable 
 */
static netsnmp_container *sctpAssocLocalAddrTable_container;

/** Initializes the sctpAssocLocalAddrTable module */
void
init_sctpAssocLocalAddrTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_sctpAssocLocalAddrTable();
}

void
shutdown_sctpAssocLocalAddrTable(void)
{
    sctpAssocLocalAddrTable_container_clear
        (sctpAssocLocalAddrTable_container);
}

/** Initialize the sctpAssocLocalAddrTable table by defining its contents and how it's structured */
void
initialize_table_sctpAssocLocalAddrTable(void)
{
    static oid      sctpAssocLocalAddrTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 104, 1, 4 };
    size_t          sctpAssocLocalAddrTable_oid_len =
        OID_LENGTH(sctpAssocLocalAddrTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;
    netsnmp_table_registration_info *table_info = NULL;

    reg =
        netsnmp_create_handler_registration("sctpAssocLocalAddrTable",
                                            sctpAssocLocalAddrTable_handler,
                                            sctpAssocLocalAddrTable_oid,
                                            sctpAssocLocalAddrTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpAssocLocalAddrTable\n");
        goto bail;
    }

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

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

    /*************************************************
     *
     * 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 sctpAssocLocalAddrTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpAssocLocalAddrTable\n");
        goto bail;
    }
    handler = NULL;             /* reg has it, will reuse below */


    /*
     * register the table
     */
    if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
        snmp_log(LOG_ERR,
                 "error registering table handler for sctpAssocLocalAddrTable\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 (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 sctpAssocLocalAddrTable table */
int
sctpAssocLocalAddrTable_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;
    sctpAssocLocalAddrTable_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 = (sctpAssocLocalAddrTable_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 sctpAssocLocalAddrTable\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_SCTPASSOCLOCALADDRSTARTTIME:
                if (!table_entry) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
                snmp_set_var_typed_integer(request->requestvb,
                                           ASN_TIMETICKS,
                                           table_entry->sctpAssocLocalAddrStartTime);
                break;
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

    }
    return SNMP_ERR_NOERROR;
}

sctpAssocLocalAddrTable_entry *
sctpAssocLocalAddrTable_entry_create(void)
{
    sctpAssocLocalAddrTable_entry *entry =
        SNMP_MALLOC_TYPEDEF(sctpAssocLocalAddrTable_entry);
    if (entry != NULL) {
        entry->oid_index.len = SCTP_ASSOC_LOCAL_ADDR_TABLE_INDEX_SIZE;
        entry->oid_index.oids = entry->oid_tmp;
    }

    return entry;
}

int
sctpAssocLocalAddrTable_entry_update_index(sctpAssocLocalAddrTable_entry *
                                           entry)
{
    int             err = 0;

    netsnmp_variable_list var_sctpAssocId;
    netsnmp_variable_list var_sctpAssocLocalAddrType;
    netsnmp_variable_list var_sctpAssocLocalAddr;

    /*
     * prepare the values to be converted 
     */
    memset(&var_sctpAssocId, 0, sizeof(var_sctpAssocId));
    var_sctpAssocId.type = ASN_UNSIGNED;
    memset(&var_sctpAssocLocalAddrType, 0,
           sizeof(var_sctpAssocLocalAddrType));
    var_sctpAssocLocalAddrType.type = ASN_INTEGER;
    memset(&var_sctpAssocLocalAddr, 0, sizeof(var_sctpAssocLocalAddr));
    var_sctpAssocLocalAddr.type = ASN_OCTET_STR;

    var_sctpAssocId.next_variable = &var_sctpAssocLocalAddrType;
    var_sctpAssocLocalAddrType.next_variable = &var_sctpAssocLocalAddr;
    var_sctpAssocLocalAddr.next_variable = NULL;

    snmp_set_var_value(&var_sctpAssocId, (u_char *) & entry->sctpAssocId,
                       sizeof(entry->sctpAssocId));
    snmp_set_var_value(&var_sctpAssocLocalAddrType,
                       (u_char *) & entry->sctpAssocLocalAddrType,
                       sizeof(entry->sctpAssocLocalAddrType));
    snmp_set_var_value(&var_sctpAssocLocalAddr,
                       (u_char *) & entry->sctpAssocLocalAddr,
                       entry->sctpAssocLocalAddr_len *
                       sizeof(entry->sctpAssocLocalAddr[0]));

    /*
     * 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
sctpAssocLocalAddrTable_entry_copy(sctpAssocLocalAddrTable_entry * from,
                                   sctpAssocLocalAddrTable_entry * to)
{
    memcpy(to, from, sizeof(sctpAssocLocalAddrTable_entry));
    to->oid_index.oids = to->oid_tmp;
}

void
sctpAssocLocalAddrTable_entry_free(sctpAssocLocalAddrTable_entry * entry)
{
    if (entry != NULL)
        SNMP_FREE(entry);
}

netsnmp_container *
sctpAssocLocalAddrTable_get_container(void)
{
    return sctpAssocLocalAddrTable_container;
}

static void
sctpAssocLocalAddrTable_entry_clear(void *what, void *magic)
{
    sctpAssocLocalAddrTable_entry_free(what);
}

void
sctpAssocLocalAddrTable_container_clear(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, sctpAssocLocalAddrTable_entry_clear, NULL);
}
