/*
 * 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 "sctpLookupRemIPAddrTable.h"

static netsnmp_container *sctpLookupRemIPAddrTable_container;

/** Initializes the sctpLookupRemIPAddrTable module */
void
init_sctpLookupRemIPAddrTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_sctpLookupRemIPAddrTable();
}

void
shutdown_sctpLookupRemIPAddrTable(void)
{
    sctpLookupRemIPAddrTable_container_clear
        (sctpLookupRemIPAddrTable_container);
}

/** Initialize the sctpLookupRemIPAddrTable table by defining its contents and how it's structured */
void
initialize_table_sctpLookupRemIPAddrTable(void)
{
    static oid      sctpLookupRemIPAddrTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 104, 1, 10 };
    size_t          sctpLookupRemIPAddrTable_oid_len =
        OID_LENGTH(sctpLookupRemIPAddrTable_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("sctpLookupRemIPAddrTable",
                                            sctpLookupRemIPAddrTable_handler,
                                            sctpLookupRemIPAddrTable_oid,
                                            sctpLookupRemIPAddrTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpLookupRemIPAddrTable\n");
        goto bail;
    }

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

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

    /*************************************************
     *
     * 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 sctpLookupRemIPAddrTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpLookupRemIPAddrTable\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 sctpLookupRemIPAddrTable\n");
        reg = NULL; /* it was freed inside netsnmp_register_table */
        goto bail;
    }

    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 sctpLookupRemIPAddrTable table */
int
sctpLookupRemIPAddrTable_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;
    sctpLookupRemIPAddrTable_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 = (sctpLookupRemIPAddrTable_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 sctpLookupRemIPAddrTable\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

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

    }
    return SNMP_ERR_NOERROR;
}

sctpLookupRemIPAddrTable_entry *
sctpLookupRemIPAddrTable_entry_create(void)
{
    sctpLookupRemIPAddrTable_entry *entry =
        SNMP_MALLOC_TYPEDEF(sctpLookupRemIPAddrTable_entry);
    if (entry != NULL) {
        entry->oid_index.len = SCTP_LOOKUP_REM_IP_ADDR_TABLE_INDEX_SIZE;
        entry->oid_index.oids = entry->oid_tmp;
    }

    return entry;
}

int
sctpLookupRemIPAddrTable_entry_update_index(sctpLookupRemIPAddrTable_entry
                                            * entry)
{
    netsnmp_variable_list var_sctpAssocRemIPAddrType;
    netsnmp_variable_list var_sctpAssocRemIPAddr;
    netsnmp_variable_list var_sctpAssocId;
    int             err = 0;

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

    memset(&var_sctpAssocRemIPAddr, 0, sizeof(var_sctpAssocRemIPAddr));
    var_sctpAssocRemIPAddr.type = ASN_OCTET_STR;
    var_sctpAssocRemIPAddr.next_variable = &var_sctpAssocId;
    snmp_set_var_value(&var_sctpAssocRemIPAddr,
                       (u_char *) & entry->sctpAssocRemAddr,
                       entry->sctpAssocRemAddr_len);

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

    return err;
}

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


void
sctpLookupRemIPAddrTable_entry_free(sctpLookupRemIPAddrTable_entry * entry)
{
    if (entry != NULL)
        SNMP_FREE(entry);
}

netsnmp_container *
sctpLookupRemIPAddrTable_get_container(void)
{
    return sctpLookupRemIPAddrTable_container;
}


static void
sctpLookupRemIPAddrTable_entry_clear(void *what, void *magic)
{
    sctpLookupRemIPAddrTable_entry_free(what);
}

void
sctpLookupRemIPAddrTable_container_clear(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, sctpLookupRemIPAddrTable_entry_clear, NULL);
}
