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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  TCP MIB group implementation - tcp.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include "mibII_common.h"
  7. #if HAVE_STDLIB_H
  8. #include <stdlib.h>
  9. #endif
  10. #if HAVE_UNISTD_H
  11. #include <unistd.h>
  12. #endif
  13. #if HAVE_SYS_PROTOSW_H
  14. #include <sys/protosw.h>
  15. #endif
  16. #if HAVE_ARPA_INET_H
  17. #include <arpa/inet.h>
  18. #endif
  19. #if defined(osf4) || defined(osf5) || defined(aix4) || defined(hpux10)
  20. /*
  21.  * these are undefed to remove a stupid warning on osf compilers
  22.  * because they get redefined with a slightly different notation of the
  23.  * same value.  -- Wes 
  24.  */
  25. #undef TCP_NODELAY
  26. #undef TCP_MAXSEG
  27. #endif
  28. #if HAVE_NETINET_TCP_H
  29. #include <netinet/tcp.h>
  30. #endif
  31. #if HAVE_NETINET_TCPIP_H
  32. #include <netinet/tcpip.h>
  33. #endif
  34. #if HAVE_NETINET_TCP_TIMER_H
  35. #include <netinet/tcp_timer.h>
  36. #endif
  37. #if HAVE_SYS_SOCKETVAR_H
  38. #include <sys/socketvar.h>
  39. #endif
  40. #if HAVE_NETINET_TCP_VAR_H
  41. #include <netinet/tcp_var.h>
  42. #endif
  43. #if HAVE_NETINET_TCP_FSM_H
  44. #include <netinet/tcp_fsm.h>
  45. #endif
  46. #include <net-snmp/net-snmp-includes.h>
  47. #include <net-snmp/agent/net-snmp-agent-includes.h>
  48. #include <net-snmp/agent/auto_nlist.h>
  49. #include "util_funcs.h"
  50. #include "tcp.h"
  51. #include "tcpTable.h"
  52. #include "sysORTable.h"
  53. #ifndef MIB_STATS_CACHE_TIMEOUT
  54. #define MIB_STATS_CACHE_TIMEOUT 5
  55. #endif
  56. #ifndef TCP_STATS_CACHE_TIMEOUT
  57. #define TCP_STATS_CACHE_TIMEOUT MIB_STATS_CACHE_TIMEOUT
  58. #endif
  59.         /*********************
  60.  *
  61.  *  Kernel & interface information,
  62.  *   and internal forward declarations
  63.  *
  64.  *********************/
  65.                 /*
  66.                  * FreeBSD4 *does* need an explicit variable 'hz'
  67.                  *   since this appears in a system header file.
  68.                  * But only define it under FreeBSD, since it
  69.                  *   breaks other systems (notable AIX)
  70.                  */
  71. #if defined (freebsd4)
  72. int  hz = 1000;
  73. #endif
  74. extern int TCP_Count_Connections( void );
  75.         /*********************
  76.  *
  77.  *  Initialisation & common implementation functions
  78.  *
  79.  *********************/
  80. /*
  81.  * Define the OID pointer to the top of the mib tree that we're
  82.  * registering underneath, and the OID for the MIB module 
  83.  */
  84. oid             tcp_oid[]               = { SNMP_OID_MIB2, 6 };
  85. oid             tcp_module_oid[]        = { SNMP_OID_MIB2, 49 };
  86. void
  87. init_tcp(void)
  88. {
  89.     netsnmp_handler_registration *reginfo;
  90.     /*
  91.      * register ourselves with the agent as a group of scalars...
  92.      */
  93.     DEBUGMSGTL(("mibII/tcpScalar", "Initialising TCP scalar groupn"));
  94.     reginfo = netsnmp_create_handler_registration("tcp", tcp_handler,
  95.     tcp_oid, OID_LENGTH(tcp_oid), HANDLER_CAN_RONLY);
  96.     netsnmp_register_scalar_group(reginfo, TCPRTOALGORITHM, TCPOUTRSTS);
  97.     /*
  98.      * .... with a local cache
  99.      *    (except for HP-UX 11, which extracts objects individually)
  100.      */
  101. #ifndef hpux11
  102.     netsnmp_inject_handler( reginfo,
  103.     netsnmp_get_cache_handler(TCP_STATS_CACHE_TIMEOUT,
  104.     tcp_load, tcp_free,
  105. tcp_oid, OID_LENGTH(tcp_oid)));
  106. #endif
  107.     REGISTER_SYSOR_ENTRY(tcp_module_oid,
  108.                          "The MIB module for managing TCP implementations");
  109. #ifdef TCPSTAT_SYMBOL
  110.     auto_nlist(TCPSTAT_SYMBOL, 0, 0);
  111. #endif
  112. #ifdef TCP_SYMBOL
  113.     auto_nlist(TCP_SYMBOL, 0, 0);
  114. #endif
  115. #if freebsd4
  116.     hz = sysconf(_SC_CLK_TCK);  /* get ticks/s from system */
  117. #endif
  118. #ifdef solaris2
  119.     init_kernel_sunos5();
  120. #endif
  121. }
  122.         /*********************
  123.  *
  124.  *  System specific implementation functions
  125.  *
  126.  *********************/
  127. #ifdef hpux11
  128. #define TCP_STAT_STRUCTURE int
  129. #endif
  130. #ifdef linux
  131. #define TCP_STAT_STRUCTURE struct tcp_mib
  132. #define USES_SNMP_DESIGNED_TCPSTAT
  133. #undef TCPSTAT_SYMBOL
  134. #endif
  135. #ifdef solaris2
  136. #define TCP_STAT_STRUCTURE mib2_tcp_t
  137. #define USES_SNMP_DESIGNED_TCPSTAT
  138. #endif
  139. #if defined (WIN32) || defined (cygwin)
  140. #include <iphlpapi.h>
  141. #define TCP_STAT_STRUCTURE     MIB_TCPSTATS
  142. #endif
  143. #ifdef HAVE_SYS_TCPIPSTATS_H
  144. #define TCP_STAT_STRUCTURE struct kna
  145. #define USES_TRADITIONAL_TCPSTAT
  146. #endif
  147. #if !defined(TCP_STAT_STRUCTURE)
  148. #define TCP_STAT_STRUCTURE struct tcpstat
  149. #define USES_TRADITIONAL_TCPSTAT
  150. #endif
  151. TCP_STAT_STRUCTURE tcpstat;
  152.         /*********************
  153.  *
  154.  *  System independent handler (mostly)
  155.  *
  156.  *********************/
  157. int
  158. tcp_handler(netsnmp_mib_handler          *handler,
  159.             netsnmp_handler_registration *reginfo,
  160.             netsnmp_agent_request_info   *reqinfo,
  161.             netsnmp_request_info         *requests)
  162. {
  163.     netsnmp_request_info  *request;
  164.     netsnmp_variable_list *requestvb;
  165.     long     ret_value = -1;
  166.     oid      subid;
  167.     int      type = ASN_COUNTER;
  168.     /*
  169.      * The cached data should already have been loaded by the
  170.      *    cache handler, higher up the handler chain.
  171.      * But just to be safe, check this and load it manually if necessary
  172.      */
  173. #ifndef hpux11
  174.     if (!netsnmp_cache_is_valid(reqinfo, reginfo->handlerName)) {
  175.         netsnmp_assert("cache" == "valid"); /* always false */
  176.         tcp_load( NULL, NULL ); /* XXX - check for failure */
  177.     }
  178. #endif
  179.     /*
  180.      * 
  181.      *
  182.      */
  183.     DEBUGMSGTL(("mibII/tcpScalar", "Handler - mode %sn",
  184.                     se_find_label_in_slist("agent_mode", reqinfo->mode)));
  185.     switch (reqinfo->mode) {
  186.     case MODE_GET:
  187.         for (request=requests; request; request=request->next) {
  188.             requestvb = request->requestvb;
  189.             subid = requestvb->name[OID_LENGTH(tcp_oid)];  /* XXX */
  190.             DEBUGMSGTL(( "mibII/tcpScalar", "oid: "));
  191.             DEBUGMSGOID(("mibII/tcpScalar", requestvb->name,
  192.                                             requestvb->name_length));
  193.             DEBUGMSG((   "mibII/tcpScalar", "n"));
  194.             switch (subid) {
  195. #ifdef USES_SNMP_DESIGNED_TCPSTAT
  196.     case TCPRTOALGORITHM:
  197.         ret_value = tcpstat.tcpRtoAlgorithm;
  198.         type = ASN_INTEGER;
  199.         break;
  200.     case TCPRTOMIN:
  201.         ret_value = tcpstat.tcpRtoMin;
  202.         type = ASN_INTEGER;
  203.         break;
  204.     case TCPRTOMAX:
  205.         ret_value = tcpstat.tcpRtoMax;
  206.         type = ASN_INTEGER;
  207.         break;
  208.     case TCPMAXCONN:
  209.         ret_value = tcpstat.tcpMaxConn;
  210.         type = ASN_INTEGER;
  211.         break;
  212.     case TCPACTIVEOPENS:
  213.         ret_value = tcpstat.tcpActiveOpens;
  214.         break;
  215.     case TCPPASSIVEOPENS:
  216.         ret_value = tcpstat.tcpPassiveOpens;
  217.         break;
  218.     case TCPATTEMPTFAILS:
  219.         ret_value = tcpstat.tcpAttemptFails;
  220.         break;
  221.     case TCPESTABRESETS:
  222.         ret_value = tcpstat.tcpEstabResets;
  223.         break;
  224.     case TCPCURRESTAB:
  225.         ret_value = tcpstat.tcpCurrEstab;
  226.         type = ASN_GAUGE;
  227.         break;
  228.     case TCPINSEGS:
  229.         ret_value = tcpstat.tcpInSegs;
  230.         break;
  231.     case TCPOUTSEGS:
  232.         ret_value = tcpstat.tcpOutSegs;
  233.         break;
  234.     case TCPRETRANSSEGS:
  235.         ret_value = tcpstat.tcpRetransSegs;
  236.         break;
  237.     case TCPINERRS:
  238. #ifdef solaris2
  239.         ret_value = tcp_load(NULL, (void *)TCPINERRS);
  240. if (ret_value == -1) {
  241.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  242.             continue;
  243. }
  244.         break;
  245. #else /* solaris2 */
  246. #ifdef linux
  247.         if (tcpstat.tcpInErrsValid) {
  248.             ret_value = tcpstat.tcpInErrs;
  249.             break;
  250. } else {
  251.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  252.             continue;
  253. }
  254. #else /* linux */
  255.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  256.         continue;
  257. #endif /* linux */
  258. #endif /* solaris2 */
  259.     case TCPOUTRSTS:
  260. #ifdef linux
  261.         if (tcpstat.tcpOutRstsValid) {
  262.             ret_value = tcpstat.tcpOutRsts;
  263.             break;
  264. }
  265. #endif /* linux */
  266.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  267.         continue;
  268. #else /* USES_SNMP_DESIGNED_TCPSTAT */
  269. #ifdef USES_TRADITIONAL_TCPSTAT
  270. #ifdef HAVE_SYS_TCPIPSTATS_H
  271.     /*
  272.      * This actually reads statistics for *all* the groups together,
  273.      * so we need to isolate the TCP-specific bits.  
  274.      */
  275. #define tcpstat          tcpstat.tcpstat
  276. #endif
  277.     case TCPRTOALGORITHM:      /* Assume Van Jacobsen's algorithm */
  278.         ret_value = 4;
  279.         type = ASN_INTEGER;
  280.         break;
  281.     case TCPRTOMIN:
  282. #ifdef TCPTV_NEEDS_HZ
  283.         ret_value = TCPTV_MIN;
  284. #else
  285.         ret_value = TCPTV_MIN / PR_SLOWHZ * 1000;
  286. #endif
  287.         type = ASN_INTEGER;
  288.         break;
  289.     case TCPRTOMAX:
  290. #ifdef TCPTV_NEEDS_HZ
  291.         ret_value = TCPTV_REXMTMAX;
  292. #else
  293.         ret_value = TCPTV_REXMTMAX / PR_SLOWHZ * 1000;
  294. #endif
  295.         type = ASN_INTEGER;
  296.         break;
  297.     case TCPMAXCONN:
  298.         ret_value = -1; /* Dynamic maximum */
  299.         type = ASN_INTEGER;
  300.         break;
  301.     case TCPACTIVEOPENS:
  302.         ret_value = tcpstat.tcps_connattempt;
  303.         break;
  304.     case TCPPASSIVEOPENS:
  305.         ret_value = tcpstat.tcps_accepts;
  306.         break;
  307.         /*
  308.          * NB:  tcps_drops is actually the sum of the two MIB
  309.          *      counters tcpAttemptFails and tcpEstabResets.
  310.          */
  311.     case TCPATTEMPTFAILS:
  312.         ret_value = tcpstat.tcps_conndrops;
  313.         break;
  314.     case TCPESTABRESETS:
  315.         ret_value = tcpstat.tcps_drops;
  316.         break;
  317.     case TCPCURRESTAB:
  318. #ifdef USING_MIBII_TCPTABLE_MODULE
  319.         ret_value = TCP_Count_Connections();
  320. #else
  321.         ret_value = 0;
  322. #endif
  323.         type = ASN_GAUGE;
  324.         break;
  325.     case TCPINSEGS:
  326.         ret_value = tcpstat.tcps_rcvtotal;
  327.         break;
  328.     case TCPOUTSEGS:
  329.         /*
  330.          * RFC 1213 defines this as the number of segments sent
  331.          * "excluding those containing only retransmitted octets"
  332.          */
  333.         ret_value = tcpstat.tcps_sndtotal - tcpstat.tcps_sndrexmitpack;
  334.         break;
  335.     case TCPRETRANSSEGS:
  336.         ret_value = tcpstat.tcps_sndrexmitpack;
  337.         break;
  338.     case TCPINERRS:
  339.         ret_value = tcpstat.tcps_rcvbadsum + tcpstat.tcps_rcvbadoff
  340. #ifdef STRUCT_TCPSTAT_HAS_TCPS_RCVMEMDROP
  341.             + tcpstat.tcps_rcvmemdrop
  342. #endif
  343.             + tcpstat.tcps_rcvshort;
  344.         break;
  345.     case TCPOUTRSTS:
  346.         ret_value = tcpstat.tcps_sndctrl - tcpstat.tcps_closed;
  347.         break;
  348. #ifdef HAVE_SYS_TCPIPSTATS_H
  349. #undef tcpstat
  350. #endif
  351. #else /* USES_TRADITIONAL_TCPSTAT */
  352. #ifdef hpux11
  353.     case TCPRTOALGORITHM:
  354.     case TCPRTOMIN:
  355.     case TCPRTOMAX:
  356.     case TCPMAXCONN:
  357.     case TCPCURRESTAB:
  358.         if (subid == TCPCURRESTAB)
  359.            type = ASN_GAUGE;
  360. else
  361.            type = ASN_INTEGER;
  362.     case TCPACTIVEOPENS:
  363.     case TCPPASSIVEOPENS:
  364.     case TCPATTEMPTFAILS:
  365.     case TCPESTABRESETS:
  366.     case TCPINSEGS:
  367.     case TCPOUTSEGS:
  368.     case TCPRETRANSSEGS:
  369.     case TCPINERRS:
  370.     case TCPOUTRSTS:
  371. /*
  372.  * This is a bit of a hack, to shoehorn the HP-UX 11
  373.  * single-object retrieval approach into the caching
  374.  * architecture.
  375.  */
  376. if (tcp_load(NULL, (void*)subid) == -1 ) {
  377.             netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  378.             continue;
  379. }
  380.         ret_value = tcpstat;
  381.         break;
  382. #else /* hpux11 */
  383. #if defined (WIN32) || defined (cygwin)
  384.     case TCPRTOALGORITHM:
  385.         ret_value = tcpstat.dwRtoAlgorithm;
  386.         type = ASN_INTEGER;
  387.         break;
  388.     case TCPRTOMIN:
  389.         ret_value = tcpstat.dwRtoMin;
  390.         type = ASN_INTEGER;
  391.         break;
  392.     case TCPRTOMAX:
  393.         ret_value = tcpstat.dwRtoMax;
  394.         type = ASN_INTEGER;
  395.         break;
  396.     case TCPMAXCONN:
  397.         ret_value = tcpstat.dwMaxConn;
  398.         type = ASN_INTEGER;
  399.         break;
  400.     case TCPACTIVEOPENS:
  401.         ret_value = tcpstat.dwActiveOpens;
  402.         break;
  403.     case TCPPASSIVEOPENS:
  404.         ret_value = tcpstat.dwPassiveOpens;
  405.         break;
  406.     case TCPATTEMPTFAILS:
  407.         ret_value = tcpstat.dwAttemptFails;
  408.         break;
  409.     case TCPESTABRESETS:
  410.         ret_value = tcpstat.dwEstabResets;
  411.         break;
  412.     case TCPCURRESTAB:
  413.         ret_value = tcpstat.dwCurrEstab;
  414.         type = ASN_GAUGE;
  415.         break;
  416.     case TCPINSEGS:
  417.         ret_value = tcpstat.dwInSegs;
  418.         break;
  419.     case TCPOUTSEGS:
  420.         ret_value = tcpstat.dwOutSegs;
  421.         break;
  422.     case TCPRETRANSSEGS:
  423.         ret_value = tcpstat.dwRetransSegs;
  424.         break;
  425.     case TCPINERRS:
  426.         ret_value = tcpstat.dwInErrs;
  427.         break;
  428.     case TCPOUTRSTS:
  429.         ret_value = tcpstat.dwOutRsts;
  430.         break;
  431. #endif /* WIN32 cygwin */
  432. #endif /* hpux11 */
  433. #endif /* USES_TRADITIONAL_TCPSTAT */
  434. #endif /* USES_SNMP_DESIGNED_TCPSTAT */
  435.     case TCPCONNTABLE:
  436.         /*
  437.  * This is not actually a valid scalar object.
  438.  * The table registration should take precedence,
  439.  *   so skip this subtree, regardless of architecture.
  440.  */
  441.         netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
  442.         continue;
  443.     }
  444.     snmp_set_var_typed_value(request->requestvb, (u_char)type,
  445.              (u_char *)&ret_value, sizeof(ret_value));
  446. }
  447.         break;
  448.     case MODE_GETNEXT:
  449.     case MODE_GETBULK:
  450.     case MODE_SET_RESERVE1:
  451.     case MODE_SET_RESERVE2:
  452.     case MODE_SET_ACTION:
  453.     case MODE_SET_COMMIT:
  454.     case MODE_SET_FREE:
  455.     case MODE_SET_UNDO:
  456.         snmp_log(LOG_WARNING, "mibII/tcp: Unsupported mode (%d)n",
  457.                                reqinfo->mode);
  458.         break;
  459.     default:
  460.         snmp_log(LOG_WARNING, "mibII/tcp: Unrecognised mode (%d)n",
  461.                                reqinfo->mode);
  462.         break;
  463.     }
  464.     return SNMP_ERR_NOERROR;
  465. }
  466.         /*********************
  467.  *
  468.  *  Internal implementation functions
  469.  *
  470.  *********************/
  471. #ifdef hpux11
  472. int
  473. tcp_load(netsnmp_cache *cache, void *vmagic)
  474. {
  475.     int             fd;
  476.     struct nmparms  p;
  477.     unsigned int    ulen;
  478.     int             ret;
  479.     int             magic = (int) vmagic;
  480.     
  481.     if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
  482.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP object %d (hpux11)n", magic));
  483.         return (-1);            /* error */
  484.     }
  485.     switch (magic) {
  486.     case TCPRTOALGORITHM:
  487.         p.objid = ID_tcpRtoAlgorithm;
  488.         break;
  489.     case TCPRTOMIN:
  490.         p.objid = ID_tcpRtoMin;
  491.         break;
  492.     case TCPRTOMAX:
  493.         p.objid = ID_tcpRtoMax;
  494.         break;
  495.     case TCPMAXCONN:
  496.         p.objid = ID_tcpMaxConn;
  497.         break;
  498.     case TCPACTIVEOPENS:
  499.         p.objid = ID_tcpActiveOpens;
  500.         break;
  501.     case TCPPASSIVEOPENS:
  502.         p.objid = ID_tcpPassiveOpens;
  503.         break;
  504.     case TCPATTEMPTFAILS:
  505.         p.objid = ID_tcpAttemptFails;
  506.         break;
  507.     case TCPESTABRESETS:
  508.         p.objid = ID_tcpEstabResets;
  509.         break;
  510.     case TCPCURRESTAB:
  511.         p.objid = ID_tcpCurrEstab;
  512.         break;
  513.     case TCPINSEGS:
  514.         p.objid = ID_tcpInSegs;
  515.         break;
  516.     case TCPOUTSEGS:
  517.         p.objid = ID_tcpOutSegs;
  518.         break;
  519.     case TCPRETRANSSEGS:
  520.         p.objid = ID_tcpRetransSegs;
  521.         break;
  522.     case TCPINERRS:
  523.         p.objid = ID_tcpInErrs;
  524.         break;
  525.     case TCPOUTRSTS:
  526.         p.objid = ID_tcpOutRsts;
  527.         break;
  528.     default:
  529.         tcpstat = 0;
  530.         close_mib(fd);
  531.         return -1;
  532.     }
  533.     p.buffer = (void *)&tcpstat;
  534.     ulen = sizeof(TCP_STAT_STRUCTURE);
  535.     p.len = &ulen;
  536.     ret = get_mib_info(fd, &p);
  537.     close_mib(fd);
  538.     DEBUGMSGTL(("mibII/tcpScalar", "%s TCP object %d (hpux11)n",
  539.                (ret < 0 ? "Failed to load" : "Loaded"),  magic));
  540.     return (ret);         /* 0: ok, < 0: error */
  541. }
  542. #else                           /* hpux11 */
  543. #ifdef linux
  544. int
  545. tcp_load(netsnmp_cache *cache, void *vmagic)
  546. {
  547.     long ret_value = -1;
  548.     ret_value = linux_read_tcp_stat(&tcpstat);
  549.     if ( ret_value < 0 ) {
  550.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (linux)n"));
  551.     } else {
  552.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (linux)n"));
  553.     }
  554.     return ret_value;
  555. }
  556. #else                           /* linux */
  557. #ifdef solaris2
  558. int
  559. tcp_load(netsnmp_cache *cache, void *vmagic)
  560. {
  561.     long ret_value = -1;
  562.     int  magic = (int)vmagic;
  563.     mib2_ip_t ipstat;
  564.     /*
  565.      * tcpInErrs is actually implemented as part of the MIB_IP group
  566.      * so we need to retrieve this independently
  567.      */
  568.     if (magic == TCPINERRS) {
  569.         if (getMibstat
  570.             (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
  571.              &Get_everything, NULL) < 0) {
  572.             DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP object %d (solaris)n", magic));
  573.             return -1;
  574.         } else {
  575.             DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP object %d (solaris)n", magic));
  576.             return ipstat.tcpInErrs;
  577.         }
  578.     }
  579.     /*
  580.      * Otherwise, retrieve the whole of the MIB_TCP group (and cache it)
  581.      */
  582.     ret_value = getMibstat(MIB_TCP, &tcpstat, sizeof(mib2_tcp_t),
  583.                            GET_FIRST, &Get_everything, NULL);
  584.     if ( ret_value < 0 ) {
  585.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (solaris)n"));
  586.     } else {
  587.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (solaris)n"));
  588.     }
  589.     return ret_value;
  590. }
  591. #else                           /* solaris2 */
  592. #if defined (WIN32) || defined (cygwin)
  593. int
  594. tcp_load(netsnmp_cache *cache, void *vmagic)
  595. {
  596.     long ret_value = -1;
  597.     ret_value = GetTcpStatistics(&tcpstat);
  598.     if ( ret_value < 0 ) {
  599.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (win32)n"));
  600.     } else {
  601.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (win32)n"));
  602.     }
  603.     return ret_value;
  604. }
  605. #else                           /* WIN32 cygwin */
  606. #if (defined(CAN_USE_SYSCTL) && defined(TCPCTL_STATS))
  607. int
  608. tcp_load(netsnmp_cache *cache, void *vmagic)
  609. {
  610.     int     sname[4]  = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS };
  611.     size_t  len       = sizeof(tcpstat);
  612.     long    ret_value = -1;
  613.     ret_value = sysctl(sname, 4, &tcpstat, &len, 0, 0);
  614.     if ( ret_value < 0 ) {
  615.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (sysctl)n"));
  616.     } else {
  617.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (sysctl)n"));
  618.     }
  619.     return ret_value;
  620. }
  621. #else /* (defined(CAN_USE_SYSCTL) && defined(TCPCTL_STATS)) */
  622. #ifdef HAVE_SYS_TCPIPSTATS_H
  623. int
  624. tcp_load(netsnmp_cache *cache, void *vmagic)
  625. {
  626.     long ret_value = -1;
  627.     ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &tcpstat, sizeof(tcpstat));
  628.     if ( ret_value < 0 ) {
  629.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (tcpipstats)n"));
  630.     } else {
  631.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (tcpipstats)n"));
  632.     }
  633.     return ret_value;
  634. }
  635. #else /* HAVE_SYS_TCPIPSTATS_H */
  636. #ifdef TCPSTAT_SYMBOL
  637. int
  638. tcp_load(netsnmp_cache *cache, void *vmagic)
  639. {
  640.     long ret_value = -1;
  641.     if (auto_nlist(TCPSTAT_SYMBOL, (char *)&tcpstat, sizeof(tcpstat)))
  642.         ret_value = 0;
  643.     if ( ret_value < 0 ) {
  644.         DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (tcpstat)n"));
  645.     } else {
  646.         DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (tcpstat)n"));
  647.     }
  648.     return ret_value;
  649. }
  650. #else /* TCPSTAT_SYMBOL */
  651. int
  652. tcp_load(netsnmp_cache *cache, void *vmagic)
  653. {
  654.     long ret_value = -1;
  655.     DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (null)n"));
  656.     return ret_value;
  657. }
  658. #endif /* TCPSTAT_SYMBOL */
  659. #endif /* HAVE_SYS_TCPIPSTATS_H */
  660. #endif /* (defined(CAN_USE_SYSCTL) && defined(TCPCTL_STATS)) */
  661. #endif                          /* hpux11 */
  662. #endif                          /* linux */
  663. #endif                          /* solaris2 */
  664. #endif                          /* WIN32 cygwin */
  665. void
  666. tcp_free(netsnmp_cache *cache, void *magic)
  667. {
  668.     memset(&tcpstat, 0, sizeof(tcpstat));
  669. }