udp.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:14k
- /*
- * UDP MIB group implementation - udp.c
- *
- */
- #include <net-snmp/net-snmp-config.h>
- #include "mibII_common.h"
- #ifdef HAVE_NETINET_UDP_H
- #include <netinet/udp.h>
- #endif
- #if HAVE_NETINET_UDP_VAR_H
- #include <netinet/udp_var.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 "util_funcs.h"
- #ifdef solaris2
- #include "kernel_sunos5.h"
- #else
- #include "kernel.h"
- #endif
- #ifdef linux
- #include "kernel_linux.h"
- #endif
- #ifdef cygwin
- #define WIN32
- #include <windows.h>
- #endif
- #ifdef hpux
- #include <sys/mib.h>
- #include <netinet/mib_kern.h>
- #endif /* hpux */
- #ifdef linux
- #include "tcp.h"
- #endif
- #include "udp.h"
- #include "udpTable.h"
- #include "sysORTable.h"
- #ifdef CAN_USE_SYSCTL
- #include <sys/sysctl.h>
- #endif
- #if HAVE_DMALLOC_H
- #include <dmalloc.h>
- #endif
- #ifndef MIB_STATS_CACHE_TIMEOUT
- #define MIB_STATS_CACHE_TIMEOUT 5
- #endif
- #ifndef UDP_STATS_CACHE_TIMEOUT
- #define UDP_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
- #endif
- /*********************
- *
- * Kernel & interface information,
- * and internal forward declarations
- *
- *********************/
- /*********************
- *
- * Initialisation & common implementation functions
- *
- *********************/
- /*
- * Define the OID pointer to the top of the mib tree that we're
- * registering underneath, and the OID for the MIB module
- */
- oid udp_oid[] = { SNMP_OID_MIB2, 7 };
- oid udp_module_oid[] = { SNMP_OID_MIB2, 50 };
- void
- init_udp(void)
- {
- netsnmp_handler_registration *reginfo;
- /*
- * register ourselves with the agent as a group of scalars...
- */
- DEBUGMSGTL(("mibII/udpScalar", "Initialising UDP scalar groupn"));
- reginfo = netsnmp_create_handler_registration("udp", udp_handler,
- udp_oid, OID_LENGTH(udp_oid), HANDLER_CAN_RONLY);
- netsnmp_register_scalar_group(reginfo, UDPINDATAGRAMS, UDPOUTDATAGRAMS);
- /*
- * .... with a local cache
- * (except for HP-UX 11, which extracts objects individually)
- */
- #ifndef hpux11
- netsnmp_inject_handler( reginfo,
- netsnmp_get_cache_handler(UDP_STATS_CACHE_TIMEOUT,
- udp_load, udp_free,
- udp_oid, OID_LENGTH(udp_oid)));
- #endif
- REGISTER_SYSOR_ENTRY(udp_module_oid,
- "The MIB module for managing UDP implementations");
- #ifdef UDPSTAT_SYMBOL
- auto_nlist(UDPSTAT_SYMBOL, 0, 0);
- #endif
- #ifdef UDB_SYMBOL
- auto_nlist(UDB_SYMBOL, 0, 0);
- #endif
- #ifdef solaris2
- init_kernel_sunos5();
- #endif
- }
- /*********************
- *
- * System specific implementation functions
- *
- *********************/
- #ifdef hpux11
- #define UDP_STAT_STRUCTURE int
- #endif
- #ifdef linux
- #define UDP_STAT_STRUCTURE struct udp_mib
- #define USES_SNMP_DESIGNED_UDPSTAT
- #undef UDPSTAT_SYMBOL
- #endif
- #ifdef solaris2
- #define UDP_STAT_STRUCTURE mib2_udp_t
- #define USES_SNMP_DESIGNED_UDPSTAT
- #endif
- #ifdef WIN32
- #include <iphlpapi.h>
- #define UDP_STAT_STRUCTURE MIB_UDPSTATS
- #endif
- #ifdef HAVE_SYS_TCPIPSTATS_H
- #define UDP_STAT_STRUCTURE struct kna
- #define USES_TRADITIONAL_UDPSTAT
- #endif
- #if !defined(UDP_STAT_STRUCTURE)
- #define UDP_STAT_STRUCTURE struct udpstat
- #define USES_TRADITIONAL_UDPSTAT
- #endif
- UDP_STAT_STRUCTURE udpstat;
- /*********************
- *
- * System independent handler (mostly)
- *
- *********************/
- int
- udp_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 = -1;
- oid subid;
- int type = ASN_COUNTER;
- /*
- * The cached data should already have been loaded by the
- * cache handler, higher up the handler chain.
- * But just to be safe, check this and load it manually if necessary
- */
- #ifndef hpux11
- if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) {
- netsnmp_assert("cache" == "valid"); /* always false */
- udp_load( NULL, NULL ); /* XXX - check for failure */
- }
- #endif
- /*
- *
- *
- */
- DEBUGMSGTL(("mibII/udpScalar", "Handler - mode %sn",
- 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(udp_oid)]; /* XXX */
- DEBUGMSGTL(( "mibII/udpScalar", "oid: "));
- DEBUGMSGOID(("mibII/udpScalar", requestvb->name,
- requestvb->name_length));
- DEBUGMSG(( "mibII/udpScalar", "n"));
- switch (subid) {
- #ifdef USES_SNMP_DESIGNED_UDPSTAT
- case UDPINDATAGRAMS:
- ret_value = udpstat.udpInDatagrams;
- break;
- case UDPNOPORTS:
- #ifdef solaris2
- ret_value = udp_load(NULL, (void *)UDPNOPORTS);
- if (ret_value == -1) {
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- }
- break;
- #else
- ret_value = udpstat.udpNoPorts;
- break;
- #endif
- case UDPOUTDATAGRAMS:
- ret_value = udpstat.udpOutDatagrams;
- break;
- case UDPINERRORS:
- ret_value = udpstat.udpInErrors;
- break;
- #else /* USES_SNMP_DESIGNED_UDPSTAT */
- #ifdef USES_TRADITIONAL_UDPSTAT
- #ifdef HAVE_SYS_TCPIPSTATS_H
- /*
- * This actually reads statistics for *all* the groups together,
- * so we need to isolate the UDP-specific bits.
- */
- #define udpstat udpstat.udpstat
- #endif
- case UDPINDATAGRAMS:
- #if STRUCT_UDPSTAT_HAS_UDPS_IPACKETS
- ret_value = udpstat.udps_ipackets;
- break;
- #else
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- #endif
- case UDPNOPORTS:
- #if STRUCT_UDPSTAT_HAS_UDPS_NOPORT
- ret_value = udpstat.udps_noport;
- break;
- #else
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- #endif
- case UDPOUTDATAGRAMS:
- #if STRUCT_UDPSTAT_HAS_UDPS_OPACKETS
- ret_value = udpstat.udps_opackets;
- break;
- #else
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- #endif
- case UDPINERRORS:
- ret_value = udpstat.udps_hdrops + udpstat.udps_badsum +
- #ifdef STRUCT_UDPSTAT_HAS_UDPS_DISCARD
- udpstat.udps_discard +
- #endif
- #ifdef STRUCT_UDPSTAT_HAS_UDPS_FULLSOCK
- udpstat.udps_fullsock +
- #endif
- udpstat.udps_badlen;
- break;
- #ifdef HAVE_SYS_TCPIPSTATS_H
- #undef udpstat
- #endif
- #else /* USES_TRADITIONAL_UDPSTAT */
- #ifdef hpux11
- case UDPINDATAGRAMS:
- case UDPNOPORTS:
- case UDPOUTDATAGRAMS:
- case UDPINERRORS:
- /*
- * This is a bit of a hack, to shoehorn the HP-UX 11
- * single-object retrieval approach into the caching
- * architecture.
- */
- if (udp_load(NULL, (void*)subid) == -1 ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- }
- ret_value = udpstat;
- break;
- #else /* hpux11 */
- #ifdef WIN32
- case UDPINDATAGRAMS:
- ret_value = udpstat.dwInDatagrams;
- break;
- case UDPNOPORTS:
- ret_value = udpstat.dwNoPorts;
- break;
- case UDPOUTDATAGRAMS:
- ret_value = udpstat.dwOutDatagrams;
- break;
- case UDPINERRORS:
- ret_value = udpstat.dwInErrors;
- break;
- #endif /* WIN32 */
- #endif /* hpux11 */
- #endif /* USES_TRADITIONAL_UDPSTAT */
- #endif /* USES_SNMP_DESIGNED_UDPSTAT */
- }
- snmp_set_var_typed_value(request->requestvb, (u_char)type,
- (u_char *)&ret_value, sizeof(ret_value));
- }
- break;
- case MODE_GETNEXT:
- case MODE_GETBULK:
- case MODE_SET_RESERVE1:
- 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/udp: Unsupported mode (%d)n",
- reqinfo->mode);
- break;
- default:
- snmp_log(LOG_WARNING, "mibII/udp: Unrecognised mode (%d)n",
- reqinfo->mode);
- break;
- }
- return SNMP_ERR_NOERROR;
- }
- /*********************
- *
- * Internal implementation functions
- *
- *********************/
- #ifdef hpux11
- int
- udp_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/udpScalar", "Failed to load UDP object %d (hpux11)n", magic));
- return (-1); /* error */
- }
- switch (magic) {
- case UDPINDATAGRAMS:
- p.objid = ID_udpInDatagrams;
- break;
- case UDPNOPORTS:
- p.objid = ID_udpNoPorts;
- break;
- case UDPOUTDATAGRAMS:
- p.objid = ID_udpOutDatagrams;
- break;
- case UDPINERRORS:
- p.objid = ID_udpInErrors;
- break;
- default:
- udpstat = 0;
- close_mib(fd);
- return -1;
- }
- p.buffer = (void *)&udpstat;
- ulen = sizeof(UDP_STAT_STRUCTURE);
- p.len = &ulen;
- ret = get_mib_info(fd, &p);
- close_mib(fd);
- DEBUGMSGTL(("mibII/udpScalar", "%s UDP object %d (hpux11)n",
- (ret < 0 ? "Failed to load" : "Loaded"), magic));
- return (ret); /* 0: ok, < 0: error */
- }
- #else /* hpux11 */
- #ifdef linux
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- ret_value = linux_read_udp_stat(&udpstat);
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (linux)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (linux)n"));
- }
- return ret_value;
- }
- #else /* linux */
- #ifdef solaris2
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- int magic = (int)vmagic;
- mib2_ip_t ipstat;
- /*
- * udpNoPorts is actually implemented as part of the MIB_IP group
- * so we need to retrieve this independently
- */
- if (magic == UDPNOPORTS) {
- if (getMibstat
- (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
- &Get_everything, NULL) < 0) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP object %d (solaris)n", magic));
- return -1;
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP object %d (solaris)n", magic));
- return ipstat.udpNoPorts;
- }
- }
- /*
- * Otherwise, retrieve the whole of the MIB_UDP group (and cache it)
- */
- ret_value = getMibstat(MIB_UDP, &udpstat, sizeof(mib2_udp_t),
- GET_FIRST, &Get_everything, NULL);
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (solaris)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (solaris)n"));
- }
- return ret_value;
- }
- #else /* solaris2 */
- #ifdef WIN32
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- ret_value = GetUdpStatistics(&udpstat);
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (win32)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (win32)n"));
- }
- return ret_value;
- }
- #else /* WIN32 */
- #if (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS))
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- int sname[4] = { CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS };
- size_t len = sizeof(udpstat);
- long ret_value = -1;
- ret_value = sysctl(sname, 4, &udpstat, &len, 0, 0);
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (sysctl)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (sysctl)n"));
- }
- return ret_value;
- }
- #else /* (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) */
- #ifdef HAVE_SYS_TCPIPSTATS_H
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &udpstat, sizeof(udpstat));
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (tcpipstats)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (tcpipstats)n"));
- }
- return ret_value;
- }
- #else /* HAVE_SYS_TCPIPSTATS_H */
- #ifdef UDPSTAT_SYMBOL
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- if (auto_nlist(UDPSTAT_SYMBOL, (char *)&udpstat, sizeof(udpstat)))
- ret_value = 0;
- if ( ret_value < 0 ) {
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (udpstat)n"));
- } else {
- DEBUGMSGTL(("mibII/udpScalar", "Loaded UDP scalar Group (udpstat)n"));
- }
- return ret_value;
- }
- #else /* UDPSTAT_SYMBOL */
- int
- udp_load(netsnmp_cache *cache, void *vmagic)
- {
- long ret_value = -1;
- DEBUGMSGTL(("mibII/udpScalar", "Failed to load UDP scalar Group (null)n"));
- return ret_value;
- }
- #endif /* UDPSTAT_SYMBOL */
- #endif /* HAVE_SYS_TCPIPSTATS_H */
- #endif /* (defined(CAN_USE_SYSCTL) && defined(UDPCTL_STATS)) */
- #endif /* hpux11 */
- #endif /* linux */
- #endif /* solaris2 */
- #endif /* WIN32 */
- void
- udp_free(netsnmp_cache *cache, void *magic)
- {
- memset(&udpstat, 0, sizeof(udpstat));
- }