/*
 *  Interface MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include "mibII/mibII_common.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"
#include "ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h"
#include "mibgroup/util_funcs.h"

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

netsnmp_feature_require(prefix_info)
netsnmp_feature_require(find_prefix_info)

netsnmp_feature_child_of(ipaddress_arch_entry_copy, ipaddress_common)

#ifdef NETSNMP_FEATURE_REQUIRE_IPADDRESS_ARCH_ENTRY_COPY
netsnmp_feature_require(ipaddress_ioctl_entry_copy)
#endif /* NETSNMP_FEATURE_REQUIRE_IPADDRESS_ARCH_ENTRY_COPY */

#include "ipaddress_ioctl.h"
#ifdef SUPPORT_PREFIX_FLAGS
extern prefix_cbx *prefix_head_list;
#endif

#define ROUNDUP(a) \
  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))

/*
 * initialize arch specific storage
 *
 * @retval  0: success
 * @retval <0: error
 */
int
netsnmp_arch_ipaddress_entry_init(netsnmp_ipaddress_entry *entry)
{
    /*
     * init ipv4 stuff
     */
    //if (NULL == netsnmp_ioctl_ipaddress_entry_init(entry))
    //    return -1;

    /*
     * init ipv6 stuff
     *   so far, we can just share the ipv4 stuff, so nothing to do
     */
    
    return 0;
}

/*
 * cleanup arch specific storage
 */
void
netsnmp_arch_ipaddress_entry_cleanup(netsnmp_ipaddress_entry *entry)
{
    /*
     * cleanup ipv4 stuff
     */
    //netsnmp_ioctl_ipaddress_entry_cleanup(entry);

    /*
     * cleanup ipv6 stuff
     *   so far, we can just share the ipv4 stuff, so nothing to do
     */
}

#ifndef NETSNMP_FEATURE_REMOVE_IPADDRESS_ARCH_ENTRY_COPY
/*
 * copy arch specific storage
 */
int
netsnmp_arch_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs,
                                  netsnmp_ipaddress_entry *rhs)
{
    int rc;

    rc = 0;

    /*
     * copy ipv4 stuff
     */
    //rc = netsnmp_ioctl_ipaddress_entry_copy(lhs, rhs);
    if (rc)
        return rc;

    /*
     * copy ipv6 stuff
     *   so far, we can just share the ipv4 stuff, so nothing to do
     */

    return rc;
}
#endif /* NETSNMP_FEATURE_REMOVE_IPADDRESS_ARCH_ENTRY_COPY */

/*
 * create a new entry
 */
int
netsnmp_arch_ipaddress_create(netsnmp_ipaddress_entry *entry)
{
    if (NULL == entry)
        return -1;

    if (4 == entry->ia_address_len) {
        return -1;
    } else if (16 == entry->ia_address_len) {
        return -1;
    } else {
        DEBUGMSGT(("access:ipaddress:create", "wrong length of IP address\n"));
        return -2;
    }
}

/*
 * create a new entry
 */
int
netsnmp_arch_ipaddress_delete(netsnmp_ipaddress_entry *entry)
{
    if (NULL == entry)
        return -1;

    if (4 == entry->ia_address_len) {
        return -2;
    } else if (16 == entry->ia_address_len) {
        return -3;
    } else {
        DEBUGMSGT(("access:ipaddress:create", "only ipv4 supported\n"));
        return -2;
    }
}

/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
int
netsnmp_arch_ipaddress_container_load(netsnmp_container *container,
                                      u_int load_flags)
{
    netsnmp_ipaddress_entry *entry = NULL;
    u_char *if_list = NULL, *cp;
    size_t if_list_size = 0;
    int sysctl_oid[] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
    struct ifa_msghdr *ifa;
    struct sockaddr *a;
    int amask;
    int rc = 0;
    int idx_offset = 0;

    DEBUGMSGTL(("access:ipaddress:container:sysctl",
                "load (flags %u)\n", load_flags));

    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for interface\n");
        return -1;
    }

    if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), 0,
               &if_list_size, 0, 0) == -1) {
        snmp_log(LOG_ERR, "could not get interface info (size)\n");
        return -2;
    }

    if_list = (u_char*)malloc(if_list_size);
    if (if_list == NULL) {
        snmp_log(LOG_ERR, "could not allocate memory for interface info "
                 "(%zu bytes)\n", if_list_size);
        return -3;
    } else {
        DEBUGMSGTL(("access:ipaddress:container:sysctl",
                    "allocated %zu bytes for if_list\n", if_list_size));
    }

    if (sysctl(sysctl_oid, sizeof(sysctl_oid)/sizeof(int), if_list,
               &if_list_size, 0, 0) == -1) {
        snmp_log(LOG_ERR, "could not get interface info\n");
        free(if_list);
        return -2;
    }

    /* pass 2: walk addresses */
    for (cp = if_list; cp < if_list + if_list_size; cp += ifa->ifam_msglen) {
        ifa = (struct ifa_msghdr *) cp;
        int rtax;

        if (ifa->ifam_type != RTM_NEWADDR)
            continue;

        DEBUGMSGTL(("access:ipaddress:container:sysctl",
                    "received 0x%x in RTM_NEWADDR for ifindex %u\n",
                    ifa->ifam_addrs, ifa->ifam_index));

        entry = netsnmp_access_ipaddress_entry_create();
        if (entry == NULL) {
            rc = -3;
            break;
        }

        a = (struct sockaddr *) (ifa + 1);
        entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
        entry->ia_origin = IPADDRESSORIGINTC_OTHER;
	entry->ia_address_len = 0;
        for (amask = ifa->ifam_addrs, rtax = 0; amask != 0; amask >>= 1, rtax++) {
            if ((amask & 1) != 0) {
                entry->ns_ia_index = ++idx_offset;
                entry->if_index = ifa->ifam_index;
                DEBUGMSGTL(("access:ipaddress:container:sysctl",
                            "%d: a=%p, sa_len=%d, sa_family=0x%x\n",
                            (int)entry->if_index, a, a->sa_len, a->sa_family));

                if (a->sa_family == AF_INET || a->sa_family == 0) {
                    struct sockaddr_in *a4 = (struct sockaddr_in *)a;
		    char str[128];
		    DEBUGMSGTL(("access:ipaddress:container:sysctl",
		                "IPv4 addr %s\n", inet_ntop(AF_INET, &a4->sin_addr.s_addr, str, 128)));
                    if (rtax == RTAX_IFA) {
			entry->ia_address_len = 4;
                        memcpy(entry->ia_address, &a4->sin_addr.s_addr, entry->ia_address_len);
		    }
                    else if (rtax == RTAX_NETMASK)
                        entry->ia_prefix_len = netsnmp_ipaddress_ipv4_prefix_len(a4->sin_addr.s_addr);
                }
                else if (a->sa_family == AF_INET6) {
                    struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)a;
		    char str[128];
		    DEBUGMSGTL(("access:ipaddress:container:sysctl",
		                "IPv6 addr %s\n", inet_ntop(AF_INET6, &a6->sin6_addr.s6_addr, str, 128)));
                    if (rtax == RTAX_IFA) {
			entry->ia_address_len = 16;
                        memcpy(entry->ia_address, &a6->sin6_addr, entry->ia_address_len);
		    }
                    else if (rtax == RTAX_NETMASK) {
                        entry->ia_prefix_len = netsnmp_ipaddress_ipv6_prefix_len(a6->sin6_addr);
			DEBUGMSGTL(("access:ipaddress:container:sysctl",
			            "prefix_len=%d\n", entry->ia_prefix_len));
		    }
                }
                a = (struct sockaddr *) ( ((char *) a) + ROUNDUP(a->sa_len) );
            }
        }
	if (entry->ia_address_len == 0) {
	    DEBUGMSGTL(("access:ipaddress:container:sysctl",
	                "entry skipped\n"));
	    netsnmp_access_ipaddress_entry_free(entry);
	}
	else if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:ipaddress:container","error with ipaddress_entry: insert into container failed.\n"));
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
    }

    if (if_list != NULL)
        free(if_list);

    return 0;
}
