/*
 *  Ipaddress MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

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

#include "ip-mib/ipAddressTable/ipAddressTable_constants.h"

/**---------------------------------------------------------------------*/
/*
 * local static prototypes
 */
static int _access_ipaddress_entry_compare_addr(const void *lhs,
                                                const void *rhs);
static void _access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry,
                                            void *unused);

/**---------------------------------------------------------------------*/
/*
 * external per-architecture functions prototypes
 *
 * These shouldn't be called by the general public, so they aren't in
 * the header file.
 */
extern int
netsnmp_arch_ipaddress_container_load(netsnmp_container* container,
                                      u_int load_flags);
extern int
netsnmp_arch_ipaddress_entry_init(netsnmp_ipaddress_entry *entry);
extern int
netsnmp_arch_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
                                  netsnmp_ipaddress_entry *rhs);
extern void
netsnmp_arch_ipaddress_entry_cleanup(netsnmp_ipaddress_entry *entry);
extern int
netsnmp_arch_ipaddress_create(netsnmp_ipaddress_entry *entry);
extern int
netsnmp_arch_ipaddress_delete(netsnmp_ipaddress_entry *entry);


/**---------------------------------------------------------------------*/
/*
 * container functions
 */
/**
 */
netsnmp_container *
netsnmp_access_ipaddress_container_init(u_int flags)
{
    netsnmp_container *container1;

    DEBUGMSGTL(("access:ipaddress:container", "init\n"));

    /*
     * create the containers. one indexed by ifIndex, the other
     * indexed by ifName.
     */
    container1 = netsnmp_container_find("access_ipaddress:table_container");
    if (NULL == container1) {
        snmp_log(LOG_ERR, "ipaddress primary container not found\n");
        return NULL;
    }
    container1->container_name = strdup("ia_index");

    if (flags & NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR) {
        netsnmp_container *container2 =
            netsnmp_container_find("ipaddress_addr:access_ipaddress:table_container");
        if (NULL == container2) {
            snmp_log(LOG_ERR, "ipaddress secondary container not found\n");
            CONTAINER_FREE(container1);
            return NULL;
        }
        
        container2->compare = _access_ipaddress_entry_compare_addr;
        container2->container_name = strdup("ia_addr");
        
        netsnmp_container_add_index(container1, container2);
    }

    return container1;
}

/**
 * @retval NULL  error
 * @retval !NULL pointer to container
 */
netsnmp_container*
netsnmp_access_ipaddress_container_load(netsnmp_container* container,
                                        u_int load_flags)
{
    int rc;
    u_int container_flags = 0;

    DEBUGMSGTL(("access:ipaddress:container", "load\n"));

    if (NULL == container) {
        if (load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_ADDL_IDX_BY_ADDR)
            container_flags |= NETSNMP_ACCESS_IPADDRESS_INIT_ADDL_IDX_BY_ADDR;
        container = netsnmp_access_ipaddress_container_init(container_flags);
    }
    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for access_ipaddress\n");
        return NULL;
    }

    rc =  netsnmp_arch_ipaddress_container_load(container, load_flags);
    if (0 != rc) {
        netsnmp_access_ipaddress_container_free(container,
                                                NETSNMP_ACCESS_IPADDRESS_FREE_NOFLAGS);
        container = NULL;
    }

    return container;
}

void
netsnmp_access_ipaddress_container_free(netsnmp_container *container, u_int free_flags)
{
    DEBUGMSGTL(("access:ipaddress:container", "free\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR, "invalid container for netsnmp_access_ipaddress_free\n");
        return;
    }

    if(! (free_flags & NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR)) {
        /*
         * free all items.
         */
        CONTAINER_CLEAR(container,
                        (netsnmp_container_obj_func*)_access_ipaddress_entry_release,
                        NULL);
    }

    if(! (free_flags & NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER))
        CONTAINER_FREE(container);
}

/**---------------------------------------------------------------------*/
/*
 * ipaddress_entry functions
 */
/**
 */
/**
 */
netsnmp_ipaddress_entry *
netsnmp_access_ipaddress_entry_create(void)
{
    netsnmp_ipaddress_entry *entry =
        SNMP_MALLOC_TYPEDEF(netsnmp_ipaddress_entry);
    int rc = 0;

    entry->oid_index.len = 1;
    entry->oid_index.oids = &entry->ns_ia_index;

    /*
     * set up defaults
     */
    entry->ia_type = IPADDRESSTYPE_UNICAST;
    entry->ia_status = IPADDRESSSTATUSTC_PREFERRED;
    entry->ia_storagetype = STORAGETYPE_VOLATILE;

    rc = netsnmp_arch_ipaddress_entry_init(entry);
    if (SNMP_ERR_NOERROR != rc) {
        DEBUGMSGT(("access:ipaddress:create","error %d in arch init\n", rc));
        netsnmp_access_ipaddress_entry_free(entry);
        entry = NULL;
    }

    return entry;
}

/**
 */
void
netsnmp_access_ipaddress_entry_free(netsnmp_ipaddress_entry * entry)
{
    if (NULL == entry)
        return;

    if (NULL != entry->arch_data)
        netsnmp_arch_ipaddress_entry_cleanup(entry);

    free(entry);
}

/**
 * update underlying data store (kernel) for entry
 *
 * @retval  0 : success
 * @retval -1 : error
 */
int
netsnmp_access_ipaddress_entry_set(netsnmp_ipaddress_entry * entry)
{
    int rc = SNMP_ERR_NOERROR;

    if (NULL == entry) {
        netsnmp_assert(NULL != entry);
        return -1;
    }
    
    /*
     * make sure interface and ifIndex match up
     */
    if (NULL == netsnmp_access_interface_name_find(entry->if_index)) {
        DEBUGMSGT(("access:ipaddress:set", "cant find name for index %ld\n",
                  entry->if_index));
        return -1;
    }

    /*
     * don't support non-volatile yet
     */
    if (STORAGETYPE_VOLATILE != entry->ia_storagetype) {
        DEBUGMSGT(("access:ipaddress:set",
                   "non-volatile storagetypes unsupported\n"));
        return -1;
    }

    /*
     *
     */
    rc = -1;
    if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CREATE) {
        rc = netsnmp_arch_ipaddress_create(entry);
    }
    else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_CHANGE) {
    }
    else if (entry->flags & NETSNMP_ACCESS_IPADDRESS_DELETE) {
        rc = netsnmp_arch_ipaddress_delete(entry);
    }
    else {
        snmp_log(LOG_ERR,"netsnmp_access_ipaddress_entry_set with no mode\n");
        netsnmp_assert(!"ipaddress_entry_set == unknown mode"); /* always false */
        rc = -1;
    }
    
    return rc;
}

/**
 * update an old ipaddress_entry from a new one
 *
 * @note: only mib related items are compared. Internal objects
 * such as oid_index, ns_ia_index and flags are not compared.
 *
 * @retval -1  : error
 * @retval >=0 : number of fields updated
 */
int
netsnmp_access_ipaddress_entry_update(netsnmp_ipaddress_entry *lhs,
                                      netsnmp_ipaddress_entry *rhs)
{
    int rc, changed = 0;

    /*
     * copy arch stuff. we don't care if it changed
     */
    rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
    if (0 != rc) {
        snmp_log(LOG_ERR,"arch ipaddress copy failed\n");
        return -1;
    }

    if (lhs->if_index != rhs->if_index) {
        ++changed;
        lhs->if_index = rhs->if_index;
    }

    if (lhs->ia_storagetype != rhs->ia_storagetype) {
        ++changed;
        lhs->ia_storagetype = rhs->ia_storagetype;
    }

    if (lhs->ia_address_len != rhs->ia_address_len) {
        changed += 2;
        lhs->ia_address_len = rhs->ia_address_len;
        memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
    }
    else if (memcmp(lhs->ia_address, rhs->ia_address, rhs->ia_address_len) != 0) {
        ++changed;
        memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
    }

    if (lhs->ia_type != rhs->ia_type) {
        ++changed;
        lhs->ia_type = rhs->ia_type;
    }

    if (lhs->ia_status != rhs->ia_status) {
        ++changed;
        lhs->ia_status = rhs->ia_status;
    }

    if (lhs->ia_origin != rhs->ia_origin) {
        ++changed;
        lhs->ia_origin = rhs->ia_origin;
    }
   
    if (lhs->ia_onlink_flag != rhs->ia_onlink_flag) {
        ++changed;
        lhs->ia_onlink_flag = rhs->ia_onlink_flag;
    }

    if (lhs->ia_autonomous_flag != rhs->ia_autonomous_flag) {
        ++changed;
        lhs->ia_autonomous_flag = rhs->ia_autonomous_flag;
    }

    if (lhs->ia_prefered_lifetime != rhs->ia_prefered_lifetime) {
        ++changed;
        lhs->ia_prefered_lifetime = rhs->ia_prefered_lifetime;
    }

    if (lhs->ia_valid_lifetime != rhs->ia_valid_lifetime) {
        ++changed;
        lhs->ia_valid_lifetime = rhs->ia_valid_lifetime;
    }


    return changed;
}

/**
 * copy an  ipaddress_entry
 *
 * @retval -1  : error
 * @retval 0   : no error
 */
int
netsnmp_access_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
                                    netsnmp_ipaddress_entry *rhs)
{
    int rc;

    /*
     * copy arch stuff. we don't care if it changed
     */
    rc = netsnmp_arch_ipaddress_entry_copy(lhs,rhs);
    if (0 != rc) {
        snmp_log(LOG_ERR,"arch ipaddress copy failed\n");
        return -1;
    }

    lhs->if_index = rhs->if_index;
    lhs->ia_storagetype = rhs->ia_storagetype;
    lhs->ia_address_len = rhs->ia_address_len;
    memcpy(lhs->ia_address, rhs->ia_address, rhs->ia_address_len);
    lhs->ia_type = rhs->ia_type;
    lhs->ia_status = rhs->ia_status;
    lhs->ia_origin = rhs->ia_origin;
    
    return 0;
}

/**---------------------------------------------------------------------*/
/*
 * Utility routines
 */

/**
 * copy the prefix portion of an ip address
 */
int
netsnmp_ipaddress_prefix_copy(u_char *dst, u_char *src, int addr_len, int pfx_len)
{
    int    bytes = pfx_len / 8;
    int    bits = pfx_len % 8;

    if ((NULL == dst) || (NULL == src) || (0 == pfx_len))
        return 0;

    memcpy(dst, src, bytes);

    if (bytes < addr_len)
        memset(&dst[bytes],0x0, addr_len - bytes);

    if (bits) {
        u_char mask = (0xff << (8-bits));
        
        dst[bytes] = (src[bytes] & mask);
    }

    return pfx_len;
}


/**
 * Compute the prefix length of a network mask
 *
 * @param  mask  network byte order mask
 *
 * @returns number of prefix bits
 */
int
netsnmp_ipaddress_ipv4_prefix_len(in_addr_t mask)
{
    int i, len = 0;
    unsigned char *mp = (unsigned char *)&mask;

    for (i = 0; i < 4; i++)
	if (mp[i] == 0xFF) len += 8;
	else break;

    if (i == 4)
	return len;

    while(0x80 & mp[i]) {
        ++len;
        mp[i] <<= 1;
    }

    return len;
}


/**
 */
void
_access_ipaddress_entry_release(netsnmp_ipaddress_entry * entry, void *context)
{
    netsnmp_access_ipaddress_entry_free(entry);
}

static int _access_ipaddress_entry_compare_addr(const void *lhs,
                                                const void *rhs)
{
    const netsnmp_ipaddress_entry *lh = (const netsnmp_ipaddress_entry *)lhs;
    const netsnmp_ipaddress_entry *rh = (const netsnmp_ipaddress_entry *)rhs;

    netsnmp_assert(NULL != lhs);
    netsnmp_assert(NULL != rhs);

    /*
     * compare address length
     */
    if (lh->ia_address_len < rh->ia_address_len)
        return -1;
    else if (lh->ia_address_len > rh->ia_address_len)
        return 1;

    /*
     * length equal, compare address
     */
    return memcmp(lh->ia_address, rh->ia_address, lh->ia_address_len);
}

int
netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
                             u_long *ipAddressPrefixAdvValidLifetime,
                             u_long *ipAddressPrefixOnLinkFlag,
                             u_long *ipAddressPrefixAutonomousFlag, 
                             u_long *ia_prefered_lifetime,
                             u_long *ia_valid_lifetime,
                             u_char *ia_onlink_flag,
                             u_char *ia_autonomous_flag)
{

    /*Copy all the flags*/
    *ipAddressPrefixAdvPreferredLifetime = *ia_prefered_lifetime;
    *ipAddressPrefixAdvValidLifetime = *ia_valid_lifetime;
    *ipAddressPrefixOnLinkFlag = *ia_onlink_flag;
    *ipAddressPrefixAutonomousFlag = *ia_autonomous_flag;
    return 0;
}

int
netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
                                     u_char ia_origin,
                                     int flags,
                                     u_long ipAddressAddrType)
{
    if(ipAddressAddrType == INETADDRESSTYPE_IPV4){
       if(ia_origin == 6) /*Random*/
          (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
       else
          (*ipAddressPrefixOrigin) = ia_origin;
    } else {
       if(ia_origin == 5) { /*Link Layer*/
          if(!flags) /*Global address assigned by router adv*/
             (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
          else
             (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
       }
       else if(ia_origin == 6) /*Random*/
          (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
       else
          (*ipAddressPrefixOrigin) = ia_origin;
    }
    return 0;
}

