blob: 5d8ad22bc212d9a6860a5e9759bed9ceee0cd019 [file] [log] [blame]
/*
* 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;
}