/*
 * 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;
static netsnmp_table_registration_info *table_info;

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

/** 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;

    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);
}

void
shutdown_table_sctpAssocLocalAddrTable(void)
{
    if (table_info) {
        netsnmp_table_registration_info_free(table_info);
	table_info = NULL;
    }
    sctpAssocLocalAddrTable_container_clear
        (sctpAssocLocalAddrTable_container);
}

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