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

static netsnmp_container *sctpLookupRemHostNameTable_container;
static netsnmp_table_registration_info *table_info;

/** Initializes the sctpLookupRemHostNameTable module */
void
init_sctpLookupRemHostNameTable(void)
{
    /*
     * here we initialize all the tables we're planning on supporting 
     */
    initialize_table_sctpLookupRemHostNameTable();
}

void
shutdown_sctpLookupRemHostNameTable(void)
{
    shutdown_table_sctpLookupRemHostNameTable();
}

/** Initialize the sctpLookupRemHostNameTable table by defining its contents and how it's structured */
void
initialize_table_sctpLookupRemHostNameTable(void)
{
    static oid      sctpLookupRemHostNameTable_oid[] =
        { 1, 3, 6, 1, 2, 1, 104, 1, 8 };
    size_t          sctpLookupRemHostNameTable_oid_len =
        OID_LENGTH(sctpLookupRemHostNameTable_oid);
    netsnmp_handler_registration *reg = NULL;
    netsnmp_mib_handler *handler = NULL;
    netsnmp_container *container = NULL;

    reg =
        netsnmp_create_handler_registration("sctpLookupRemHostNameTable",
                                            sctpLookupRemHostNameTable_handler,
                                            sctpLookupRemHostNameTable_oid,
                                            sctpLookupRemHostNameTable_oid_len,
                                            HANDLER_CAN_RONLY);
    if (NULL == reg) {
        snmp_log(LOG_ERR,
                 "error creating handler registration for sctpLookupRemHostNameTable\n");
        goto bail;
    }

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


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

    /*************************************************
     *
     * 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 sctpLookupRemHostNameTable\n");
        goto bail;
    }
    if (SNMPERR_SUCCESS != netsnmp_inject_handler(reg, handler)) {
        snmp_log(LOG_ERR,
                 "error injecting container_table handler for sctpLookupRemHostNameTable\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 sctpLookupRemHostNameTable\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_sctpLookupRemHostNameTable(void)
{
    if (table_info) {
        netsnmp_table_registration_info_free(table_info);
	table_info = NULL;
    }
    sctpLookupRemHostNameTable_container_clear
        (sctpLookupRemHostNameTable_container);
}

/** handles requests for the sctpLookupRemHostNameTable table */
int
sctpLookupRemHostNameTable_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;
    sctpLookupRemHostNameTable_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 = (sctpLookupRemHostNameTable_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 sctpLookupRemHostNameTable\n");
                snmp_set_var_typed_value(request->requestvb,
                                         SNMP_ERR_GENERR, NULL, 0);
                continue;
            }

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

    }
    return SNMP_ERR_NOERROR;
}

sctpLookupRemHostNameTable_entry *
sctpLookupRemHostNameTable_entry_create(void)
{
    sctpLookupRemHostNameTable_entry *entry =
        SNMP_MALLOC_TYPEDEF(sctpLookupRemHostNameTable_entry);
    if (entry != NULL) {
        entry->oid_index.len = SCTP_LOOKUP_REM_HOST_NAME_TABLE_INDEX_SIZE;
        entry->oid_index.oids = entry->oid_tmp;
    }

    return entry;
}

int
sctpLookupRemHostNameTable_entry_update_index
    (sctpLookupRemHostNameTable_entry * entry)
{
    netsnmp_variable_list var_sctpAssocRemHostName;
    netsnmp_variable_list var_sctpAssocId;
    int             err = 0;

    /*
     * prepare the value to be converted 
     */
    memset(&var_sctpAssocRemHostName, 0, sizeof(var_sctpAssocRemHostName));
    var_sctpAssocRemHostName.type = ASN_OCTET_STR;
    var_sctpAssocRemHostName.next_variable = &var_sctpAssocId;
    snmp_set_var_value(&var_sctpAssocRemHostName,
                       (u_char *) & entry->sctpAssocRemHostName,
                       entry->sctpAssocRemHostName_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_sctpAssocRemHostName);
    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_sctpAssocRemHostName);

    return err;
}

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


void
sctpLookupRemHostNameTable_entry_free(sctpLookupRemHostNameTable_entry *
                                      entry)
{
    SNMP_FREE(entry);
}

netsnmp_container *
sctpLookupRemHostNameTable_get_container(void)
{
    return sctpLookupRemHostNameTable_container;
}


static void
sctpLookupRemHostNameTable_entry_clear(void *what, void *magic)
{
    sctpLookupRemHostNameTable_entry_free(what);
}

void
sctpLookupRemHostNameTable_container_clear(netsnmp_container *container)
{
    CONTAINER_CLEAR(container, sctpLookupRemHostNameTable_entry_clear,
                    NULL);
}
