/*
 * 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) {
        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 = magic[0];
    netsnmp_container *to_delete = (netsnmp_container *) magic[1];

    /*
     * check for matching entry using secondary index.
     */
    netsnmp_ipaddress_entry *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,
                                    (char *) 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 = 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",
               "%d records\n", 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 */

/** @} */
