/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.17 $ of : mfd-data-access.m2c,v $ 
 *
 * $Id$
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "ifTable.h"
#include "ifTable_defs.h"

#include "ifTable_data_access.h"

#ifdef USING_IP_MIB_IPV4INTERFACETABLE_IPV4INTERFACETABLE_MODULE
#   include "mibgroup/ip-mib/ipv4InterfaceTable/ipv4InterfaceTable.h"
#endif

#ifdef USING_IP_MIB_IPV6INTERFACETABLE_IPV6INTERFACETABLE_MODULE
#   include "mibgroup/ip-mib/ipv6InterfaceTable/ipv6InterfaceTable.h"
#endif

typedef struct cd_container_s {
    netsnmp_container *current;
    netsnmp_container *deleted;
} cd_container;

/*
 * flag so we know not to set row/table last change times
 * during startup.
 */
static int      _first_load = 1;

/*
 * Value of interface_fadeout config option
 */
static int fadeout = IFTABLE_REMOVE_MISSING_AFTER;
/*
 * Value of interface_replace_old config option
 */
static int replace_old = 0;

static void
_delete_missing_interface(ifTable_rowreq_ctx *rowreq_ctx,
                          netsnmp_container *container);

/** @ingroup interface 
 * @defgroup data_access data_access: Routines to access data
 *
 * These routines are used to locate the data used to satisfy
 * requests.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ifTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IF-MIB::ifTable is subid 2 of interfaces.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.2.2, length: 8
 */

static void
parse_interface_fadeout(const char *token, char *line)
{
    fadeout = atoi(line);
}
static void
parse_interface_replace_old(const char *token, char *line)
{
    if (strcmp(line, "yes") == 0
            || strcmp(line, "y") == 0
            || strcmp(line, "true") == 0
            || strcmp(line, "1") == 0) {
        replace_old = 1;
        return;
    }
    if (strcmp(line, "no") == 0
            || strcmp(line, "n") == 0
            || strcmp(line, "false") == 0
            || strcmp(line, "0") == 0) {
        replace_old = 0;
        return;
    }
    snmp_log(LOG_ERR, "Invalid value of interface_replace_old parameter: '%s'\n",
            line);
}

/**
 * initialization for ifTable data access
 *
 * This function is called during startup to allow you to
 * allocate any resources you need for the data table.
 *
 * @param ifTable_reg
 *        Pointer to ifTable_registration
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : unrecoverable error.
 */
int
ifTable_init_data(ifTable_registration * ifTable_reg)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_init_data", "called\n"));

    /*
     * TODO:303:o: Initialize ifTable data.
     */
    snmpd_register_config_handler("interface_fadeout", parse_interface_fadeout, NULL,
            "interface_fadeout seconds");
    snmpd_register_config_handler("interface_replace_old",
            parse_interface_replace_old, NULL, "interface_replace_old yes|no");

    return MFD_SUCCESS;
}                               /* ifTable_init_data */

/**
 * container overview
 *
 */

/**
 * container initialization
 *
 * @param container_ptr_ptr A pointer to a container pointer. If you
 *        create a custom container, use this parameter to return it
 *        to the MFD helper. If set to NULL, the MFD helper will
 *        allocate a container for you.
 * @param  cache A pointer to a cache structure. You can set the timeout
 *         and other cache flags using this pointer.
 *
 *  This function is called at startup to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases. If no custom
 *  container is allocated, the MFD code will create one for your.
 *
 *  This is also the place to set up cache behavior. The default, to
 *  simply set the cache timeout, will work well with the default
 *  container. If you are using a custom container, you may want to
 *  look at the cache helper documentation to see if there are any
 *  flags you want to set.
 *
 * @remark
 *  This would also be a good place to do any initialization needed
 *  for you data source. For example, opening a connection to another
 *  process that will supply the data, opening a database, etc.
 */
void
ifTable_container_init(netsnmp_container **container_ptr_ptr,
                       netsnmp_cache * cache)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_container_init", "called\n"));

    if (NULL == container_ptr_ptr) {
        snmp_log(LOG_ERR,
                 "bad container param to ifTable_container_init\n");
        return;
    }

    /*
     * For advanced users, you can use a custom container. If you
     * do not create one, one will be created for you.
     */
    *container_ptr_ptr = NULL;

    if (NULL == cache) {
        snmp_log(LOG_ERR, "bad cache param to ifTable_container_init\n");
        return;
    }

    /*
     * TODO:345:A: Set up ifTable cache properties.
     *
     * Also for advanced users, you can set parameters for the
     * cache. Do not change the magic pointer, as it is used
     * by the MFD helper. To completely disable caching, set
     * cache->enabled to 0.
     */
    /*
     * since we set AUTO_RELOAD below, this timer controls how
     * often the cache is reloaded. A 10 Mbps stream can wrap if*Octets in ~57 minutes.
     * At 100 Mbps it is ~5 minutes, and at 1 Gbps, ~34 seconds.
     */
    cache->timeout = IFTABLE_CACHE_TIMEOUT;     /* seconds */

    /*
     * don't release resources
     */
    cache->flags |=
        (NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_FREE_EXPIRED
         | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_PRELOAD |
         NETSNMP_CACHE_AUTO_RELOAD | NETSNMP_CACHE_DONT_INVALIDATE_ON_SET);
}                               /* ifTable_container_init */

void
send_linkUpDownNotifications(oid *notification_oid, size_t notification_oid_len, int if_index, int if_admin_status, int if_oper_status)
{
    /*
     * In the notification, we have to assign our notification OID to
     * the snmpTrapOID.0 object. Here is it's definition. 
     */
    oid             objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
    size_t          objid_snmptrap_len = OID_LENGTH(objid_snmptrap);

    /*
     * define the OIDs for the varbinds we're going to include
     *  with the notification -
     * IF-MIB::ifIndex,
     * IF-MIB::ifAdminStatus, and
     * IF-MIB::ifOperStatus
     */
    oid      if_index_oid[]   = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 0 };
    size_t   if_index_oid_len = OID_LENGTH(if_index_oid);
    oid      if_admin_status_oid[]   = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 0 };
    size_t   if_admin_status_oid_len = OID_LENGTH(if_admin_status_oid);
    oid      if_oper_status_oid[]   = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 0 };
    size_t   if_oper_status_oid_len = OID_LENGTH(if_oper_status_oid);

    /*
     * here is where we store the variables to be sent in the trap 
     */
    netsnmp_variable_list *notification_vars = NULL;

    DEBUGMSGTL(("rsys:linkUpDownNotifications", "defining the trap\n"));

    /*
     * update the instance for each variable to be sent in the trap
     */
    if_index_oid[10] = if_index;
    if_admin_status_oid[10] = if_index;
    if_oper_status_oid[10] = if_index;

    /*
     * add in the trap definition object 
     */
    snmp_varlist_add_variable(&notification_vars,
                              /*
                               * the snmpTrapOID.0 variable 
                               */
                              objid_snmptrap, objid_snmptrap_len,
                              /*
                               * value type is an OID 
                               */
                              ASN_OBJECT_ID,
                              /*
                               * value contents is our notification OID 
                               */
                              (u_char *) notification_oid,
                              /*
                               * size in bytes = oid length * sizeof(oid) 
                               */
                              notification_oid_len * sizeof(oid));

    /*
     * add in the additional objects defined as part of the trap
     */
    snmp_varlist_add_variable(&notification_vars,
                               if_index_oid, if_index_oid_len,
                               ASN_INTEGER,
                              (u_char *)&if_index,
                                  sizeof(if_index));

    /*
     * if we want to insert additional objects, we do it here 
     */
    snmp_varlist_add_variable(&notification_vars,
                               if_admin_status_oid, if_admin_status_oid_len,
                               ASN_INTEGER,
                              (u_char *)&if_admin_status,
                                  sizeof(if_admin_status));

    snmp_varlist_add_variable(&notification_vars,
                               if_oper_status_oid, if_oper_status_oid_len,
                               ASN_INTEGER,
                              (u_char *)&if_oper_status,
                                  sizeof(if_oper_status));

    /*
     * send the trap out.  This will send it to all registered
     * receivers (see the "SETTING UP TRAP AND/OR INFORM DESTINATIONS"
     * section of the snmpd.conf manual page. 
     */
    DEBUGMSGTL(("rsys:linkUpDownNotifications", "sending the trap\n"));
    send_v2trap(notification_vars);

    /*
     * free the created notification variable list 
     */
    DEBUGMSGTL(("rsys:linkUpDownNotifications", "cleaning up\n"));
    snmp_free_varbind(notification_vars);
}

/**
 * check entry for update
 *
 */
static void
_check_interface_entry_for_updates(ifTable_rowreq_ctx * rowreq_ctx,
                                   cd_container *cdc)
{
    char            oper_changed = 0;
    int lastchanged = rowreq_ctx->data.ifLastChange;
    netsnmp_container *ifcontainer = cdc->current;

    /*
     * check for matching entry. We can do this directly, since
     * both containers use the same index.
     */
    netsnmp_interface_entry *ifentry =
        (netsnmp_interface_entry*)CONTAINER_FIND(ifcontainer, rowreq_ctx);

#ifdef USING_IP_MIB_IPV4INTERFACETABLE_IPV4INTERFACETABLE_MODULE
    /*
     * give ipv4If table a crack at the entry
     */
    ipv4InterfaceTable_check_entry_for_updates(rowreq_ctx, ifentry);
#endif

#ifdef USING_IP_MIB_IPV6INTERFACETABLE_IPV6INTERFACETABLE_MODULE
    /*
     * give ipv6If table a crack at the entry
     */
    ipv6InterfaceTable_check_entry_for_updates(rowreq_ctx, ifentry);
#endif

    if (NULL == ifentry) {
        /*
         * if this is the first time we detected that this interface is
         * missing, set admin/oper status down, and set last change.
         *
         * yyy-rks: when, if ever, would we consider an entry
         * deleted (and thus need to update ifTableLastChanged)?
         */
        if (!rowreq_ctx->known_missing) {
            rowreq_ctx->known_missing = 1;
            DEBUGMSGTL(("ifTable:access", "updating missing entry %s\n",rowreq_ctx->data.ifName));
            rowreq_ctx->data.ifAdminStatus = IFADMINSTATUS_DOWN;
            rowreq_ctx->data.ifOperStatus = IFOPERSTATUS_DOWN;
            oper_changed = 1;
        }
        if (rowreq_ctx->known_missing) {
            time_t now = netsnmp_get_agent_uptime();
            u_long diff = (now - rowreq_ctx->data.ifLastChange) / 100;
            DEBUGMSGTL(("verbose:ifTable:access", "missing entry for %ld seconds\n", diff));
            if (diff >= fadeout) {
                DEBUGMSGTL(("ifTable:access", "marking missing entry %s for "
                            "removal after %d seconds\n", rowreq_ctx->data.ifName,
                            fadeout));
                if (NULL == cdc->deleted)
                   cdc->deleted = netsnmp_container_find("ifTable_deleted:linked_list");
                if (NULL == cdc->deleted)
                   snmp_log(LOG_ERR, "couldn't create container for deleted interface\n");
                else {
                   CONTAINER_INSERT(cdc->deleted, rowreq_ctx);
                }
            }
        }
    } else {
        DEBUGMSGTL(("ifTable:access", "updating existing entry %s\n",
                    rowreq_ctx->data.ifName));

#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
        {
            int rc = strcmp(rowreq_ctx->data.ifName,
                            ifentry->name);
            if (rc != 0) {
                NETSNMP_LOGONCE((LOG_ERR, "Name of an interface changed. Such " \
                        "interfaces will keep its old name in IF-MIB.\n"));
                DEBUGMSGTL(("ifTable:access", "interface %s changed name to %s, ignoring\n",
                    rowreq_ctx->data.ifName, ifentry->name));
            }
        }
#endif
        /*
         * if the interface was missing, but came back, clear the
         * missing flag and set the discontinuity time. (if an os keeps
         * persistent counters, tough cookies. We'll cross that 
         * bridge if we come to it).
         */
        if (rowreq_ctx->known_missing) {
            rowreq_ctx->known_missing = 0;
#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
            rowreq_ctx->data.ifCounterDiscontinuityTime =
                netsnmp_get_agent_uptime();
#endif
        }

        /*
         * Check for changes, then update
         */
        if ((!(ifentry->ns_flags & NETSNMP_INTERFACE_FLAGS_HAS_LASTCHANGE))
            && (rowreq_ctx->data.ifOperStatus != ifentry->oper_status))
            oper_changed = 1;
        netsnmp_access_interface_entry_copy(rowreq_ctx->data.ifentry,
                                            ifentry);

        /*
         * remove entry from temporary ifcontainer
         */
        CONTAINER_REMOVE(ifcontainer, ifentry);
        netsnmp_access_interface_entry_free(ifentry);
    }

    /*
     * if ifOperStatus changed, update ifLastChange
     */
    if (oper_changed) {
        rowreq_ctx->data.ifLastChange = netsnmp_get_agent_uptime();
#ifdef USING_IF_MIB_IFXTABLE_IFXTABLE_MODULE
        if (rowreq_ctx->data.ifLinkUpDownTrapEnable == 1) {
            if (rowreq_ctx->data.ifOperStatus == IFOPERSTATUS_UP) {
                oid notification_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5, 4 };
                send_linkUpDownNotifications(notification_oid, OID_LENGTH(notification_oid),
                                             rowreq_ctx->tbl_idx.ifIndex,
                                             rowreq_ctx->data.ifAdminStatus,
                                             rowreq_ctx->data.ifOperStatus);
            } else if (rowreq_ctx->data.ifOperStatus == IFOPERSTATUS_DOWN) {
                oid notification_oid[] = { 1, 3, 6, 1, 6, 3, 1, 1, 5, 3 };
                send_linkUpDownNotifications(notification_oid, OID_LENGTH(notification_oid),
                                             rowreq_ctx->tbl_idx.ifIndex,
                                             rowreq_ctx->data.ifAdminStatus,
                                             rowreq_ctx->data.ifOperStatus);
            }
        }
#endif
    }

    else
        rowreq_ctx->data.ifLastChange = lastchanged;
}

/**
 * Remove all old interfaces with the same name as the newly added one.
 */
static void
_check_and_replace_old(netsnmp_interface_entry *ifentry,
                   netsnmp_container *container)
{
    netsnmp_iterator *it;
    ifTable_rowreq_ctx * rowreq_ctx;
    netsnmp_container *to_delete;

    to_delete = netsnmp_container_find("ifTable_deleted:linked_list");
    if (NULL == to_delete) {
       snmp_log(LOG_ERR, "couldn't create container for deleted interface\n");
       return;
    }

    it = CONTAINER_ITERATOR(container);
    for (rowreq_ctx = ITERATOR_FIRST(it); rowreq_ctx; rowreq_ctx = ITERATOR_NEXT(it)) {
        if (strcmp(ifentry->name, rowreq_ctx->data.ifentry->name) == 0) {
            DEBUGMSGTL(("ifTable:access",
                    "removing interface %ld due to new %s\n",
                    (long) rowreq_ctx->data.ifentry->index, ifentry->name));
            CONTAINER_INSERT(to_delete, rowreq_ctx);
        }
    }
    ITERATOR_RELEASE(it);

    CONTAINER_FOR_EACH(to_delete,
                       (netsnmp_container_obj_func *) _delete_missing_interface,
                       container);
    CONTAINER_FREE(to_delete);
}

/**
 * add new entry
 */
static void
_add_new_interface(netsnmp_interface_entry *ifentry,
                   netsnmp_container *container)
{
    ifTable_rowreq_ctx *rowreq_ctx;

    DEBUGMSGTL(("ifTable:access", "creating new entry\n"));

    /*
     * allocate an row context and set the index(es), then add it to
     * the container and set ifTableLastChanged.
     */
    rowreq_ctx = ifTable_allocate_rowreq_ctx(ifentry);
    if ((NULL != rowreq_ctx) &&
        (MFD_SUCCESS == ifTable_indexes_set(rowreq_ctx, ifentry->index))) {
        if (replace_old)
                _check_and_replace_old(ifentry, container);

        CONTAINER_INSERT(container, rowreq_ctx);
        /*
         * fix this when we hit an arch that reports its own last change
         */
        netsnmp_assert(0 == (ifentry->ns_flags &
                             NETSNMP_INTERFACE_FLAGS_HAS_LASTCHANGE));
        if (0 == _first_load) {
            rowreq_ctx->data.ifLastChange = netsnmp_get_agent_uptime();
            ifTable_lastChange_set(rowreq_ctx->data.ifLastChange);
        }
#ifdef USING_IP_MIB_IPV4INTERFACETABLE_IPV4INTERFACETABLE_MODULE
        /*
         * give ipv4If table a crack at the entry
         */
        ipv4InterfaceTable_check_entry_for_updates(rowreq_ctx, ifentry);
#endif
#ifdef USING_IP_MIB_IPV6INTERFACETABLE_IPV6INTERFACETABLE_MODULE
        /*
         * give ipv6If table a crack at the entry
         */
        ipv6InterfaceTable_check_entry_for_updates(rowreq_ctx, ifentry);
#endif
    } else {
        if (rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "ifTable cache.\n");
            ifTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "ifTable cache.\n");
            netsnmp_access_interface_entry_free(ifentry);
        }
    }
}

/**
 * add new entry
 */
static void
_delete_missing_interface(ifTable_rowreq_ctx *rowreq_ctx,
                          netsnmp_container *container)
{
    DEBUGMSGTL(("ifTable:access", "removing missing entry %s\n",
                rowreq_ctx->data.ifName));

    CONTAINER_REMOVE(container, rowreq_ctx);

    ifTable_release_rowreq_ctx(rowreq_ctx);
}

/**
 * container shutdown
 *
 * @param container_ptr A pointer to the container.
 *
 *  This function is called at shutdown to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases.
 *
 *  This function is called before ifTable_container_free().
 *
 * @remark
 *  This would also be a good place to do any cleanup needed
 *  for you data source. For example, closing a connection to another
 *  process that supplied the data, closing a database, etc.
 */
void
ifTable_container_shutdown(netsnmp_container *container_ptr)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_container_shutdown", "called\n"));

    if (NULL == container_ptr) {
        snmp_log(LOG_ERR, "bad params to ifTable_container_shutdown\n");
        return;
    }

}                               /* ifTable_container_shutdown */

/**
 * load initial data
 *
 * TODO:350:M: Implement ifTable data load
 * This function will also be called by the cache helper to load
 * the container again (after the container free function has been
 * called to free the previous contents).
 *
 * @param container container to which items should be inserted
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
 * @retval MFD_ERROR                : other error.
 *
 *  This function is called to load the index(es) (and data, optionally)
 *  for the every row in the data set.
 *
 * @remark
 *  While loading the data, the only important thing is the indexes.
 *  If access to your data is cheap/fast (e.g. you have a pointer to a
 *  structure in memory), it would make sense to update the data here.
 *  If, however, the accessing the data invovles more work (e.g. parsing
 *  some other existing data, or peforming calculations to derive the data),
 *  then you can limit yourself to setting the indexes and saving any
 *  information you will need later. Then use the saved information in
 *  ifTable_row_prep() for populating data.
 *
 * @note
 *  If you need consistency between rows (like you want statistics
 *  for each row to be from the same time frame), you should set all
 *  data here.
 *
 */
int
ifTable_container_load(netsnmp_container *container)
{
    cd_container cdc;

    DEBUGMSGTL(("verbose:ifTable:ifTable_container_load", "called\n"));

    /*
     * TODO:351:M: |-> Load/update data in the ifTable container.
     * loop over your ifTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    /*
     * ifTable gets its data from the netsnmp_interface API.
     */
    cdc.current =
        netsnmp_access_interface_container_load(NULL,
                                                NETSNMP_ACCESS_INTERFACE_INIT_NOFLAGS);
    if (NULL == cdc.current)
        return MFD_RESOURCE_UNAVAILABLE;        /* msg already logged */

    cdc.deleted = NULL; /* created as needed */

    /*
     * we just got a fresh copy of interface data. compare it to
     * what we've already got, and make any adjustements...
     */
    CONTAINER_FOR_EACH(container, (netsnmp_container_obj_func *)
                       _check_interface_entry_for_updates, &cdc);

    /*
     * now remove any missing interfaces
     */
    if (NULL != cdc.deleted) {
       CONTAINER_FOR_EACH(cdc.deleted,
                          (netsnmp_container_obj_func *) _delete_missing_interface,
                          container);
       CONTAINER_FREE(cdc.deleted);
    }

    /*
     * now add any new interfaces
     */
    CONTAINER_FOR_EACH(cdc.current,
                       (netsnmp_container_obj_func *) _add_new_interface,
                       container);

    /*
     * free the container. we've either claimed each ifentry, or released it,
     * so the dal function doesn't need to clear the container.
     */
    netsnmp_access_interface_container_free(cdc.current,
                                            NETSNMP_ACCESS_INTERFACE_FREE_DONT_CLEAR);

    DEBUGMSGT(("verbose:ifTable:ifTable_cache_load",
               "%lu records\n", (unsigned long)CONTAINER_SIZE(container)));

    if (_first_load)
        _first_load = 0;

    return MFD_SUCCESS;
}                               /* ifTable_container_load */

/**
 * container clean up
 *
 * @param container container with all current items
 *
 *  This optional callback is called prior to all
 *  item's being removed from the container. If you
 *  need to do any processing before that, do it here.
 *
 * @note
 *  The MFD helper will take care of releasing all the row contexts.
 *
 */
void
ifTable_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_container_free", "called\n"));

    /*
     * TODO:380:M: Free ifTable container data.
     */
}                               /* ifTable_container_free */

/**
 * prepare row for processing.
 *
 *  When the agent has located the row for a request, this function is
 *  called to prepare the row for processing. If you fully populated
 *  the data context during the index setup phase, you may not need to
 *  do anything.
 *
 * @param rowreq_ctx pointer to a context.
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 */
int
ifTable_row_prep(ifTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ifTable:ifTable_row_prep", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:390:o: Prepare row for request.
     * If populating row data was delayed, this is the place to
     * fill in the row for this request.
     */

    return MFD_SUCCESS;
}                               /* ifTable_row_prep */

/** @} */
