ip.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:24k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  IP MIB group implementation - ip.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include "mibII_common.h"
  7. #if HAVE_SYS_HASHING_H
  8. #include <sys/hashing.h>
  9. #endif
  10. #if HAVE_NETINET_IN_VAR_H
  11. #include <netinet/in_var.h>
  12. #endif
  13. #if HAVE_SYSLOG_H
  14. #include <syslog.h>
  15. #endif
  16. #include <net-snmp/net-snmp-includes.h>
  17. #include <net-snmp/agent/net-snmp-agent-includes.h>
  18. #include <net-snmp/agent/auto_nlist.h>
  19. #include "util_funcs.h"
  20. #include "ip.h"
  21. #include "ipAddr.h"
  22. #include "interfaces.h"
  23. #include "sysORTable.h"
  24. #ifndef MIB_STATS_CACHE_TIMEOUT
  25. #define MIB_STATS_CACHE_TIMEOUT 5
  26. #endif
  27. #ifndef IP_STATS_CACHE_TIMEOUT
  28. #define IP_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
  29. #endif
  30.         /*********************
  31.  *
  32.  *  Kernel & interface information,
  33.  *   and internal forward declarations
  34.  *
  35.  *********************/
  36.         /*********************
  37.  *
  38.  *  Initialisation & common implementation functions
  39.  *
  40.  *********************/
  41. extern void     init_routes(void);
  42. /*
  43.  * define the structure we're going to ask the agent to register our
  44.  * information at 
  45.  */
  46. struct variable1 ipaddr_variables[] = {
  47.     {IPADADDR,      ASN_IPADDRESS, RONLY, var_ipAddrEntry, 1, {1}},
  48.     {IPADIFINDEX,   ASN_INTEGER,   RONLY, var_ipAddrEntry, 1, {2}},
  49. #ifndef sunV3
  50.     {IPADNETMASK,   ASN_IPADDRESS, RONLY, var_ipAddrEntry, 1, {3}},
  51. #endif
  52.     {IPADBCASTADDR, ASN_INTEGER,   RONLY, var_ipAddrEntry, 1, {4}},
  53.     {IPADREASMMAX,  ASN_INTEGER,   RONLY, var_ipAddrEntry, 1, {5}}
  54. };
  55. struct variable1 iproute_variables[] = {
  56.     {IPROUTEDEST,    ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 1, {1}},
  57.     {IPROUTEIFINDEX, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {2}},
  58.     {IPROUTEMETRIC1, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {3}},
  59.     {IPROUTEMETRIC2, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {4}},
  60.     {IPROUTEMETRIC3, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {5}},
  61.     {IPROUTEMETRIC4, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {6}},
  62.     {IPROUTENEXTHOP, ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 1, {7}},
  63.     {IPROUTETYPE,    ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {8}},
  64.     {IPROUTEPROTO,   ASN_INTEGER,   RONLY,  var_ipRouteEntry, 1, {9}},
  65.     {IPROUTEAGE,     ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {10}},
  66.     {IPROUTEMASK,    ASN_IPADDRESS, RWRITE, var_ipRouteEntry, 1, {11}},
  67.     {IPROUTEMETRIC5, ASN_INTEGER,   RWRITE, var_ipRouteEntry, 1, {12}},
  68.     {IPROUTEINFO,    ASN_OBJECT_ID, RONLY,  var_ipRouteEntry, 1, {13}}
  69. };
  70. struct variable1 ipmedia_variables[] = {
  71. #ifdef USING_MIBII_AT_MODULE
  72. #if defined (WIN32) || defined (cygwin)
  73.     {IPMEDIAIFINDEX,     ASN_INTEGER,   RWRITE, var_atEntry, 1, {1}},
  74.     {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, RWRITE, var_atEntry, 1, {2}},
  75.     {IPMEDIANETADDRESS,  ASN_IPADDRESS, RWRITE, var_atEntry, 1, {3}},
  76.     {IPMEDIATYPE,        ASN_INTEGER,   RWRITE, var_atEntry, 1, {4}}
  77. #else
  78.     {IPMEDIAIFINDEX,     ASN_INTEGER,   RONLY, var_atEntry, 1, {1}},
  79.     {IPMEDIAPHYSADDRESS, ASN_OCTET_STR, RONLY, var_atEntry, 1, {2}},
  80.     {IPMEDIANETADDRESS,  ASN_IPADDRESS, RONLY, var_atEntry, 1, {3}},
  81.     {IPMEDIATYPE,        ASN_INTEGER,   RONLY, var_atEntry, 1, {4}}
  82. #endif
  83. #endif
  84. };
  85. /*
  86.  * Define the OID pointer to the top of the mib tree that we're
  87.  * registering underneath, and the OID of the MIB module 
  88.  */
  89. oid             ip_oid[]                = { SNMP_OID_MIB2, 4 };
  90. oid             ipaddr_variables_oid[]  = { SNMP_OID_MIB2, 4, 20, 1 };
  91. oid             iproute_variables_oid[] = { SNMP_OID_MIB2, 4, 21, 1 };
  92. oid             ipmedia_variables_oid[] = { SNMP_OID_MIB2, 4, 22, 1 };
  93. oid             ip_module_oid[] = { SNMP_OID_MIB2, 4 };
  94. oid             ip_module_oid_len = sizeof(ip_module_oid) / sizeof(oid);
  95. int             ip_module_count = 0;    /* Need to liaise with icmp.c */
  96. void
  97. init_ip(void)
  98. {
  99.     netsnmp_handler_registration *reginfo;
  100.     /*
  101.      * register ourselves with the agent as a group of scalars...
  102.      */
  103.     DEBUGMSGTL(("mibII/ip", "Initialising IP groupn"));
  104.     reginfo = netsnmp_create_handler_registration("ip", ip_handler,
  105.                             ip_oid, OID_LENGTH(ip_oid), HANDLER_CAN_RONLY);
  106.     netsnmp_register_scalar_group(reginfo, IPFORWARDING, IPROUTEDISCARDS);
  107.     /*
  108.      * .... with a local cache
  109.      *    (except for HP-UX 11, which extracts objects individually)
  110.      */
  111. #ifndef hpux11
  112.     netsnmp_inject_handler( reginfo,
  113.     netsnmp_get_cache_handler(IP_STATS_CACHE_TIMEOUT,
  114.     ip_load, ip_free,
  115. ip_oid, OID_LENGTH(ip_oid)));
  116. #endif
  117.     /*
  118.      * register (using the old-style API) to handle the IP tables
  119.      */
  120.     REGISTER_MIB("mibII/ipaddr",  ipaddr_variables,
  121.                        variable1, ipaddr_variables_oid);
  122.     REGISTER_MIB("mibII/iproute", iproute_variables,
  123.                        variable1, iproute_variables_oid);
  124.     REGISTER_MIB("mibII/ipmedia", ipmedia_variables,
  125.                        variable1, ipmedia_variables_oid);
  126.     if (++ip_module_count == 2)
  127.         REGISTER_SYSOR_ENTRY(ip_module_oid,
  128.                              "The MIB module for managing IP and ICMP implementations");
  129.     /*
  130.      * for speed optimization, we call this now to do the lookup 
  131.      */
  132. #ifdef IPSTAT_SYMBOL
  133.     auto_nlist(IPSTAT_SYMBOL, 0, 0);
  134. #endif
  135. #ifdef IP_FORWARDING_SYMBOL
  136.     auto_nlist(IP_FORWARDING_SYMBOL, 0, 0);
  137. #endif
  138. #ifdef TCP_TTL_SYMBOL
  139.     auto_nlist(TCP_TTL_SYMBOL, 0, 0);
  140. #endif
  141. #ifdef MIB_IPCOUNTER_SYMBOL
  142.     auto_nlist(MIB_IPCOUNTER_SYMBOL, 0, 0);
  143. #endif
  144. #ifdef solaris2
  145.     init_kernel_sunos5();
  146. #endif
  147. }
  148.         /*********************
  149.  *
  150.  *  System specific data formats
  151.  *
  152.  *********************/
  153. #ifdef hpux11
  154. #define IP_STAT_STRUCTURE int
  155. #endif
  156. #ifdef linux
  157. #define IP_STAT_STRUCTURE struct ip_mib
  158. #define USES_SNMP_DESIGNED_IPSTAT
  159. #endif
  160. #ifdef solaris2
  161. #define IP_STAT_STRUCTURE mib2_ip_t
  162. #define USES_SNMP_DESIGNED_IPSTAT
  163. #endif
  164. #if defined (WIN32) || defined (cygwin)
  165. #include <iphlpapi.h>
  166. #define IP_STAT_STRUCTURE MIB_IPSTATS
  167. long            ipForwarding;
  168. long            oldipForwarding;
  169. long            ipTTL, oldipTTL;
  170. #endif                          /* WIN32 cygwin */
  171. #ifdef HAVE_SYS_TCPIPSTATS_H
  172. #define IP_STAT_STRUCTURE struct kna
  173. #define USES_TRADITIONAL_IPSTAT
  174. #endif
  175. #if !defined(IP_STAT_STRUCTURE)
  176. #define IP_STAT_STRUCTURE struct ipstat
  177. #define USES_TRADITIONAL_IPSTAT
  178. #endif
  179. IP_STAT_STRUCTURE ipstat;
  180.         /*********************
  181.  *
  182.  *  System independent handler
  183.  *      (mostly)
  184.  *
  185.  *********************/
  186. int
  187. ip_handler(netsnmp_mib_handler          *handler,
  188.            netsnmp_handler_registration *reginfo,
  189.            netsnmp_agent_request_info   *reqinfo,
  190.            netsnmp_request_info         *requests)
  191. {
  192.     netsnmp_request_info  *request;
  193.     netsnmp_variable_list *requestvb;
  194.     long     ret_value;
  195.     oid      subid;
  196.     int      type = ASN_COUNTER;
  197.     /*
  198.      * The cached data should already have been loaded by the
  199.      *    cache handler, higher up the handler chain.
  200.      * But just to be safe, check this and load it manually if necessary
  201.      */
  202. #ifndef hpux11
  203.     if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) {
  204.         netsnmp_assert("cache" == "valid"); /* always false */
  205.         ip_load( NULL, NULL ); /* XXX - check for failure */
  206.     }
  207. #endif
  208.     /*
  209.      * 
  210.      *
  211.      */
  212.     DEBUGMSGTL(("mibII/ip", "Handler - mode %sn",
  213.                     se_find_label_in_slist("agent_mode", reqinfo->mode)));
  214.     switch (reqinfo->mode) {
  215.     case MODE_GET:
  216.         for (request=requests; request; request=request->next) {
  217.             requestvb = request->requestvb;
  218.             subid = requestvb->name[OID_LENGTH(ip_oid)];  /* XXX */
  219.             DEBUGMSGTL(( "mibII/ip", "oid: "));
  220.             DEBUGMSGOID(("mibII/ip", requestvb->name,
  221.                                      requestvb->name_length));
  222.             DEBUGMSG((   "mibII/ip", "n"));
  223.             switch (subid) {
  224. #ifdef USES_SNMP_DESIGNED_IPSTAT
  225.     case IPFORWARDING:
  226.         ret_value = ipstat.ipForwarding;
  227.         type = ASN_INTEGER;
  228.         break;
  229.     case IPDEFAULTTTL:
  230.         ret_value = ipstat.ipDefaultTTL;
  231.         type = ASN_INTEGER;
  232.         break;
  233.     case IPINRECEIVES:
  234.         ret_value = ipstat.ipInReceives;
  235.         break;
  236.     case IPINHDRERRORS:
  237.         ret_value = ipstat.ipInHdrErrors;
  238.         break;
  239.     case IPINADDRERRORS:
  240.         ret_value = ipstat.ipInAddrErrors;
  241.         break;
  242.     case IPFORWDATAGRAMS:
  243.         ret_value = ipstat.ipForwDatagrams;
  244.         break;
  245.     case IPINUNKNOWNPROTOS:
  246.         ret_value = ipstat.ipInUnknownProtos;
  247.         break;
  248.     case IPINDISCARDS:
  249.         ret_value = ipstat.ipInDiscards;
  250.         break;
  251.     case IPINDELIVERS:
  252.         ret_value = ipstat.ipInDelivers;
  253.         break;
  254.     case IPOUTREQUESTS:
  255.         ret_value = ipstat.ipOutRequests;
  256.         break;
  257.     case IPOUTDISCARDS:
  258.         ret_value = ipstat.ipOutDiscards;
  259.         break;
  260.     case IPOUTNOROUTES:
  261.         ret_value = ipstat.ipOutNoRoutes;
  262.         break;
  263.     case IPREASMTIMEOUT:
  264.         ret_value = ipstat.ipReasmTimeout;
  265.         type = ASN_INTEGER;
  266.         break;
  267.     case IPREASMREQDS:
  268.         ret_value = ipstat.ipReasmReqds;
  269.         break;
  270.     case IPREASMOKS:
  271.         ret_value = ipstat.ipReasmOKs;
  272.         break;
  273.     case IPREASMFAILS:
  274.         ret_value = ipstat.ipReasmFails;
  275.         break;
  276.     case IPFRAGOKS:
  277.         ret_value = ipstat.ipFragOKs;
  278.         break;
  279.     case IPFRAGFAILS:
  280.         ret_value = ipstat.ipFragFails;
  281.         break;
  282.     case IPFRAGCREATES:
  283.         ret_value = ipstat.ipFragCreates;
  284.         break;
  285.     case IPROUTEDISCARDS:
  286.         ret_value = ipstat.ipRoutingDiscards;
  287.         break;
  288. #else /* USES_SNMP_DESIGNED_IPSTAT */
  289. #ifdef USES_TRADITIONAL_IPSTAT
  290. #ifdef HAVE_SYS_TCPIPSTATS_H
  291.     /*
  292.      * This actually reads statistics for *all* the groups together,
  293.      * so we need to isolate the IP-specific bits.  
  294.      */
  295. #define ipstat ipstat.ipstat
  296. #endif
  297.     case IPFORWARDING:
  298.     case IPDEFAULTTTL:
  299.         /* 
  300.          * Query these two individually
  301.          */
  302.         ret_value = ip_load(NULL, (void *)subid);
  303.         if (ret_value == -1 ) {
  304.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  305.             continue;
  306. }
  307.         type = ASN_INTEGER;
  308.         break;
  309.     case IPINRECEIVES:
  310.         ret_value = ipstat.ips_total;
  311.         break;
  312.     case IPINHDRERRORS:
  313.         ret_value = ipstat.ips_badsum
  314.             + ipstat.ips_tooshort
  315.             + ipstat.ips_toosmall + ipstat.ips_badhlen + ipstat.ips_badlen;
  316.         break;
  317.     case IPINADDRERRORS:
  318.         ret_value = ipstat.ips_cantforward;
  319.         break;
  320.     case IPFORWDATAGRAMS:
  321.         ret_value = ipstat.ips_forward;
  322.         break;
  323.     case IPINUNKNOWNPROTOS:
  324. #if STRUCT_IPSTAT_HAS_IPS_NOPROTO
  325.         ret_value = ipstat.ips_noproto;
  326.         break;
  327. #else
  328.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  329.         continue;
  330. #endif
  331.     case IPINDISCARDS:
  332. #if STRUCT_IPSTAT_HAS_IPS_FRAGDROPPED
  333.         ret_value = ipstat.ips_fragdropped;   /* ?? */
  334.         break;
  335. #else
  336.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  337.         continue;
  338. #endif
  339.     case IPINDELIVERS:
  340. #if STRUCT_IPSTAT_HAS_IPS_DELIVERED
  341.         ret_value = ipstat.ips_delivered;
  342.         break;
  343. #else
  344.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  345.         continue;
  346. #endif
  347.     case IPOUTREQUESTS:
  348. #if STRUCT_IPSTAT_HAS_IPS_LOCALOUT
  349.         ret_value = ipstat.ips_localout;
  350.         break;
  351. #else
  352.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  353.         continue;
  354. #endif
  355.     case IPOUTDISCARDS:
  356. #if STRUCT_IPSTAT_HAS_IPS_ODROPPED
  357.         ret_value = ipstat.ips_odropped;
  358.         break;
  359. #else
  360.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  361.         continue;
  362. #endif
  363.     case IPOUTNOROUTES:
  364.         /*
  365.          * XXX: how to calculate this (counts dropped routes, not packets)?
  366.          * ipstat.ips_cantforward isn't right, as it counts packets.
  367.          * ipstat.ips_noroute is also incorrect.
  368.          */
  369.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  370.         continue;
  371.     case IPREASMTIMEOUT:
  372.         ret_value = IPFRAGTTL;
  373.         type = ASN_INTEGER;
  374.         break;
  375.     case IPREASMREQDS:
  376.         ret_value = ipstat.ips_fragments;
  377.         break;
  378.     case IPREASMOKS:
  379. #if STRUCT_IPSTAT_HAS_IPS_REASSEMBLED
  380.         ret_value = ipstat.ips_reassembled;
  381.         break;
  382. #else
  383.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  384.         continue;
  385. #endif
  386.     case IPREASMFAILS:
  387.         ret_value = ipstat.ips_fragdropped + ipstat.ips_fragtimeout;
  388.         break;
  389.     case IPFRAGOKS:            /* XXX */
  390.         ret_value = ipstat.ips_fragments
  391.             - (ipstat.ips_fragdropped + ipstat.ips_fragtimeout);
  392.         break;
  393.     case IPFRAGFAILS:
  394. #if STRUCT_IPSTAT_HAS_IPS_CANTFRAG
  395.         ret_value = ipstat.ips_cantfrag;
  396.         break;
  397. #else
  398.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  399.         continue;
  400. #endif
  401.     case IPFRAGCREATES:
  402. #if STRUCT_IPSTAT_HAS_IPS_OFRAGMENTS
  403.         ret_value = ipstat.ips_ofragments;
  404.         break;
  405. #else
  406.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  407.         continue;
  408. #endif
  409.     case IPROUTEDISCARDS:
  410. #if STRUCT_IPSTAT_HAS_IPS_NOROUTE
  411.         ret_value = ipstat.ips_noroute;
  412.         break;
  413. #else
  414.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  415.         continue;
  416. #endif
  417. #ifdef HAVE_SYS_TCPIPSTATS_H
  418. #undef ipstat
  419. #endif
  420. #else                          /* USE_TRADITIONAL_IPSTAT */
  421. #ifdef hpux11
  422.     case IPFORWARDING:
  423.     case IPDEFAULTTTL:
  424.     case IPREASMTIMEOUT:
  425.         type = ASN_INTEGER;
  426.     case IPINRECEIVES:
  427.     case IPINHDRERRORS:
  428.     case IPINADDRERRORS:
  429.     case IPFORWDATAGRAMS:
  430.     case IPINUNKNOWNPROTOS:
  431.     case IPINDISCARDS:
  432.     case IPINDELIVERS:
  433.     case IPOUTREQUESTS:
  434.     case IPOUTDISCARDS:
  435.     case IPOUTNOROUTES:
  436.     case IPREASMREQDS:
  437.     case IPREASMOKS:
  438.     case IPREASMFAILS:
  439.     case IPFRAGOKS:
  440.     case IPFRAGFAILS:
  441.     case IPFRAGCREATES:
  442.     case IPROUTEDISCARDS:
  443. /*
  444.  * This is a bit of a hack, to shoehorn the HP-UX 11
  445.  * single-object retrieval approach into the caching
  446.  * architecture.
  447.  */
  448. if (ip_load(NULL, (void*)subid) == -1 ) {
  449.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  450.             continue;
  451. }
  452.         ret_value = ipstat;
  453.         break;
  454. #else                  /* hpux11 */
  455. #if defined (WIN32) || defined (cygwin)
  456.     case IPFORWARDING:
  457.         ipForwarding = ipstat.dwForwarding;
  458.         ret_value    = ipstat.dwForwarding;
  459.         type = ASN_INTEGER;
  460.         break;
  461.     case IPDEFAULTTTL:
  462.         ipTTL     = ipstat.dwDefaultTTL;
  463.         ret_value = ipstat.dwDefaultTTL;
  464.         type = ASN_INTEGER;
  465.         break;
  466.     case IPINRECEIVES:
  467.         ret_value = ipstat.dwInReceives;
  468.         break;
  469.     case IPINHDRERRORS:
  470.         ret_value = ipstat.dwInHdrErrors;
  471.         break;
  472.     case IPINADDRERRORS:
  473.         ret_value = ipstat.dwInAddrErrors;
  474.         break;
  475.     case IPFORWDATAGRAMS:
  476.         ret_value = ipstat.dwForwDatagrams;
  477.         break;
  478.     case IPINUNKNOWNPROTOS:
  479.         ret_value = ipstat.dwInUnknownProtos;
  480.         break;
  481.     case IPINDISCARDS:
  482.         ret_value = ipstat.dwInDiscards;
  483.         break;
  484.     case IPINDELIVERS:
  485.         ret_value = ipstat.dwInDelivers;
  486.         break;
  487.     case IPOUTREQUESTS:
  488.         ret_value = ipstat.dwOutRequests;
  489.         break;
  490.     case IPOUTDISCARDS:
  491.         ret_value = ipstat.dwOutDiscards;
  492.         break;
  493.     case IPOUTNOROUTES:
  494.         ret_value = ipstat.dwOutNoRoutes;
  495.         break;
  496.     case IPREASMTIMEOUT:
  497.         ret_value = ipstat.dwReasmTimeout;
  498.         type = ASN_INTEGER;
  499.         break;
  500.     case IPREASMREQDS:
  501.         ret_value = ipstat.dwReasmReqds;
  502.         break;
  503.     case IPREASMOKS:
  504.         ret_value = ipstat.dwReasmOks;
  505.         break;
  506.     case IPREASMFAILS:
  507.         ret_value = ipstat.dwReasmFails;
  508.         break;
  509.     case IPFRAGOKS:
  510.         ret_value = ipstat.dwFragOks;
  511.         break;
  512.     case IPFRAGFAILS:
  513.         ret_value = ipstat.dwFragFails;
  514.         break;
  515.     case IPFRAGCREATES:
  516.         ret_value = ipstat.dwFragCreates;
  517.         break;
  518.     case IPROUTEDISCARDS:
  519.         ret_value = ipstat.dwRoutingDiscards;
  520.         break;
  521. #endif                  /* WIN32 || cygwin */
  522. #endif                  /* hpux11 */
  523. #endif                  /* USE_TRADITIONAL_IPSTAT */
  524. #endif /* USES_SNMP_DESIGNED_IPSTAT */
  525.     case IPADDRTABLE:
  526.     case IPROUTETABLE:
  527.     case IPMEDIATABLE:
  528.         /*
  529.  * These are not actually valid scalar objects.
  530.  * The relevant table registrations should take precedence,
  531.  *   so skip these three subtrees, regardless of architecture.
  532.  */
  533.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  534.         continue;
  535.     }
  536.     snmp_set_var_typed_value(request->requestvb, (u_char)type,
  537.              (u_char *)&ret_value, sizeof(ret_value));
  538. }
  539.         break;
  540.     case MODE_GETNEXT:
  541.     case MODE_GETBULK:
  542.     case MODE_SET_RESERVE1:
  543. /* XXX - Windows currently supports setting this */
  544.     case MODE_SET_RESERVE2:
  545.     case MODE_SET_ACTION:
  546.     case MODE_SET_COMMIT:
  547.     case MODE_SET_FREE:
  548.     case MODE_SET_UNDO:
  549.         snmp_log(LOG_WARNING, "mibII/ip: Unsupported mode (%d)n",
  550.                                reqinfo->mode);
  551.         break;
  552.     default:
  553.         snmp_log(LOG_WARNING, "mibII/ip: Unrecognised mode (%d)n",
  554.                                reqinfo->mode);
  555.         break;
  556.     }
  557.     return SNMP_ERR_NOERROR;
  558. }
  559.         /*********************
  560.  *
  561.  *  Internal implementation functions
  562.  *
  563.  *********************/
  564. #ifdef hpux11
  565. int
  566. ip_load(netsnmp_cache *cache, void *vmagic)
  567. {
  568.     int             fd;
  569.     struct nmparms  p;
  570.     unsigned int    ulen;
  571.     int             ret;
  572.     int             magic = (int) vmagic;
  573.     
  574.     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
  575.         DEBUGMSGTL(("mibII/ip", "Failed to load IP object %d (hpux11)n", magic));
  576.         return (-1);            /* error */
  577.     }
  578.     switch (magic) {
  579.     case IPFORWARDING:
  580.         p.objid = ID_ipForwarding;
  581.         break;
  582.     case IPDEFAULTTTL:
  583.         p.objid = ID_ipDefaultTTL;
  584.         break;
  585.     case IPINRECEIVES:
  586.         p.objid = ID_ipInReceives;
  587.         break;
  588.     case IPINHDRERRORS:
  589.         p.objid = ID_ipInHdrErrors;
  590.         break;
  591.     case IPINADDRERRORS:
  592.         p.objid = ID_ipInAddrErrors;
  593.         break;
  594.     case IPFORWDATAGRAMS:
  595.         p.objid = ID_ipForwDatagrams;
  596.         break;
  597.     case IPINUNKNOWNPROTOS:
  598.         p.objid = ID_ipInUnknownProtos;
  599.         break;
  600.     case IPINDISCARDS:
  601.         p.objid = ID_ipInDiscards;
  602.         break;
  603.     case IPINDELIVERS:
  604.         p.objid = ID_ipInDelivers;
  605.         break;
  606.     case IPOUTREQUESTS:
  607.         p.objid = ID_ipOutRequests;
  608.         break;
  609.     case IPOUTDISCARDS:
  610.         p.objid = ID_ipOutDiscards;
  611.         break;
  612.     case IPOUTNOROUTES:
  613.         p.objid = ID_ipOutNoRoutes;
  614.         break;
  615.     case IPREASMTIMEOUT:
  616.         p.objid = ID_ipReasmTimeout;
  617.         break;
  618.     case IPREASMREQDS:
  619.         p.objid = ID_ipReasmReqds;
  620.         break;
  621.     case IPREASMOKS:
  622.         p.objid = ID_ipReasmOKs;
  623.         break;
  624.     case IPREASMFAILS:
  625.         p.objid = ID_ipReasmFails;
  626.         break;
  627.     case IPFRAGOKS:
  628.         p.objid = ID_ipFragOKs;
  629.         break;
  630.     case IPFRAGFAILS:
  631.         p.objid = ID_ipFragFails;
  632.         break;
  633.     case IPFRAGCREATES:
  634.         p.objid = ID_ipFragCreates;
  635.         break;
  636.     case IPROUTEDISCARDS:
  637.         p.objid = ID_ipRoutingDiscards;
  638.         break;
  639.     default:
  640.         ipstat = 0;
  641.         close_mib(fd);
  642.         return (0);
  643.     }
  644.     p.buffer = (void *)&ipstat;
  645.     ulen = sizeof(IP_STAT_STRUCTURE);
  646.     p.len = &ulen;
  647.     ret = get_mib_info(fd, &p);
  648.     close_mib(fd);
  649.     DEBUGMSGTL(("mibII/ip", "%s IP object %d (hpux11)n",
  650.                (ret < 0 ? "Failed to load" : "Loaded"),  magic));
  651.     return (ret);         /* 0: ok, < 0: error */
  652. }
  653. #else                           /* hpux11 */
  654. #ifdef linux
  655. int
  656. ip_load(netsnmp_cache *cache, void *vmagic)
  657. {
  658.     long ret_value = -1;
  659.     ret_value = linux_read_ip_stat(&ipstat);
  660.     if ( ret_value < 0 ) {
  661.         DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (linux)n"));
  662.     } else {
  663.         DEBUGMSGTL(("mibII/ip", "Loaded IP Group (linux)n"));
  664.     }
  665.     return ret_value;
  666. }
  667. #else                           /* linux */
  668. #ifdef solaris2
  669. int
  670. ip_load(netsnmp_cache *cache, void *vmagic)
  671. {
  672.     long ret_value = -1;
  673.     ret_value =
  674.         getMibstat(MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
  675.                    &Get_everything, NULL);
  676.     if ( ret_value < 0 ) {
  677.         DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (solaris)n"));
  678.     } else {
  679.         DEBUGMSGTL(("mibII/ip", "Loaded IP Group (solaris)n"));
  680.     }
  681.     return ret_value;
  682. }
  683. #else                           /* solaris2 */
  684. #if defined (WIN32) || defined (cygwin)
  685. int
  686. ip_load(netsnmp_cache *cache, void *vmagic)
  687. {
  688.     long ret_value = -1;
  689.     ret_value = GetIpStatistics(&ipstat);
  690.     if ( ret_value < 0 ) {
  691.         DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (win32)n"));
  692.     } else {
  693.         DEBUGMSGTL(("mibII/ip", "Loaded IP Group (win32)n"));
  694.     }
  695.     return ret_value;
  696. }
  697. #else                           /* WIN32 cygwin */
  698. #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS))
  699. int
  700. ip_load(netsnmp_cache *cache, void *vmagic)
  701. {
  702.     long            ret_value = 0;
  703.     int             i;
  704.     static int      sname[4] = { CTL_NET, PF_INET, IPPROTO_IP, 0 };
  705.     size_t          len;
  706.     int             magic = (int) vmagic;
  707.     switch (magic) {
  708.     case IPFORWARDING:
  709.         len = sizeof i;
  710.         sname[3] = IPCTL_FORWARDING;
  711.         if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
  712.             return -1;
  713.         else
  714.             return (i ? 1 /* GATEWAY */
  715.                       : 2 /* HOST    */ );
  716.     case IPDEFAULTTTL:
  717.         len = sizeof i;
  718.         sname[3] = IPCTL_DEFTTL;
  719.         if (sysctl(sname, 4, &i, &len, 0, 0) < 0)
  720.             return -1;
  721.         else
  722.             return i;
  723.     default:
  724.         len = sizeof(ipstat);
  725.         sname[3] = IPCTL_STATS;
  726.         ret_value = sysctl(sname, 4, &ipstat, &len, 0, 0);
  727.         if ( ret_value < 0 ) {
  728.             DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (sysctl)n"));
  729.         } else {
  730.             DEBUGMSGTL(("mibII/ip", "Loaded IP Group (sysctl)n"));
  731.         }
  732.         return ret_value;
  733.     }
  734. }
  735. #else /* (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) */
  736. #ifdef HAVE_SYS_TCPIPSTATS_H
  737. int
  738. ip_load(netsnmp_cache *cache, void *vmagic)
  739. {
  740.     long ret_value = -1;
  741.     int  magic     = (int) vmagic;
  742.     switch (magic) {
  743.     case IPFORWARDING:
  744.         if (!auto_nlist
  745.             (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
  746.             return -1;
  747.         else
  748.             return (ret_value ? 1 /* GATEWAY */
  749.                               : 2 /* HOST    */ );
  750.     case IPDEFAULTTTL:
  751.         if (!auto_nlist
  752.             (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
  753.             return -1;
  754.         else
  755.             return ret_value;
  756.     default:
  757.         ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &ipstat, sizeof ipstat);
  758.         if ( ret_value < 0 ) {
  759.             DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (tcpipstats)n"));
  760.         } else {
  761.             DEBUGMSGTL(("mibII/ip", "Loaded IP Group (tcpipstats)n"));
  762.         }
  763.         return ret_value;
  764.     }
  765. }
  766. #else /* HAVE_SYS_TCPIPSTATS_H */
  767. #ifdef IPSTAT_SYMBOL
  768. int
  769. ip_load(netsnmp_cache *cache, void *vmagic)
  770. {
  771.     long ret_value = -1;
  772.     int  magic     = (int) vmagic;
  773.     switch (magic) {
  774.     case IPFORWARDING:
  775.         if (!auto_nlist
  776.             (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
  777.             return -1;
  778.         else
  779.             return (ret_value ? 1 /* GATEWAY */
  780.                               : 2 /* HOST    */ );
  781.     case IPDEFAULTTTL:
  782.         if (!auto_nlist
  783.             (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value)))
  784.             return -1;
  785.         else
  786.             return ret_value;
  787.     default:
  788.         if (auto_nlist(IPSTAT_SYMBOL, (char *)&ipstat, sizeof(ipstat)))
  789.             ret_value = 0;
  790.         if ( ret_value < 0 ) {
  791.             DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (ipstat)n"));
  792.         } else {
  793.             DEBUGMSGTL(("mibII/ip", "Loaded IP Group (ipstat)n"));
  794.         }
  795.         return ret_value;
  796.     }
  797. }
  798. #else /* IPSTAT_SYMBOL */
  799. int
  800. ip_load(netsnmp_cache *cache, void *vmagic)
  801. {
  802.     long ret_value = -1;
  803.     DEBUGMSGTL(("mibII/ip", "Failed to load IP Group (null)n"));
  804.     return ret_value;
  805. }
  806. #endif /* IPSTAT_SYMBOL */
  807. #endif /* HAVE_SYS_TCPIPSTATS_H */
  808. #endif /* (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) */
  809. #endif                          /* hpux11 */
  810. #endif                          /* linux */
  811. #endif                          /* solaris2 */
  812. #endif                          /* WIN32 cygwin */
  813. void
  814. ip_free(netsnmp_cache *cache, void *magic)
  815. {
  816.     memset(&ipstat, 0, sizeof(ipstat));
  817. }