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