Blame agent/mibgroup/mibII/tcp.c

Packit fcad23
Packit fcad23
/*
Packit fcad23
 *  TCP MIB group implementation - tcp.c
Packit fcad23
 *
Packit fcad23
 */
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
#include <net-snmp/net-snmp-features.h>
Packit fcad23
#include "mibII_common.h"
Packit fcad23
Packit fcad23
#if HAVE_STDLIB_H
Packit fcad23
#include <stdlib.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
#include <unistd.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if HAVE_SYS_PROTOSW_H
Packit fcad23
#include <sys/protosw.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_ARPA_INET_H
Packit fcad23
#include <arpa/inet.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if defined(osf4) || defined(osf5) || defined(aix4) || defined(hpux10)
Packit fcad23
/*
Packit fcad23
 * these are undefed to remove a stupid warning on osf compilers
Packit fcad23
 * because they get redefined with a slightly different notation of the
Packit fcad23
 * same value.  -- Wes 
Packit fcad23
 */
Packit fcad23
#undef TCP_NODELAY
Packit fcad23
#undef TCP_MAXSEG
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETINET_TCP_H
Packit fcad23
#include <netinet/tcp.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETINET_TCPIP_H
Packit fcad23
#include <netinet/tcpip.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETINET_TCP_TIMER_H
Packit fcad23
#include <netinet/tcp_timer.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETINET_TCP_VAR_H
Packit fcad23
#include <netinet/tcp_var.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NETINET_TCP_FSM_H
Packit fcad23
#include <netinet/tcp_fsm.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-includes.h>
Packit fcad23
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit fcad23
#include <net-snmp/agent/auto_nlist.h>
Packit fcad23
#include <net-snmp/agent/sysORTable.h>
Packit fcad23
Packit fcad23
#include "util_funcs/MIB_STATS_CACHE_TIMEOUT.h"
Packit fcad23
#include "tcp.h"
Packit fcad23
#include "tcpTable.h"
Packit fcad23
Packit fcad23
#ifndef MIB_STATS_CACHE_TIMEOUT
Packit fcad23
#define MIB_STATS_CACHE_TIMEOUT	5
Packit fcad23
#endif
Packit fcad23
#ifndef TCP_STATS_CACHE_TIMEOUT
Packit fcad23
#define TCP_STATS_CACHE_TIMEOUT	MIB_STATS_CACHE_TIMEOUT
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if defined(HAVE_LIBPERFSTAT_H) && (defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) && !defined(FIRST_PROTOCOL)
Packit fcad23
#ifdef HAVE_SYS_PROTOSW_H
Packit fcad23
#include <sys/protosw.h>
Packit fcad23
#endif
Packit fcad23
#include <libperfstat.h>
Packit fcad23
#ifdef FIRST_PROTOCOL
Packit fcad23
perfstat_protocol_t ps_proto;
Packit fcad23
perfstat_id_t ps_name;
Packit fcad23
#define _USE_FIRST_PROTOCOL 1
Packit fcad23
#endif
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Kernel & interface information,
Packit fcad23
	 *   and internal forward declarations
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
                /*
Packit fcad23
                 * FreeBSD4 *does* need an explicit variable 'hz'
Packit fcad23
                 *   since this appears in a system header file.
Packit fcad23
                 * But only define it under FreeBSD, since it
Packit fcad23
                 *   breaks other systems (notable AIX)
Packit fcad23
                 */
Packit fcad23
#ifdef freebsd4
Packit fcad23
int  hz = 1000;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Initialisation & common implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Define the OID pointer to the top of the mib tree that we're
Packit fcad23
 * registering underneath, and the OID for the MIB module 
Packit fcad23
 */
Packit fcad23
oid             tcp_oid[]               = { SNMP_OID_MIB2, 6 };
Packit fcad23
oid             tcp_module_oid[]        = { SNMP_OID_MIB2, 49 };
Packit fcad23
Packit fcad23
void
Packit fcad23
init_tcp(void)
Packit fcad23
{
Packit fcad23
    netsnmp_handler_registration *reginfo;
Packit fcad23
    int rc;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * register ourselves with the agent as a group of scalars...
Packit fcad23
     */
Packit fcad23
    DEBUGMSGTL(("mibII/tcpScalar", "Initialising TCP scalar group\n"));
Packit fcad23
    reginfo = netsnmp_create_handler_registration("tcp", tcp_handler,
Packit fcad23
		    tcp_oid, OID_LENGTH(tcp_oid), HANDLER_CAN_RONLY);
Packit fcad23
    rc = netsnmp_register_scalar_group(reginfo, TCPRTOALGORITHM, TCPOUTRSTS);
Packit fcad23
    if (rc != SNMPERR_SUCCESS)
Packit fcad23
        return;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * .... with a local cache
Packit fcad23
     *    (except for HP-UX 11, which extracts objects individually)
Packit fcad23
     */
Packit fcad23
#ifndef hpux11
Packit fcad23
    netsnmp_inject_handler( reginfo,
Packit fcad23
		    netsnmp_get_cache_handler(TCP_STATS_CACHE_TIMEOUT,
Packit fcad23
			   		tcp_load, tcp_free,
Packit fcad23
					tcp_oid, OID_LENGTH(tcp_oid)));
Packit fcad23
#endif
Packit fcad23
Packit fcad23
    REGISTER_SYSOR_ENTRY(tcp_module_oid,
Packit fcad23
                         "The MIB module for managing TCP implementations");
Packit fcad23
Packit fcad23
#if !defined(_USE_FIRST_PROTOCOL)
Packit fcad23
#ifdef TCPSTAT_SYMBOL
Packit fcad23
    auto_nlist(TCPSTAT_SYMBOL, 0, 0);
Packit fcad23
#endif
Packit fcad23
#ifdef TCP_SYMBOL
Packit fcad23
    auto_nlist(TCP_SYMBOL, 0, 0);
Packit fcad23
#endif
Packit fcad23
#ifdef freebsd4
Packit fcad23
    hz = sysconf(_SC_CLK_TCK);  /* get ticks/s from system */
Packit fcad23
#endif
Packit fcad23
#ifdef solaris2
Packit fcad23
    init_kernel_sunos5();
Packit fcad23
#endif
Packit fcad23
#endif
Packit fcad23
}
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  System specific implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
#ifdef hpux11
Packit fcad23
#define TCP_STAT_STRUCTURE	int
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef linux
Packit fcad23
#define TCP_STAT_STRUCTURE	struct tcp_mib
Packit fcad23
#define USES_SNMP_DESIGNED_TCPSTAT
Packit fcad23
#undef TCPSTAT_SYMBOL
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef solaris2
Packit fcad23
#define TCP_STAT_STRUCTURE	mib2_tcp_t
Packit fcad23
#define USES_SNMP_DESIGNED_TCPSTAT
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef NETBSD_STATS_VIA_SYSCTL
Packit fcad23
#define TCP_STAT_STRUCTURE      struct tcp_mib
Packit fcad23
#define USES_SNMP_DESIGNED_TCPSTAT
Packit fcad23
#undef TCP_NSTATS
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef HAVE_IPHLPAPI_H
Packit fcad23
#include <iphlpapi.h>
Packit fcad23
#define TCP_STAT_STRUCTURE     MIB_TCPSTATS
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef HAVE_SYS_TCPIPSTATS_H
Packit fcad23
#define TCP_STAT_STRUCTURE	struct kna
Packit fcad23
#define USES_TRADITIONAL_TCPSTAT
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#ifdef dragonfly
Packit fcad23
#define TCP_STAT_STRUCTURE	struct tcp_stats
Packit fcad23
#define USES_TRADITIONAL_TCPSTAT
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if !defined(TCP_STAT_STRUCTURE)
Packit fcad23
#define TCP_STAT_STRUCTURE	struct tcpstat
Packit fcad23
#define USES_TRADITIONAL_TCPSTAT
Packit fcad23
#endif
Packit fcad23
Packit fcad23
TCP_STAT_STRUCTURE tcpstat;
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  System independent handler (mostly)
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
int
Packit fcad23
tcp_handler(netsnmp_mib_handler          *handler,
Packit fcad23
            netsnmp_handler_registration *reginfo,
Packit fcad23
            netsnmp_agent_request_info   *reqinfo,
Packit fcad23
            netsnmp_request_info         *requests)
Packit fcad23
{
Packit fcad23
    netsnmp_request_info  *request;
Packit fcad23
    netsnmp_variable_list *requestvb;
Packit fcad23
    long     ret_value = -1;
Packit fcad23
    oid      subid;
Packit fcad23
    int      type = ASN_COUNTER;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * The cached data should already have been loaded by the
Packit fcad23
     *    cache handler, higher up the handler chain.
Packit fcad23
     * But just to be safe, check this and load it manually if necessary
Packit fcad23
     */
Packit fcad23
#if defined(_USE_FIRST_PROTOCOL)
Packit fcad23
    tcp_load(NULL, NULL);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * 
Packit fcad23
     *
Packit fcad23
     */
Packit fcad23
    DEBUGMSGTL(("mibII/tcpScalar", "Handler - mode %s\n",
Packit fcad23
                    se_find_label_in_slist("agent_mode", reqinfo->mode)));
Packit fcad23
    switch (reqinfo->mode) {
Packit fcad23
    case MODE_GET:
Packit fcad23
        for (request=requests; request; request=request->next) {
Packit fcad23
            requestvb = request->requestvb;
Packit fcad23
            subid = requestvb->name[OID_LENGTH(tcp_oid)];  /* XXX */
Packit fcad23
Packit fcad23
            DEBUGMSGTL(( "mibII/tcpScalar", "oid: "));
Packit fcad23
            DEBUGMSGOID(("mibII/tcpScalar", requestvb->name,
Packit fcad23
                                            requestvb->name_length));
Packit fcad23
            DEBUGMSG((   "mibII/tcpScalar", "\n"));
Packit fcad23
            switch (subid) {
Packit fcad23
#ifdef USES_SNMP_DESIGNED_TCPSTAT
Packit fcad23
    case TCPRTOALGORITHM:
Packit fcad23
        ret_value = tcpstat.tcpRtoAlgorithm;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
        ret_value = tcpstat.tcpRtoMin;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
        ret_value = tcpstat.tcpRtoMax;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
        ret_value = tcpstat.tcpMaxConn;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
        ret_value = tcpstat.tcpActiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
        ret_value = tcpstat.tcpPassiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
        ret_value = tcpstat.tcpAttemptFails;
Packit fcad23
        break;
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
        ret_value = tcpstat.tcpEstabResets;
Packit fcad23
        break;
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
        ret_value = tcpstat.tcpCurrEstab;
Packit fcad23
        type = ASN_GAUGE;
Packit fcad23
        break;
Packit fcad23
    case TCPINSEGS:
Packit fcad23
        ret_value = tcpstat.tcpInSegs & 0xffffffff;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
        ret_value = tcpstat.tcpOutSegs & 0xffffffff;
Packit fcad23
        break;
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
        ret_value = tcpstat.tcpRetransSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPINERRS:
Packit fcad23
#ifdef solaris2
Packit fcad23
        ret_value = tcp_load(NULL, (void *)TCPINERRS);
Packit fcad23
	if (ret_value == -1) {
Packit fcad23
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
            continue;
Packit fcad23
	}
Packit fcad23
        break;
Packit fcad23
#elif defined(linux)
Packit fcad23
        if (tcpstat.tcpInErrsValid) {
Packit fcad23
            ret_value = tcpstat.tcpInErrs;
Packit fcad23
            break;
Packit fcad23
	} else {
Packit fcad23
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
            continue;
Packit fcad23
	}
Packit fcad23
#else			/* linux */
Packit fcad23
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
        continue;
Packit fcad23
#endif			/* solaris2 */
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
#ifdef linux
Packit fcad23
        if (tcpstat.tcpOutRstsValid) {
Packit fcad23
            ret_value = tcpstat.tcpOutRsts;
Packit fcad23
            break;
Packit fcad23
	}
Packit fcad23
#elif defined(solaris2)
Packit fcad23
        ret_value = tcpstat.tcpOutRsts;
Packit fcad23
        break;
Packit fcad23
#endif			/* linux */
Packit fcad23
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
        continue;
Packit fcad23
#elif defined(USES_TRADITIONAL_TCPSTAT) && !defined(_USE_FIRST_PROTOCOL)
Packit fcad23
#ifdef HAVE_SYS_TCPIPSTATS_H
Packit fcad23
    /*
Packit fcad23
     * This actually reads statistics for *all* the groups together,
Packit fcad23
     * so we need to isolate the TCP-specific bits.  
Packit fcad23
     */
Packit fcad23
#define tcpstat          tcpstat.tcpstat
Packit fcad23
#endif
Packit fcad23
    case TCPRTOALGORITHM:      /* Assume Van Jacobsen's algorithm */
Packit fcad23
        ret_value = 4;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
#ifdef TCPTV_NEEDS_HZ
Packit fcad23
        ret_value = TCPTV_MIN;
Packit fcad23
#else
Packit fcad23
        ret_value = TCPTV_MIN / PR_SLOWHZ * 1000;
Packit fcad23
#endif
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
#ifdef TCPTV_NEEDS_HZ
Packit fcad23
        ret_value = TCPTV_REXMTMAX;
Packit fcad23
#else
Packit fcad23
        ret_value = TCPTV_REXMTMAX / PR_SLOWHZ * 1000;
Packit fcad23
#endif
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
        ret_value = -1;		/* Dynamic maximum */
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
        ret_value = tcpstat.tcps_connattempt;
Packit fcad23
        break;
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
        ret_value = tcpstat.tcps_accepts;
Packit fcad23
        break;
Packit fcad23
        /*
Packit fcad23
         * NB:  tcps_drops is actually the sum of the two MIB
Packit fcad23
         *      counters tcpAttemptFails and tcpEstabResets.
Packit fcad23
         */
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
        ret_value = tcpstat.tcps_conndrops;
Packit fcad23
        break;
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
        ret_value = tcpstat.tcps_drops;
Packit fcad23
        break;
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
#ifdef NETSNMP_FEATURE_CHECKING
Packit fcad23
        netsnmp_feature_want(tcp_count_connections)
Packit fcad23
#endif
Packit fcad23
#ifndef NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS
Packit fcad23
        ret_value = TCP_Count_Connections();
Packit fcad23
#else
Packit fcad23
        ret_value = 0;
Packit fcad23
#endif /* NETSNMP_FEATURE_REMOVE_TCP_COUNT_CONNECTIONS */
Packit fcad23
        type = ASN_GAUGE;
Packit fcad23
        break;
Packit fcad23
    case TCPINSEGS:
Packit fcad23
        ret_value = tcpstat.tcps_rcvtotal & 0xffffffff;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
        /*
Packit fcad23
         * RFC 1213 defines this as the number of segments sent
Packit fcad23
         * "excluding those containing only retransmitted octets"
Packit fcad23
         */
Packit fcad23
        ret_value = (tcpstat.tcps_sndtotal - tcpstat.tcps_sndrexmitpack) & 0xffffffff;
Packit fcad23
        break;
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
        ret_value = tcpstat.tcps_sndrexmitpack;
Packit fcad23
        break;
Packit fcad23
    case TCPINERRS:
Packit fcad23
        ret_value = tcpstat.tcps_rcvbadsum + tcpstat.tcps_rcvbadoff
Packit fcad23
#ifdef HAVE_STRUCT_TCPSTAT_TCPS_RCVMEMDROP
Packit fcad23
            + tcpstat.tcps_rcvmemdrop
Packit fcad23
#endif
Packit fcad23
            + tcpstat.tcps_rcvshort;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
        ret_value = tcpstat.tcps_sndctrl - tcpstat.tcps_closed;
Packit fcad23
        break;
Packit fcad23
#ifdef HAVE_SYS_TCPIPSTATS_H
Packit fcad23
#undef tcpstat
Packit fcad23
#endif
Packit fcad23
#elif defined(hpux11)
Packit fcad23
    case TCPRTOALGORITHM:
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
        if (subid == TCPCURRESTAB)
Packit fcad23
           type = ASN_GAUGE;
Packit fcad23
	else
Packit fcad23
           type = ASN_INTEGER;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
    case TCPINSEGS:
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
    case TCPINERRS:
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
	/*
Packit fcad23
	 * This is a bit of a hack, to shoehorn the HP-UX 11
Packit fcad23
	 * single-object retrieval approach into the caching
Packit fcad23
	 * architecture.
Packit fcad23
	 */
Packit fcad23
	if (tcp_load(NULL, (void*)subid) == -1 ) {
Packit fcad23
            netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
            continue;
Packit fcad23
	}
Packit fcad23
        ret_value = tcpstat;
Packit fcad23
        break;
Packit fcad23
#elif defined (WIN32) || defined (cygwin)
Packit fcad23
    case TCPRTOALGORITHM:
Packit fcad23
        ret_value = tcpstat.dwRtoAlgorithm;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
        ret_value = tcpstat.dwRtoMin;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
        ret_value = tcpstat.dwRtoMax;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
        ret_value = tcpstat.dwMaxConn;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
        ret_value = tcpstat.dwActiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
        ret_value = tcpstat.dwPassiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
        ret_value = tcpstat.dwAttemptFails;
Packit fcad23
        break;
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
        ret_value = tcpstat.dwEstabResets;
Packit fcad23
        break;
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
        ret_value = tcpstat.dwCurrEstab;
Packit fcad23
        type = ASN_GAUGE;
Packit fcad23
        break;
Packit fcad23
    case TCPINSEGS:
Packit fcad23
        ret_value = tcpstat.dwInSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
        ret_value = tcpstat.dwOutSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
        ret_value = tcpstat.dwRetransSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPINERRS:
Packit fcad23
        ret_value = tcpstat.dwInErrs;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
        ret_value = tcpstat.dwOutRsts;
Packit fcad23
        break;
Packit fcad23
#elif defined(_USE_FIRST_PROTOCOL)
Packit fcad23
    case TCPRTOALGORITHM:
Packit fcad23
        ret_value = 4;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
        ret_value = 0;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
        ret_value = 0;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
        ret_value = -1;
Packit fcad23
        type = ASN_INTEGER;
Packit fcad23
        break;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
        ret_value = ps_proto.u.tcp.initiated;
Packit fcad23
        break;
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
        ret_value = ps_proto.u.tcp.accepted;
Packit fcad23
        break;
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
        ret_value = ps_proto.u.tcp.dropped;
Packit fcad23
        break;
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
        ret_value = ps_proto.u.tcp.dropped;
Packit fcad23
        break;
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
        /* this value is currently missing */
Packit fcad23
        ret_value = 0; /*ps_proto.u.tcp.established;*/
Packit fcad23
        type = ASN_GAUGE;
Packit fcad23
        break;
Packit fcad23
    case TCPINSEGS:
Packit fcad23
        ret_value = ps_proto.u.tcp.ipackets;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
        ret_value = ps_proto.u.tcp.opackets;
Packit fcad23
        break;
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
        ret_value = 0;
Packit fcad23
        break;
Packit fcad23
    case TCPINERRS:
Packit fcad23
        ret_value = ps_proto.u.tcp.ierrors;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
        ret_value = 0;
Packit fcad23
        break;
Packit fcad23
#endif			/* USES_SNMP_DESIGNED_TCPSTAT */
Packit fcad23
Packit fcad23
    case TCPCONNTABLE:
Packit fcad23
        /*
Packit fcad23
	 * This is not actually a valid scalar object.
Packit fcad23
	 * The table registration should take precedence,
Packit fcad23
	 *   so skip this subtree, regardless of architecture.
Packit fcad23
	 */
Packit fcad23
        netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
Packit fcad23
        continue;
Packit fcad23
Packit fcad23
	    }
Packit fcad23
	    snmp_set_var_typed_value(request->requestvb, (u_char)type,
Packit fcad23
			             (u_char *)&ret_value, sizeof(ret_value));
Packit fcad23
	}
Packit fcad23
        break;
Packit fcad23
Packit fcad23
    case MODE_GETNEXT:
Packit fcad23
    case MODE_GETBULK:
Packit fcad23
#ifndef NETSNMP_NO_WRITE_SUPPORT
Packit fcad23
    case MODE_SET_RESERVE1:
Packit fcad23
    case MODE_SET_RESERVE2:
Packit fcad23
    case MODE_SET_ACTION:
Packit fcad23
    case MODE_SET_COMMIT:
Packit fcad23
    case MODE_SET_FREE:
Packit fcad23
    case MODE_SET_UNDO:
Packit fcad23
        snmp_log(LOG_WARNING, "mibII/tcp: Unsupported mode (%d)\n",
Packit fcad23
                               reqinfo->mode);
Packit fcad23
        break;
Packit fcad23
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
Packit fcad23
    default:
Packit fcad23
        snmp_log(LOG_WARNING, "mibII/tcp: Unrecognised mode (%d)\n",
Packit fcad23
                               reqinfo->mode);
Packit fcad23
        break;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return SNMP_ERR_NOERROR;
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Internal implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
#ifdef hpux11
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    int             fd;
Packit fcad23
    struct nmparms  p;
Packit fcad23
    unsigned int    ulen;
Packit fcad23
    int             ret;
Packit fcad23
    int             magic = (int) vmagic;
Packit fcad23
    
Packit fcad23
    if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP object %d (hpux11)\n", magic));
Packit fcad23
        return (-1);            /* error */
Packit fcad23
    }
Packit fcad23
Packit fcad23
    switch (magic) {
Packit fcad23
    case TCPRTOALGORITHM:
Packit fcad23
        p.objid = ID_tcpRtoAlgorithm;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMIN:
Packit fcad23
        p.objid = ID_tcpRtoMin;
Packit fcad23
        break;
Packit fcad23
    case TCPRTOMAX:
Packit fcad23
        p.objid = ID_tcpRtoMax;
Packit fcad23
        break;
Packit fcad23
    case TCPMAXCONN:
Packit fcad23
        p.objid = ID_tcpMaxConn;
Packit fcad23
        break;
Packit fcad23
    case TCPACTIVEOPENS:
Packit fcad23
        p.objid = ID_tcpActiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPPASSIVEOPENS:
Packit fcad23
        p.objid = ID_tcpPassiveOpens;
Packit fcad23
        break;
Packit fcad23
    case TCPATTEMPTFAILS:
Packit fcad23
        p.objid = ID_tcpAttemptFails;
Packit fcad23
        break;
Packit fcad23
    case TCPESTABRESETS:
Packit fcad23
        p.objid = ID_tcpEstabResets;
Packit fcad23
        break;
Packit fcad23
    case TCPCURRESTAB:
Packit fcad23
        p.objid = ID_tcpCurrEstab;
Packit fcad23
        break;
Packit fcad23
    case TCPINSEGS:
Packit fcad23
        p.objid = ID_tcpInSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTSEGS:
Packit fcad23
        p.objid = ID_tcpOutSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPRETRANSSEGS:
Packit fcad23
        p.objid = ID_tcpRetransSegs;
Packit fcad23
        break;
Packit fcad23
    case TCPINERRS:
Packit fcad23
        p.objid = ID_tcpInErrs;
Packit fcad23
        break;
Packit fcad23
    case TCPOUTRSTS:
Packit fcad23
        p.objid = ID_tcpOutRsts;
Packit fcad23
        break;
Packit fcad23
    default:
Packit fcad23
        tcpstat = 0;
Packit fcad23
        close_mib(fd);
Packit fcad23
        return -1;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    p.buffer = (void *)&tcpstat;
Packit fcad23
    ulen = sizeof(TCP_STAT_STRUCTURE);
Packit fcad23
    p.len = &ule;;
Packit fcad23
    ret = get_mib_info(fd, &p);
Packit fcad23
    close_mib(fd);
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("mibII/tcpScalar", "%s TCP object %d (hpux11)\n",
Packit fcad23
               (ret < 0 ? "Failed to load" : "Loaded"),  magic));
Packit fcad23
    return (ret);         /* 0: ok, < 0: error */
Packit fcad23
}
Packit fcad23
#elif defined(linux)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    ret_value = linux_read_tcp_stat(&tcpstat);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (linux)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (linux)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined(solaris2)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
    int  magic = (int)vmagic;
Packit fcad23
    mib2_ip_t ipstat;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * tcpInErrs is actually implemented as part of the MIB_IP group
Packit fcad23
     * so we need to retrieve this independently
Packit fcad23
     */
Packit fcad23
    if (magic == TCPINERRS) {
Packit fcad23
        if (getMibstat
Packit fcad23
            (MIB_IP, &ipstat, sizeof(mib2_ip_t), GET_FIRST,
Packit fcad23
             &Get_everything, NULL) < 0) {
Packit fcad23
            DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP object %d (solaris)\n", magic));
Packit fcad23
            return -1;
Packit fcad23
        } else {
Packit fcad23
            DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP object %d (solaris)\n", magic));
Packit fcad23
            return ipstat.tcpInErrs;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Otherwise, retrieve the whole of the MIB_TCP group (and cache it)
Packit fcad23
     */
Packit fcad23
    ret_value = getMibstat(MIB_TCP, &tcpstat, sizeof(mib2_tcp_t),
Packit fcad23
                           GET_FIRST, &Get_everything, NULL);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (solaris)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (solaris)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined(NETBSD_STATS_VIA_SYSCTL)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    ret_value = netbsd_read_tcp_stat(&tcpstat);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
       DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (netbsd)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (netbsd)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined (WIN32) || defined (cygwin)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    ret_value = GetTcpStatistics(&tcpstat);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (win32)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (win32)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined(_USE_FIRST_PROTOCOL)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    strcpy(ps_name.name, "tcp");
Packit fcad23
    ret_value = perfstat_protocol(&ps_name, &ps_proto, sizeof(ps_proto), 1);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (AIX)\n"));
Packit fcad23
    } else {
Packit fcad23
        ret_value = 0;
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (AIX)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif (defined(NETSNMP_CAN_USE_SYSCTL) && defined(TCPCTL_STATS))
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    int     sname[4]  = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS };
Packit fcad23
    size_t  len       = sizeof(tcpstat);
Packit fcad23
    long    ret_value = -1;
Packit fcad23
Packit fcad23
    ret_value = sysctl(sname, 4, &tcpstat, &len, 0, 0);
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (sysctl)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (sysctl)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined(HAVE_SYS_TCPIPSTATS_H)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, &tcpstat, sizeof(tcpstat));
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (tcpipstats)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (tcpipstats)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#elif defined(TCPSTAT_SYMBOL)
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    if (auto_nlist(TCPSTAT_SYMBOL, (char *)&tcpstat, sizeof(tcpstat)))
Packit fcad23
        ret_value = 0;
Packit fcad23
Packit fcad23
    if ( ret_value < 0 ) {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (tcpstat)\n"));
Packit fcad23
    } else {
Packit fcad23
        DEBUGMSGTL(("mibII/tcpScalar", "Loaded TCP scalar Group (tcpstat)\n"));
Packit fcad23
    }
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#else				/* TCPSTAT_SYMBOL */
Packit fcad23
int
Packit fcad23
tcp_load(netsnmp_cache *cache, void *vmagic)
Packit fcad23
{
Packit fcad23
    long ret_value = -1;
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("mibII/tcpScalar", "Failed to load TCP scalar Group (null)\n"));
Packit fcad23
    return ret_value;
Packit fcad23
}
Packit fcad23
#endif                          /* WIN32 cygwin */
Packit fcad23
Packit fcad23
Packit fcad23
void
Packit fcad23
tcp_free(netsnmp_cache *cache, void *magic)
Packit fcad23
{
Packit fcad23
#if defined(_USE_FIRST_PROTOCOL)
Packit fcad23
    memset(&ps_proto, 0, sizeof(ps_proto));
Packit fcad23
#else
Packit fcad23
    memset(&tcpstat, 0, sizeof(tcpstat));
Packit fcad23
#endif
Packit fcad23
}
Packit fcad23