/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.scalar.conf 11805 2005-01-07 09:37:18Z dts12 $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "sctpScalars.h"
#include "sctpScalars_common.h"

oid             sctp_stats_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 1 };
oid             sctp_params_oid[] = { 1, 3, 6, 1, 2, 1, 104, 1, 2 };

/** Initializes the sctp_scalars module */
void
init_sctpScalars(void)
{
    netsnmp_handler_registration *reginfo_stats;
    netsnmp_handler_registration *reginfo_params;

    DEBUGMSGTL(("sctp:scalars:init", "Initializing\n"));

    reginfo_stats =
        netsnmp_create_handler_registration("sctpStats",
                                            sctp_stats_handler,
                                            sctp_stats_oid,
                                            OID_LENGTH(sctp_stats_oid),
                                            HANDLER_CAN_RONLY);
    netsnmp_register_scalar_group(reginfo_stats, SCTP_CURRESTAB,
                                  SCTP_DISCONTINUITYTIME);
    netsnmp_inject_handler(reginfo_stats,
                           netsnmp_get_cache_handler
                           (SCTP_STATS_CACHE_TIMEOUT,
                            netsnmp_access_sctp_stats_load,
                            netsnmp_access_sctp_stats_free, sctp_stats_oid,
                            OID_LENGTH(sctp_stats_oid)));


    reginfo_params =
        netsnmp_create_handler_registration("sctpParams",
                                            sctp_params_handler,
                                            sctp_params_oid,
                                            OID_LENGTH(sctp_params_oid),
                                            HANDLER_CAN_RONLY);
    netsnmp_register_scalar_group(reginfo_params, SCTP_RTOALGORITHM,
                                  SCTP_MAXINITRETR);
    netsnmp_inject_handler(reginfo_params,
                           netsnmp_get_cache_handler
                           (SCTP_PARAMS_CACHE_TIMEOUT,
                            netsnmp_access_sctp_params_load,
                            netsnmp_access_sctp_params_free,
                            sctp_params_oid, OID_LENGTH(sctp_params_oid)));
}

/**
 * Handle request for sctpStats.
 * Handles only one request at a time, serialize_handler is automatically added by netsnmp_register_scalar_group.
 */
int
sctp_stats_handler(netsnmp_mib_handler *handler,
                   netsnmp_handler_registration *reginfo,
                   netsnmp_agent_request_info *reqinfo,
                   netsnmp_request_info *request)
{
    netsnmp_variable_list *requestvb;
    int             subid;
    int             ret;

    DEBUGMSGTL(("sctp:scalars:stats", "Handler - mode %s\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode)));
    if (reqinfo->mode != MODE_GET) {
        snmp_log(LOG_WARNING, "sctp/stats: Unsupported mode (%d)\n",
                 reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    requestvb = request->requestvb;
    subid = requestvb->name[OID_LENGTH(sctp_stats_oid)];
    DEBUGMSGTL(("sctp:scalars:stats", "oid: "));
    DEBUGMSGOID(("sctp:scalars:stats", requestvb->name,
                 requestvb->name_length));
    DEBUGMSG(("sctp:scalars:stats", "\n"));

    switch (subid) {

    case SCTP_CURRESTAB:
        snmp_set_var_typed_value(request->requestvb, ASN_GAUGE,
                                 (u_char *) & sctp_stats.curr_estab,
                                 sizeof(sctp_stats.curr_estab));
        break;

    case SCTP_ACTIVEESTABS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.active_estabs,
                                 sizeof(sctp_stats.active_estabs));
        break;

    case SCTP_PASSIVEESTABS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.passive_estabs,
                                 sizeof(sctp_stats.passive_estabs));
        break;

    case SCTP_ABORTEDS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.aborteds,
                                 sizeof(sctp_stats.aborteds));
        break;

    case SCTP_SHUTDOWNS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.shutdowns,
                                 sizeof(sctp_stats.shutdowns));
        break;

    case SCTP_OUTOFBLUES:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.out_of_blues,
                                 sizeof(sctp_stats.out_of_blues));
        break;

    case SCTP_CHECKSUMERRORS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER,
                                 (u_char *) & sctp_stats.checksum_errors,
                                 sizeof(sctp_stats.checksum_errors));
        break;

    case SCTP_OUTCTRLCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.out_ctrl_chunks,
                                 sizeof(sctp_stats.out_ctrl_chunks));
        break;

    case SCTP_OUTORDERCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.out_order_chunks,
                                 sizeof(sctp_stats.out_order_chunks));
        break;

    case SCTP_OUTUNORDERCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) &
                                 sctp_stats.out_unorder_chunks,
                                 sizeof(sctp_stats.out_unorder_chunks));
        break;

    case SCTP_INCTRLCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.in_ctrl_chunks,
                                 sizeof(sctp_stats.in_ctrl_chunks));
        break;

    case SCTP_INORDERCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.in_order_chunks,
                                 sizeof(sctp_stats.in_order_chunks));
        break;

    case SCTP_INUNORDERCHUNKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.in_unorder_chunks,
                                 sizeof(sctp_stats.in_unorder_chunks));
        break;

    case SCTP_FRAGUSRMSGS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.frag_usr_msgs,
                                 sizeof(sctp_stats.frag_usr_msgs));
        break;

    case SCTP_REASMUSRMSGS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.reasm_usr_msgs,
                                 sizeof(sctp_stats.reasm_usr_msgs));
        break;

    case SCTP_OUTSCTPPACKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.out_sctp_packs,
                                 sizeof(sctp_stats.out_sctp_packs));
        break;

    case SCTP_INSCTPPACKS:
        snmp_set_var_typed_value(request->requestvb, ASN_COUNTER64,
                                 (u_char *) & sctp_stats.in_sctp_packs,
                                 sizeof(sctp_stats.in_sctp_packs));
        break;

    case SCTP_DISCONTINUITYTIME:
        snmp_set_var_typed_value(request->requestvb, ASN_TIMETICKS,
                                 (u_char *) &
                                 sctp_stats.discontinuity_time,
                                 sizeof(sctp_stats.discontinuity_time));
        break;

    default:
        snmp_log(LOG_WARNING, "sctp/stats: Unsupported subid (%d)\n",
                 subid);
        break;
    }
    return SNMP_ERR_NOERROR;
}


/**
 * Handle request for sctpParams.
 * Handles only one request at a time, serialize_handler is automatically added by netsnmp_register_scalar_group.
 */
int
sctp_params_handler(netsnmp_mib_handler *handler,
                    netsnmp_handler_registration *reginfo,
                    netsnmp_agent_request_info *reqinfo,
                    netsnmp_request_info *request)
{
    netsnmp_variable_list *requestvb;
    int             subid;
    int             ret;

    DEBUGMSGTL(("sctp:scalars:params", "Handler - mode %s\n",
                se_find_label_in_slist("agent_mode", reqinfo->mode)));
    if (reqinfo->mode != MODE_GET) {
        snmp_log(LOG_WARNING, "sctp/params: Unsupported mode (%d)\n",
                 reqinfo->mode);
        return SNMP_ERR_NOERROR;
    }

    requestvb = request->requestvb;
    subid = requestvb->name[OID_LENGTH(sctp_stats_oid)];
    DEBUGMSGTL(("sctp:scalars:params", "oid: "));
    DEBUGMSGOID(("sctp:scalars:params", requestvb->name,
                 requestvb->name_length));
    DEBUGMSG(("sctp:scalars:params", "\n"));

    switch (subid) {

    case SCTP_RTOALGORITHM:
        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                 (u_char *) & sctp_params.rto_algorithm,
                                 sizeof(sctp_params.rto_algorithm));
        break;

    case SCTP_RTOMIN:
        snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                 (u_char *) & sctp_params.rto_min,
                                 sizeof(sctp_params.rto_min));
        break;

    case SCTP_RTOMAX:
        snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                 (u_char *) & sctp_params.rto_max,
                                 sizeof(sctp_params.rto_max));
        break;

    case SCTP_RTOINITIAL:
        snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                 (u_char *) & sctp_params.rto_initial,
                                 sizeof(sctp_params.rto_initial));
        break;

    case SCTP_MAXASSOCS:
        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                 (u_char *) & sctp_params.max_assocs,
                                 sizeof(sctp_params.max_assocs));
        break;

    case SCTP_VALCOOKIELIFE:
        snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                 (u_char *) & sctp_params.val_cookie_life,
                                 sizeof(sctp_params.val_cookie_life));
        break;

    case SCTP_MAXINITRETR:
        snmp_set_var_typed_value(request->requestvb, ASN_UNSIGNED,
                                 (u_char *) & sctp_params.max_init_retr,
                                 sizeof(sctp_params.max_init_retr));
        break;

    default:
        snmp_log(LOG_WARNING, "sctp/params: Unsupported subid (%d)\n",
                 subid);
        break;
    }
    return SNMP_ERR_NOERROR;
}
