summaryrefslogtreecommitdiff
path: root/agent/mibgroup/mibII/ip.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/mibII/ip.c')
-rw-r--r--agent/mibgroup/mibII/ip.c1011
1 files changed, 1011 insertions, 0 deletions
diff --git a/agent/mibgroup/mibII/ip.c b/agent/mibgroup/mibII/ip.c
new file mode 100644
index 0000000..40b5d2f
--- /dev/null
+++ b/agent/mibgroup/mibII/ip.c
@@ -0,0 +1,1011 @@
+/*
+ * IP MIB group implementation - ip.c
+ *
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include "mibII_common.h"
+
+#if HAVE_SYS_HASHING_H
+#include <sys/hashing.h>
+#endif
+#if HAVE_NETINET_IN_VAR_H
+#include <netinet/in_var.h>
+#endif
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/agent/auto_nlist.h>
+#include <net-snmp/agent/sysORTable.h>
+
+#include "util_funcs/MIB_STATS_CACHE_TIMEOUT.h"
+#include "ip.h"
+#include "ipAddr.h"
+#include "interfaces.h"
+
+#ifndef MIB_STATS_CACHE_TIMEOUT
+#define MIB_STATS_CACHE_TIMEOUT 5
+#endif
+#ifndef IP_STATS_CACHE_TIMEOUT
+#define IP_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
+#endif
+
+#if defined(HAVE_LIBPERFSTAT_H) && (defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) && !defined(FIRST_PROTOCOL)
+#ifdef HAVE_SYS_PROTOSW_H
+#include <sys/protosw.h>
+#endif
+#include <libperfstat.h>
+#ifdef FIRST_PROTOCOL
+perfstat_protocol_t ps_proto;
+perfstat_id_t ps_name;
+#define _USE_PERFSTAT_PROTOCOL 1
+#endif
+#endif
+
+ /*********************
+ *
+ * Kernel & interface information,
+ * and internal forward declarations
+ *
+ *********************/
+
+
+ /*********************
+ *
+ * Initialisation & common implementation functions
+ *
+ *********************/
+
+extern void init_routes(void);
+
+
+/*
+ * define the structure we're going to ask the agent to register our
+ * information at
+ */
+struct variable1 ipaddr_variables[] = {
+ {IPADADDR, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
+ var_ipAddrEntry, 1, {1}},
+ {IPADIFINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_ipAddrEntry, 1, {2}},
+#ifndef sunV3
+ {IPADNETMASK, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
+ var_ipAddrEntry, 1, {3}},
+#endif
+ {IPADBCASTADDR, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_ipAddrEntry, 1, {4}},
+ {IPADREASMMAX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_ipAddrEntry, 1, {5}}
+};
+
+struct variable1 iproute_variables[] = {
+ {IPROUTEDEST, ASN_IPADDRESS, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {1}},
+ {IPROUTEIFINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {2}},
+ {IPROUTEMETRIC1, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {3}},
+ {IPROUTEMETRIC2, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {4}},
+ {IPROUTEMETRIC3, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {5}},
+ {IPROUTEMETRIC4, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {6}},
+ {IPROUTENEXTHOP, ASN_IPADDRESS, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {7}},
+ {IPROUTETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {8}},
+ {IPROUTEPROTO, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_ipRouteEntry, 1, {9}},
+ {IPROUTEAGE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {10}},
+ {IPROUTEMASK, ASN_IPADDRESS, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {11}},
+ {IPROUTEMETRIC5, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_ipRouteEntry, 1, {12}},
+ {IPROUTEINFO, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
+ var_ipRouteEntry, 1, {13}}
+};
+
+struct variable1 ipmedia_variables[] = {
+#ifdef USING_MIBII_AT_MODULE
+#if defined (WIN32) || defined (cygwin)
+ {IPMEDIAIFINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_atEntry, 1, {1}},
+ {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
+ var_atEntry, 1, {2}},
+ {IPMEDIANETADDRESS, ASN_IPADDRESS, NETSNMP_OLDAPI_RWRITE,
+ var_atEntry, 1, {3}},
+ {IPMEDIATYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
+ var_atEntry, 1, {4}}
+#else
+ {IPMEDIAIFINDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_atEntry, 1, {1}},
+ {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
+ var_atEntry, 1, {2}},
+ {IPMEDIANETADDRESS, ASN_IPADDRESS, NETSNMP_OLDAPI_RONLY,
+ var_atEntry, 1, {3}},
+ {IPMEDIATYPE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
+ var_atEntry, 1, {4}}
+#endif
+#endif
+};
+
+/*
+ * Define the OID pointer to the top of the mib tree that we're
+ * registering underneath, and the OID of the MIB module
+ */
+oid ip_oid[] = { SNMP_OID_MIB2, 4 };
+
+oid ipaddr_variables_oid[] = { SNMP_OID_MIB2, 4, 20, 1 };
+oid iproute_variables_oid[] = { SNMP_OID_MIB2, 4, 21, 1 };
+oid ipmedia_variables_oid[] = { SNMP_OID_MIB2, 4, 22, 1 };
+oid ip_module_oid[] = { SNMP_OID_MIB2, 4 };
+oid ip_module_oid_len = sizeof(ip_module_oid) / sizeof(oid);
+int ip_module_count = 0; /* Need to liaise with icmp.c */
+
+void
+init_ip(void)
+{
+ netsnmp_handler_registration *reginfo;
+ int rc;
+
+ /*
+ * register ourselves with the agent as a group of scalars...
+ */
+ DEBUGMSGTL(("mibII/ip", "Initialising IP group\n"));
+ reginfo = netsnmp_create_handler_registration("ip", ip_handler,
+ ip_oid, OID_LENGTH(ip_oid), HANDLER_CAN_RONLY);
+ rc = netsnmp_register_scalar_group(reginfo, IPFORWARDING, IPROUTEDISCARDS);
+ if (rc != SNMPERR_SUCCESS)
+ return;
+
+ /*
+ * .... with a local cache
+ * (except for HP-UX 11, which extracts objects individually)
+ */
+#ifndef hpux11
+ netsnmp_inject_handler( reginfo,
+ netsnmp_get_cache_handler(IP_STATS_CACHE_TIMEOUT,
+ ip_load, ip_free,
+ ip_oid, OID_LENGTH(ip_oid)));
+#endif
+
+ /*
+ * register (using the old-style API) to handle the IP tables
+ */
+ REGISTER_MIB("mibII/ipaddr", ipaddr_variables,
+ variable1, ipaddr_variables_oid);
+ REGISTER_MIB("mibII/iproute", iproute_variables,
+ variable1, iproute_variables_oid);
+ REGISTER_MIB("mibII/ipmedia", ipmedia_variables,
+ variable1, ipmedia_variables_oid);
+ if (++ip_module_count == 2)
+ REGISTER_SYSOR_ENTRY(ip_module_oid,
+ "The MIB module for managing IP and ICMP implementations");
+
+
+ /*
+ * for speed optimization, we call this now to do the lookup
+ */
+#ifndef _USE_PERFSTAT_PROTOCOL
+#ifdef IPSTAT_SYMBOL
+ auto_nlist(IPSTAT_SYMBOL, 0, 0);
+#endif
+#ifdef IP_FORWARDING_SYMBOL
+ auto_nlist(IP_FORWARDING_SYMBOL, 0, 0);
+#endif
+#ifdef TCP_TTL_SYMBOL
+ auto_nlist(TCP_TTL_SYMBOL, 0, 0);
+#endif
+#ifdef MIB_IPCOUNTER_SYMBOL
+ auto_nlist(MIB_IPCOUNTER_SYMBOL, 0, 0);
+#endif
+#ifdef solaris2
+ init_kernel_sunos5();
+#endif
+#endif
+}
+
+
+ /*********************
+ *
+ * System specific data formats
+ *
+ *********************/
+
+#ifdef hpux11
+#define IP_STAT_STRUCTURE int
+#endif
+
+#ifdef linux
+#define IP_STAT_STRUCTURE struct ip_mib
+#define USES_SNMP_DESIGNED_IPSTAT
+#endif
+
+#ifdef solaris2
+#define IP_STAT_STRUCTURE mib2_ip_t
+#define USES_SNMP_DESIGNED_IPSTAT
+#endif
+
+#ifdef NETBSD_STATS_VIA_SYSCTL
+#define IP_STAT_STRUCTURE struct ip_mib
+#define USES_SNMP_DESIGNED_IPSTAT
+#undef IP_NSTATS
+#endif
+
+#ifdef HAVE_IPHLPAPI_H
+#include <iphlpapi.h>
+#define IP_STAT_STRUCTURE MIB_IPSTATS
+long ipForwarding;
+long oldipForwarding;
+long ipTTL, oldipTTL;
+#endif /* WIN32 cygwin */
+
+#ifdef HAVE_SYS_TCPIPSTATS_H
+#define IP_STAT_STRUCTURE struct kna
+#define USES_TRADITIONAL_IPSTAT
+#endif
+
+#ifdef dragonfly
+#define IP_STAT_STRUCTURE struct ip_stats
+#define USES_TRADITIONAL_IPSTAT
+#endif
+
+#if !defined(IP_STAT_STRUCTURE)
+#define IP_STAT_STRUCTURE struct ipstat
+#define USES_TRADITIONAL_IPSTAT
+#endif
+
+IP_STAT_STRUCTURE ipstat;
+
+
+
+ /*********************
+ *
+ * System independent handler
+ * (mostly)
+ *
+ *********************/
+
+
+int
+ip_handler(netsnmp_mib_handler *handler,
+ netsnmp_handler_registration *reginfo,
+ netsnmp_agent_request_info *reqinfo,
+ netsnmp_request_info *requests)
+{
+ netsnmp_request_info *request;
+ netsnmp_variable_list *requestvb;
+ long ret_value;
+ oid subid;
+ int type = ASN_COUNTER;
+
+ /*
+ * The cached data should already have been loaded by the
+ * cache handler, higher up the handler chain.
+ */
+#ifdef _USE_PERFSTAT_PROTOCOL
+ ip_load(NULL, NULL);
+#endif
+
+
+ /*
+ *
+ *
+ */
+ DEBUGMSGTL(("mibII/ip", "Handler - mode %s\n",
+ se_find_label_in_slist("agent_mode", reqinfo->mode)));
+ switch (reqinfo->mode) {
+ case MODE_GET:
+ for (request=requests; request; request=request->next) {
+ requestvb = request->requestvb;
+ subid = requestvb->name[OID_LENGTH(ip_oid)]; /* XXX */
+ DEBUGMSGTL(( "mibII/ip", "oid: "));
+ DEBUGMSGOID(("mibII/ip", requestvb->name,
+ requestvb->name_length));
+ DEBUGMSG(( "mibII/ip", "\n"));
+
+ switch (subid) {
+#ifdef USES_SNMP_DESIGNED_IPSTAT
+ case IPFORWARDING:
+ ret_value = ipstat.ipForwarding;
+ type = ASN_INTEGER;
+ break;
+ case IPDEFAULTTTL:
+ ret_value = ipstat.ipDefaultTTL;
+ type = ASN_INTEGER;
+ break;
+ case IPINRECEIVES:
+ ret_value = ipstat.ipInReceives & 0xffffffff;
+ break;
+ case IPINHDRERRORS:
+ ret_value = ipstat.ipInHdrErrors;
+ break;
+ case IPINADDRERRORS:
+ ret_value = ipstat.ipInAddrErrors;
+ break;
+ case IPFORWDATAGRAMS:
+ ret_value = ipstat.ipForwDatagrams;
+ break;
+ case IPINUNKNOWNPROTOS:
+ ret_value = ipstat.ipInUnknownProtos;
+ break;
+ case IPINDISCARDS:
+ ret_value = ipstat.ipInDiscards;
+ break;
+ case IPINDELIVERS:
+ ret_value = ipstat.ipInDelivers & 0xffffffff;
+ break;
+ case IPOUTREQUESTS:
+ ret_value = ipstat.ipOutRequests & 0xffffffff;
+ break;
+ case IPOUTDISCARDS:
+ ret_value = ipstat.ipOutDiscards;
+ break;
+ case IPOUTNOROUTES:
+ ret_value = ipstat.ipOutNoRoutes;
+ break;
+ case IPREASMTIMEOUT:
+ ret_value = ipstat.ipReasmTimeout;
+ type = ASN_INTEGER;
+ break;
+ case IPREASMREQDS:
+ ret_value = ipstat.ipReasmReqds;
+ break;
+ case IPREASMOKS:
+ ret_value = ipstat.ipReasmOKs;
+ break;
+ case IPREASMFAILS:
+ ret_value = ipstat.ipReasmFails;
+ break;
+ case IPFRAGOKS:
+ ret_value = ipstat.ipFragOKs;
+ break;
+ case IPFRAGFAILS:
+ ret_value = ipstat.ipFragFails;
+ break;
+ case IPFRAGCREATES:
+ ret_value = ipstat.ipFragCreates;
+ break;
+ case IPROUTEDISCARDS:
+ ret_value = ipstat.ipRoutingDiscards;
+ break;
+
+#elif defined(USES_TRADITIONAL_IPSTAT) && !defined(_USE_PERFSTAT_PROTOCOL)
+#ifdef HAVE_SYS_TCPIPSTATS_H
+ /*
+ * This actually reads statistics for *all* the groups together,
+ * so we need to isolate the IP-specific bits.
+ */
+#define ipstat ipstat.ipstat
+#endif
+ case IPFORWARDING:
+ case IPDEFAULTTTL:
+ /*
+ * Query these two individually
+ */
+ ret_value = ip_load(NULL, (void *)subid);
+ if (ret_value == -1 ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+ }
+ type = ASN_INTEGER;
+ break;
+ case IPINRECEIVES:
+ ret_value = ipstat.ips_total & 0xffffffff;
+ break;
+ case IPINHDRERRORS:
+ ret_value = ipstat.ips_badsum
+ + ipstat.ips_tooshort
+ + ipstat.ips_toosmall + ipstat.ips_badhlen + ipstat.ips_badlen;
+ break;
+ case IPINADDRERRORS:
+ ret_value = ipstat.ips_cantforward;
+ break;
+ case IPFORWDATAGRAMS:
+ ret_value = ipstat.ips_forward;
+ break;
+ case IPINUNKNOWNPROTOS:
+#if HAVE_STRUCT_IPSTAT_IPS_NOPROTO
+ ret_value = ipstat.ips_noproto;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPINDISCARDS:
+#if HAVE_STRUCT_IPSTAT_IPS_FRAGDROPPED
+ ret_value = ipstat.ips_fragdropped; /* ?? */
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPINDELIVERS:
+#if HAVE_STRUCT_IPSTAT_IPS_DELIVERED
+ ret_value = ipstat.ips_delivered & 0xffffffff;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPOUTREQUESTS:
+#if HAVE_STRUCT_IPSTAT_IPS_LOCALOUT
+ ret_value = ipstat.ips_localout & 0xffffffff;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPOUTDISCARDS:
+#if HAVE_STRUCT_IPSTAT_IPS_ODROPPED
+ ret_value = ipstat.ips_odropped;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPOUTNOROUTES:
+ /*
+ * XXX: how to calculate this (counts dropped routes, not packets)?
+ * ipstat.ips_cantforward isn't right, as it counts packets.
+ * ipstat.ips_noroute is also incorrect.
+ */
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+ case IPREASMTIMEOUT:
+ ret_value = IPFRAGTTL;
+ type = ASN_INTEGER;
+ break;
+ case IPREASMREQDS:
+ ret_value = ipstat.ips_fragments;
+ break;
+ case IPREASMOKS:
+#if HAVE_STRUCT_IPSTAT_IPS_REASSEMBLED
+ ret_value = ipstat.ips_reassembled;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPREASMFAILS:
+ ret_value = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
+ break;
+ case IPFRAGOKS:
+#if HAVE_STRUCT_IPSTAT_IPS_FRAGMENTED
+ ret_value = ipstat.ips_fragments;
+ break;
+#else /* XXX */
+ ret_value = ipstat.ips_fragments
+ - (ipstat.ips_fragdropped + ipstat.ips_fragtimeout);
+ break;
+#endif
+ case IPFRAGFAILS:
+#if HAVE_STRUCT_IPSTAT_IPS_CANTFRAG
+ ret_value = ipstat.ips_cantfrag;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPFRAGCREATES:
+#if HAVE_STRUCT_IPSTAT_IPS_OFRAGMENTS
+ ret_value = ipstat.ips_ofragments;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+ case IPROUTEDISCARDS:
+#if HAVE_STRUCT_IPSTAT_IPS_NOROUTE
+ ret_value = ipstat.ips_noroute;
+ break;
+#else
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+#endif
+#ifdef HAVE_SYS_TCPIPSTATS_H
+#undef ipstat
+#endif
+#elif defined(hpux11)
+ case IPFORWARDING:
+ case IPDEFAULTTTL:
+ case IPREASMTIMEOUT:
+ type = ASN_INTEGER;
+ case IPINRECEIVES:
+ case IPINHDRERRORS:
+ case IPINADDRERRORS:
+ case IPFORWDATAGRAMS:
+ case IPINUNKNOWNPROTOS:
+ case IPINDISCARDS:
+ case IPINDELIVERS:
+ case IPOUTREQUESTS:
+ case IPOUTDISCARDS:
+ case IPOUTNOROUTES:
+ case IPREASMREQDS:
+ case IPREASMOKS:
+ case IPREASMFAILS:
+ case IPFRAGOKS:
+ case IPFRAGFAILS:
+ case IPFRAGCREATES:
+ case IPROUTEDISCARDS:
+ /*
+ * This is a bit of a hack, to shoehorn the HP-UX 11
+ * single-object retrieval approach into the caching
+ * architecture.
+ */
+ if (ip_load(NULL, (void*)subid) == -1 ) {
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+ }
+ ret_value = ipstat;
+ break;
+#elif defined (WIN32) || defined (cygwin)
+ case IPFORWARDING:
+ ipForwarding = ipstat.dwForwarding;
+ ret_value = ipstat.dwForwarding;
+ type = ASN_INTEGER;
+ break;
+ case IPDEFAULTTTL:
+ ipTTL = ipstat.dwDefaultTTL;
+ ret_value = ipstat.dwDefaultTTL;
+ type = ASN_INTEGER;
+ break;
+ case IPINRECEIVES:
+ ret_value = ipstat.dwInReceives;
+ break;
+ case IPINHDRERRORS:
+ ret_value = ipstat.dwInHdrErrors;
+ break;
+ case IPINADDRERRORS:
+ ret_value = ipstat.dwInAddrErrors;
+ break;
+ case IPFORWDATAGRAMS:
+ ret_value = ipstat.dwForwDatagrams;
+ break;
+ case IPINUNKNOWNPROTOS:
+ ret_value = ipstat.dwInUnknownProtos;
+ break;
+ case IPINDISCARDS:
+ ret_value = ipstat.dwInDiscards;
+ break;
+ case IPINDELIVERS:
+ ret_value = ipstat.dwInDelivers;
+ break;
+ case IPOUTREQUESTS:
+ ret_value = ipstat.dwOutRequests;
+ break;
+ case IPOUTDISCARDS:
+ ret_value = ipstat.dwOutDiscards;
+ break;
+ case IPOUTNOROUTES:
+ ret_value = ipstat.dwOutNoRoutes;
+ break;
+ case IPREASMTIMEOUT:
+ ret_value = ipstat.dwReasmTimeout;
+ type = ASN_INTEGER;
+ break;
+ case IPREASMREQDS:
+ ret_value = ipstat.dwReasmReqds;
+ break;
+ case IPREASMOKS:
+ ret_value = ipstat.dwReasmOks;
+ break;
+ case IPREASMFAILS:
+ ret_value = ipstat.dwReasmFails;
+ break;
+ case IPFRAGOKS:
+ ret_value = ipstat.dwFragOks;
+ break;
+ case IPFRAGFAILS:
+ ret_value = ipstat.dwFragFails;
+ break;
+ case IPFRAGCREATES:
+ ret_value = ipstat.dwFragCreates;
+ break;
+ case IPROUTEDISCARDS:
+ ret_value = ipstat.dwRoutingDiscards;
+ break;
+#elif defined(_USE_PERFSTAT_PROTOCOL)
+ case IPFORWARDING:
+ ret_value = 0;
+ type = ASN_INTEGER;
+ break;
+ case IPDEFAULTTTL:
+ ret_value = 0;
+ type = ASN_INTEGER;
+ break;
+ case IPINRECEIVES:
+ ret_value = ps_proto.u.ip.ipackets;
+ break;
+ case IPINHDRERRORS:
+ case IPINADDRERRORS:
+ case IPFORWDATAGRAMS:
+ ret_value = 0;
+ break;
+ case IPINUNKNOWNPROTOS:
+ ret_value = ps_proto.u.ip.ierrors;
+ break;
+ case IPINDISCARDS:
+ ret_value = 0;
+ break;
+ case IPINDELIVERS:
+ case IPOUTREQUESTS:
+ ret_value = ps_proto.u.ip.opackets;
+ break;
+ case IPOUTDISCARDS:
+ case IPOUTNOROUTES:
+ ret_value = 0;
+ break;
+ case IPREASMTIMEOUT:
+ ret_value = 0;
+ type = ASN_INTEGER;
+ break;
+ case IPREASMREQDS:
+ case IPREASMOKS:
+ case IPREASMFAILS:
+ case IPFRAGOKS:
+ case IPFRAGFAILS:
+ case IPFRAGCREATES:
+ ret_value = 0;
+ break;
+ case IPROUTEDISCARDS:
+ ret_value = ps_proto.u.ip.oerrors;
+ break;
+#endif /* USES_SNMP_DESIGNED_IPSTAT */
+
+ case IPADDRTABLE:
+ case IPROUTETABLE:
+ case IPMEDIATABLE:
+ /*
+ * These are not actually valid scalar objects.
+ * The relevant table registrations should take precedence,
+ * so skip these three subtrees, regardless of architecture.
+ */
+ netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+ continue;
+
+ }
+ snmp_set_var_typed_value(request->requestvb, (u_char)type,
+ (u_char *)&ret_value, sizeof(ret_value));
+ }
+ break;
+
+ case MODE_GETNEXT:
+ case MODE_GETBULK:
+#ifndef NETSNMP_NO_WRITE_SUPPORT
+ case MODE_SET_RESERVE1:
+ /* XXX - Windows currently supports setting this */
+ case MODE_SET_RESERVE2:
+ case MODE_SET_ACTION:
+ case MODE_SET_COMMIT:
+ case MODE_SET_FREE:
+ case MODE_SET_UNDO:
+ snmp_log(LOG_WARNING, "mibII/ip: Unsupported mode (%d)\n",
+ reqinfo->mode);
+ break;
+#endif /* !NETSNMP_NO_WRITE_SUPPORT */
+ default:
+ snmp_log(LOG_WARNING, "mibII/ip: Unrecognised mode (%d)\n",
+ reqinfo->mode);
+ break;
+ }
+
+ return SNMP_ERR_NOERROR;
+}
+
+
+
+ /*********************
+ *
+ * Internal implementation functions
+ *
+ *********************/
+
+
+#ifdef hpux11
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ int fd;
+ struct nmparms p;
+ unsigned int ulen;
+ int ret;
+ int magic = (int) vmagic;
+
+ if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP object %d (hpux11)\n", magic));
+ return (-1); /* error */
+ }
+
+ switch (magic) {
+ case IPFORWARDING:
+ p.objid = ID_ipForwarding;
+ break;
+ case IPDEFAULTTTL:
+ p.objid = ID_ipDefaultTTL;
+ break;
+ case IPINRECEIVES:
+ p.objid = ID_ipInReceives;
+ break;
+ case IPINHDRERRORS:
+ p.objid = ID_ipInHdrErrors;
+ break;
+ case IPINADDRERRORS:
+ p.objid = ID_ipInAddrErrors;
+ break;
+ case IPFORWDATAGRAMS:
+ p.objid = ID_ipForwDatagrams;
+ break;
+ case IPINUNKNOWNPROTOS:
+ p.objid = ID_ipInUnknownProtos;
+ break;
+ case IPINDISCARDS:
+ p.objid = ID_ipInDiscards;
+ break;
+ case IPINDELIVERS:
+ p.objid = ID_ipInDelivers;
+ break;
+ case IPOUTREQUESTS:
+ p.objid = ID_ipOutRequests;
+ break;
+ case IPOUTDISCARDS:
+ p.objid = ID_ipOutDiscards;
+ break;
+ case IPOUTNOROUTES:
+ p.objid = ID_ipOutNoRoutes;
+ break;
+ case IPREASMTIMEOUT:
+ p.objid = ID_ipReasmTimeout;
+ break;
+ case IPREASMREQDS:
+ p.objid = ID_ipReasmReqds;
+ break;
+ case IPREASMOKS:
+ p.objid = ID_ipReasmOKs;
+ break;
+ case IPREASMFAILS:
+ p.objid = ID_ipReasmFails;
+ break;
+ case IPFRAGOKS:
+ p.objid = ID_ipFragOKs;
+ break;
+ case IPFRAGFAILS:
+ p.objid = ID_ipFragFails;
+ break;
+ case IPFRAGCREATES:
+ p.objid = ID_ipFragCreates;
+ break;
+ case IPROUTEDISCARDS:
+ p.objid = ID_ipRoutingDiscards;
+ break;
+ default:
+ ipstat = 0;
+ close_mib(fd);
+ return (0);
+ }
+
+ p.buffer = (void *)&ipstat;
+ ulen = sizeof(IP_STAT_STRUCTURE);
+ p.len = &ulen;
+ ret = get_mib_info(fd, &p);
+ close_mib(fd);
+
+ DEBUGMSGTL(("mibII/ip", "%s IP object %d (hpux11)\n",
+ (ret < 0 ? "Failed to load" : "Loaded"), magic));
+ return (ret); /* 0: ok, < 0: error */
+}
+#elif defined(linux)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ ret_value = linux_read_ip_stat(&ipstat);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (linux)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (linux)\n"));
+ }
+ return ret_value;
+}
+#elif defined(solaris2)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ ret_value =
+ getMibstat(MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
+ &Get_everything, NULL);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (solaris)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (solaris)\n"));
+ }
+ return ret_value;
+}
+#elif defined (NETBSD_STATS_VIA_SYSCTL)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ ret_value = netbsd_read_ip_stat(&ipstat);
+
+ if ( ret_value < 0) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (netbsd)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (netbsd)\n"));
+ }
+ return ret_value;
+}
+#elif defined (WIN32) || defined (cygwin)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ ret_value = GetIpStatistics(&ipstat);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (win32)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (win32)\n"));
+ }
+ return ret_value;
+}
+#elif defined(_USE_PERFSTAT_PROTOCOL)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ strcpy(ps_name.name, "ip");
+ ret_value = perfstat_protocol(&ps_name, &ps_proto, sizeof(ps_proto), 1);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (AIX)\n"));
+ } else {
+ ret_value = 0;
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (AIX)\n"));
+ }
+ return ret_value;
+}
+#elif defined(NETSNMP_CAN_USE_SYSCTL) && defined(IPCTL_STATS)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = 0;
+ int i;
+ static int sname[4] = { CTL_NET, PF_INET, IPPROTO_IP, 0 };
+ size_t len;
+ int magic = (int) vmagic;
+
+ switch (magic) {
+ case IPFORWARDING:
+ len = sizeof i;
+ sname[3] = IPCTL_FORWARDING;
+ if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
+ return -1;
+ else
+ return (i ? 1 /* GATEWAY */
+ : 2 /* HOST */ );
+
+ case IPDEFAULTTTL:
+ len = sizeof i;
+ sname[3] = IPCTL_DEFTTL;
+ if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
+ return -1;
+ else
+ return i;
+
+ default:
+ len = sizeof(ipstat);
+ sname[3] = IPCTL_STATS;
+ ret_value = sysctl(sname, 4, &ipstat, &len, 0, 0);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (sysctl)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (sysctl)\n"));
+ }
+ return ret_value;
+ }
+}
+#elif defined(HAVE_SYS_TCPIPSTATS_H)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+ int magic = (int) vmagic;
+
+ switch (magic) {
+ case IPFORWARDING:
+ if (!auto_nlist
+ (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
+ return -1;
+ else
+ return (ret_value ? 1 /* GATEWAY */
+ : 2 /* HOST */ );
+
+ case IPDEFAULTTTL:
+ if (!auto_nlist
+ (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
+ return -1;
+ else
+ return ret_value;
+
+ default:
+ ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &ipstat, sizeof ipstat);
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (tcpipstats)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (tcpipstats)\n"));
+ }
+ return ret_value;
+ }
+}
+#elif defined(IPSTAT_SYMBOL)
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+ int magic = (int) vmagic;
+
+ switch (magic) {
+ case IPFORWARDING:
+ if (!auto_nlist
+ (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
+ return -1;
+ else
+ return (ret_value ? 1 /* GATEWAY */
+ : 2 /* HOST */ );
+
+ case IPDEFAULTTTL:
+ if (!auto_nlist
+ (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
+ return -1;
+ else
+ return ret_value;
+
+ default:
+ if (auto_nlist(IPSTAT_SYMBOL, (char *)&ipstat, sizeof(ipstat)))
+ ret_value = 0;
+
+ if ( ret_value < 0 ) {
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (ipstat)\n"));
+ } else {
+ DEBUGMSGTL(("mibII/ip", "Loaded IP Group (ipstat)\n"));
+ }
+ return ret_value;
+ }
+}
+#else /* IPSTAT_SYMBOL */
+int
+ip_load(netsnmp_cache *cache, void *vmagic)
+{
+ long ret_value = -1;
+
+ DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (null)\n"));
+ return ret_value;
+}
+#endif /* hpux11 */
+
+void
+ip_free(netsnmp_cache *cache, void *magic)
+{
+#if defined(_USE_PERFSTAT_PROTOCOL)
+ memset(&ps_proto, 0, sizeof(ps_proto));
+#else
+ memset(&ipstat, 0, sizeof(ipstat));
+#endif
+}
+