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

    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);
    if (!reginfo_stats)
        return;

    rc = netsnmp_register_scalar_group(reginfo_stats, SCTP_CURRESTAB,
                                  SCTP_DISCONTINUITYTIME);
    if (rc != SNMPERR_SUCCESS)
        return;

    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);
    if (!reginfo_params)
        return;

    rc = netsnmp_register_scalar_group(reginfo_params, SCTP_RTOALGORITHM,
                                  SCTP_MAXINITRETR);
    if (!rc)
        return;
    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;

    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;

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