/*
 *  Interface MIB architecture support
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.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/interface.h>
#include <net-snmp/data_access/route.h>
#include <net-snmp/data_access/ipaddress.h>

#include <inet/ip.h>
#include <inet/mib2.h>

#include "ip-forward-mib/data_access/route_ioctl.h"
#include "ip-forward-mib/inetCidrRouteTable/inetCidrRouteTable_constants.h"
#include "if-mib/data_access/interface_ioctl.h"

static int _load_v4(netsnmp_container *container, u_long *count);
static int _load_v6(netsnmp_container *container, u_long *count);

/** arch specific load
 * @internal
 *
 * @retval  0 success
 * @retval -1 no container specified
 * @retval -2 could not open data file
 */
int
netsnmp_access_route_container_arch_load(netsnmp_container* container,
                                         u_int load_flags)
{
    u_long          count = 0;
    int             rc;

    DEBUGMSGTL(("access:route:container",
                "route_container_arch_load (flags %x)\n", load_flags));

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

    rc = _load_v4(container, &count);
    
#ifdef NETSNMP_ENABLE_IPV6
    if((0 != rc) || (load_flags & NETSNMP_ACCESS_ROUTE_LOAD_IPV4_ONLY))
        return rc;

    /*
     * load ipv6. ipv6 module might not be loaded,
     * so ignore -2 err (file not found)
     */
    rc = _load_v6(container, &count);
    if (-2 == rc)
        rc = 0;
#endif

    return rc;
}

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

    if (4 != entry->rt_dest_len) {
        DEBUGMSGT(("access:route:create", "only ipv4 supported\n"));
        return -2;
    }

    /* return _netsnmp_ioctl_route_set_v4(entry); */
    return -2;
}

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

    if (4 != entry->rt_dest_len) {
        DEBUGMSGT(("access:route:create", "only ipv4 supported\n"));
        return -2;
    }

    /* return _netsnmp_ioctl_route_delete_v4(entry); */
    return -2;
}


static int
IP_Cmp_Route(void *addr, void *ep)
{
    mib2_ipRouteEntry_t *Ep = ep, *Addr = addr;

    if ((Ep->ipRouteDest == Addr->ipRouteDest) &&
        (Ep->ipRouteNextHop == Addr->ipRouteNextHop) &&
        (Ep->ipRouteType == Addr->ipRouteType) &&
        (Ep->ipRouteProto == Addr->ipRouteProto) &&
        (Ep->ipRouteMask == Addr->ipRouteMask) &&
        (Ep->ipRouteInfo.re_max_frag == Addr->ipRouteInfo.re_max_frag) &&
        (Ep->ipRouteInfo.re_rtt == Addr->ipRouteInfo.re_rtt) &&
        (Ep->ipRouteInfo.re_ref == Addr->ipRouteInfo.re_ref) &&
        (Ep->ipRouteInfo.re_frag_flag == Addr->ipRouteInfo.re_frag_flag) &&
        (Ep->ipRouteInfo.re_src_addr == Addr->ipRouteInfo.re_src_addr) &&
        (Ep->ipRouteInfo.re_ire_type == Addr->ipRouteInfo.re_ire_type) &&
        (Ep->ipRouteInfo.re_obpkt == Addr->ipRouteInfo.re_obpkt) &&
        (Ep->ipRouteInfo.re_ibpkt == Addr->ipRouteInfo.re_ibpkt)
        )
        return (0);
    else
        return (1);             /* Not found */
}


static int
IP6_Cmp_Route(void *addr, void *ep)
{
    mib2_ipv6RouteEntry_t *Ep = ep, *Addr = addr;

    if ((memcmp(&Ep->ipv6RouteDest, &Addr->ipv6RouteDest, 16) == 0) &&
        (memcmp(&Ep->ipv6RouteNextHop, &Addr->ipv6RouteNextHop, 16) == 0) &&
        (Ep->ipv6RouteType == Addr->ipv6RouteType) &&
        (Ep->ipv6RouteInfo.re_max_frag == Addr->ipv6RouteInfo.re_max_frag) &&
        (Ep->ipv6RouteInfo.re_rtt == Addr->ipv6RouteInfo.re_rtt) &&
        (Ep->ipv6RouteInfo.re_ref == Addr->ipv6RouteInfo.re_ref) &&
        (Ep->ipv6RouteInfo.re_frag_flag == Addr->ipv6RouteInfo.re_frag_flag) &&
        (memcmp(&Ep->ipv6RouteInfo.re_src_addr, &Addr->ipv6RouteInfo.re_src_addr, 16) == 0) &&
        (Ep->ipv6RouteInfo.re_ire_type == Addr->ipv6RouteInfo.re_ire_type) &&
        (Ep->ipv6RouteInfo.re_obpkt == Addr->ipv6RouteInfo.re_obpkt) &&
        (Ep->ipv6RouteInfo.re_ibpkt == Addr->ipv6RouteInfo.re_ibpkt)
        )
        return (0);
    else
        return (1);             /* Not found */
}


static int _load_v4(netsnmp_container *container, u_long *count)
{
    netsnmp_route_entry *entry;
    mib2_ipRouteEntry_t Curentry, Nextentry;
    int req_type;

    for (Nextentry.ipRouteDest = (u_long) -2, req_type = GET_FIRST;;
             Nextentry = Curentry, req_type = GET_NEXT) {
	if (getMibstat(MIB_IP_ROUTE, &Curentry, sizeof(mib2_ipRouteEntry_t),
		       req_type, &IP_Cmp_Route, &Nextentry) != 0)
	    break;
#ifdef HAVE_DEFINED_IRE_CACHE
	if (Curentry.ipRouteInfo.re_ire_type & IRE_CACHE)
	    continue;
#endif /* HAVE_DEFINED_IRE_CACHE */
	if (Curentry.ipRouteInfo.re_ire_type & IRE_BROADCAST)
	    continue;
	entry = netsnmp_access_route_entry_create();
	Curentry.ipRouteIfIndex.o_bytes[Curentry.ipRouteIfIndex.o_length] = '\0';
	entry->if_index = netsnmp_access_interface_index_find(
                Curentry.ipRouteIfIndex.o_bytes);
	entry->ns_rt_index = entry->if_index;

	entry->rt_dest_type = INETADDRESSTYPE_IPV4;
	entry->rt_dest_len = 4;
	memcpy(entry->rt_dest, &Curentry.ipRouteDest, 4);
	memcpy(&entry->rt_mask, &Curentry.ipRouteMask, 4);

	entry->rt_nexthop_type = INETADDRESSTYPE_IPV4;
	entry->rt_nexthop_len = 4;
	memcpy(entry->rt_nexthop, &Curentry.ipRouteNextHop, 4);

	entry->rt_pfx_len = netsnmp_ipaddress_ipv4_prefix_len(Curentry.ipRouteMask);
	entry->rt_type = Curentry.ipRouteType;
	entry->rt_proto = Curentry.ipRouteProto;
	entry->rt_age = Curentry.ipRouteAge;
	entry->rt_metric1 = Curentry.ipRouteMetric1;
	entry->rt_metric2 = Curentry.ipRouteMetric2;
	entry->rt_metric3 = Curentry.ipRouteMetric3;
	entry->rt_metric4 = Curentry.ipRouteMetric4;

	/*
	 * insert into container
	 */
	if (CONTAINER_INSERT(container, entry) < 0) {
	    DEBUGMSGTL(("access:route:container", "error with route_entry: insert into container failed.\n"));
	    netsnmp_access_route_entry_free(entry);
	    continue;
	}
	*count++;
    }
    return 0;
}


static int _load_v6(netsnmp_container *container, u_long *count)
{
    netsnmp_route_entry *entry;
    mib2_ipv6RouteEntry_t Curentry, Nextentry;
    int req_type;

    memset(&Nextentry, 0, sizeof(Nextentry));
    for (req_type = GET_FIRST;;
             Nextentry = Curentry, req_type = GET_NEXT) {
	if (getMibstat(MIB_IP6_ROUTE, &Curentry, sizeof(mib2_ipv6RouteEntry_t),
		       req_type, &IP6_Cmp_Route, &Nextentry) != 0)
	    break;
#ifdef HAVE_DEFINED_IRE_CACHE
	if (Curentry.ipv6RouteInfo.re_ire_type & IRE_CACHE)
	    continue;
#endif /* HAVE_DEFINED_IRE_CACHE */
	if (Curentry.ipv6RouteInfo.re_ire_type & IRE_BROADCAST)
	    continue;
	entry = netsnmp_access_route_entry_create();
	Curentry.ipv6RouteIfIndex.o_bytes[Curentry.ipv6RouteIfIndex.o_length] = '\0';
	entry->if_index = netsnmp_access_interface_index_find(
                Curentry.ipv6RouteIfIndex.o_bytes);
	entry->ns_rt_index = entry->if_index;

	entry->rt_dest_type = INETADDRESSTYPE_IPV6;
	entry->rt_dest_len = 16;
	memcpy(entry->rt_dest, &Curentry.ipv6RouteDest, 16);

	entry->rt_nexthop_type = INETADDRESSTYPE_IPV6;
	entry->rt_nexthop_len = 16;
	memcpy(entry->rt_nexthop, &Curentry.ipv6RouteNextHop, 16);

	entry->rt_pfx_len = Curentry.ipv6RoutePfxLength;
	entry->rt_type = Curentry.ipv6RouteType;
	entry->rt_proto = Curentry.ipv6RouteProtocol;
	entry->rt_age = Curentry.ipv6RouteAge;
	entry->rt_policy = calloc(3, sizeof(oid));
	entry->rt_policy_len = 3;
	entry->rt_policy[2] = Curentry.ipv6RoutePolicy;
	entry->rt_metric1 = Curentry.ipv6RouteMetric;
	entry->rt_metric2 = Curentry.ipv6RouteWeight;

	/*
	 * insert into container
	 */
	if (CONTAINER_INSERT(container, entry) < 0) {
	    DEBUGMSGTL(("access:route:container", "error with route_entry: insert into container failed.\n"));
	    netsnmp_access_route_entry_free(entry);
	    continue;
	}
	*count++;
    }
    return 0;
}
