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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  UDP MIB group implementation - udp.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include "mibII_common.h"
  7. #ifdef HAVE_NETINET_UDP_H
  8. #include <netinet/udp.h>
  9. #endif
  10. #if HAVE_NETINET_UDP_VAR_H
  11. #include <netinet/udp_var.h>
  12. #endif
  13. #include <net-snmp/net-snmp-includes.h>
  14. #include <net-snmp/agent/net-snmp-agent-includes.h>
  15. #include <net-snmp/agent/auto_nlist.h>
  16. #include "util_funcs.h"
  17. #ifdef solaris2
  18. #include "kernel_sunos5.h"
  19. #else
  20. #include "kernel.h"
  21. #endif
  22. #ifdef linux
  23. #include "kernel_linux.h"
  24. #endif
  25. #ifdef cygwin
  26. #define WIN32
  27. #include <windows.h>
  28. #endif
  29. #ifdef hpux
  30. #include <sys/mib.h>
  31. #include <netinet/mib_kern.h>
  32. #endif                          /* hpux */
  33. #ifdef linux
  34. #include "tcp.h"
  35. #endif
  36. #include "udp.h"
  37. #include "udpTable.h"
  38. #include "sysORTable.h"
  39. #ifdef CAN_USE_SYSCTL
  40. #include <sys/sysctl.h>
  41. #endif
  42. #if HAVE_DMALLOC_H
  43. #include <dmalloc.h>
  44. #endif
  45. #ifndef MIB_STATS_CACHE_TIMEOUT
  46. #define MIB_STATS_CACHE_TIMEOUT 5
  47. #endif
  48. #ifndef UDP_STATS_CACHE_TIMEOUT
  49. #define UDP_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
  50. #endif
  51.         /*********************
  52.  *
  53.  *  Kernel & interface information,
  54.  *   and internal forward declarations
  55.  *
  56.  *********************/
  57.         /*********************
  58.  *
  59.  *  Initialisation & common implementation functions
  60.  *
  61.  *********************/
  62. /*
  63.  * Define the OID pointer to the top of the mib tree that we're
  64.  * registering underneath, and the OID for the MIB module 
  65.  */
  66. oid             udp_oid[]               = { SNMP_OID_MIB2, 7 };
  67. oid             udp_module_oid[]        = { SNMP_OID_MIB2, 50 };
  68. void
  69. init_udp(void)
  70. {
  71.     netsnmp_handler_registration *reginfo;
  72.     /*
  73.      * register ourselves with the agent as a group of scalars...
  74.      */
  75.     DEBUGMSGTL(("mibII/udpScalar", "Initialising UDP scalar groupn"));
  76.     reginfo = netsnmp_create_handler_registration("udp", udp_handler,
  77.     udp_oid, OID_LENGTH(udp_oid), HANDLER_CAN_RONLY);
  78.     netsnmp_register_scalar_group(reginfo, UDPINDATAGRAMS, UDPOUTDATAGRAMS);
  79.     /*
  80.      * .... with a local cache
  81.      *    (except for HP-UX 11, which extracts objects individually)
  82.      */
  83. #ifndef hpux11
  84.     netsnmp_inject_handler( reginfo,
  85.     netsnmp_get_cache_handler(UDP_STATS_CACHE_TIMEOUT,
  86.     udp_load, udp_free,
  87. udp_oid, OID_LENGTH(udp_oid)));
  88. #endif
  89.     REGISTER_SYSOR_ENTRY(udp_module_oid,
  90.                          "The MIB module for managing UDP implementations");
  91. #ifdef UDPSTAT_SYMBOL
  92.     auto_nlist(UDPSTAT_SYMBOL, 0, 0);
  93. #endif
  94. #ifdef UDB_SYMBOL
  95.     auto_nlist(UDB_SYMBOL, 0, 0);
  96. #endif
  97. #ifdef solaris2
  98.     init_kernel_sunos5();
  99. #endif
  100. }
  101.         /*********************
  102.  *
  103.  *  System specific implementation functions
  104.  *
  105.  *********************/
  106. #ifdef hpux11
  107. #define UDP_STAT_STRUCTURE int
  108. #endif
  109. #ifdef linux
  110. #define UDP_STAT_STRUCTURE struct udp_mib
  111. #define USES_SNMP_DESIGNED_UDPSTAT
  112. #undef UDPSTAT_SYMBOL
  113. #endif
  114. #ifdef solaris2
  115. #define UDP_STAT_STRUCTURE mib2_udp_t
  116. #define USES_SNMP_DESIGNED_UDPSTAT
  117. #endif
  118. #ifdef WIN32
  119. #include <iphlpapi.h>
  120. #define UDP_STAT_STRUCTURE MIB_UDPSTATS
  121. #endif
  122. #ifdef HAVE_SYS_TCPIPSTATS_H
  123. #define UDP_STAT_STRUCTURE struct kna
  124. #define USES_TRADITIONAL_UDPSTAT
  125. #endif
  126. #if !defined(UDP_STAT_STRUCTURE)
  127. #define UDP_STAT_STRUCTURE struct udpstat
  128. #define USES_TRADITIONAL_UDPSTAT
  129. #endif
  130. UDP_STAT_STRUCTURE udpstat;
  131.         /*********************
  132.  *
  133.  *  System independent handler (mostly)
  134.  *
  135.  *********************/
  136. int
  137. udp_handler(netsnmp_mib_handler          *handler,
  138.             netsnmp_handler_registration *reginfo,
  139.             netsnmp_agent_request_info   *reqinfo,
  140.             netsnmp_request_info         *requests)
  141. {
  142.     netsnmp_request_info  *request;
  143.     netsnmp_variable_list *requestvb;
  144.     long     ret_value = -1;
  145.     oid      subid;
  146.     int      type = ASN_COUNTER;
  147.     /*
  148.      * The cached data should already have been loaded by the
  149.      *    cache handler, higher up the handler chain.
  150.      * But just to be safe, check this and load it manually if necessary
  151.      */
  152. #ifndef hpux11
  153.     if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) {
  154.         netsnmp_assert("cache" == "valid"); /* always false */
  155.         udp_load( NULL, NULL ); /* XXX - check for failure */
  156.     }
  157. #endif
  158.     /*
  159.      * 
  160.      *
  161.      */
  162.     DEBUGMSGTL(("mibII/udpScalar", "Handler - mode %sn",
  163.                     se_find_label_in_slist("agent_mode", reqinfo->mode)));
  164.     switch (reqinfo->mode) {
  165.     case MODE_GET:
  166.         for (request=requests; request; request=request->next) {
  167.             requestvb = request->requestvb;
  168.             subid = requestvb->name[OID_LENGTH(udp_oid)];  /* XXX */
  169.             DEBUGMSGTL(( "mibII/udpScalar", "oid: "));
  170.             DEBUGMSGOID(("mibII/udpScalar", requestvb->name,
  171.                                             requestvb->name_length));
  172.             DEBUGMSG((   "mibII/udpScalar", "n"));
  173.             switch (subid) {
  174. #ifdef USES_SNMP_DESIGNED_UDPSTAT
  175.     case UDPINDATAGRAMS:
  176.         ret_value = udpstat.udpInDatagrams;
  177.         break;
  178.     case UDPNOPORTS:
  179. #ifdef solaris2
  180.         ret_value = udp_load(NULL, (void *)UDPNOPORTS);
  181. if (ret_value == -1) {
  182.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  183.             continue;
  184. }
  185.         break;
  186. #else
  187.         ret_value = udpstat.udpNoPorts;
  188.         break;
  189. #endif
  190.     case UDPOUTDATAGRAMS:
  191.         ret_value = udpstat.udpOutDatagrams;
  192.         break;
  193.     case UDPINERRORS:
  194.         ret_value = udpstat.udpInErrors;
  195.         break;
  196. #else /* USES_SNMP_DESIGNED_UDPSTAT */
  197. #ifdef USES_TRADITIONAL_UDPSTAT
  198. #ifdef HAVE_SYS_TCPIPSTATS_H
  199.     /*
  200.      * This actually reads statistics for *all* the groups together,
  201.      * so we need to isolate the UDP-specific bits.  
  202.      */
  203. #define udpstat          udpstat.udpstat
  204. #endif
  205.     case UDPINDATAGRAMS:
  206. #if STRUCT_UDPSTAT_HAS_UDPS_IPACKETS
  207.         ret_value = udpstat.udps_ipackets;
  208.         break;
  209. #else
  210.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  211.         continue;
  212. #endif
  213.     case UDPNOPORTS:
  214. #if STRUCT_UDPSTAT_HAS_UDPS_NOPORT
  215.         ret_value = udpstat.udps_noport;
  216.         break;
  217. #else
  218.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  219.         continue;
  220. #endif
  221.     case UDPOUTDATAGRAMS:
  222. #if STRUCT_UDPSTAT_HAS_UDPS_OPACKETS
  223.         ret_value = udpstat.udps_opackets;
  224.         break;
  225. #else
  226.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  227.         continue;
  228. #endif
  229.     case UDPINERRORS:
  230.         ret_value = udpstat.udps_hdrops + udpstat.udps_badsum +
  231. #ifdef STRUCT_UDPSTAT_HAS_UDPS_DISCARD
  232.             udpstat.udps_discard +
  233. #endif
  234. #ifdef STRUCT_UDPSTAT_HAS_UDPS_FULLSOCK
  235.             udpstat.udps_fullsock +
  236. #endif
  237.             udpstat.udps_badlen;
  238.         break;
  239. #ifdef HAVE_SYS_TCPIPSTATS_H
  240. #undef udpstat
  241. #endif
  242. #else /* USES_TRADITIONAL_UDPSTAT */
  243. #ifdef hpux11
  244.     case UDPINDATAGRAMS:
  245.     case UDPNOPORTS:
  246.     case UDPOUTDATAGRAMS:
  247.     case UDPINERRORS:
  248. /*
  249.  * This is a bit of a hack, to shoehorn the HP-UX 11
  250.  * single-object retrieval approach into the caching
  251.  * architecture.
  252.  */
  253. if (udp_load(NULL, (void*)subid) == -1 ) {
  254.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  255.             continue;
  256. }
  257.         ret_value = udpstat;
  258.         break;
  259. #else /* hpux11 */
  260. #ifdef WIN32
  261.     case UDPINDATAGRAMS:
  262.         ret_value = udpstat.dwInDatagrams;
  263.         break;
  264.     case UDPNOPORTS:
  265.         ret_value = udpstat.dwNoPorts;
  266.         break;
  267.     case UDPOUTDATAGRAMS:
  268.         ret_value = udpstat.dwOutDatagrams;
  269.         break;
  270.     case UDPINERRORS:
  271.         ret_value = udpstat.dwInErrors;
  272.         break;
  273. #endif /* WIN32 */
  274. #endif /* hpux11 */
  275. #endif /* USES_TRADITIONAL_UDPSTAT */
  276. #endif /* USES_SNMP_DESIGNED_UDPSTAT */
  277.     }
  278.     snmp_set_var_typed_value(request->requestvb, (u_char)type,
  279.              (u_char *)&ret_value, sizeof(ret_value));
  280. }
  281.         break;
  282.     case MODE_GETNEXT:
  283.     case MODE_GETBULK:
  284.     case MODE_SET_RESERVE1:
  285.     case MODE_SET_RESERVE2:
  286.     case MODE_SET_ACTION:
  287.     case MODE_SET_COMMIT:
  288.     case MODE_SET_FREE:
  289.     case MODE_SET_UNDO:
  290.         snmp_log(LOG_WARNING, "mibII/udp: Unsupported mode (%d)n",
  291.                                reqinfo->mode);
  292.         break;
  293.     default:
  294.         snmp_log(LOG_WARNING, "mibII/udp: Unrecognised mode (%d)n",
  295.                                reqinfo->mode);
  296.         break;
  297.     }
  298.     return SNMP_ERR_NOERROR;
  299. }
  300.         /*********************
  301.  *
  302.  *  Internal implementation functions
  303.  *
  304.  *********************/
  305. #ifdef hpux11
  306. int
  307. udp_load(netsnmp_cache *cache, void *vmagic)
  308. {
  309.     int             fd;
  310.     struct nmparms  p;
  311.     unsigned int    ulen;
  312.     int             ret;
  313.     int             magic = (int) vmagic;
  314.     
  315.     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
  316.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP object %d (hpux11)n", magic));
  317.         return (-1);            /* error */
  318.     }
  319.     switch (magic) {
  320.     case UDPINDATAGRAMS:
  321.         p.objid = ID_udpInDatagrams;
  322.         break;
  323.     case UDPNOPORTS:
  324.         p.objid = ID_udpNoPorts;
  325.         break;
  326.     case UDPOUTDATAGRAMS:
  327.         p.objid = ID_udpOutDatagrams;
  328.         break;
  329.     case UDPINERRORS:
  330.         p.objid = ID_udpInErrors;
  331.         break;
  332.     default:
  333.         udpstat = 0;
  334.         close_mib(fd);
  335.         return -1;
  336.     }
  337.     p.buffer = (void *)&udpstat;
  338.     ulen = sizeof(UDP_STAT_STRUCTURE);
  339.     p.len = &ulen;
  340.     ret = get_mib_info(fd, &p);
  341.     close_mib(fd);
  342.     DEBUGMSGTL(("mibII/udpScalar", "%s UDP object %d (hpux11)n",
  343.                (ret < 0 ? "Failed to load" : "Loaded"),  magic));
  344.     return (ret);         /* 0: ok, < 0: error */
  345. }
  346. #else                           /* hpux11 */
  347. #ifdef linux
  348. int
  349. udp_load(netsnmp_cache *cache, void *vmagic)
  350. {
  351.     long ret_value = -1;
  352.     ret_value = linux_read_udp_stat(&udpstat);
  353.     if ( ret_value < 0 ) {
  354.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (linux)n"));
  355.     } else {
  356.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (linux)n"));
  357.     }
  358.     return ret_value;
  359. }
  360. #else                           /* linux */
  361. #ifdef solaris2
  362. int
  363. udp_load(netsnmp_cache *cache, void *vmagic)
  364. {
  365.     long ret_value = -1;
  366.     int  magic = (int)vmagic;
  367.     mib2_ip_t ipstat;
  368.     /*
  369.      * udpNoPorts is actually implemented as part of the MIB_IP group
  370.      * so we need to retrieve this independently
  371.      */
  372.     if (magic == UDPNOPORTS) {
  373.         if (getMibstat
  374.             (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
  375.              &Get_everything, NULL) < 0) {
  376.             DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP object %d (solaris)n", magic));
  377.             return -1;
  378.         } else {
  379.             DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP object %d (solaris)n", magic));
  380.             return ipstat.udpNoPorts;
  381.         }
  382.     }
  383.     /*
  384.      * Otherwise, retrieve the whole of the MIB_UDP group (and cache it)
  385.      */
  386.     ret_value = getMibstat(MIB_UDP, &udpstat, sizeof(mib2_udp_t),
  387.                            GET_FIRST, &Get_everything, NULL);
  388.     if ( ret_value < 0 ) {
  389.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (solaris)n"));
  390.     } else {
  391.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (solaris)n"));
  392.     }
  393.     return ret_value;
  394. }
  395. #else                           /* solaris2 */
  396. #ifdef WIN32
  397. int
  398. udp_load(netsnmp_cache *cache, void *vmagic)
  399. {
  400.     long ret_value = -1;
  401.     ret_value = GetUdpStatistics(&udpstat);
  402.     if ( ret_value < 0 ) {
  403.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (win32)n"));
  404.     } else {
  405.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (win32)n"));
  406.     }
  407.     return ret_value;
  408. }
  409. #else                           /* WIN32 */
  410. #if (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS))
  411. int
  412. udp_load(netsnmp_cache *cache, void *vmagic)
  413. {
  414.     int     sname[4]  = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS };
  415.     size_t  len       = sizeof(udpstat);
  416.     long    ret_value = -1;
  417.     ret_value = sysctl(sname, 4, &udpstat, &len, 0, 0);
  418.     if ( ret_value < 0 ) {
  419.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (sysctl)n"));
  420.     } else {
  421.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (sysctl)n"));
  422.     }
  423.     return ret_value;
  424. }
  425. #else /* (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) */
  426. #ifdef HAVE_SYS_TCPIPSTATS_H
  427. int
  428. udp_load(netsnmp_cache *cache, void *vmagic)
  429. {
  430.     long ret_value = -1;
  431.     ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &udpstat, sizeof(udpstat));
  432.     if ( ret_value < 0 ) {
  433.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (tcpipstats)n"));
  434.     } else {
  435.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (tcpipstats)n"));
  436.     }
  437.     return ret_value;
  438. }
  439. #else /* HAVE_SYS_TCPIPSTATS_H */
  440. #ifdef UDPSTAT_SYMBOL
  441. int
  442. udp_load(netsnmp_cache *cache, void *vmagic)
  443. {
  444.     long ret_value = -1;
  445.     if (auto_nlist(UDPSTAT_SYMBOL, (char *)&udpstat, sizeof(udpstat)))
  446.         ret_value = 0;
  447.     if ( ret_value < 0 ) {
  448.         DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (udpstat)n"));
  449.     } else {
  450.         DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (udpstat)n"));
  451.     }
  452.     return ret_value;
  453. }
  454. #else /* UDPSTAT_SYMBOL */
  455. int
  456. udp_load(netsnmp_cache *cache, void *vmagic)
  457. {
  458.     long ret_value = -1;
  459.     DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (null)n"));
  460.     return ret_value;
  461. }
  462. #endif /* UDPSTAT_SYMBOL */
  463. #endif /* HAVE_SYS_TCPIPSTATS_H */
  464. #endif /* (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) */
  465. #endif                          /* hpux11 */
  466. #endif                          /* linux */
  467. #endif                          /* solaris2 */
  468. #endif                          /* WIN32 */
  469. void
  470. udp_free(netsnmp_cache *cache, void *magic)
  471. {
  472.     memset(&udpstat, 0, sizeof(udpstat));
  473. }