~ubuntu-branches/ubuntu/gutsy/net-snmp/gutsy-security

« back to all changes in this revision

Viewing changes to agent/mibgroup/mibII/tcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

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