/*
 *  Interface 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/defaultrouter.h>

#include "ip-mib/ipDefaultRouterTable/ipDefaultRouterTable.h"

#include <sys/param.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>

#if !defined(SA_SIZE) && !defined(RT_ROUNDUP)
#define RT_ROUNDUP(a)  \
        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
#endif

/**---------------------------------------------------------------------*/
/*
 * local static prototypes
 */
static int _load_defaultrouter_from_sysctl(netsnmp_container *, int);

static int idx_offset;

/*
 * initialize arch specific storage
 *
 * @retval  0: success
 * @retval <0: error
 */
int
netsnmp_arch_defaultrouter_entry_init(netsnmp_defaultrouter_entry *entry)
{
    /*
     * init
     */
    return 0;
}

/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
int
netsnmp_arch_defaultrouter_container_load(netsnmp_container *container,
                                          u_int load_flags)
{
    int err;

    err = 0;
    idx_offset = 0;

    DEBUGMSGTL(("access:defaultrouter:entry:arch", "load\n"));
    if (NULL == container) {
        snmp_log(LOG_ERR,
            "netsnmp_arch_defaultrouter_container_load: container invalid\n");
        return 1;
    }

    err = _load_defaultrouter_from_sysctl(container, AF_INET);
    if (err != 0) {
        u_int flags = NETSNMP_ACCESS_DEFAULTROUTER_FREE_KEEP_CONTAINER;
        netsnmp_access_defaultrouter_container_free(container, flags);
        goto out;
    }

#ifdef NETSNMP_ENABLE_IPV6
    err = _load_defaultrouter_from_sysctl(container, AF_INET6);
    if (err != 0) {
        u_int flags = NETSNMP_ACCESS_DEFAULTROUTER_FREE_KEEP_CONTAINER;
        netsnmp_access_defaultrouter_container_free(container, flags);
        goto out;
    }
#endif

out:
    return err;
}

/**
 *
 * @retval  0 no errors
 * @retval !0 errors
 */
static int
_load_defaultrouter_from_sysctl(netsnmp_container *container, int family)
{
    netsnmp_defaultrouter_entry *entry;
    struct rt_msghdr *rtm;
    struct sockaddr *dst_sa, *gw_sa;
    char *buf, *lim, *newbuf, *next;
    char address[NETSNMP_ACCESS_DEFAULTROUTER_BUF_SIZE];
    int mib[6];
    size_t address_len, needed;
    int address_type, err, preference, st;

    netsnmp_assert(NULL != container);

    mib[0] = CTL_NET;
    mib[1] = PF_ROUTE;
    mib[2] = 0;
    mib[3] = family;
    mib[4] = NET_RT_DUMP;
    mib[5] = 0;

    err = 0;

    buf = newbuf = NULL;

    if (family == AF_INET) {
        address_len = 4;
        address_type = INETADDRESSTYPE_IPV4;
#ifdef NETSNMP_ENABLE_IPV6
    } else if (family == AF_INET6) {
        address_len = 16;
        address_type = INETADDRESSTYPE_IPV6;
#endif
    } else {
        err = EINVAL;
        goto out;
    }

    if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
        err = errno;
        goto out;
    }

    /* Empty arp table. */
    if (needed == 0)
        goto out;

    for (;;) {
        newbuf = realloc(buf, needed);
        if (newbuf == NULL) {
            err = ENOMEM;
            goto out;
        }
        buf = newbuf;
        st = sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0);
        if (st == 0 || errno != ENOMEM)
            break;
        else
            needed += needed / 8; /* XXX: why 8? */
    }
    if (st == -1) {
        err = errno;
        goto out;
    }

    lim = buf + needed;
    for (next = buf; next < lim; next += rtm->rtm_msglen) {
#ifdef NETSNMP_ENABLE_IPV6
	struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
#endif

        rtm = (struct rt_msghdr *)next;

        if (!(rtm->rtm_addrs & RTA_GATEWAY))
            continue;

        dst_sa = (struct sockaddr*)(rtm + 1);
#ifdef SA_SIZE
        gw_sa = (struct sockaddr*)(SA_SIZE(dst_sa) + (char*)dst_sa);
#else
        gw_sa = (struct sockaddr*)(RT_ROUNDUP(dst_sa->sa_len) + (char*)dst_sa);
#endif

        switch (family) {
        case AF_INET:
            if (((struct sockaddr_in*)dst_sa)->sin_addr.s_addr != INADDR_ANY)
                continue;
	    memcpy(address, &((struct sockaddr_in*)gw_sa)->sin_addr.s_addr,
	           address_len);
            break;
#ifdef NETSNMP_ENABLE_IPV6
        case AF_INET6:
            if (memcmp(((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
			&in6addr_any, sizeof in6addr_any) != 0)
		continue; /* XXX: need to determine qualifying criteria for
                       * default gateways in IPv6. */
            memcpy(address, &((struct sockaddr_in6*)dst_sa)->sin6_addr.s6_addr,
		   address_len);
            break;
#endif
        default:
            break;
        }

        entry = netsnmp_access_defaultrouter_entry_create();
        if (NULL == entry) {
            err = ENOMEM;
            break;
        }

        /* XXX: this is wrong (hardcoding the router preference to medium). */
        preference = 0;

        entry->ns_dr_index    = ++idx_offset;
        entry->dr_addresstype = address_type;
        entry->dr_address_len = address_len;
        memcpy(entry->dr_address, address, sizeof(address));
        entry->dr_if_index = rtm->rtm_index;
        entry->dr_lifetime    = rtm->rtm_rmx.rmx_expire;
        entry->dr_preference  = preference;

        if (CONTAINER_INSERT(container, entry) < 0) {
            DEBUGMSGTL(("access:arp:container",
                        "error with defaultrouter_entry: "
                        "insert into container failed.\n"));
            netsnmp_access_defaultrouter_entry_free(entry);
            goto out;
        }
    }

out:
    free(buf);
    return err;
}
