/*
 *  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

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

/*
 * header_generic() comes from here 
 */
#include "util_funcs/header_generic.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: NETSNMP_OLDAPI_RONLY (or NETSNMP_OLDAPI_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, NETSNMP_OLDAPI_RONLY,
     var_example, 1, {1}},
    {EXAMPLEINTEGER, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_example, 2, {2, 1}},
    {EXAMPLEOBJECTID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
     var_example, 2, {2, 2}},
    {EXAMPLETIMETICKS, ASN_TIMETICKS, NETSNMP_OLDAPI_RONLY,
     var_example, 1, {3}},
    {EXAMPLEIPADDRESS, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
     var_example, 1, {4}},
    {EXAMPLECOUNTER, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
     var_example, 1, {5}},
    {EXAMPLEGAUGE, ASN_GAUGE, NETSNMP_OLDAPI_RONLY,
     var_example, 1, {6}},
    {EXAMPLETRIGGERTRAP, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_example, 1, {7}},
    {EXAMPLETRIGGERTRAP2, ASN_INTEGER, NETSNMP_OLDAPI_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:
        strcpy(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 %" NETSNMP_PRIz "u",
                        var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval > MAX_EXAMPLE_INT) {
            DEBUGMSGTL(("example", "wrong value %lx", 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 %" NETSNMP_PRIz "u",
                        var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval != 1) {
            DEBUGMSGTL(("example", "wrong value %lx", 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 characterize the
 * trap.
 * 
 * The function send_v2trap adds automatically 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 %" NETSNMP_PRIz "u",
                        var_val_len));
            return SNMP_ERR_WRONGLENGTH;
        }

        intval = *((long *) var_val);
        if (intval != 1) {
            DEBUGMSGTL(("example", "wrong value %lx", 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 = (unsigned char *) 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;
}
