/*
 *  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 + 1];
    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;
}
