| /* |
| * IP-MIB architecture support |
| * |
| */ |
| #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/ipaddress.h> |
| #include <net-snmp/data_access/interface.h> |
| |
| #include "ip-mib/ipAddressTable/ipAddressTable_constants.h" |
| |
| #include "kernel_sunos5.h" |
| #include "mibII/mibII_common.h" |
| |
| static int _load_v4(netsnmp_container *container, int idx_offset); |
| #if defined( NETSNMP_ENABLE_IPV6 ) |
| static int _load_v6(netsnmp_container *container, int idx_offset); |
| #endif |
| |
| /* |
| * initialize arch specific storage |
| * |
| * @retval 0: success |
| * @retval <0: error |
| */ |
| int |
| netsnmp_arch_ipaddress_entry_init(netsnmp_ipaddress_entry *entry) |
| { |
| init_kernel_sunos5(); |
| return 0; |
| } |
| |
| /* |
| * cleanup arch specific storage |
| */ |
| void |
| netsnmp_arch_ipaddress_entry_cleanup(netsnmp_ipaddress_entry *entry) |
| { |
| /* |
| * Nothing to do. |
| */ |
| } |
| |
| /* |
| * copy arch specific storage |
| */ |
| int |
| netsnmp_arch_ipaddress_entry_copy(netsnmp_ipaddress_entry *lhs, |
| netsnmp_ipaddress_entry *rhs) |
| { |
| /* |
| * Nothing to do. |
| */ |
| return 0; |
| } |
| |
| /* |
| * create a new entry |
| */ |
| int |
| netsnmp_arch_ipaddress_create(netsnmp_ipaddress_entry *entry) |
| { |
| if (NULL == entry) |
| return -1; |
| |
| DEBUGMSGT(("access:ipaddress:create", "not applicable\n")); |
| return 0; |
| } |
| |
| /* |
| * delete an entry |
| */ |
| int |
| netsnmp_arch_ipaddress_delete(netsnmp_ipaddress_entry *entry) |
| { |
| if (NULL == entry) |
| return -1; |
| |
| DEBUGMSGT(("access:ipaddress:create", "not applicable\n")); |
| return 0; |
| } |
| |
| /** |
| * |
| * @retval 0 no errors |
| * @retval !0 errors |
| */ |
| int |
| netsnmp_arch_ipaddress_container_load(netsnmp_container *container, |
| u_int load_flags) |
| { |
| int rc = 0, idx_offset = 0; |
| |
| if (!(load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_IPV6_ONLY)) { |
| rc = _load_v4(container, idx_offset); |
| if(rc < 0) { |
| u_int flags = NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER; |
| netsnmp_access_ipaddress_container_free(container, flags); |
| } |
| } |
| |
| #if defined( NETSNMP_ENABLE_IPV6 ) |
| |
| if (!(load_flags & NETSNMP_ACCESS_IPADDRESS_LOAD_IPV4_ONLY)) { |
| if (rc < 0) |
| rc = 0; |
| |
| idx_offset = rc; |
| |
| rc = _load_v6(container, idx_offset); |
| if(rc < 0) { |
| u_int flags = NETSNMP_ACCESS_IPADDRESS_FREE_KEEP_CONTAINER; |
| netsnmp_access_ipaddress_container_free(container, flags); |
| } |
| } |
| #endif |
| |
| /* |
| * return no errors (0) if we found any interfaces |
| */ |
| if(rc > 0) |
| rc = 0; |
| return rc; |
| } |
| |
| /* |
| * @retval >=idx_offset ok |
| * @retval -1 memory allocation error |
| * @retval -2 interface lookup error |
| * @retval -3 container error |
| */ |
| static int |
| _load_v4(netsnmp_container *container, int idx_offset) |
| { |
| mib2_ipAddrEntry_t ipae; |
| netsnmp_ipaddress_entry *entry; |
| req_e req = GET_FIRST; |
| int rc = 0; |
| |
| DEBUGMSGTL(("access:ipaddress:container", "loading v4\n")); |
| while ((rc = getMibstat(MIB_IP_ADDR, &ipae, sizeof(ipae), req, |
| &Get_everything, NULL)) == 0) { |
| req = GET_NEXT; |
| entry = netsnmp_access_ipaddress_entry_create(); |
| if (entry == NULL) |
| return (-1); |
| if (ipae.ipAdEntAddr == INADDR_ANY) |
| continue; |
| |
| ipae.ipAdEntIfIndex.o_bytes[ipae.ipAdEntIfIndex.o_length] = '\0'; |
| DEBUGMSGTL(("access:ipaddress:container", "found if %s\n", |
| ipae.ipAdEntIfIndex.o_bytes)); |
| /* Obtain interface index */ |
| entry->if_index = |
| netsnmp_access_interface_index_find(ipae.ipAdEntIfIndex.o_bytes); |
| if (entry->if_index == 0) { |
| DEBUGMSGTL(("access:ipaddress:container", "cannot find if %s\n", |
| ipae.ipAdEntIfIndex.o_bytes)); |
| netsnmp_access_ipaddress_entry_free(entry); |
| return (-2); |
| } |
| |
| if (strchr((const char *)&ipae.ipAdEntIfIndex.o_bytes, ':') != 0) |
| entry->flags |= NETSNMP_ACCESS_IPADDRESS_ISALIAS; |
| |
| /* Get the address */ |
| entry->ia_address_len = sizeof(ipae.ipAdEntAddr); |
| netsnmp_assert(entry->ia_address_len == 4 && |
| entry->ia_address_len <= sizeof(entry->ia_address)); |
| memcpy(&entry->ia_address, &ipae.ipAdEntAddr, entry->ia_address_len); |
| |
| /* prefix */ |
| entry->ia_prefix_len = ipae.ipAdEntInfo.ae_subnet_len; |
| |
| /* set the Origin */ |
| if (ipae.ipAdEntInfo.ae_flags & IFF_DHCPRUNNING) |
| entry->ia_origin = IPADDRESSORIGINTC_DHCP; |
| else |
| entry->ia_origin = IPADDRESSORIGINTC_MANUAL; |
| |
| /* set ipv4 constants */ |
| entry->ia_type = IPADDRESSTYPE_UNICAST; |
| entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; |
| |
| entry->ns_ia_index = ++idx_offset; |
| |
| DEBUGMSGTL(("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n", |
| entry->if_index, entry->ia_address_len)); |
| |
| if (CONTAINER_INSERT(container, entry) < 0) { |
| DEBUGMSGTL(("access:ipaddress:container", "unable to insert %s\n", |
| ipae.ipAdEntIfIndex.o_bytes)); |
| netsnmp_access_ipaddress_entry_free(entry); |
| return (-3); |
| } |
| } |
| return (idx_offset); |
| } |
| |
| /* |
| * @retval >=idx_offset ok |
| * @retval -1 memory allocation error |
| * @retval -2 interface lookup error |
| * @retval -3 container error |
| */ |
| #if defined( NETSNMP_ENABLE_IPV6 ) |
| static int |
| _load_v6(netsnmp_container *container, int idx_offset) |
| { |
| mib2_ipv6AddrEntry_t ip6ae; |
| netsnmp_ipaddress_entry *entry; |
| req_e req = GET_FIRST; |
| int rc = 0; |
| |
| DEBUGMSGTL(("access:ipaddress:container", "loading v6... cache %d\n", |
| MIB_IP6_ADDR)); |
| while ((rc = getMibstat(MIB_IP6_ADDR, &ip6ae, sizeof(ip6ae), req, |
| &Get_everything, NULL)) == 0) { |
| req = GET_NEXT; |
| entry = netsnmp_access_ipaddress_entry_create(); |
| if (entry == NULL) |
| return (-1); |
| if (memcmp((const void *)&ip6ae.ipv6AddrAddress, |
| (const void *)&in6addr_any, |
| sizeof (ip6ae.ipv6AddrAddress)) == 0) |
| continue; |
| |
| ip6ae.ipv6AddrIfIndex.o_bytes[ip6ae.ipv6AddrIfIndex.o_length] = '\0'; |
| DEBUGMSGTL(("access:ipaddress:container", "found if %s\n", |
| ip6ae.ipv6AddrIfIndex.o_bytes)); |
| |
| /* Obtain interface index */ |
| entry->if_index = |
| netsnmp_access_interface_index_find( |
| ip6ae.ipv6AddrIfIndex.o_bytes); |
| if (entry->if_index == 0) { |
| DEBUGMSGTL(("access:ipaddress:container", "cannot find if %s\n", |
| ip6ae.ipv6AddrIfIndex.o_bytes)); |
| netsnmp_access_ipaddress_entry_free(entry); |
| return (-2); |
| } |
| |
| /* Get the address */ |
| entry->ia_address_len = sizeof(ip6ae.ipv6AddrAddress); |
| netsnmp_assert(entry->ia_address_len == 16 && |
| entry->ia_address_len <= sizeof(entry->ia_address)); |
| memcpy(&entry->ia_address, &ip6ae.ipv6AddrAddress, |
| entry->ia_address_len); |
| |
| /* prefix */ |
| entry->ia_prefix_len = ip6ae.ipv6AddrPfxLength; |
| |
| /* type is anycast? (mib2.h: 1 = yes, 2 = no) */ |
| entry->ia_type = (ip6ae.ipv6AddrAnycastFlag == 1) ? |
| IPADDRESSTYPE_ANYCAST : IPADDRESSTYPE_UNICAST; |
| |
| /* origin (mib2.h: 1 = stateless, 2 = stateful, 3 = unknown) */ |
| DEBUGMSGTL(("access:ipaddress:container", "origin %d\n", |
| ip6ae.ipv6AddrType)); |
| if (ip6ae.ipv6AddrType == 1) |
| entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER; |
| else if (ip6ae.ipv6AddrInfo.ae_flags & IFF_DHCPRUNNING) |
| entry->ia_origin = IPADDRESSORIGINTC_DHCP; |
| else |
| entry->ia_origin = IPADDRESSORIGINTC_MANUAL; |
| |
| /* status */ |
| entry->ia_status = ip6ae.ipv6AddrStatus; |
| |
| entry->ns_ia_index = ++idx_offset; |
| |
| DEBUGMSGTL(("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n", |
| entry->if_index, entry->ia_address_len)); |
| |
| if (CONTAINER_INSERT(container, entry) < 0) { |
| DEBUGMSGTL(("access:ipaddress:container", "unable to insert %s\n", |
| ip6ae.ipv6AddrIfIndex.o_bytes)); |
| netsnmp_access_ipaddress_entry_free(entry); |
| return (-3); |
| } |
| } |
| return (idx_offset); |
| } |
| #endif /* defined( NETSNMP_ENABLE_IPV6 ) */ |