/*
 * 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 "ipAddressTable.h"


#include "ipAddressTable_data_access.h"

#include <sys/ioctl.h>
#include <errno.h>


/** @ingroup interface 
 * @addtogroup data_access data_access: Routines to access data
 *
 * These routines are used to locate the data used to satisfy
 * requests.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ipAddressTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-MIB::ipAddressTable is subid 34 of ip.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.34, length: 8
 */

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

    /*
     * TODO:303:o: Initialize ipAddressTable data.
     */

    return MFD_SUCCESS;
}                               /* ipAddressTable_init_data */

/**
 * container overview
 *
 */
/**
 * check entry for update
 */
static void
_clear_times(ipAddressTable_rowreq_ctx * rowreq_ctx, void *magic)
{
    rowreq_ctx->ipAddressLastChanged = rowreq_ctx->ipAddressCreated = 0;
}

/**
 * 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
ipAddressTable_container_init(netsnmp_container **container_ptr_ptr,
                              netsnmp_cache * cache)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_container_init",
                "called\n"));

    if (NULL == container_ptr_ptr) {
        snmp_log(LOG_ERR,
                 "bad container param to ipAddressTable_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.
     */
    /*
     * We create a custom container here so we can pre-load it, which
     * will result in all new entries with last changed values. we need
     * to clear those...  We also need to make sure ifIndexes have been
     * assigned...
     */
    *container_ptr_ptr =
        netsnmp_container_find("ipAddressTable:table_container");
    if (NULL != *container_ptr_ptr) {
        (*container_ptr_ptr)->container_name = strdup("ipAddressTable");
        ipAddressTable_container_load(*container_ptr_ptr);
        CONTAINER_FOR_EACH(*container_ptr_ptr,
                           (netsnmp_container_obj_func *) _clear_times,
                           NULL);
    }

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

    /*
     * TODO:345:A: Set up ipAddressTable 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.
     */

    /*
     * basically, turn off all automatic cache handling except autoload.
     */
    cache->flags |=
        (NETSNMP_CACHE_DONT_AUTO_RELEASE | NETSNMP_CACHE_DONT_FREE_EXPIRED
         | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD | NETSNMP_CACHE_AUTO_RELOAD
         | NETSNMP_CACHE_DONT_INVALIDATE_ON_SET);
}                               /* ipAddressTable_container_init */

/**
 * 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 ipAddressTable_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
ipAddressTable_container_shutdown(netsnmp_container *container_ptr)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_container_shutdown",
                "called\n"));

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

}                               /* ipAddressTable_container_shutdown */

/**
 * check entry for update
 */
static void
_check_entry_for_updates(ipAddressTable_rowreq_ctx * rowreq_ctx,
                         void **magic)
{
    netsnmp_container *ipaddress_container = (netsnmp_container*)magic[0];
    netsnmp_container *to_delete           = (netsnmp_container*)magic[1];

    /*
     * check for matching entry using secondary index.
     */
    netsnmp_ipaddress_entry *ipaddress_entry = (netsnmp_ipaddress_entry*)
        CONTAINER_FIND(ipaddress_container, rowreq_ctx->data);
    if (NULL == ipaddress_entry) {
        DEBUGMSGTL(("ipAddressTable:access", "removing missing entry\n"));

        if (NULL == to_delete) {
            magic[1] = to_delete = netsnmp_container_find("lifo");
            if (NULL == to_delete)
                snmp_log(LOG_ERR, "couldn't create delete container\n");
        }
        if (NULL != to_delete)
            CONTAINER_INSERT(to_delete, rowreq_ctx);
    } else {
        DEBUGMSGTL(("ipAddressTable:access", "updating existing entry\n"));

        /*
         * Check for changes & update
         */
        if (netsnmp_access_ipaddress_entry_update(rowreq_ctx->data,
                                                  ipaddress_entry) > 0)
            rowreq_ctx->ipAddressLastChanged = netsnmp_get_agent_uptime();

        /*
         * remove entry from ifcontainer
         */
        CONTAINER_REMOVE(ipaddress_container, ipaddress_entry);
        netsnmp_access_ipaddress_entry_free(ipaddress_entry);
    }
}

/**
 * add new entry
 */
static void
_add_new_entry(netsnmp_ipaddress_entry *ipaddress_entry,
               netsnmp_container *container)
{
    ipAddressTable_rowreq_ctx *rowreq_ctx;

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

    netsnmp_assert(NULL != ipaddress_entry);
    netsnmp_assert(NULL != container);

    /*
     * allocate an row context and set the index(es)
     */
    rowreq_ctx = ipAddressTable_allocate_rowreq_ctx(ipaddress_entry, NULL);
    if ((NULL != rowreq_ctx) &&
        (MFD_SUCCESS ==
         ipAddressTable_indexes_set(rowreq_ctx,
                                    ipaddress_entry->ia_address_len,
                                    ipaddress_entry->ia_address,
                                    ipaddress_entry->ia_address_len))) {
        if (CONTAINER_INSERT(container, rowreq_ctx) < 0) {
            DEBUGMSGTL (("ipAddressTable:access","container insert failed for new entry\n"));
            ipAddressTable_release_rowreq_ctx(rowreq_ctx);
            return;
        }
        rowreq_ctx->ipAddressLastChanged =
            rowreq_ctx->ipAddressCreated = netsnmp_get_agent_uptime();
    } else {
        if (NULL != rowreq_ctx) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "ipAddressTable cache.\n");
            ipAddressTable_release_rowreq_ctx(rowreq_ctx);
        } else {
            snmp_log(LOG_ERR, "memory allocation failed while loading "
                     "ipAddressTable cache.\n");
            netsnmp_access_ipaddress_entry_free(ipaddress_entry);
        }

        return;
    }

    /*-------------------------------------------------------------------
     * handle data that isn't part of the data_access ipaddress structure
     */
    rowreq_ctx->ipAddressRowStatus = ROWSTATUS_ACTIVE;
}

/**
 * load initial data
 *
 * TODO:350:M: Implement ipAddressTable 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
 *  ipAddressTable_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
ipAddressTable_container_load(netsnmp_container *container)
{
    netsnmp_container *ipaddress_container;
    void           *tmp_ptr[2];

    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_cache_load",
                "called\n"));

    /*
     * TODO:351:M: |-> Load/update data in the ipAddressTable container.
     * loop over your ipAddressTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    ipaddress_container =
        netsnmp_access_ipaddress_container_load(NULL,
                                                NETSNMP_ACCESS_IPADDRESS_LOAD_ADDL_IDX_BY_ADDR);
    /*
     * we just got a fresh copy of interface data. compare it to
     * what we've already got, and make any adjustments, saving
     * missing addresses to be deleted.
     */
    tmp_ptr[0] = ipaddress_container->next;
    tmp_ptr[1] = NULL;
    CONTAINER_FOR_EACH(container, (netsnmp_container_obj_func *)
                       _check_entry_for_updates, tmp_ptr);

    /*
     * now add any new interfaces
     */
    CONTAINER_FOR_EACH(ipaddress_container,
                       (netsnmp_container_obj_func *) _add_new_entry,
                       container);

    /*
     * free the container. we've either claimed each entry, or released it,
     * so the access function doesn't need to clear the container.
     */
    netsnmp_access_ipaddress_container_free(ipaddress_container,
                                            NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR);

    /*
     * remove deleted addresses from table container
     */
    if (NULL != tmp_ptr[1]) {
        netsnmp_container *tmp_container =
            (netsnmp_container *) tmp_ptr[1];
        ipAddressTable_rowreq_ctx *tmp_ctx;

        /*
         * this works because the tmp_container is a linked list,
         * which can be used like a stack...
         */
        while (CONTAINER_SIZE(tmp_container)) {
            /*
             * get from delete list
             */
            tmp_ctx = (ipAddressTable_rowreq_ctx*)CONTAINER_FIRST(tmp_container);

            /*
             * release context, delete from table container
             */
            CONTAINER_REMOVE(container, tmp_ctx);
            ipAddressTable_release_rowreq_ctx(tmp_ctx);

            /*
             * pop off delete list
             */
            CONTAINER_REMOVE(tmp_container, NULL);
        }
    }

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

    return MFD_SUCCESS;
}

/**
 * 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
ipAddressTable_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_container_free",
                "called\n"));

    /*
     * TODO:380:M: Free ipAddressTable container data.
     */
}                               /* ipAddressTable_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
ipAddressTable_row_prep(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_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;
}                               /* ipAddressTable_row_prep */

/*
 * TODO:420:r: Implement ipAddressTable index validation.
 */
/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressAddrType
 * ipAddressAddrType is subid 1 of ipAddressEntry.
 * Its status is Current, and its access level is NoAccess.
 * OID: .1.3.6.1.2.1.4.34.1.1
 * Description:
The address type of ipAddressAddr.
 *
 * Attributes:
 *   accessible 0     isscalar 0     enums  1      hasdefval 0
 *   readable   0     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 5/8. Values:  unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
 *
 * Its syntax is InetAddressType (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 *
 *
 *
 * NOTE: NODE ipAddressAddrType IS NOT ACCESSIBLE
 *
 *
 */
/**
 * check validity of ipAddressAddrType index portion
 *
 * @retval MFD_SUCCESS   : the incoming value is legal
 * @retval MFD_ERROR     : the incoming value is NOT legal
 *
 * @note this is not the place to do any checks for the sanity
 *       of multiple indexes. Those types of checks should be done in the
 *       ipAddressTable_validate_index() function.
 *
 * @note Also keep in mind that if the index refers to a row in this or
 *       some other table, you can't check for that row here to make
 *       decisions, since that row might not be created yet, but may
 *       be created during the processing this request. If you have
 *       such checks, they should be done in the check_dependencies
 *       function, because any new/deleted/changed rows should be
 *       available then.
 *
 * The following checks have already been done for you:
 *    The value is one of  unknown(0), ipv4(1), ipv6(2), ipv4z(3), ipv6z(4), dns(16)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 */
int
ipAddressAddrType_check_index(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddrType_check_index",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:426:M: |-> Check ipAddressTable index ipAddressAddrType.
     * check that index value in the table context is legal.
     * (rowreq_ctx->tbl_index.ipAddressAddrType)
     */
    switch (rowreq_ctx->tbl_idx.ipAddressAddrType) {

    case INETADDRESSTYPE_IPV4:
    case INETADDRESSTYPE_IPV6:
        break;

    default:
        DEBUGMSGT(("ipAddressTable", "illegal addr type\n"));
        return MFD_ERROR;
    }


    return MFD_SUCCESS;         /* ipAddressAddrType index ok */
}                               /* ipAddressAddrType_check_index */

/*---------------------------------------------------------------------
 * IP-MIB::ipAddressEntry.ipAddressAddr
 * ipAddressAddr is subid 2 of ipAddressEntry.
 * Its status is Current, and its access level is NoAccess.
 * OID: .1.3.6.1.2.1.4.34.1.2
 * Description:
The IP address to which this entry's addressing information
            pertains.  The address type of this object is specified in
            ipAddressAddrType.


            Implementors need to be aware that if the size of
            ipAddressAddr exceeds 116 octets then OIDS of instances of
            columns in this row will have more than 128 sub-identifiers
            and cannot be accessed using SNMPv1, SNMPv2c or SNMPv3.
 *
 * Attributes:
 *   accessible 0     isscalar 0     enums  0      hasdefval 0
 *   readable   0     iscolumn 1     ranges 1      hashint   0
 *   settable   0
 *
 * Ranges:  0 - 255;
 *
 * Its syntax is InetAddress (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 255)
 *
 *
 *
 * NOTE: NODE ipAddressAddr IS NOT ACCESSIBLE
 *
 *
 */
/**
 * check validity of ipAddressAddr index portion
 *
 * @retval MFD_SUCCESS   : the incoming value is legal
 * @retval MFD_ERROR     : the incoming value is NOT legal
 *
 * @note this is not the place to do any checks for the sanity
 *       of multiple indexes. Those types of checks should be done in the
 *       ipAddressTable_validate_index() function.
 *
 * @note Also keep in mind that if the index refers to a row in this or
 *       some other table, you can't check for that row here to make
 *       decisions, since that row might not be created yet, but may
 *       be created during the processing this request. If you have
 *       such checks, they should be done in the check_dependencies
 *       function, because any new/deleted/changed rows should be
 *       available then.
 *
 * The following checks have already been done for you:
 *    The length is in (one of) the range set(s):  0 - 255
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 */
int
ipAddressAddr_check_index(ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressAddr_check_index",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:426:M: |-> Check ipAddressTable index ipAddressAddr.
     * check that index value in the table context is legal.
     * (rowreq_ctx->tbl_index.ipAddressAddr)
     */
    switch (rowreq_ctx->tbl_idx.ipAddressAddrType) {

    case INETADDRESSTYPE_IPV4:
        if (4 != rowreq_ctx->tbl_idx.ipAddressAddr_len) {
            DEBUGMSGT(("ipAddressTable", "bad addr len\n"));
            return MFD_ERROR;
        }
        break;

    case INETADDRESSTYPE_IPV6:
            /** xxx-rks: allow 20? */
        if (16 != rowreq_ctx->tbl_idx.ipAddressAddr_len) {
            DEBUGMSGT(("ipAddressTable", "bad addr len\n"));
            return MFD_ERROR;
        }
        break;

    default:
        return MFD_ERROR;
    }

    return MFD_SUCCESS;         /* ipAddressAddr index ok */
}                               /* ipAddressAddr_check_index */

/**
 * verify specified index is valid.
 *
 * This check is independent of whether or not the values specified for
 * the columns of the new row are valid. Column values and row consistency
 * will be checked later. At this point, only the index values should be
 * checked.
 *
 * All of the individual index validation functions have been called, so this
 * is the place to make sure they are valid as a whole when combined. If
 * you only have one index, then you probably don't need to do anything else
 * here.
 * 
 * @note Keep in mind that if the indexes refer to a row in this or
 *       some other table, you can't check for that row here to make
 *       decisions, since that row might not be created yet, but may
 *       be created during the processing this request. If you have
 *       such checks, they should be done in the check_dependencies
 *       function, because any new/deleted/changed rows should be
 *       available then.
 *
 *
 * @param ipAddressTable_reg
 *        Pointer to the user registration data
 * @param rowreq_ctx
 *        Pointer to the users context.
 * @retval MFD_SUCCESS            : success
 * @retval MFD_CANNOT_CREATE_NOW  : index not valid right now
 * @retval MFD_CANNOT_CREATE_EVER : index never valid
 */
int
ipAddressTable_validate_index(ipAddressTable_registration *
                              ipAddressTable_reg,
                              ipAddressTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_validate_index",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:430:M: |-> Validate potential ipAddressTable index.
     *
     *
     * xxx-rks: we only plan ipv4 support initially
     */
    if ((4 != rowreq_ctx->tbl_idx.ipAddressAddr_len)) {
        snmp_log(LOG_WARNING, "invalid index for a new row in the "
                 "ipAddressTable table.\n");
        /*
         * determine failure type.
         *
         * If the index could not ever be created, return MFD_NOT_EVER
         * If the index can not be created under the present circumstances
         * (even though it could be created under other circumstances),
         * return MFD_NOT_NOW.
         */
        if (0) {
            return MFD_CANNOT_CREATE_EVER;
        } else {
            return MFD_CANNOT_CREATE_NOW;
        }
    } else {
        rowreq_ctx->data->ia_address[0] =
            rowreq_ctx->tbl_idx.ipAddressAddr[0];
        rowreq_ctx->data->ia_address[1] =
            rowreq_ctx->tbl_idx.ipAddressAddr[1];
        rowreq_ctx->data->ia_address[2] =
            rowreq_ctx->tbl_idx.ipAddressAddr[2];
        rowreq_ctx->data->ia_address[3] =
            rowreq_ctx->tbl_idx.ipAddressAddr[3];
        rowreq_ctx->data->ia_address_len = 4;
    }

    return rc;
}                               /* ipAddressTable_validate_index */

/** @} */
