/*
 *Copyright(c)2004,Cisco URP imburses and Network Information Center in Beijing University of Posts and Telecommunications researches.
 *
 *All right reserved
 *
 *File Name:traceRouteResultsTable.c
 *File Description:Rows of traceRouteResultsTable MIB read.
 *
 *Current Version:1.0
 *Author:ChenJing
 *Date:2004.8.20
 */

/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.create-dataset.conf,v 5.3 2002/12/05 00:29:45 hardaker Exp $
 */


#include <net-snmp/net-snmp-config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif

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

#include "traceRouteResultsTable.h"
#include "traceRouteCtlTable.h"
#include "traceRouteProbeHistoryTable.h"
#include "traceRouteHopsTable.h"
#include "header_complex.h"

/*
 *traceRouteResultsTable_variables_oid:
 *
 */
oid             traceRouteResultsTable_variables_oid[] =
    { 1, 3, 6, 1, 2, 1, 81, 1, 3 };

struct variable2 traceRouteResultsTable_variables[] = {
    {COLUMN_TRACEROUTERESULTSOPERSTATUS,     ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 1}},
    {COLUMN_TRACEROUTERESULTSCURHOPCOUNT,      ASN_GAUGE, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 2}},
    {COLUMN_TRACEROUTERESULTSCURPROBECOUNT,    ASN_GAUGE, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 3}},
    {COLUMN_TRACEROUTERESULTSIPTGTADDRTYPE,  ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 4}},
    {COLUMN_TRACEROUTERESULTSIPTGTADDR,    ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 5}},
    {COLUMN_TRACEROUTERESULTSTESTATTEMPTS,  ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 6}},
    {COLUMN_TRACEROUTERESULTSTESTSUCCESSES, ASN_UNSIGNED, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 7}},
    {COLUMN_TRACEROUTERESULTSLASTGOODPATH, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_traceRouteResultsTable, 2, {1, 8}}
};



/*
 * global storage of our data, saved in and configured by header_complex() 
 */

extern struct header_complex_index *traceRouteCtlTableStorage;
extern struct header_complex_index *traceRouteResultsTableStorage;
void
traceRouteResultsTable_inadd(struct traceRouteResultsTable_data *thedata);

void
traceRouteResultsTable_cleaner(struct header_complex_index *thestuff)
{
    struct header_complex_index *hciptr = NULL;
    struct traceRouteResultsTable_data *StorageDel = NULL;
    DEBUGMSGTL(("traceRouteResultsTable", "cleanerout  "));
    for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
        StorageDel =
            header_complex_extract_entry(&traceRouteResultsTableStorage,
                                         hciptr);
        if (StorageDel != NULL) {
            free(StorageDel->traceRouteCtlOwnerIndex);
            StorageDel->traceRouteCtlOwnerIndex = NULL;
            free(StorageDel->traceRouteCtlTestName);
            StorageDel->traceRouteCtlTestName = NULL;
            free(StorageDel->traceRouteResultsIpTgtAddr);
            StorageDel->traceRouteResultsIpTgtAddr = NULL;
            free(StorageDel->traceRouteResultsLastGoodPath);
            StorageDel->traceRouteResultsLastGoodPath = NULL;
            free(StorageDel);
            StorageDel = NULL;

        }
        DEBUGMSGTL(("traceRouteResultsTable", "cleaner  "));
    }

}

void
init_traceRouteResultsTable(void)
{

    DEBUGMSGTL(("traceRouteResultsTable", "initializing...  "));


    /*
     * register ourselves with the agent to handle our mib tree 
     */
    REGISTER_MIB("traceRouteResultsTable",
                 traceRouteResultsTable_variables, variable2,
                 traceRouteResultsTable_variables_oid);


    /*
     * register our config handler(s) to deal with registrations 
     */
    snmpd_register_config_handler("traceRouteResultsTable",
                                  parse_traceRouteResultsTable, NULL,
                                  NULL);

    /*
     * we need to be called back later to store our data 
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_traceRouteResultsTable, NULL);

    DEBUGMSGTL(("traceRouteResultsTable", "done.\n"));
}

/*
 * parse_mteObjectsTable():
 *   parses .conf file entries needed to configure the mib.
 */

void
parse_traceRouteResultsTable(const char *token, char *line)
{
    size_t          tmpint;
    struct traceRouteResultsTable_data *StorageTmp =
        SNMP_MALLOC_STRUCT(traceRouteResultsTable_data);

    DEBUGMSGTL(("traceRouteResultsTable", "parsing config...  "));


    if (StorageTmp == NULL) {
        config_perror("malloc failure");
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->traceRouteCtlOwnerIndex,
                              &StorageTmp->traceRouteCtlOwnerIndexLen);
    if (StorageTmp->traceRouteCtlOwnerIndex == NULL) {
        config_perror("invalid specification for traceRouteCtlOwnerIndex");
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->traceRouteCtlTestName,
                              &StorageTmp->traceRouteCtlTestNameLen);
    if (StorageTmp->traceRouteCtlTestName == NULL) {
        config_perror("invalid specification for traceRouteCtlTestName");
        return;
    }

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->traceRouteResultsOperStatus,
                              &tmpint);
    line =
        read_config_read_data(ASN_GAUGE, line,
                              &StorageTmp->traceRouteResultsCurHopCount,
                              &tmpint);
    line =
        read_config_read_data(ASN_GAUGE, line,
                              &StorageTmp->traceRouteResultsCurProbeCount,
                              &tmpint);
    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->traceRouteResultsIpTgtAddrType,
                              &tmpint);
    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->traceRouteResultsIpTgtAddr,
                              &StorageTmp->traceRouteResultsIpTgtAddrLen);
    if (StorageTmp->traceRouteResultsIpTgtAddr == NULL) {
        config_perror
            ("invalid specification for traceRouteResultsIpTgtAddr");
        return;
    }

    line =
        read_config_read_data(ASN_UNSIGNED, line,
                              &StorageTmp->traceRouteResultsTestAttempts,
                              &tmpint);
    line =
        read_config_read_data(ASN_UNSIGNED, line,
                              &StorageTmp->traceRouteResultsTestSuccesses,
                              &tmpint);
    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->traceRouteResultsLastGoodPath,
                              &StorageTmp->
                              traceRouteResultsLastGoodPathLen);
    if (StorageTmp->traceRouteResultsLastGoodPath == NULL) {
        config_perror
            ("invalid specification for traceRouteResultsLastGoodPath!");
        return;
    }


    traceRouteResultsTable_inadd(StorageTmp);

    /*     traceRouteResultsTable_cleaner(traceRouteResultsTableStorage); */

    DEBUGMSGTL(("traceRouteResultsTable", "done.\n"));
}





/*
 * store_traceRouteResultsTable():
 *   stores .conf file entries needed to configure the mib.
 */

int
store_traceRouteResultsTable(int majorID, int minorID, void *serverarg,
                             void *clientarg)
{
    char            line[SNMP_MAXBUF];
    char           *cptr = NULL;
    size_t          tmpint;
    struct traceRouteResultsTable_data *StorageTmp = NULL;
    struct header_complex_index *hcindex = NULL;


    DEBUGMSGTL(("traceRouteResultsTable", "storing data...  "));


    for (hcindex = traceRouteResultsTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        StorageTmp = (struct traceRouteResultsTable_data *) hcindex->data;

        if (StorageTmp->storageType != ST_READONLY) {
            memset(line, 0, sizeof(line));
            strcat(line, "traceRouteResultsTable ");
            cptr = line + strlen(line);

            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->
                                       traceRouteCtlOwnerIndex,
                                       &StorageTmp->
                                       traceRouteCtlOwnerIndexLen);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->traceRouteCtlTestName,
                                       &StorageTmp->
                                       traceRouteCtlTestNameLen);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->
                                       traceRouteResultsOperStatus,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_GAUGE, cptr,
                                       &StorageTmp->
                                       traceRouteResultsCurHopCount,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_GAUGE, cptr,
                                       &StorageTmp->
                                       traceRouteResultsCurProbeCount,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->
                                       traceRouteResultsIpTgtAddrType,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->
                                       traceRouteResultsIpTgtAddr,
                                       &StorageTmp->
                                       traceRouteResultsIpTgtAddrLen);

            cptr =
                read_config_store_data(ASN_UNSIGNED, cptr,
                                       &StorageTmp->
                                       traceRouteResultsTestAttempts,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_UNSIGNED, cptr,
                                       &StorageTmp->
                                       traceRouteResultsTestSuccesses,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->
                                       traceRouteResultsLastGoodPath,
                                       &StorageTmp->
                                       traceRouteResultsLastGoodPathLen);

            snmpd_store_config(line);
        }
    }
    DEBUGMSGTL(("traceRouteResultsTable", "done.\n"));
    return SNMPERR_SUCCESS;
}

void
traceRouteResultsTable_inadd(struct traceRouteResultsTable_data *thedata)
{
    netsnmp_variable_list *vars_list = NULL;

    snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlOwnerIndex, thedata->traceRouteCtlOwnerIndexLen);      /* traceRouteCtlOwnerIndex */
    snmp_varlist_add_variable(&vars_list, NULL, 0, ASN_OCTET_STR, (char *) thedata->traceRouteCtlTestName, thedata->traceRouteCtlTestNameLen);  /* traceRouteCtlTestName */

    DEBUGMSGTL(("traceRouteResultsTable", "adding data...  "));
    /*
     * add the index variables to the varbind list, which is 
     * used by header_complex to index the data 
     */

    header_complex_add_data(&traceRouteResultsTableStorage, vars_list,
                            thedata);
    DEBUGMSGTL(("traceRouteResultsTable", "registered an entry\n"));


    DEBUGMSGTL(("traceRouteResultsTable", "done.\n"));
}


/*
 * var_traceRouteResultsTable():
 *   Handle this table separately from the scalar value case.
 *   The workings of this are basically the same as for var_traceRouteResultsTable above.
 */
unsigned char  *
var_traceRouteResultsTable(struct variable *vp,
                           oid * name,
                           size_t *length,
                           int exact,
                           size_t *var_len, WriteMethod ** write_method)
{


    struct traceRouteResultsTable_data *StorageTmp = NULL;

    *write_method = NULL;

    /*
     * this assumes you have registered all your data properly
     */
    if ((StorageTmp =
         header_complex(traceRouteResultsTableStorage, vp, name, length,
                        exact, var_len, write_method)) == NULL) {
        return NULL;
    }

    /*
     * this is where we do the value assignments for the mib results.
     */

    switch (vp->magic) {

    case COLUMN_TRACEROUTERESULTSOPERSTATUS:
        *var_len = sizeof(StorageTmp->traceRouteResultsOperStatus);
        return (u_char *) & StorageTmp->traceRouteResultsOperStatus;

    case COLUMN_TRACEROUTERESULTSCURHOPCOUNT:
        *var_len = sizeof(StorageTmp->traceRouteResultsCurHopCount);
        return (u_char *) & StorageTmp->traceRouteResultsCurHopCount;

    case COLUMN_TRACEROUTERESULTSCURPROBECOUNT:
        *var_len = sizeof(StorageTmp->traceRouteResultsCurProbeCount);
        return (u_char *) & StorageTmp->traceRouteResultsCurProbeCount;

    case COLUMN_TRACEROUTERESULTSIPTGTADDRTYPE:
        *var_len = sizeof(StorageTmp->traceRouteResultsIpTgtAddrType);
        return (u_char *) & StorageTmp->traceRouteResultsIpTgtAddrType;

    case COLUMN_TRACEROUTERESULTSIPTGTADDR:
        *var_len = (StorageTmp->traceRouteResultsIpTgtAddrLen);
        return (u_char *) StorageTmp->traceRouteResultsIpTgtAddr;

    case COLUMN_TRACEROUTERESULTSTESTATTEMPTS:
        *var_len = sizeof(StorageTmp->traceRouteResultsTestAttempts);
        return (u_char *) & StorageTmp->traceRouteResultsTestAttempts;

    case COLUMN_TRACEROUTERESULTSTESTSUCCESSES:
        *var_len = sizeof(StorageTmp->traceRouteResultsTestSuccesses);
        return (u_char *) & StorageTmp->traceRouteResultsTestSuccesses;

    case COLUMN_TRACEROUTERESULTSLASTGOODPATH:
        *var_len = (StorageTmp->traceRouteResultsLastGoodPathLen);
        return (u_char *) StorageTmp->traceRouteResultsLastGoodPath;

    default:
        ERROR_MSG("");
    }

    return NULL;
}
