PageRenderTime 39ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/release/src-rt-6.x.4708/router/snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c

https://bitbucket.org/koitsu2018/freshtomato-arm
C | 364 lines | 256 code | 40 blank | 68 comment | 27 complexity | 093a6daaeb3a479298ad908f3a8d118a MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, BSD-3-Clause, 0BSD, WTFPL, LGPL-3.0, MPL-2.0-no-copyleft-exception, GPL-2.0, LGPL-2.0, GPL-3.0
  1. /*
  2. * Interface MIB architecture support for Solaris
  3. */
  4. #include <net-snmp/net-snmp-config.h>
  5. #include <net-snmp/net-snmp-features.h>
  6. #include <net-snmp/net-snmp-includes.h>
  7. #include "if-mib/ifTable/ifTable_constants.h"
  8. #include "kernel_sunos5.h"
  9. #include "mibII/mibII_common.h"
  10. #include <net-snmp/agent/net-snmp-agent-includes.h>
  11. #include <net-snmp/data_access/interface.h>
  12. #include "if-mib/data_access/interface.h"
  13. #include "interface_private.h"
  14. #include <sys/ioctl.h>
  15. #include <sys/sockio.h>
  16. #include <strings.h>
  17. #include <string.h>
  18. netsnmp_feature_child_of(interface_arch_set_admin_status, interface_all)
  19. static int _set_ip_flags_v4(netsnmp_interface_entry *, mib2_ifEntry_t *);
  20. static int _match_ifname_v4addr(void *ifname, void *ipaddr);
  21. static int _get_v4addr(mib2_ifEntry_t *ife, mib2_ipAddrEntry_t *e);
  22. static int _set_ip_flags_v6(netsnmp_interface_entry *, mib2_ifEntry_t *);
  23. #ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
  24. static int _get_v6addr(mib2_ifEntry_t *ife, mib2_ipv6AddrEntry_t *ipv6e);
  25. static int _match_ifname_v6addr(void *ifname, void *ipaddr);
  26. #endif
  27. void
  28. netsnmp_arch_interface_init(void)
  29. {
  30. init_kernel_sunos5();
  31. }
  32. /*
  33. * find the ifIndex for an interface name
  34. *
  35. * @retval 0 : no index found
  36. * @retval >0: ifIndex for interface
  37. */
  38. oid
  39. netsnmp_arch_interface_index_find(const char *name)
  40. {
  41. #if defined(HAVE_IF_NAMETOINDEX)
  42. return if_nametoindex(name);
  43. #else /* use GIFINDEX */
  44. return solaris2_if_nametoindex(name, strlen(name));
  45. #endif /* defined(HAVE_IF_NAMETOINDEX) */
  46. }
  47. /*
  48. * @retval 0 success
  49. * @retval -1 no container specified
  50. * @retval -2 could not create entry (probably malloc)
  51. */
  52. int
  53. netsnmp_arch_interface_container_load(netsnmp_container* container,
  54. u_int l_flags)
  55. {
  56. netsnmp_interface_entry *entry = NULL;
  57. mib2_ifEntry_t ife;
  58. int rc;
  59. req_e req = GET_FIRST;
  60. int error = 0;
  61. DEBUGMSGTL(("access:interface:container:arch", "load (flags %u)\n",
  62. l_flags));
  63. if (container == NULL) {
  64. snmp_log(LOG_ERR,
  65. "no container specified/found for interface\n");
  66. return -1;
  67. }
  68. while ((rc = getMibstat(MIB_INTERFACES, &ife, sizeof(ife), req,
  69. &Get_everything, NULL)) == 0) {
  70. req = GET_NEXT;
  71. DEBUGMSGTL(("access:interface:container:arch",
  72. "processing '%s'\n", ife.ifDescr.o_bytes));
  73. entry =
  74. netsnmp_access_interface_entry_create(ife.ifDescr.o_bytes,
  75. ife.ifIndex);
  76. if (entry == NULL) {
  77. error = 1;
  78. break;
  79. }
  80. entry->ns_flags = 0;
  81. if (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP4_ONLY &&
  82. _set_ip_flags_v4(entry, &ife) == 0) {
  83. netsnmp_access_interface_entry_free(entry);
  84. continue;
  85. } else if (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_IP6_ONLY &&
  86. _set_ip_flags_v6(entry, &ife) == 0) {
  87. netsnmp_access_interface_entry_free(entry);
  88. continue;
  89. } else {
  90. (void) _set_ip_flags_v4(entry, &ife);
  91. (void) _set_ip_flags_v6(entry, &ife);
  92. }
  93. /*
  94. * collect the information needed by IF-MIB
  95. */
  96. entry->paddr = (char*)malloc(ife.ifPhysAddress.o_length);
  97. if (entry->paddr == NULL) {
  98. netsnmp_access_interface_entry_free(entry);
  99. error = 1;
  100. break;
  101. }
  102. entry->paddr_len = ife.ifPhysAddress.o_length;
  103. (void)memcpy(entry->paddr, ife.ifPhysAddress.o_bytes,
  104. ife.ifPhysAddress.o_length);
  105. entry->type = ife.ifType;
  106. entry->mtu = ife.ifMtu;
  107. entry->speed = ife.ifSpeed;
  108. entry->speed_high = entry->speed / 1000000;
  109. entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_HIGH_SPEED;
  110. entry->oper_status = ife.ifOperStatus;
  111. entry->admin_status = ife.ifAdminStatus;
  112. if (ife.flags & IFF_PROMISC)
  113. entry->promiscuous = 1;
  114. entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_ACTIVE;
  115. /*
  116. * Interface Stats.
  117. */
  118. if (! (l_flags & NETSNMP_ACCESS_INTERFACE_LOAD_NO_STATS)) {
  119. entry->ns_flags |=
  120. NETSNMP_INTERFACE_FLAGS_HAS_BYTES |
  121. NETSNMP_INTERFACE_FLAGS_HAS_DROPS |
  122. NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS;
  123. if (ife.ifHCInOctets > 0 || ife.ifHCOutOctets > 0) {
  124. /*
  125. * We make the assumption that if we have
  126. * a 64-bit Octet counter, then the other
  127. * counters are 64-bit as well.
  128. */
  129. DEBUGMSGTL(("access:interface:container:arch",
  130. "interface '%s' have 64-bit stat counters\n",
  131. entry->name));
  132. entry->ns_flags |=
  133. NETSNMP_INTERFACE_FLAGS_HAS_HIGH_BYTES |
  134. NETSNMP_INTERFACE_FLAGS_HAS_HIGH_PACKETS;
  135. /* in stats */
  136. entry->stats.ibytes.low = ife.ifHCInOctets & 0xffffffff;
  137. entry->stats.ibytes.high = ife.ifHCInOctets >> 32;
  138. entry->stats.iucast.low = ife.ifHCInUcastPkts & 0xffffffff;
  139. entry->stats.iucast.high = ife.ifHCInUcastPkts >> 32;
  140. entry->stats.imcast.low = ife.ifHCInMulticastPkts & 0xffffffff;
  141. entry->stats.imcast.high = ife.ifHCInMulticastPkts >> 32;
  142. entry->stats.ibcast.low = ife.ifHCInBroadcastPkts & 0xffffffff;
  143. entry->stats.ibcast.high = ife.ifHCInBroadcastPkts >> 32;
  144. /* out stats */
  145. entry->stats.obytes.low = ife.ifHCOutOctets & 0xffffffff;
  146. entry->stats.obytes.high = ife.ifHCOutOctets >> 32;
  147. entry->stats.oucast.low = ife.ifHCOutUcastPkts & 0xffffffff;
  148. entry->stats.oucast.high = ife.ifHCOutUcastPkts >> 32;
  149. entry->stats.omcast.low = ife.ifHCOutMulticastPkts & 0xffffffff;
  150. entry->stats.omcast.high = ife.ifHCOutMulticastPkts >> 32;
  151. entry->stats.obcast.low = ife.ifHCOutBroadcastPkts & 0xffffffff;
  152. entry->stats.obcast.high = ife.ifHCOutBroadcastPkts >> 32;
  153. } else {
  154. DEBUGMSGTL(("access:interface:container:arch",
  155. "interface '%s' have 32-bit stat counters\n",
  156. entry->name));
  157. /* in stats */
  158. entry->stats.ibytes.low = ife.ifInOctets;
  159. entry->stats.iucast.low = ife.ifInUcastPkts;
  160. entry->stats.imcast.low = ife.ifHCInMulticastPkts & 0xffffffff;
  161. entry->stats.ibcast.low = ife.ifHCInBroadcastPkts & 0xffffffff;
  162. /* out stats */
  163. entry->stats.obytes.low = ife.ifOutOctets;
  164. entry->stats.oucast.low = ife.ifOutUcastPkts;
  165. entry->stats.omcast.low = ife.ifHCOutMulticastPkts & 0xffffffff;
  166. entry->stats.obcast.low = ife.ifHCOutBroadcastPkts & 0xffffffff;
  167. }
  168. /* in stats */
  169. entry->stats.ierrors = ife.ifInErrors;
  170. entry->stats.idiscards = ife.ifInDiscards;
  171. entry->stats.iunknown_protos = ife.ifInUnknownProtos;
  172. entry->stats.inucast = ife.ifInNUcastPkts;
  173. /* out stats */
  174. entry->stats.oerrors = ife.ifOutErrors;
  175. entry->stats.odiscards = ife.ifOutDiscards;
  176. entry->stats.onucast = ife.ifOutNUcastPkts;
  177. entry->stats.oqlen = ife.ifOutQLen;
  178. /* other stats */
  179. entry->stats.collisions = ife.ifCollisions;
  180. }
  181. netsnmp_access_interface_entry_overrides(entry);
  182. /*
  183. * add to container
  184. */
  185. CONTAINER_INSERT(container, entry);
  186. }
  187. DEBUGMSGTL(("access:interface:container:arch", "rc = %d\n", rc));
  188. if (error) {
  189. DEBUGMSGTL(("access:interface:container:arch",
  190. "error %d, free container\n", error));
  191. netsnmp_access_interface_container_free(container,
  192. NETSNMP_ACCESS_INTERFACE_FREE_NOFLAGS);
  193. return -2;
  194. }
  195. return 0;
  196. }
  197. /**
  198. * @internal
  199. */
  200. static int
  201. _set_ip_flags_v4(netsnmp_interface_entry *entry, mib2_ifEntry_t *ife)
  202. {
  203. mib2_ipAddrEntry_t ipv4e;
  204. if (_get_v4addr(ife, &ipv4e) > 0) {
  205. entry->reasm_max_v4 = ipv4e.ipAdEntReasmMaxSize;
  206. entry->ns_flags |=
  207. NETSNMP_INTERFACE_FLAGS_HAS_IPV4 |
  208. NETSNMP_INTERFACE_FLAGS_HAS_V4_REASMMAX;
  209. #if defined( SOLARIS_HAVE_RFC4293_SUPPORT )
  210. entry->retransmit_v4 = ipv4e.ipAdEntRetransmitTime;
  211. entry->ns_flags |=
  212. NETSNMP_INTERFACE_FLAGS_HAS_V4_RETRANSMIT;
  213. #endif
  214. return (1);
  215. }
  216. return (0);
  217. }
  218. /**
  219. * @internal
  220. */
  221. static int
  222. _set_ip_flags_v6(netsnmp_interface_entry *entry, mib2_ifEntry_t *ife)
  223. {
  224. #ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
  225. mib2_ipv6AddrEntry_t ipv6e;
  226. if (_get_v6addr(ife, &ipv6e) > 0) {
  227. entry->ns_flags |=
  228. NETSNMP_INTERFACE_FLAGS_HAS_IPV6;
  229. #if defined( SOLARIS_HAVE_RFC4293_SUPPORT )
  230. if (ipv6e.ipv6AddrIdentifierLen <= sizeof(entry->v6_if_id)) {
  231. entry->v6_if_id_len = ipv6e.ipv6AddrIdentifierLen;
  232. (void)memcpy(&entry->v6_if_id, &ipv6e.ipv6AddrIdentifier,
  233. entry->v6_if_id_len);
  234. entry->ns_flags |=
  235. NETSNMP_INTERFACE_FLAGS_HAS_V6_IFID;
  236. }
  237. entry->reasm_max_v6 = ipv6e.ipv6AddrReasmMaxSize;
  238. entry->retransmit_v6 = ipv6e.ipv6AddrRetransmitTime;
  239. entry->reachable_time = ipv6e.ipv6AddrReachableTime;
  240. entry->ns_flags |=
  241. NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX |
  242. NETSNMP_INTERFACE_FLAGS_HAS_V6_RETRANSMIT |
  243. NETSNMP_INTERFACE_FLAGS_HAS_V6_REACHABLE;
  244. /* XXX forwarding info missing */
  245. #else
  246. /* XXX Don't have this info, 1500 is the minimum */
  247. entry->reasm_max_v6 = 1500;
  248. entry->ns_flags |=
  249. NETSNMP_INTERFACE_FLAGS_HAS_V6_REASMMAX; /* ??? */
  250. #endif /* SOLARIS_HAVE_RFC4293_SUPPORT */
  251. return (1);
  252. }
  253. #endif /* SOLARIS_HAVE_IPV6_MIB_SUPPORT */
  254. return (0);
  255. }
  256. /**
  257. * @internal
  258. */
  259. static int
  260. _match_ifname_v4addr(void *ifname, void *ipaddr)
  261. {
  262. DeviceName *devname = &((mib2_ipAddrEntry_t *)ipaddr)->ipAdEntIfIndex;
  263. return (strncmp((char *)ifname, devname->o_bytes, devname->o_length));
  264. }
  265. /**
  266. * @internal
  267. *
  268. * Search for address entry that belongs to the IF entry.
  269. * Returns 1 if an address was found, in which case the entry
  270. * will be stored in ipv4e. If not entry was found, 0 is returned.
  271. *
  272. */
  273. static int
  274. _get_v4addr(mib2_ifEntry_t *ife, mib2_ipAddrEntry_t *ipv4e)
  275. {
  276. int rc;
  277. if ((rc = getMibstat(MIB_IP_ADDR, ipv4e, sizeof(*ipv4e), GET_EXACT,
  278. &_match_ifname_v4addr, &ife->ifDescr.o_bytes)) == 0)
  279. return (1);
  280. memset(ipv4e, '\0', sizeof(*ipv4e));
  281. return (0);
  282. }
  283. #ifdef SOLARIS_HAVE_IPV6_MIB_SUPPORT
  284. /**
  285. * @internal
  286. */
  287. static int
  288. _match_ifname_v6addr(void *ifname, void *ipaddr)
  289. {
  290. DeviceName *devname = &((mib2_ipv6AddrEntry_t*)ipaddr)->ipv6AddrIfIndex;
  291. return (strncmp((char *)ifname, devname->o_bytes, devname->o_length));
  292. }
  293. /**
  294. * @internal
  295. *
  296. * Search for address entry that belongs to the IF entry.
  297. * Returns 1 if an address was found, in which case the entry
  298. * will be stored in ipv4e. If not entry was found, 0 is returned.
  299. *
  300. */
  301. static int
  302. _get_v6addr(mib2_ifEntry_t *ife, mib2_ipv6AddrEntry_t *ipv6e)
  303. {
  304. int rc;
  305. if ((rc = getMibstat(MIB_IP6_ADDR, ipv6e, sizeof(*ipv6e), GET_EXACT,
  306. &_match_ifname_v6addr, &ife->ifDescr.o_bytes)) == 0) {
  307. return (1);
  308. }
  309. memset(ipv6e, '\0', sizeof(*ipv6e));
  310. return (0);
  311. }
  312. #endif /* SOLARIS_HAVE_IPV6_MIB_SUPPORT */
  313. #ifndef NETSNMP_FEATURE_REMOVE_INTERFACE_ARCH_SET_ADMIN_STATUS
  314. int
  315. netsnmp_arch_set_admin_status(netsnmp_interface_entry * entry,
  316. int ifAdminStatus_val)
  317. {
  318. DEBUGMSGTL(("access:interface:arch", "set_admin_status\n"));
  319. /*
  320. * XXX Not supported yet
  321. */
  322. return (-1);
  323. }
  324. #endif /* NETSNMP_FEATURE_REMOVE_INTERFACE_ARCH_SET_ADMIN_STATUS */