summaryrefslogtreecommitdiff
path: root/agent/mibgroup/if-mib/data_access/interface_solaris2.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/if-mib/data_access/interface_solaris2.c')
-rw-r--r--agent/mibgroup/if-mib/data_access/interface_solaris2.c358
1 files changed, 358 insertions, 0 deletions
diff --git a/agent/mibgroup/if-mib/data_access/interface_solaris2.c b/agent/mibgroup/if-mib/data_access/interface_solaris2.c
new file mode 100644
index 0000000..66fb22f
--- /dev/null
+++ b/agent/mibgroup/if-mib/data_access/interface_solaris2.c
@@ -0,0 +1,358 @@
+/*
+ * Interface MIB architecture support for Solaris
+ */
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include "mibII/mibII_common.h"
+#include "if-mib/ifTable/ifTable_constants.h"
+#include "kernel_sunos5.h"
+
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include <net-snmp/data_access/interface.h>
+#include "if-mib/data_access/interface.h"
+#include <sys/ioctl.h>
+#include <sys/sockio.h>
+#include <strings.h>
+#include <string.h>
+
+static int _set_ip_flags_v4(netsnmp_interface_entry *, mib2_ifEntry_t *);
+static int _match_ifname_v4addr(void *ifname, void *ipaddr);
+static int _get_v4addr(mib2_ifEntry_t *ife, mib2_ipAddrEntry_t *e);
+
+static int _set_ip_flags_v6(netsnmp_interface_entry *, mib2_ifEntry_t *);
+#ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
+static int _get_v6addr(mib2_ifEntry_t *ife, mib2_ipv6AddrEntry_t *ipv6e);
+static int _match_ifname_v6addr(void *ifname, void *ipaddr);
+#endif
+
+void
+netsnmp_arch_interface_init(void)
+{
+ init_kernel_sunos5();
+}
+
+/*
+ * find the ifIndex for an interface name
+ *
+ * @retval 0 : no index found
+ * @retval >0: ifIndex for interface
+ */
+oid
+netsnmp_arch_interface_index_find(const char *name)
+{
+#if defined(HAVE_IF_NAMETOINDEX)
+ return if_nametoindex(name);
+#else /* use GIFINDEX */
+ return solaris2_if_nametoindex(name, strlen(name));
+#endif /* defined(HAVE_IF_NAMETOINDEX) */
+}
+
+/*
+ * @retval 0 success
+ * @retval -1 no container specified
+ * @retval -2 could not create entry (probably malloc)
+ */
+int
+netsnmp_arch_interface_container_load(netsnmp_container* container,
+ u_int l_flags)
+{
+ netsnmp_interface_entry *entry = NULL;
+ mib2_ifEntry_t ife;
+ int rc;
+ req_e req = GET_FIRST;
+ int error = 0;
+
+ DEBUGMSGTL(("access:interface:container:arch", "load (flags %p)\n",
+ l_flags));
+
+ if (container == NULL) {
+ snmp_log(LOG_ERR,
+ "no container specified/found for interface\n");
+ return -1;
+ }
+
+ while ((rc = getMibstat(MIB_INTERFACES, &ife, sizeof(ife), req,
+ &Get_everything, NULL)) == 0) {
+
+ req = GET_NEXT;
+
+ DEBUGMSGTL(("access:interface:container:arch",
+ "processing '%s'\n", ife.ifDescr.o_bytes));
+ entry =
+ netsnmp_access_interface_entry_create(ife.ifDescr.o_bytes,
+ ife.ifIndex);
+ if (entry == NULL) {
+ error = 1;
+ break;
+ }
+ entry->ns_flags = 0;
+
+ if (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP4_ONLY &&
+ _set_ip_flags_v4(entry, &ife) == 0) {
+ netsnmp_access_interface_entry_free(entry);
+ continue;
+ } else if (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP6_ONLY &&
+ _set_ip_flags_v6(entry, &ife) == 0) {
+ netsnmp_access_interface_entry_free(entry);
+ continue;
+ } else {
+ (void) _set_ip_flags_v4(entry, &ife);
+ (void) _set_ip_flags_v6(entry, &ife);
+ }
+
+ /*
+ * collect the information needed by IF-MIB
+ */
+ entry->paddr = malloc(ife.ifPhysAddress.o_length);
+ if (entry->paddr == NULL) {
+ netsnmp_access_interface_entry_free(entry);
+ error = 1;
+ break;
+ }
+ entry->paddr_len = ife.ifPhysAddress.o_length;
+ (void)memcpy(entry->paddr, ife.ifPhysAddress.o_bytes,
+ ife.ifPhysAddress.o_length);
+
+ entry->type = ife.ifType;
+ entry->mtu = ife.ifMtu;
+ entry->speed = ife.ifSpeed;
+ entry->speed_high = entry->speed / 1000000;
+ entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_SPEED;
+ entry->oper_status = ife.ifOperStatus;
+ entry->admin_status = ife.ifAdminStatus;
+
+ if (ife.flags & IFF_PROMISC)
+ entry->promiscuous = 1;
+
+ entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_ACTIVE;
+
+ /*
+ * Interface Stats.
+ */
+ if (! (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_NO_STATS)) {
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_BYTES |
+ NETSNMP_INTERFACE_FLAGS_HAS_DROPS |
+ NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS;
+ if (ife.ifHCInOctets > 0 || ife.ifHCOutOctets > 0) {
+ /*
+ * We make the assumption that if we have
+ * a 64-bit Octet counter, then the other
+ * counters are 64-bit as well.
+ */
+ DEBUGMSGTL(("access:interface:container:arch",
+ "interface '%s' have 64-bit stat counters\n",
+ entry->name));
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_HIGH_BYTES |
+ NETSNMP_INTERFACE_FLAGS_HAS_HIGH_PACKETS;
+ /* in stats */
+ entry->stats.ibytes.low = ife.ifHCInOctets & 0xffffffff;
+ entry->stats.ibytes.high = ife.ifHCInOctets >> 32;
+ entry->stats.iucast.low = ife.ifHCInUcastPkts & 0xffffffff;
+ entry->stats.iucast.high = ife.ifHCInUcastPkts >> 32;
+ entry->stats.imcast.low = ife.ifHCInMulticastPkts & 0xffffffff;
+ entry->stats.imcast.high = ife.ifHCInMulticastPkts >> 32;
+ entry->stats.ibcast.low = ife.ifHCInBroadcastPkts & 0xffffffff;
+ entry->stats.ibcast.high = ife.ifHCInBroadcastPkts >> 32;
+ /* out stats */
+ entry->stats.obytes.low = ife.ifHCOutOctets & 0xffffffff;
+ entry->stats.obytes.high = ife.ifHCOutOctets >> 32;
+ entry->stats.oucast.low = ife.ifHCOutUcastPkts & 0xffffffff;
+ entry->stats.oucast.high = ife.ifHCOutUcastPkts >> 32;
+ entry->stats.omcast.low = ife.ifHCOutMulticastPkts & 0xffffffff;
+ entry->stats.omcast.high = ife.ifHCOutMulticastPkts >> 32;
+ entry->stats.obcast.low = ife.ifHCOutBroadcastPkts & 0xffffffff;
+ entry->stats.obcast.high = ife.ifHCOutBroadcastPkts >> 32;
+ } else {
+ DEBUGMSGTL(("access:interface:container:arch",
+ "interface '%s' have 32-bit stat counters\n",
+ entry->name));
+ /* in stats */
+ entry->stats.ibytes.low = ife.ifInOctets;
+ entry->stats.iucast.low = ife.ifInUcastPkts;
+ entry->stats.imcast.low = ife.ifHCInMulticastPkts & 0xffffffff;
+ entry->stats.ibcast.low = ife.ifHCInBroadcastPkts & 0xffffffff;
+ /* out stats */
+ entry->stats.obytes.low = ife.ifOutOctets;
+ entry->stats.oucast.low = ife.ifOutUcastPkts;
+ entry->stats.omcast.low = ife.ifHCOutMulticastPkts & 0xffffffff;
+ entry->stats.obcast.low = ife.ifHCOutBroadcastPkts & 0xffffffff;
+ }
+ /* in stats */
+ entry->stats.ierrors = ife.ifInErrors;
+ entry->stats.idiscards = ife.ifInDiscards;
+ entry->stats.iunknown_protos = ife.ifInUnknownProtos;
+ entry->stats.inucast = ife.ifInNUcastPkts;
+ /* out stats */
+ entry->stats.oerrors = ife.ifOutErrors;
+ entry->stats.odiscards = ife.ifOutDiscards;
+ entry->stats.onucast = ife.ifOutNUcastPkts;
+ entry->stats.oqlen = ife.ifOutQLen;
+
+ /* other stats */
+ entry->stats.collisions = ife.ifCollisions;
+ }
+
+ netsnmp_access_interface_entry_overrides(entry);
+
+ /*
+ * add to container
+ */
+ CONTAINER_INSERT(container, entry);
+ }
+ DEBUGMSGTL(("access:interface:container:arch", "rc = %d\n", rc));
+
+ if (error) {
+ DEBUGMSGTL(("access:interface:container:arch",
+ "error %d, free container\n", error));
+ netsnmp_access_interface_container_free(container,
+ NETSNMP_ACCESS_INTERFACE_FREE_NOFLAGS);
+ return -2;
+ }
+
+ return 0;
+}
+/**
+ * @internal
+ */
+static int
+_set_ip_flags_v4(netsnmp_interface_entry *entry, mib2_ifEntry_t *ife)
+{
+ mib2_ipAddrEntry_t ipv4e;
+
+ if (_get_v4addr(ife, &ipv4e) > 0) {
+ entry->reasm_max_v4 = ipv4e.ipAdEntReasmMaxSize;
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_IPV4 |
+ NETSNMP_INTERFACE_FLAGS_HAS_V4_REASMMAX;
+#if defined( SOLARIS_HAVE_RFC4293_SUPPORT )
+ entry->retransmit_v4 = ipv4e.ipAdEntRetransmitTime;
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_V4_RETRANSMIT;
+#endif
+ return (1);
+ }
+ return (0);
+}
+
+/**
+ * @internal
+ */
+static int
+_set_ip_flags_v6(netsnmp_interface_entry *entry, mib2_ifEntry_t *ife)
+{
+#ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
+ mib2_ipv6AddrEntry_t ipv6e;
+
+ if (_get_v6addr(ife, &ipv6e) > 0) {
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_IPV6;
+#if defined( SOLARIS_HAVE_RFC4293_SUPPORT )
+ if (ipv6e.ipv6AddrIdentifierLen <= sizeof(entry->v6_if_id)) {
+ entry->v6_if_id_len = ipv6e.ipv6AddrIdentifierLen;
+ (void)memcpy(&entry->v6_if_id, &ipv6e.ipv6AddrIdentifier,
+ entry->v6_if_id_len);
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_V6_IFID;
+ }
+ entry->reasm_max_v6 = ipv6e.ipv6AddrReasmMaxSize;
+ entry->retransmit_v6 = ipv6e.ipv6AddrRetransmitTime;
+ entry->reachable_time = ipv6e.ipv6AddrReachableTime;
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX |
+ NETSNMP_INTERFACE_FLAGS_HAS_V6_RETRANSMIT |
+ NETSNMP_INTERFACE_FLAGS_HAS_V6_REACHABLE;
+
+ /* XXX forwarding info missing */
+#else
+ /* XXX Don't have this info, 1500 is the minimum */
+ entry->reasm_max_v6 = 1500;
+ entry->ns_flags |=
+ NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX; /* ??? */
+#endif /* SOLARIS_HAVE_RFC4293_SUPPORT */
+ return (1);
+ }
+#endif /* SOLARIS_HAVE_IPV6_MIB_SUPPORT */
+ return (0);
+}
+
+/**
+ * @internal
+ */
+static int
+_match_ifname_v4addr(void *ifname, void *ipaddr)
+{
+ DeviceName *devname = &((mib2_ipAddrEntry_t *)ipaddr)->ipAdEntIfIndex;
+
+ return (strncmp((char *)ifname, devname->o_bytes, devname->o_length));
+
+}
+
+/**
+ * @internal
+ *
+ * Search for address entry that belongs to the IF entry.
+ * Returns 1 if an address was found, in which case the entry
+ * will be stored in ipv4e. If not entry was found, 0 is returned.
+ *
+ */
+static int
+_get_v4addr(mib2_ifEntry_t *ife, mib2_ipAddrEntry_t *ipv4e)
+{
+ int rc;
+
+ if ((rc = getMibstat(MIB_IP_ADDR, ipv4e, sizeof(*ipv4e), GET_EXACT,
+ &_match_ifname_v4addr, &ife->ifDescr.o_bytes)) == 0)
+ return (1);
+ bzero((void *)ipv4e, sizeof(*ipv4e));
+ return (0);
+}
+
+#ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
+/**
+ * @internal
+ */
+static int
+_match_ifname_v6addr(void *ifname, void *ipaddr)
+{
+ DeviceName *devname = &((mib2_ipv6AddrEntry_t*)ipaddr)->ipv6AddrIfIndex;
+
+ return (strncmp((char *)ifname, devname->o_bytes, devname->o_length));
+
+}
+
+/**
+ * @internal
+ *
+ * Search for address entry that belongs to the IF entry.
+ * Returns 1 if an address was found, in which case the entry
+ * will be stored in ipv4e. If not entry was found, 0 is returned.
+ *
+ */
+static int
+_get_v6addr(mib2_ifEntry_t *ife, mib2_ipv6AddrEntry_t *ipv6e)
+{
+ int rc;
+
+ if ((rc = getMibstat(MIB_IP6_ADDR, ipv6e, sizeof(*ipv6e), GET_EXACT,
+ &_match_ifname_v6addr, &ife->ifDescr.o_bytes)) == 0) {
+ return (1);
+ }
+ bzero((void *)ipv6e, sizeof(*ipv6e));
+ return (0);
+}
+#endif /* SOLARIS_HAVE_IPV6_MIB_SUPPORT */
+
+int
+netsnmp_arch_set_admin_status(netsnmp_interface_entry * entry,
+ int ifAdminStatus_val)
+{
+ DEBUGMSGTL(("access:interface:arch", "set_admin_status\n"));
+
+ /*
+ * XXX Not supported yet
+ */
+ return (-1);
+}