diff options
Diffstat (limited to 'agent/mibgroup/if-mib/data_access/interface_solaris2.c')
-rw-r--r-- | agent/mibgroup/if-mib/data_access/interface_solaris2.c | 358 |
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); +} |