/*
 *  Template MIB group implementation - example.c
 *
 */

/*
 * include important headers 
 */
#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

/*
 * needed by util_funcs.h 
 */
#if TIME_WITH_SYS_TIME
# ifdef WIN32
#  include <sys/timeb.h>
# else
#  include <sys/time.h>
# endif
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#if HAVE_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

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

/*
 * header_generic() comes from here 
 */
#include "util_funcs.h"

/*
 * include our .h file 
 */
#include "example.h"


   /*
    *  Certain objects can be set via configuration file directives.
    *  These variables hold the values for such objects, as they need to
    *   be accessible to both the config handlers, and the callback routine.
    */
#define EXAMPLE_STR_LEN	300
#define EXAMPLE_STR_DEFAULT	"life the universe and everything"
int             example_int = 42;
char            example_str[EXAMPLE_STR_LEN];

        /*
         * Forward declarations for the config handlers 
         */
void            example_parse_config_exampleint(const char *token,
                                                char *cptr);
void            example_parse_config_examplestr(const char *token,
                                                char *cptr);
void            example_free_config_exampleint(void);
void            example_free_config_examplestr(void);


        /*********************
	 *
	 *  Initialisation & common implementation functions
	 *
	 *********************/

    /*
     * This array structure defines a representation of the
     *  MIB being implemented.
     *
     * The type of the array is 'struct variableN', where N is
     *  large enough to contain the longest OID sub-component
     *  being loaded.  This will normally be the maximum value
     *  of the fifth field in each line.  In this case, the second
     *  and third entries are both of size 2, so we're using
     *  'struct variable2'
     *
     * The supported values for N are listed in <agent/var_struct.h>
     *  If the value you need is not listed there, simply use the
     *  next largest that is.
     *
     * The format of each line is as follows
     *  (using the first entry as an example):
     *      1: EXAMPLESTRING:
     *          The magic number defined in the example header file.
     *          This is passed to the callback routine and is used
     *            to determine which object is being queried.
     *      2: ASN_OCTET_STR:
     *          The type of the object.
     *          Valid types are listed in <snmp_impl.h>
     *      3: RONLY (or RWRITE):
     *          Whether this object can be SET or not.
     *      4: var_example:
     *          The callback routine, used when the object is queried.
     *          This will usually be the same for all objects in a module
     *            and is typically defined later in this file.
     *      5: 1:
     *          The length of the OID sub-component (the next field)
     *      6: {1}:
     *          The OID sub-components of this entry.
     *          In other words, the bits of the full OID that differ
     *            between the various entries of this array.
     *          This value is appended to the common prefix (defined later)
     *            to obtain the full OID of each entry.
     */
struct variable2 example_variables[] = {
    {EXAMPLESTRING, ASN_OCTET_STR, RONLY, var_example, 1, {1}},
    {EXAMPLEINTEGER, ASN_INTEGER, RWRITE, var_example, 2, {2, 1}},
    {EXAMPLEOBJECTID, ASN_OBJECT_ID, RONLY, var_example, 2, {2, 2}},
    {EXAMPLETIMETICKS, ASN_TIMETICKS, RONLY, var_example, 1, {3}},
    {EXAMPLEIPADDRESS, ASN_IPADDRESS, RONLY, var_example, 1, {4}},
    {EXAMPLECOUNTER, ASN_COUNTER, RONLY, var_example, 1, {5}},
    {EXAMPLEGAUGE, ASN_GAUGE, RONLY, var_example, 1, {6}},
    {EXAMPLETRIGGERTRAP, ASN_INTEGER, RWRITE, var_example, 1, {7}},
    {EXAMPLETRIGGERTRAP2, ASN_INTEGER, RWRITE, var_example, 1, {8}}
};

    /*
     * This array defines the OID of the top of the mib tree that we're
     *  registering underneath.
     * Note that this needs to be the correct size for the OID being 
     *  registered, so that the length of the OID can be calculated.
     *  The format given here is the simplest way to achieve this.
     */
oid             example_variables_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 254 };



    /*
     * This function is called at the time the agent starts up
     *  to do any initializations that might be required.
     *
     * In theory it is optional and can be omitted if no
     *  initialization is needed.  In practise, every module
     *  will need to register itself (or the objects being
     *  implemented will not appear in the MIB tree), and this
     *  registration is typically done here.
     *
     * If this function is added or removed, you must re-run
     *  the configure script, to detect this change.
     */
void
init_example(void)
{
    /*
     * Register ourselves with the agent to handle our mib tree.
     * The arguments are:
     *    descr:   A short description of the mib group being loaded.
     *    var:     The variable structure to load.
     *                  (the name of the variable structure defined above)
     *    vartype: The type of this variable structure
     *    theoid:  The OID pointer this MIB is being registered underneath.
     */
    REGISTER_MIB("example", example_variables, variable2,
                 example_variables_oid);


    /*
     *  Register config handlers for the two objects that can be set
     *   via configuration file directive.
     *  Also set a default value for the string object.  Note that the
     *   example integer variable was initialised above.
     */
    strlcpy(example_str, EXAMPLE_STR_DEFAULT, sizeof(example_str));

    snmpd_register_config_handler("exampleint",
                                  example_parse_config_exampleint,
                                  example_free_config_exampleint,
                                  "exampleint value");
    snmpd_register_config_handler("examplestr",
                                  example_parse_config_examplestr,
                                  example_free_config_examplestr,
                                  "examplestr value");
    snmpd_register_config_handler("examplestring",
                                  example_parse_config_examplestr,
                                  example_free_config_examplestr,
                                  "examplestring value");

    /*
     * One common requirement is to read values from the kernel.
     * This is usually initialised here, to speed up access when the
     *  information is read in, as a response to an incoming request.
     *
     * This module doesn't actually use this mechanism,
     * so this call is commented out here.
     */
    /*
     * auto_nlist( "example_symbol", 0, 0 ); 
     */
}

        /*********************
	 *
	 *  Configuration file handling functions
	 *
	 *********************/

void
example_parse_config_exampleint(const char *token, char *cptr)
{
    example_int = atoi(cptr);
}

void
example_parse_config_examplestr(const char *token, char *cptr)
{
    /*
     * Make sure the string fits in the space allocated for it.
     */
    if (strlen(cptr) < sizeof(example_str))
        strcpy(example_str, cptr);
    else {
        /*
         * Truncate the string if necessary.
         * An alternative approach would be to log an error,
         *  and discard this value altogether.
         */
        sprintf(example_str, "%.*s...", (int) (sizeof(example_str) - 4), cptr);
        netsnmp_assert(strlen(example_str) < sizeof(example_str));
    }
}

        /*
         * We don't need to do anything special when closing down 
         */
void
example_free_config_exampleint(void)
{
}

void
example_free_config_examplestr(void)
{
}

        /*********************
	 *
	 *  System specific implementation functions
	 *
	 *********************/

    /*
     * Define the callback function used in the example_variables structure.
     * This is called whenever an incoming request refers to an object
     *  within this sub-tree.
     *
     * Four of the parameters are used to pass information in.
     * These are:
     *    vp      The entry from the 'example_variables' array for the
     *             object being queried.
     *    name    The OID from the request.
     *    length  The length of this OID.
     *    exact   A flag to indicate whether this is an 'exact' request
     *             (GET/SET) or an 'inexact' one (GETNEXT/GETBULK).
     *
     * Four of the parameters are used to pass information back out.
     * These are:
     *    name     The OID being returned.
     *    length   The length of this OID.
     *    var_len  The length of the answer being returned.
     *    write_method   A pointer to the SET function for this object.
     *
     * Note that name & length serve a dual purpose in both roles.
     */

u_char         *
var_example(struct variable *vp,
            oid * name,
            size_t * length,
            int exact, size_t * var_len, WriteMethod ** write_method)
{
    /*
     *  The result returned from this function needs to be a pointer to
     *    static data (so that it can be accessed from outside).
     *  Define suitable variables for any type of data we may return.
     */
    static char     string[EXAMPLE_STR_LEN];    /* for EXAMPLESTRING   */
    static oid      oid_ret[8]; /* for EXAMPLEOBJECTID */
    static long     long_ret;   /* for everything else */

    /*
     * Before returning an answer, we need to check that the request
     *  refers to a valid instance of this object.  The utility routine
     *  'header_generic' can be used to do this for scalar objects.
     *
     * This routine 'header_simple_table' does the same thing for "simple"
     *  tables. (See the AGENT.txt file for the definition of a simple table).
     *
     * Both these utility routines also set up default values for the
     *  return arguments (assuming the check succeeded).
     * The name and length are set suitably for the current object,
     *  var_len assumes that the result is an integer of some form,
     *  and write_method assumes that the object cannot be set.
     *
     * If these assumptions are correct, this callback routine simply
     * needs to return a pointer to the appropriate value (using 'long_ret').
     * Otherwise, 'var_len' and/or 'write_method' should be set suitably.
     */
    DEBUGMSGTL(("example", "var_example entered\n"));
    if (header_generic(vp, name, length, exact, var_len, write_method) ==
        MATCH_FAILED)
        return NULL;


    /*
     * Many object will need to obtain data from the operating system in
     *  order to return the appropriate value.  Typically, this is done
     *  here - immediately following the 'header' call, and before the
     *  switch statement. This is particularly appropriate if a single 
     *  interface call can return data for all the objects supported.
     *
     * This example module does not rely on external data, so no such
     *  calls are needed in this case.  
     */

    /*
     * Now use the magic number from the variable pointer 'vp' to
     *  select the particular object being queried.
     * In each case, one of the static objects is set up with the
     *  appropriate information, and returned mapped to a 'u_char *'
     */
    switch (vp->magic) {
    case EXAMPLESTRING:
        sprintf(string, example_str);
        /*
         * Note that the assumption that the answer will be an
         *  integer does not hold true in this case, so the length
         *  of the answer needs to be set explicitly.           
         */
        *var_len = strlen(string);
        return (u_char *) string;

    case EXAMPLEINTEGER:
        /*
         * Here the length assumption is correct, but the
         *  object is writeable, so we need to set the
         *  write_method pointer as well as the current value.
         */
        long_ret = example_int;
        *write_method = write_exampleint;
        return (u_char *) & long_ret;

    case EXAMPLEOBJECTID:
        oid_ret[0] = 1;
        oid_ret[1] = 3;
        oid_ret[2] = 6;
        oid_ret[3] = 1;
        oid_ret[4] = 4;
        oid_ret[5] = oid_ret[6] = oid_ret[7] = 42;
        /*
         * Again, the assumption regarding the answer length is wrong.
         */
        *var_len = 8 * sizeof(oid);
        return (u_char *) oid_ret;

    case EXAMPLETIMETICKS:
        /*
         * Here both assumptions are correct,
         *  so we just need to set up the answer.
         */
        long_ret = 363136200;   /* 42 days, 42 minutes and 42.0 seconds */
        return (u_char *) & long_ret;

    case EXAMPLEIPADDRESS:
        /*
         * ipaddresses get returned as a long.  ick 
         */
        /*
         * we're returning 127.0.0.1 
         */
        {
            in_addr_t addr = ntohl(INADDR_LOOPBACK);
            memcpy(string, &addr, sizeof(addr));
            *var_len = sizeof(addr);
        }
        return (u_char *) string;

    case EXAMPLECOUNTER:
        long_ret = 42;
        return (u_char *) & long_ret;

    case EXAMPLEGAUGE:
        long_ret = 42;          /* Do we detect a theme running through these answers? */
        return (u_char *) & long_ret;

    case EXAMPLETRIGGERTRAP:
        /*
         * This object is essentially "write-only".
         * It only exists to trigger the sending of a trap.
         * Reading it will always return 0.
         */
        long_ret = 0;
        *write_method = write_exampletrap;
        return (u_char *) & long_ret;

    case EXAMPLETRIGGERTRAP2:
        /*
         * This object is essentially "write-only".
         * It only exists to trigger the sending of a v2 trap.
         * Reading it will always return 0.
         */
        long_ret = 0;
        *write_method = write_exampletrap2;
        return (u_char *) & long_ret;

    default:
        /*
         *  This will only be triggered if there's a problem with
         *   the coding of the module.  SNMP requests that reference
         *   a non-existant OID will be directed elsewhere.
         *  If this branch is reached, log an error, so that
         *   the problem can be investigated.
         */
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in examples/var_example\n",
                    vp->magic));
    }
    /*
     * If we fall through to here, fail by returning NULL.
     * This is essentially a continuation of the 'default' case above.
     */
    return NULL;
}

        /*********************
	 *
	 *  Writeable object SET handling routines
	 *
	 *********************/
int
write_exampleint(int action,
                 u_char * var_val,
                 u_char var_val_type,
                 size_t var_val_len,
                 u_char * statP, oid * name, size_t name_len)
{
    /*
     * Define an arbitrary maximum permissible value 
     */
#define MAX_EXAMPLE_INT	100
    static long     intval;
    static long     old_intval;

    switch (action) {
    case RESERVE1:
        /*
         *  Check that the value being set is acceptable
         */
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("example", "%x not integer type", var_val_type));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > sizeof(long)) {
            DEBUGMSGTL(("example", "wrong length %x", var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval > MAX_EXAMPLE_INT) {
            DEBUGMSGTL(("example", "wrong value %x", intval));
            return SNMP_ERR_WRONGVALUE;
        }
        break;

    case RESERVE2:
        /*
         *  This is conventially where any necesary
         *   resources are allocated (e.g. calls to malloc)
         *  Here, we are using static variables
         *   so don't need to worry about this.
         */
        break;

    case FREE:
        /*
         *  This is where any of the above resources
         *   are freed again (because one of the other
         *   values being SET failed for some reason).
         *  Again, since we are using static variables
         *   we don't need to worry about this either.
         */
        break;

    case ACTION:
        /*
         *  Set the variable as requested.
         *   Note that this may need to be reversed,
         *   so save any information needed to do this.
         */
        old_intval = example_int;
        example_int = intval;
        break;

    case UNDO:
        /*
         *  Something failed, so re-set the
         *   variable to its previous value
         *  (and free any allocated resources).
         */
        example_int = old_intval;
        break;

    case COMMIT:
        /*
         *  Everything worked, so we can discard any
         *   saved information, and make the change
         *   permanent (e.g. write to the config file).
         *  We also free any allocated resources.
         *
         *  In this case, there's nothing to do.
         */
        break;

    }
    return SNMP_ERR_NOERROR;
}

int
write_exampletrap(int action,
                  u_char * var_val,
                  u_char var_val_type,
                  size_t var_val_len,
                  u_char * statP, oid * name, size_t name_len)
{
    long            intval;

    DEBUGMSGTL(("example", "write_exampletrap entered: action=%d\n",
                action));
    switch (action) {
    case RESERVE1:
        /*
         *  The only acceptable value is the integer 1
         */
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("example", "%x not integer type", var_val_type));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > sizeof(long)) {
            DEBUGMSGTL(("example", "wrong length %x", var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval != 1) {
            DEBUGMSGTL(("example", "wrong value %x", intval));
            return SNMP_ERR_WRONGVALUE;
        }
        break;

    case RESERVE2:
        /*
         * No resources are required.... 
         */
        break;

    case FREE:
        /*
         * ... so no resources need be freed 
         */
        break;

    case ACTION:
        /*
         *  Having triggered the sending of a trap,
         *   it would be impossible to revoke this,
         *   so we can't actually invoke the action here.
         */
        break;

    case UNDO:
        /*
         * We haven't done anything yet,
         * so there's nothing to undo 
         */
        break;

    case COMMIT:
        /*
         *  Everything else worked, so it's now safe
         *   to trigger the trap.
         *  Note that this is *only* acceptable since
         *   the trap sending routines are "failsafe".
         *  (In fact, they can fail, but they return no
         *   indication of this, which is the next best thing!)
         */
        DEBUGMSGTL(("example", "write_exampletrap sending the trap\n"));
        send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 99);
        DEBUGMSGTL(("example", "write_exampletrap trap sent\n"));
        break;

    }
    return SNMP_ERR_NOERROR;
}

/*
 * this documents how to send a SNMPv2 (and higher) trap via the
 * send_v2trap() API.
 * 
 * Coding SNMP-v2 Trap:
 * 
 * The SNMPv2-Trap PDU contains at least a pair of object names and
 * values: - sysUpTime.0 whose value is the time in hundredths of a
 * second since the netwok management portion of system was last
 * reinitialized.  - snmpTrapOID.0 which is part of the trap group SNMPv2
 * MIB whose value is the object-id of the specific trap you have defined
 * in your own MIB.  Other variables can be added to caracterize the
 * trap.
 * 
 * The function send_v2trap adds automaticallys the two objects but the
 * value of snmpTrapOID.0 is 0.0 by default. If you want to add your trap
 * name, you have to reconstruct this object and to add your own
 * variable.
 * 
 */



int
write_exampletrap2(int action,
                   u_char * var_val,
                   u_char var_val_type,
                   size_t var_val_len,
                   u_char * statP, oid * name, size_t name_len)
{
    long            intval;

    /*
     * these variales will be used when we send the trap 
     */
    oid             objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };     /* snmpTrapOID.0 */
    oid             demo_trap[] = { 1, 3, 6, 1, 4, 1, 2021, 13, 990 };  /*demo-trap */
    oid             example_string_oid[] =
        { 1, 3, 6, 1, 4, 1, 2021, 254, 1, 0 };
    static netsnmp_variable_list var_trap;
    static netsnmp_variable_list var_obj;

    DEBUGMSGTL(("example", "write_exampletrap2 entered: action=%d\n",
                action));
    switch (action) {
    case RESERVE1:
        /*
         *  The only acceptable value is the integer 1
         */
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("example", "%x not integer type", var_val_type));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > sizeof(long)) {
            DEBUGMSGTL(("example", "wrong length %x", var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval != 1) {
            DEBUGMSGTL(("example", "wrong value %x", intval));
            return SNMP_ERR_WRONGVALUE;
        }
        break;

    case RESERVE2:
        /*
         * No resources are required.... 
         */
        break;

    case FREE:
        /*
         * ... so no resources need be freed 
         */
        break;

    case ACTION:
        /*
         *  Having triggered the sending of a trap,
         *   it would be impossible to revoke this,
         *   so we can't actually invoke the action here.
         */
        break;

    case UNDO:
        /*
         * We haven't done anything yet,
         * so there's nothing to undo 
         */
        break;

    case COMMIT:
        /*
         *  Everything else worked, so it's now safe
         *   to trigger the trap.
         *  Note that this is *only* acceptable since
         *   the trap sending routines are "failsafe".
         *  (In fact, they can fail, but they return no
         *   indication of this, which is the next best thing!)
         */

        /*
         * trap definition objects 
         */

        var_trap.next_variable = &var_obj;      /* next variable */
        var_trap.name = objid_snmptrap; /* snmpTrapOID.0 */
        var_trap.name_length = sizeof(objid_snmptrap) / sizeof(oid);    /* number of sub-ids */
        var_trap.type = ASN_OBJECT_ID;
        var_trap.val.objid = demo_trap; /* demo-trap objid */
        var_trap.val_len = sizeof(demo_trap);   /* length in bytes (not number of subids!) */


        /*
         * additional objects 
         */


        var_obj.next_variable = NULL;   /* No more variables after this one */
        var_obj.name = example_string_oid;
        var_obj.name_length = sizeof(example_string_oid) / sizeof(oid); /* number of sub-ids */
        var_obj.type = ASN_OCTET_STR;   /* type of variable */
        var_obj.val.string = example_str;       /* value */
        var_obj.val_len = strlen(example_str);
        DEBUGMSGTL(("example", "write_exampletrap2 sending the v2 trap\n"));
        send_v2trap(&var_trap);
        DEBUGMSGTL(("example", "write_exampletrap2 v2 trap sent\n"));

        break;

    }
    return SNMP_ERR_NOERROR;
}
