Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / router / tg585v7__ @ b43ec018

Historique | Voir | Annoter | Télécharger (47,1 ko)

1 a9575c11 Paul Saunders
#!/usr/bin/perl
2
# -*- cperl -*-
3
4
=head1 NAME
5
6
TG585v7_ - Munin plugin to monitor the stats of a Thomson TG585 v7.
7
8
=head1 APPLICABLE SYSTEMS
9
10
Any system with access to a Thomson TG585 v7 ADSL router.
11 97a0f791 Paul Saunders
Requires perl and either WWW::Mechanize or Net::Telnet.
12 a9575c11 Paul Saunders
13
=head1 CONFIGURATION
14
15
The plugin needs HTML access to the router. If you can get to http://YOUR_ROUTER/,
16 17f78427 Lars Kruse
and are greeting with a page titled "THOMSON TG585 v7", then you can probably use this plugin.
17 a9575c11 Paul Saunders
18
This is a wildcard plugin, so you will need to create symlinks to this plugin (or create copies if your filesystem doesn't support linking). Links should be of the form:
19
20
  TG585v7_<hostname of router>_<mode>
21
22
where "<mode>" is one of "bandwidth", "power", "errors" or "uptime" (thus you probably want 4 symlinks in total.
23
24 97a0f791 Paul Saunders
In addition, you may set the following environment variables:
25
26
=over 4
27
28
=item user
29
30
The username to login to the router as (Default: Administrator)
31
32
=item pass
33
34
The password to login to the router with (Default: Blank)
35
36
=item mode
37
38
How to connect to the router. Should be either C<http> or C<telnet>. (Default: C<http>).
39
40
=back
41
42 a9575c11 Paul Saunders
=head1 MAGIC MARKERS
43
44
  #%# family=auto
45
  #%# capabilities=autoconf
46
47
=head1 BUGS
48
49
Please report bugs to L<darac+munin@darac.org.uk>.
50
51
=head1 AUTHOR
52
53 97a0f791 Paul Saunders
Darac Marjal <darac+munin@darac.org.uk>
54
55
=head1 VERSION
56
57
2.0
58
59
=head1 CHANGELOG
60
61
=over 4
62
63
=item 1.0
64
65
=over 4
66
67
=item *
68
69
First release
70
71
=back
72
73
=item 2.0
74
75
=over 4
76
77
=item *
78
79
Allowed connectiosndn via telnet, for when the webpage is unavailable.
80
81
=back
82
83
=back
84 a9575c11 Paul Saunders
85
=head1 LICENSE
86
87
GPL
88
89
=cut
90
91
use strict;
92
use warnings;
93
94
use lib $ENV{'MUNIN_LIBDIR'};
95
use Munin::Plugin;
96
97 97a0f791 Paul Saunders
# Get configuration from environment
98
my $USER        = $ENV{user}        || 'Administrator';
99
my $PASS        = $ENV{pass}        || '';
100
my $ACCESS_MODE = $ENV{mode}        || 'telnet';
101
my $MUNIN_DEBUG = $ENV{MUNIN_DEBUG} || 0;
102 a9575c11 Paul Saunders
my $ret;
103 97a0f791 Paul Saunders
if ( $ACCESS_MODE eq 'http' and !eval "require WWW::Mechanize;" ) {
104
    $ret = "Could not load WWW::Mechanize";
105 a9575c11 Paul Saunders
}
106 97a0f791 Paul Saunders
if ( $ACCESS_MODE eq 'telnet' and !eval "require Net::Telnet;" ) {
107
    $ret = "Could not load Net::Telnet";
108 a9575c11 Paul Saunders
}
109
110 97a0f791 Paul Saunders
print "# Access Mode is: $ACCESS_MODE\n" if $MUNIN_DEBUG;
111 a9575c11 Paul Saunders
112
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
113 97a0f791 Paul Saunders
    if ($ret) {
114
        print "no ($ret)\n";
115 e4cd049b Lars Kruse
    } else {
116
        print "yes\n";
117 97a0f791 Paul Saunders
    }
118
    exit 0;
119 a9575c11 Paul Saunders
}
120
121 97a0f791 Paul Saunders
if ( defined $ARGV[0] and $ARGV[0] eq "suggest" ) {
122
    print join " ",
123
      sort
124
      qw(bandwidth power errors uptime firewall ids atm conntrack dhcpclient dhcprelay dhcpserver dns igmphost igmpproxy protoip prototcp protoudp protoicmp),
125
      "\n";
126
    exit 0;
127
}
128
129
our @name_fields = split /_/, $0;
130
if ( scalar @name_fields == 3 ) {
131
    if ( $name_fields[1] eq '' or $name_fields[2] eq '' ) {
132
        print "Misconfigured symlink. See Documentation\n";
133
        exit 1;
134
    }
135
}
136
else {
137
    print "Misconfigured symlink. See Documentation\n";
138
    exit 1;
139
}
140
my $host = $name_fields[1];
141
my $mode = $name_fields[2];
142
143 a9575c11 Paul Saunders
if ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
144 97a0f791 Paul Saunders
    if ($ret) {
145
        print $ret;
146
        exit 1;
147
    }
148
    print "host_name $host\n" unless $host eq 'localhost';
149
    if ( $mode eq 'bandwidth' ) {
150
        print <<EOF;
151
graph_vlabel bps down (-) / up (+)
152 33e95e6f Lars Kruse
graph_category network
153 a9575c11 Paul Saunders
graph_title ADSL Bandwidth
154
graph_info Sync rates for your ADSL line on $host
155
down.label Bandwidth
156
down.type GAUGE
157
down.graph no
158
down.min 0
159 97a0f791 Paul Saunders
down.cdef down,1024,*
160
down.draw AREA
161
down.colour 00CC00CC
162 a9575c11 Paul Saunders
up.label Bandwidth
163
up.type GAUGE
164
up.negative down
165
up.min 0
166
up.info This is your ADSL sync rate. Actual throughput is likely to be lower.
167 97a0f791 Paul Saunders
up.cdef up,1024,*
168
up.draw AREA
169
up.colour 00CC00CC
170
EOF
171
        if ( $ACCESS_MODE eq 'telnet' ) {
172
            print <<EOF
173
downrate.label Actual rate
174
downrate.type DERIVE
175
downrate.graph no
176
downrate.min 0
177
downrate.cdef downrate,8,*
178
uprate.label Actual rate
179
uprate.type DERIVE
180
uprate.negative downrate
181
uprate.min 0
182
uprate.cdef uprate,8,*
183
uprate.info This is the actual throughput of data.
184 a9575c11 Paul Saunders
EOF
185 97a0f791 Paul Saunders
        }
186
    }
187
    elsif ( $mode eq 'power' ) {
188
        print <<EOF;
189 a9575c11 Paul Saunders
graph_vlabel dB down (-) / up (+)
190 33e95e6f Lars Kruse
graph_category network
191 a9575c11 Paul Saunders
graph_title ADSL Strength
192
graph_info Signal Strengths for your ADSL line on $host
193
downout.label Output Power
194
downout.type GAUGE
195
downout.graph no
196
upout.label Output Power
197
upout.type GAUGE
198
upout.negative downout
199
downline.label Line Atten.
200
downline.type GAUGE
201
downline.graph no
202
upline.label Line Atten.
203
upline.type GAUGE
204
upline.negative downline
205
downsn.label SN Margin
206
downsn.type GAUGE
207
downsn.graph no
208
upsn.label SN Margin
209
upsn.type GAUGE
210
upsn.negative downsn
211
EOF
212 97a0f791 Paul Saunders
    }
213
    elsif ( $mode eq 'errors' ) {
214
        print <<EOF;
215
graph_vlabel Errors down (-) / up (+) per \${graph_period}
216 33e95e6f Lars Kruse
graph_category network
217 a9575c11 Paul Saunders
graph_title ADSL Errors
218
graph_info Errors on your ADSL line on $host
219
downFEC.label FEC Errors
220 97a0f791 Paul Saunders
downFEC.type DERIVE
221
downFEC.min 0
222 a9575c11 Paul Saunders
downFEC.graph no
223
upFEC.label FEC Errors
224 97a0f791 Paul Saunders
upFEC.type DERIVE
225
upFEC.min 0
226 a9575c11 Paul Saunders
upFEC.negative downFEC
227
downCRC.label CRC Errors
228 97a0f791 Paul Saunders
downCRC.type DERIVE
229
downCRC.min 0
230 a9575c11 Paul Saunders
downCRC.graph no
231
upCRC.label CRC Errors
232 97a0f791 Paul Saunders
upCRC.type DERIVE
233
upCRC.min 0
234 a9575c11 Paul Saunders
upCRC.negative downCRC
235
downHEC.label HEC Errors
236 97a0f791 Paul Saunders
downHEC.type DERIVE
237
downHEC.min 0
238 a9575c11 Paul Saunders
downHEC.graph no
239
upHEC.label HEC Errors
240 97a0f791 Paul Saunders
upHEC.type DERIVE
241
upHEC.min 0
242 a9575c11 Paul Saunders
upHEC.negative downHEC
243
EOF
244 97a0f791 Paul Saunders
    }
245
    elsif ( $mode eq 'uptime' ) {
246
        print <<EOF;
247 a9575c11 Paul Saunders
graph_vlabel uptime in days
248 33e95e6f Lars Kruse
graph_category system
249 a9575c11 Paul Saunders
graph_title Uptime
250
graph_info Uptime for your ADSL line and Router on $host
251
Box.label Router
252
Box.type GAUGE
253
DSL.label DSL
254
DSL.type GAUGE
255
iNet.label Internet
256
iNet.type GAUGE
257
EOF
258 97a0f791 Paul Saunders
    }
259
    elsif ( $mode eq 'firewall' ) {
260
        if ( $ACCESS_MODE eq 'http' ) {
261
            print "# Can't graph $mode stats unless by 'telnet'\n";
262
            exit 1;
263
        }
264
        else {
265
            print <<EOF;
266
graph_vlabel Packets per \${graph_period}
267
graph_category network
268
graph_title Firewall Statistics
269
graph_info Firewall statistics for your Router on $host
270
ParsedInput.label INPUT Parsed
271
ParsedInput.type DERIVE
272
ParsedInput.min 0
273
ParsedOutput.label OUTPUT Parsed
274
ParsedOutput.type DERIVE
275
ParsedOutput.min 0
276
ParsedForward.label FORWARD Parsed
277
ParsedForward.type DERIVE
278
ParsedForward.min 0
279
DroppedInput.label INPUT Dropped
280
DroppedInput.type DERIVE
281
DroppedInput.min 0
282
DroppedOutput.label OUTPUT Dropped
283
DroppedOutput.type DERIVE
284
DroppedOutput.min 0
285
DroppedForward.label FORWARD Dropped
286
DroppedForward.type DERIVE
287
DroppedForward.min 0
288
EOF
289
        }
290
    }
291
    elsif ( $mode eq 'ids' ) {
292
        if ( $ACCESS_MODE eq 'http' ) {
293
            print "# Can't graph $mode stats unless by 'telnet'\n";
294
            exit 1;
295
        }
296
        else {
297
            print <<EOF;
298
graph_vlabel Patterns per \${graph_period}
299
graph_category network
300
graph_title IDS Statistics
301
graph_info Intrusion Detection Statistics for your Router on $host
302
Active.label Active
303
Active.type GAUGE
304
Recycled.label Recycled
305
Recycled.type GAUGE
306
Searches.label Searches
307
Searches.type GAUGE
308
New.label New
309
New.type GAUGE
310
Collisions.label Collisions
311
Collisions.type GAUGE
312
EOF
313
        }
314
    }
315
    elsif ( $mode eq 'atm' ) {
316
        if ( $ACCESS_MODE eq 'http' ) {
317
            print "# Can't graph $mode stats unless by 'telnet'\n";
318
            exit 1;
319
        }
320
        else {
321
            print <<EOF;
322
graph_vlabel Number Recv (-) / Sent (+) per \${graph_period}
323
graph_category network
324
graph_title ATM Global Statistics
325
graph_info ATM Global Statistic for your Router on $host
326
RxOctets.label Octets
327
RxOctets.type DERIVE
328
RxOctets.min 0
329
RxOctets.graph no
330
TxOctets.label Octets
331
TxOctets.type DERIVE
332
TxOctets.min 0
333
TxOctets.negative RxOctets
334
RxCells.label Cells
335
RxCells.type DERIVE
336
RxCells.min 0
337
RxCells.graph no
338
TxCells.label Cells
339
TxCells.type DERIVE
340
TxCells.min 0
341
TxCells.negative RxCells
342
RxErrors.label Errors
343
RxErrors.type DERIVE
344
RxErrors.min 0
345
RxErrors.graph no
346
TxErrors.label Errors
347
TxErrors.type DERIVE
348
TxErrors.min 0
349
TxErrors.negative RxErrors
350
EOF
351
        }
352
    }
353
    elsif ( $mode eq 'conntrack' ) {
354
        if ( $ACCESS_MODE eq 'http' ) {
355
            print "# Can't graph $mode stats unless by 'telnet'\n";
356
            exit 1;
357
        }
358
        else {
359
            print <<EOF;
360
graph_vlabel Connections
361
graph_category network
362
graph_title Tracked Connections
363
graph_info Tracked Connection Statistics for your Router on $host
364
active.label Active
365
active.type GAUGE
366
halfopen.label Half-Open
367
halfopen.type GAUGE
368
expected.label Expected
369
expected.type GAUGE
370
loose.label Loose
371
loose.type GAUGE
372
closing.label Closing
373
closing.type GAUGE
374
idle.label Idle
375
idle.type GAUGE
376
mcast.label Multicast
377
mcast.type GAUGE
378
TCP.label TCP
379
TCP.type GAUGE
380
UDP.label UDP
381
UDP.type GAUGE
382
ICMP.label ICMP
383
ICMP.type GAUGE
384
non.label non TCP/UDP/ICMP
385
non.type GAUGE
386
TCPopen.label TCP Open
387
TCPopen.type GAUGE
388
TCPestablished.label TCP Established
389
TCPestablished.type GAUGE
390
TCPclosing.label TCP Closing
391
TCPclosing.type GAUGE
392
EOF
393
        }
394
    }
395
    elsif ( $mode eq 'dhcpclient' ) {
396
        if ( $ACCESS_MODE eq 'http' ) {
397
            print "# Can't graph $mode stats unless by 'telnet'\n";
398
            exit 1;
399
        }
400
        else {
401
            print <<EOF;
402
graph_vlabel Packets per \${graph_period}
403
graph_category network
404
graph_title DHCP Client
405
graph_info DHCP Client Statistic for your Router on $host
406
Corrupted.label Corrupted packet recv
407
Corrupted.type DERIVE
408
Corrupted.min 0
409
OFFERs.label OFFERs recv
410
OFFERs.type DERIVE
411
OFFERs.min 0
412
ACKs.label ACKs recv
413
ACKs.type DERIVE
414
ACKs.min 0
415
NAKs.label NAKs recv
416
NAKs.type DERIVE
417
NAKs.min 0
418
REPLIES.label Pure BOOTP Replies
419
REPLIES.type DERIVE
420
REPLIES.min 0
421
Other.label Other message types
422
Other.type DERIVE
423
Other.min 0
424
DISCOVERs.label DISCOVERs sent
425
DISCOVERs.type DERIVE
426
DISCOVERs.min 0
427
REQUESTs.label REQUESTs sent
428
REQUESTs.type DERIVE
429
REQUESTs.min 0
430
DECLINEs.label DECLINEs sent
431
DECLINEs.type DERIVE
432
DECLINEs.min 0
433
RELEASEs.label RELEASEs sent
434
RELEASEs.type DERIVE
435
RELEASEs.min 0
436
INFORMs.label INFORMs sent
437
INFORMs.type DERIVE
438
INFORMs.min 0
439
failures.label Packet sent failures
440
failures.type DERIVE
441
failures.min 0
442
EOF
443
        }
444
    }
445
    elsif ( $mode eq 'dhcprelay' ) {
446
        if ( $ACCESS_MODE eq 'http' ) {
447
            print "# Can't graph $mode stats unless by 'telnet'\n";
448
            exit 1;
449
        }
450
        else {
451
            print <<EOF;
452
graph_vlabel Packets per \${graph_period}
453
graph_category network
454
graph_title DHCP Relay
455
graph_info DHCP Relay statistics for your Router on $host
456
clientp.label Client packets relayed
457
clientp.type DERIVE
458
clientp.min 0
459
serverp.label Server packets relayed
460
serverp.type DERIVE
461
serverp.min 0
462
packets.label Packet sent failures
463
packets.type DERIVE
464
packets.min 0
465
bogusr.label Bogus relay agent
466
bogusr.type DERIVE
467
bogusr.min 0
468
bogusg.label Bogus giaddr recv
469
bogusg.type DERIVE
470
bogusg.min 0
471
corrupta.label Corrupt agent option
472
corrupta.type DERIVE
473
corrupta.min 0
474
missinga.label Missing agent option
475
missinga.type DERIVE
476
missinga.min 0
477
badc.label Bad circuit id
478
badc.type DERIVE
479
badc.min 0
480
missingc.label Missing circuit id
481
missingc.type DERIVE
482
missingc.min 0
483
EOF
484
        }
485
    }
486
    elsif ( $mode eq 'dhcpserver' ) {
487
        if ( $ACCESS_MODE eq 'http' ) {
488
            print "# Can't graph $mode stats unless by 'telnet'\n";
489
            exit 1;
490
        }
491
        else {
492
            print <<EOF;
493
graph_vlabel Packets per \${graph_period}
494
graph_category network
495
graph_title DHCP Server
496
graph_info DHCP Server statistics for your Router on $host
497
Corrupted.label Corrupted packet recv
498
Corrupted.type DERIVE
499
Corrupted.min 0
500
DISCOVER.label DISCOVERs recv
501
DISCOVER.type DERIVE
502
DISCOVER.min 0
503
REQUEST.label REQUESTs recv
504
REQUEST.type DERIVE
505
REQUEST.min 0
506
DECLINE.label DECLINEs recv
507
DECLINE.type DERIVE
508
DECLINE.min 0
509
RELEASE.label RELEASEs recv
510
RELEASE.type DERIVE
511
RELEASE.min 0
512
INFORM.label INFORMs recv
513
INFORM.type DERIVE
514
INFORM.min 0
515
BOOTP.label Pure BOOTP REQUESTS
516
BOOTP.type DERIVE
517
BOOTP.min 0
518
Other.label Other message types
519
Other.type DERIVE
520
Other.min 0
521
OFFERs.label OFFERs sent
522
OFFERs.type DERIVE
523
OFFERs.min 0
524
ACKs.label ACKs sent
525
ACKs.type DERIVE
526
ACKs.min 0
527
NAKs.label NAKs sent
528
NAKs.type DERIVE
529
NAKs.min 0
530
failures.label Packet sent failures
531
failures.type DERIVE
532
failures.min 0
533
dropped.label Relay agent options dropped
534
dropped.type DERIVE
535
dropped.min 0
536
EOF
537
        }
538
    }
539
    elsif ( $mode eq 'dns' ) {
540
        if ( $ACCESS_MODE eq 'http' ) {
541
            print "# Can't graph $mode stats unless by 'telnet'\n";
542
            exit 1;
543
        }
544
        else {
545
            print <<EOF
546
graph_vlabel Packets/Queries per \${graph_period}
547
graph_category network
548
graph_title DNS Server
549
graph_info DNS Server statistics for your Router on $host
550
corrupted.label Corrupted packets received
551
corrupted.type DERIVE
552
corrupted.min 0
553
resolved.label Local questions resolved
554
resolved.type DERIVE
555
resolved.min 0
556
negative.label Local negative answers sent
557
negative.type DERIVE
558
negative.min 0
559
forwarded.label Total forwarded
560
forwarded.type DERIVE
561
forwarded.min 0
562
external.label External answers received
563
external.type DERIVE
564
external.min 0
565
spoofed.label Spoofed responses
566
spoofed.type DERIVE
567
spoofed.min 0
568
discard.label Forward table full, discard
569
discard.type DERIVE
570
discard.min 0
571
spurious.label Spurious answers
572
spurious.type DERIVE
573
spurious.min 0
574
unknown.label Unknown query types
575
unknown.type DERIVE
576
unknown.min 0
577
EOF
578
        }
579
    }
580
    elsif ( $mode eq 'igmphost' ) {
581
        if ( $ACCESS_MODE eq 'http' ) {
582
            print "# Can't graph $mode stats unless by 'telnet'\n";
583
            exit 1;
584
        }
585
        else {
586
            print <<EOF
587
graph_vlabel Messages/Queries per \${graph_period}
588 33e95e6f Lars Kruse
graph_category network
589 97a0f791 Paul Saunders
graph_title IGMP Host
590
graph_info IGMP Host statistics for your Router on $host
591
toosmall.label Too small
592
toosmall.info Too small IGMP messages received
593
toosmall.type DERIVE
594
toosmall.min 0
595
toolong.label Too long
596
toolong.info Too long IGMP messages received
597
toolong.type DERIVE
598
toolong.min 0
599
badchecksum.label Bad Checksum
600
badchecksum.info IGMP messages with bad checksum received
601
badchecksum.type DERIVE
602
badchecksum.min 0
603
badttl.label Bad TTL
604
badttl.info IGMP messages with bad TTL received
605
badttl.type DERIVE
606
badttl.min 0
607
norouter.label No Router
608
norouter.info IGMP messages with no router alert IP option received
609
norouter.type DERIVE
610
norouter.min 0
611
v1membershipq.label v1 membership queries
612
v1membershipq.info IGMPv1 membership queries received
613
v1membershipq.type DERIVE
614
v1membershipq.min 0
615
v2membershipq.label v2 membership queries
616
v2membershipq.info IGMPv2 membership queries received
617
v2membershipq.type DERIVE
618
v2membershipq.min 0
619
v3membershipq.label v3 membership queries
620
v3membershipq.info IGMPv3 membership queries received
621
v3membershipq.type DERIVE
622
v3membershipq.min 0
623
badqueries.label Bad queries
624
badqueries.info IGMP bad queries received
625
badqueries.type DERIVE
626
badqueries.min 0
627
failing.label Failing queries
628
failing.info IGMP failing membership queries
629
failing.type DERIVE
630
failing.min 0
631
reportsreceived.label v1/v2 membership reports
632
reportsreceived.info IGMPv1/v2 membership reports received
633
reportsreceived.type DERIVE
634
reportsreceived.min 0
635
invalidmembership.label v1/v2 invalid membership
636
invalidmembership.info IGMPv1/v2 invalid membership reports received
637
invalidmembership.type DERIVE
638
invalidmembership.min 0
639
receivedforour.label v1/v2 membership reports for us
640
receivedforour.info IGMPv1/v2 membership reports received for our groups
641
receivedforour.type DERIVE
642
receivedforour.min 0
643
reportstransmitted.label v1/v2 membership reports sent
644
reportstransmitted.info IGMPv1/v2 membership reports transmitted
645
reportstransmitted.type DERIVE
646
reportstransmitted.min 0
647
v3membershipr.label v3 membership reports sent
648
v3membershipr.info IGMPv3 membership reports transmitted
649
v3membershipr.type DERIVE
650
v3membershipr.min 0
651
EOF
652
        }
653
    }
654
    elsif ( $mode eq 'igmpproxy' ) {
655
        if ( $ACCESS_MODE eq 'http' ) {
656
            print "# Can't graph $mode stats unless by 'telnet'\n";
657
            exit 1;
658
        }
659
        else {
660
            print <<EOF
661
graph_vlabel Messages/Queries per \${graph_period}
662 33e95e6f Lars Kruse
graph_category network
663 97a0f791 Paul Saunders
graph_title IGMP Proxy
664
graph_info IGMP Proxy statistics for your Router on $host
665
tooshort.label Too short IGMP packets recv
666
tooshort.type DERIVE
667
tooshort.min 0
668
toolong.label Too long IGMP packets recv
669
toolong.type DERIVE
670
toolong.min 0
671
badchecksum.label IGMP packets with bad checksum recv
672
badchecksum.type DERIVE
673
badchecksum.min 0
674
badttl.label IGMP packets with bad ttl recv
675
badttl.type DERIVE
676
badttl.min 0
677
noroute.label IGMP packets with no route alert option recv
678
noroute.type DERIVE
679
noroute.min 0
680
v1queriesr.label IGMPv1 queries recv
681
v1queriesr.type DERIVE
682
v1queriesr.min 0
683
v2queriesr.label IGMPv2 queries recv
684
v2queriesr.type DERIVE
685
v2queriesr.min 0
686
v3queriesr.label IGMPv3 queries recv
687
v3queriesr.type DERIVE
688
v3queriesr.min 0
689
badqueries.label IGMP bad queries recv
690
badqueries.type DERIVE
691
badqueries.min 0
692
queriesfail.label IGMP queries fail
693
queriesfail.type DERIVE
694
queriesfail.min 0
695
v1reportsr.label IGMPv1 reports recv
696
v1reportsr.type DERIVE
697
v1reportsr.min 0
698
v2reportsr.label IGMPv2 reports recv
699
v2reportsr.type DERIVE
700
v2reportsr.min 0
701
v3reportsr.label IGMPv3 reports recv
702
v3reportsr.type DERIVE
703
v3reportsr.min 0
704
badreports.label IGMP bad reports recv
705
badreports.type DERIVE
706
badreports.min 0
707
igmpleavereports.label IGMP leave reports recv
708
igmpleavereports.type DERIVE
709
igmpleavereports.min 0
710
badleavereports.label IGMP bad leave reports recv
711
badleavereports.type DERIVE
712
badleavereports.min 0
713
v1queriess.label IGMPv1 queries sent
714
v1queriess.type DERIVE
715
v1queriess.min 0
716
v2queriess.label IGMPv2 queries sent
717
v2queriess.type DERIVE
718
v2queriess.min 0
719
v3queriess.label IGMPv3 queries sent
720
v3queriess.type DERIVE
721
v3queriess.min 0
722
election.label IGMP query election switch
723
election.type DERIVE
724
election.min 0
725
mrdsolicits.label MRD solitcits recv
726
mrdsolicits.type DERIVE
727
mrdsolicits.min 0
728
mrdbad.label MRD bad solicits recv
729
mrdbad.type DERIVE
730
mrdbad.min 0
731
mrdadvertise.label MRD advertise sent
732
mrdadvertise.type DERIVE
733
mrdadvertise.min 0
734
mrdterminate.label MRD terminate sent
735
mrdterminate.type DERIVE
736
mrdterminate.min 0
737
EOF
738
        }
739
    }
740
    elsif ( $mode eq 'protoip' ) {
741
        if ( $ACCESS_MODE eq 'http' ) {
742
            print "# Can't graph $mode stats unless by 'telnet'\n";
743
            exit 1;
744
        }
745
        else {
746
            print <<EOF
747
graph_vlabel Datagrams per \${graph_period}
748 33e95e6f Lars Kruse
graph_category network
749 97a0f791 Paul Saunders
graph_title IP protocol
750
graph_info IP protocol statistics for your Router on $host
751
herrors.label IP header errors
752
herrors.type DERIVE
753
herrors.min 0
754
forwarded.label Datagrams forwarded
755
forwarded.type DERIVE
756
forwarded.min 0
757
fwderrors.label Datagram forwarding errors
758
fwderrors.type DERIVE
759
fwderrors.min 0
760
reserrors.label Datagram forwarding resource errors
761
reserrors.type DERIVE
762
reserrors.min 0
763
noroute.label Datagram dropped due to no route
764
noroute.type DERIVE
765
noroute.min 0
766
fragments.label Total fragments received
767
fragments.type DERIVE
768
fragments.min 0
769
droppedfrags.label Fragments dropped due to resources or timeouts
770
droppedfrags.type DERIVE
771
droppedfrags.min 0
772
reassembled.label Datagrams reassembled
773
reassembled.type DERIVE
774
reassembled.min 0
775
hostrec.label Host datagrams received
776
hostrec.type DERIVE
777
hostrec.min 0
778
hostfwd.label Host datagrams forwarded
779
hostfwd.type DERIVE
780
hostfwd.min 0
781
hostdrop.label Host datagrams dropped due to unknown proto
782
hostdrop.type DERIVE
783
hostdrop.min 0
784
fragged.label Datagrams fragmented successfully
785
fragged.type DERIVE
786
fragged.min 0
787
fragerrs.label Datagram fragmentation errors
788
fragerrs.type DERIVE
789
fragerrs.min 0
790
totfrags.label Total Datagram fragments created successfully
791
totfrags.type DERIVE
792
totfrags.min 0
793
EOF
794
        }
795
    }
796
    elsif ( $mode eq 'prototcp' ) {
797
        if ( $ACCESS_MODE eq 'http' ) {
798
            print "# Can't graph $mode stats unless by 'telnet'\n";
799
            exit 1;
800
        }
801
        else {
802
            print <<EOF
803 8713eb37 Lars Kruse
graph_vlabel Packets/Connections per \${graph_period}
804 33e95e6f Lars Kruse
graph_category network
805 97a0f791 Paul Saunders
graph_title TCP protocol
806
graph_info TCP protocol statistics for your Router on $host
807
attempts.label TCP connection attempts
808
attempts.type DERIVE
809
attempts.min 0
810
accepts.label TCP connection accepts
811
accepts.type DERIVE
812
accepts.min 0
813
drops.label TCP connection drops
814
drops.type DERIVE
815
drops.min 0
816
established.label TCP connections established
817
established.type GAUGE
818 fba800ae Veres Lajos
received.label TCP packets received
819 97a0f791 Paul Saunders
received.type DERIVE
820
received.min 0
821
transmitted.label TCP packets transmitted
822
transmitted.type DERIVE
823
transmitted.min 0
824
retransmitted.label TCP packets retransmitted
825
retransmitted.type DERIVE
826
retransmitted.min 0
827
errors.label TCP packet errors
828
errors.type DERIVE
829
errors.min 0
830
EOF
831
        }
832
    }
833
    elsif ( $mode eq 'protoudp' ) {
834
        if ( $ACCESS_MODE eq 'http' ) {
835
            print "# Can't graph $mode stats unless by 'telnet'\n";
836
            exit 1;
837
        }
838
        else {
839
            print <<EOF
840
graph_vlabel Datagrams per \${graph_period}
841 33e95e6f Lars Kruse
graph_category network
842 97a0f791 Paul Saunders
graph_title UDP protocol
843
graph_info UDP protocol statistics for your Router on $host
844
received.label Total UDP datagrams received
845
received.type DERIVE
846
received.min 0
847
transmitted.label Total UDP datagrams transmitted
848
transmitted.type DERIVE
849
transmitted.min 0
850
dropped.label UDP datagrams dropped due to no port
851
dropped.type DERIVE
852
dropped.min 0
853
errors.label UDP datagram errors
854
errors.type DERIVE
855
errors.min 0
856
EOF
857
        }
858
    }
859
    elsif ( $mode eq 'protoicmp' ) {
860
        if ( $ACCESS_MODE eq 'http' ) {
861
            print "# Can't graph $mode stats unless by 'telnet'\n";
862
            exit 1;
863
        }
864
        else {
865
            print <<EOF
866
graph_vlabel Datagrams recv (-) / sent (+) per \${graph_period}
867 33e95e6f Lars Kruse
graph_category network
868 97a0f791 Paul Saunders
graph_title ICMP protocol
869
graph_info ICMP protocol statistics for your Router on $host
870
errorsr.label Packet errors
871
errorsr.type DERIVE
872
errorsr.min 0
873
errorsr.graph no
874
errorss.label Packet errors
875
errorss.type DERIVE
876
errorss.min 0
877
errorss.negative errorsr
878
unreachabler.label Dest. unreach.
879
unreachabler.type DERIVE
880
unreachabler.min 0
881
unreachabler.graph no
882
unreachables.label Dest. unreach.
883
unreachables.type DERIVE
884
unreachables.min 0
885
unreachables.negative unreachabler
886
timeexceedr.label Time exceeded
887
timeexceedr.type DERIVE
888
timeexceedr.min 0
889
timeexceedr.graph no
890
timeexceeds.label Time exceeded
891
timeexceeds.type DERIVE
892
timeexceeds.min 0
893
timeexceeds.negative timeexceedr
894
paramr.label Param problem
895
paramr.type DERIVE
896
paramr.min 0
897
paramr.graph no
898
params.label Param problem
899
params.type DERIVE
900
params.min 0
901
params.negative paramr
902
quenchr.label Source quench
903
quenchr.type DERIVE
904
quenchr.min 0
905
quenchr.graph no
906
quenchs.label Source quench
907
quenchs.type DERIVE
908
quenchs.min 0
909
quenchs.negative quenchr
910
redirectr.label Redirect
911
redirectr.type DERIVE
912
redirectr.min 0
913
redirectr.graph no
914
redirects.label Redirect
915
redirects.type DERIVE
916
redirects.min 0
917
redirects.negative redirectr
918
echor.label Echo
919
echor.type DERIVE
920
echor.min 0
921
echor.graph no
922
echos.label Echo
923
echos.type DERIVE
924
echos.min 0
925
echos.negative echor
926
echorepr.label Echo reply
927
echorepr.type DERIVE
928
echorepr.min 0
929
echorepr.graph no
930
echoreps.label Echo reply
931
echoreps.type DERIVE
932
echoreps.min 0
933
echoreps.negative echorepr
934
timestampr.label Timestamp req.
935
timestampr.type DERIVE
936
timestampr.min 0
937
timestampr.graph no
938
timestamps.label Timestamp req.
939
timestamps.type DERIVE
940
timestamps.min 0
941
timestamps.negative timestampr
942
timestamprepr.label Timestamp reply
943
timestamprepr.type DERIVE
944
timestamprepr.min 0
945
timestamprepr.graph no
946
timestampreps.label Timestamp reply
947
timestampreps.type DERIVE
948
timestampreps.min 0
949
timestampreps.negative timestamprepr
950
maskr.label Mask request
951
maskr.type DERIVE
952
maskr.min 0
953
maskr.graph no
954
masks.label Mask request
955
masks.type DERIVE
956
masks.min 0
957
masks.negative maskr
958
maskrepr.label Mask reply
959
maskrepr.type DERIVE
960
maskrepr.min 0
961
maskrepr.graph no
962
maskreps.label Mask reply
963
maskreps.type DERIVE
964
maskreps.min 0
965
maskreps.negative maskrepr
966
EOF
967
        }
968
    }
969
970
    else {
971
        print "Don't know how to graph $mode\n";
972
        exit 1;
973
    }
974
    exit 0;
975 a9575c11 Paul Saunders
}
976
977
sub Uptime2Days {
978 97a0f791 Paul Saunders
    my $uptime = shift;
979
    my $days;
980
    if ( $uptime =~ m{(\d+) days?, (\d+):(\d+):(\d+)}i ) {
981
        $days =
982
          int($1) + ( int($2) / 24 ) + ( int($3) / 1440 ) + ( int($4) / 86400 );
983
    }
984
    else {
985
        $days = 'U';
986
    }
987
    print "# Uptime of '$uptime' becomes $days days\n" if $MUNIN_DEBUG;
988
    return $days;
989 a9575c11 Paul Saunders
}
990
991
# Fetch
992 97a0f791 Paul Saunders
if ( $ACCESS_MODE eq 'http' ) {
993
    my $mech = WWW::Mechanize->new();
994
    $mech->credentials( $USER, $PASS );
995
    if ( $mode eq 'bandwidth' or $mode eq 'power' or $mode eq 'errors' ) {
996
        print "# Fetching http://$host/cgi/b/dsl/dt/?be=0&l0=1&l1=0\n"
997
          if $MUNIN_DEBUG;
998
        $mech->get("http://$host/cgi/b/dsl/dt/?be=0&l0=1&l1=0");
999
    }
1000
    elsif ( $mode eq 'uptime' ) {
1001
        print "# Fetching http://$host/cgi/b/bb/?be=0&l0=2&l1=-1\n"
1002
          if $MUNIN_DEBUG;
1003
        $mech->get("http://$host/cgi/b/bb/?be=0&l0=2&l1=-1");
1004
    }
1005
    if ( $mech->success() ) {
1006
        my $page = $mech->content;
1007
        if ( $mode eq 'bandwidth' ) {
1008
            $page =~ m{Bandwidth \(Up/Down\).*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1009
            my $upBW   = $1;
1010
            my $downBW = $2;
1011
            $upBW   =~ s/,//;
1012
            $downBW =~ s/,//;
1013
            print "down.value $downBW\n";
1014
            print "up.value $upBW\n";
1015
        }
1016
        elsif ( $mode eq 'power' ) {
1017
            $page =~ m{Output Power.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1018
            my $upOUT   = $1;
1019
            my $downOUT = $2;
1020
            $upOUT   =~ s/,//;
1021
            $downOUT =~ s/,//;
1022
1023
            $page =~ m{Line Attenuation.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1024
            my $upLINE   = $1;
1025
            my $downLINE = $2;
1026
            $upLINE   =~ s/,//;
1027
            $downLINE =~ s/,//;
1028
1029
            $page =~ m{SN Margin.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1030
            my $upSN   = $1;
1031
            my $downSN = $2;
1032
            $upSN   =~ s/,//;
1033
            $downSN =~ s/,//;
1034
            print "downout.value $downOUT\n";
1035
            print "upout.value $upOUT\n";
1036
            print "downline.value $downLINE\n";
1037
            print "upline.value $upLINE\n";
1038
            print "downsn.value $downSN\n";
1039
            print "upsn.value $upSN\n";
1040
        }
1041
        elsif ( $mode eq 'errors' ) {
1042
            $page =~ m{FEC Errors.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1043
            my $upFEC   = $1;
1044
            my $downFEC = $2;
1045
            $upFEC   =~ s/,//g;
1046
            $downFEC =~ s/,//g;
1047
1048
            $page =~ m{CRC Errors.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1049
            my $upCRC   = $1;
1050
            my $downCRC = $2;
1051
            $upCRC   =~ s/,//g;
1052
            $downCRC =~ s/,//g;
1053
1054
            $page =~ m{HEC Errors.*<td[^>]+>([\d,\.]+) / ([\d,\.]+)};
1055
            my $upHEC   = $1;
1056
            my $downHEC = $2;
1057
            $upHEC   =~ s/,//g;
1058
            $downHEC =~ s/,//g;
1059
1060
            print "downFEC.value $downFEC\n";
1061
            print "upFEC.value $upFEC\n";
1062
            print "downCRC.value $downCRC\n";
1063
            print "upCRC.value $upCRC\n";
1064
            print "downHEC.value $downHEC\n";
1065
            print "upHEC.value $upHEC\n";
1066
        }
1067
        elsif ( $mode eq 'uptime' ) {
1068
            my ( $DSLRaw, $DSLUp, $iNetRaw, $iNetUp, $BoxRaw, $BoxUp );
1069
            if ( $page =~ m{Uptime:.*<td[^>]+>(.*)</td>}g ) {
1070
                $DSLRaw = $1;
1071
                $DSLUp  = Uptime2Days($DSLRaw);
1072
            }
1073
            else {
1074
                $DSLUp = 'U';
1075
            }
1076
            if ( $page =~ m{Uptime:.*<td[^>]+>(.*)</td>}g ) {
1077
                $iNetRaw = $1;
1078
                $iNetUp  = Uptime2Days($iNetRaw);
1079
            }
1080
            else {
1081
                $iNetUp = 'U';
1082
            }
1083
1084
            print "# Fetching http://$host/cgi/b/cfg/ov/?be=0&l0=1&l1=1\n"
1085
              if $MUNIN_DEBUG;
1086
            $mech->get("http://$host/cgi/b/cfg/ov/?be=0&l0=1&l1=1");
1087
            $page = $mech->content;
1088
            if ( $page =~ m{Time Since Power-on:.*<td[^>]+>(.*)</td>} ) {
1089
                $BoxRaw = $1;
1090
                $BoxUp  = Uptime2Days($BoxRaw);
1091
            }
1092
            else {
1093
                $BoxUp = 'U';
1094
            }
1095
1096
            print "Box.value $BoxUp\n";
1097
            print "Box.extinfo $BoxRaw\n";
1098
            print "DSL.value $DSLUp\n";
1099
            print "DSL.extinfo $DSLRaw\n";
1100
            print "iNet.value $iNetUp\n";
1101
            print "iNet.extinfo $iNetRaw\n";
1102
        }
1103
        else {
1104
            print "Don't know how to graph $mode\n";
1105
            exit 1;
1106
        }
1107
        exit 0;
1108
    }
1109 a9575c11 Paul Saunders
}
1110 97a0f791 Paul Saunders
else {
1111
    our $telnet;
1112
1113
    sub TelnetError {
1114
        my $errmsg = shift;
1115 6f39dc45 Paul Saunders
        my %parts  = (
1116
            'atm' => [qw(RXCells RxErrors RxOctets TxCells TxErrors TxOctets)],
1117
            'bandwidth' => [qw(down downrate up uprate)],
1118
            'conntrack' =>
1119
              [qw(Active closing expected halfopen ICMP idle loose mcast non TCP TCPclosing TCPestablished TCPopen UDP)],
1120
            'dhcpclient' =>
1121
              [qw(ACKs Corrupted DECLINEs DISCOVERs failures INFORMs NAKs OFFERs Other RELEASEs REPLIES REQUESTs)],
1122
            'dhcprelay' =>
1123
              [qw(badc bogusg bogusr clientp corrupta missinga missingc packets serverp)],
1124
            'dhcpserver' =>
1125
              [qw(ACKs BOOTP Corrupted DECLINE DISCOVER dropped failures INFORM NAKs OFFERs Other RELEASE REQUEST)],
1126
            'dns' =>
1127
              [qw(corrupted discard external forwarded negative resolved spoofed spurious unknown)],
1128
            'errors' => [qw(downCRC downFEC downHEC upCRC upFEC upHEC)],
1129
            'firewall' =>
1130
              [qw(DroppedForward DroppedInput DroppedOutput ParsedForward ParsedInput ParsedOutput)],
1131
            'ids' => [qw(Active Collisions New Recycled Searches)],
1132
            'igmphost' =>
1133
              [qw(badchecksum badqueries badttl failing invalidmembership norouter receivedforour reportsreceived reportstransmitted toolong toosmall v1membershipq v2membershipq v3membershipq v3membershipr)],
1134
            'igmpproxy' =>
1135
              [qw(badchecksum badleavereports badqueries badreports badttl election igmpleavereports mrdadvertise mrdbad mrdsolicits mrdterminate noroute queriesfail toolong tooshort v1queriesr v1queriess v1reportsr v2queriesr v2queriess v2reportsr v3queriesr v3queriess v3reportsr)],
1136
            'power' => [qw(downline downout downsn upline upout upsn)],
1137
            'protoicmp' =>
1138
              [qw(echor echorepr echoreps echos errorsr errorss maskr maskrepr maskreps masks paramr params quenchr quenchs redirectr redirects timeexceedr timeexceeds timestampr timestamprepr timestampreps timestamps unreachabler unreachables)],
1139
            'protoip' =>
1140
              [qw(droppedfrags forwarded fragerrs fragged fragments fwderrors herrors hostdrop hostfwd hostrec noroute reassembled reserrors totfrags)],
1141
            'prototcp' =>
1142
              [qw(accepts attempts drops errors established received retransmitted transmitted)],
1143
            'protoudp' => [qw(dropped errors received transmitted)],
1144
            'uptime'   => [qw(Box DSL iNet)]
1145
        );
1146
1147
        foreach ( @{$parts{$mode}} ) {
1148 97a0f791 Paul Saunders
            print "$_.value U\n";
1149
            print "$_.extinfo $errmsg\n";
1150
        }
1151
        print "# Sending \"exit\"\n" if $MUNIN_DEBUG;
1152
        if ( defined $telnet ) {
1153 6f39dc45 Paul Saunders
            $telnet->errmode('return');
1154 97a0f791 Paul Saunders
            $telnet->print('exit');
1155
            $telnet->close;
1156
        }
1157
        exit 1;
1158
    }
1159
1160
    print "# Connecting to $host:23...\n" if $MUNIN_DEBUG;
1161
    $telnet = new Net::Telnet(
1162
        Host    => $host,
1163
        Prompt  => '/{.*}.*=>$/',
1164 6f39dc45 Paul Saunders
        ErrMode => \&TelnetError,
1165
        Timeout => 10
1166 97a0f791 Paul Saunders
    );
1167
1168
    print "# Logging in...\n" if $MUNIN_DEBUG;
1169
    $telnet->login(
1170
        Name     => $USER,
1171
        Password => $PASS
1172
    );
1173 a9575c11 Paul Saunders
1174 97a0f791 Paul Saunders
    if ( $mode eq 'bandwidth' ) {
1175
        print "# Sending \"xdsl info expand enabled\"\n" if $MUNIN_DEBUG;
1176
        my @lines = $telnet->cmd( String => 'xdsl info expand enabled' );
1177
        foreach (@lines) {
1178
            if (/Payload rate .*:\s+(\d+)\s+(\d+)/) {
1179
                print "down.value $1\n";
1180
                print "up.value $2\n";
1181
            }
1182
        }
1183
        print "# Sending \"ip iflist\"\n" if $MUNIN_DEBUG;
1184
        @lines = $telnet->cmd( String => 'ip iflist' );
1185
        foreach (@lines) {
1186
            if (/.*wan\s+\d+\s+(\d+)\s+(\d+)/) {
1187
                print "downrate.value $1\n";
1188
                print "uprate.value $2\n";
1189
            }
1190
        }
1191
    }
1192
    elsif ( $mode eq 'power' ) {
1193
        print "# Sending \"xdsl info expand enabled\"\n" if $MUNIN_DEBUG;
1194
        my @lines = $telnet->cmd( String => 'xdsl info expand enabled' );
1195
        foreach (@lines) {
1196
            if (/Attenuation.*:\s+([0-9\.]+)\s+([0-9\.]+)/) {
1197
                print "downline.value $1\n";
1198
                print "upline.value $2\n";
1199
            }
1200
            elsif (/Margins.*:\s+([0-9\.]+)\s+([0-9\.]+)/) {
1201
                print "downsn.value $1\n";
1202
                print "upsn.value $2\n";
1203
            }
1204
            elsif (/Output power.*:\s+([0-9\.]+)\s+([0-9\.]+)/) {
1205
                print "downout.value $1\n";
1206
                print "upout.value $2\n";
1207
            }
1208
        }
1209
    }
1210
    elsif ( $mode eq 'errors' ) {
1211
        print "# Sending \"xdsl info expand enabled\"\n" if $MUNIN_DEBUG;
1212
        my @lines = $telnet->cmd( String => 'xdsl info expand enabled' );
1213
        my $state = 0;
1214
        foreach (@lines) {
1215
            if (/G.997.1 Statistics \(Current\)/) {
1216
                $state = 1;
1217
            }
1218
            elsif (/G.997.1 Statistics \(last/) {
1219
                $state = 0;
1220
            }
1221
            if ( $state == 1 and /Code Violation.*:\s+(\d+)/ ) {
1222
                print "downCRC.value $1\n";
1223
                print "upCRC.value U\n";
1224
            }
1225
            elsif ( $state == 1 and /FEC.*:\s+(\d+)/ ) {
1226
                print "downFEC.value $1\n";
1227
                print "upFEC.value U\n";
1228
            }
1229
            elsif ( $state == 1 and /HEC violation.*:\s+(\d+)\s+(\d+)/ ) {
1230
                print "downHEC.value $1\n";
1231
                print "upHEC.value $2\n";
1232
            }
1233
        }
1234
    }
1235
    elsif ( $mode eq 'uptime' ) {
1236
        my ( $DSLRaw, $DSLUp, $iNetRaw, $iNetUp, $BoxRaw, $BoxUp );
1237
        $DSLUp  = 'U';
1238
        $iNetUp = 'U';
1239
        $BoxUp  = 'U';
1240
        print "# Sending \"xdsl info expand enabled\"\n" if $MUNIN_DEBUG;
1241
        my @lines = $telnet->cmd( String => 'xdsl info expand enabled' );
1242
        foreach (@lines) {
1243
            if (/Up time.*:\s+(.*)$/) {
1244
                $DSLRaw = $1;
1245
                $DSLUp  = Uptime2Days($DSLRaw);
1246
            }
1247
        }
1248
        print "# Sending \"system settime\"\n" if $MUNIN_DEBUG;
1249
        @lines = $telnet->cmd( String => 'system settime' );
1250
        foreach (@lines) {
1251
            if (/uptime = (.*)$/) {
1252
                $BoxRaw = $1;
1253
                $BoxUp  = Uptime2Days($BoxRaw);
1254
            }
1255
        }
1256
1257
        print "# Sending \"ppp iflist\"\n" if $MUNIN_DEBUG;
1258
        @lines = $telnet->cmd( String => 'ppp iflist' );
1259
        foreach (@lines) {
1260
            if (/\[(\d+:\d+:\d+)\]/) {
1261
                $iNetRaw = $1;
1262
                $iNetUp  = Uptime2Days("0 days, $iNetRaw");
1263
            }
1264
        }
1265
        print "Box.value $BoxUp\n";
1266
        print "Box.extinfo $BoxRaw\n";
1267
        print "DSL.value $DSLUp\n";
1268
        print "DSL.extinfo $DSLRaw\n";
1269
        print "iNet.value $iNetUp\n";
1270
        print "iNet.extinfo $iNetRaw\n";
1271
    }
1272
    elsif ( $mode eq 'firewall' ) {
1273
        my ( $PI, $PO, $PF, $DI, $DO, $DF ) = ( 'U', 'U', 'U', 'U', 'U', 'U' );
1274
        print "# Sending \"firewall debug stats\"\n" if $MUNIN_DEBUG;
1275
        my @lines = $telnet->cmd( String => 'firewall debug stats' );
1276
        foreach (@lines) {
1277
            $PI = $1 if (/Packets parsed in hook sink\s+:\s+(\d+)/);
1278
            $PO = $1 if (/Packets parsed in hook source\s+:\s+(\d+)/);
1279
            $PF = $1 if (/Packets parsed in hook forward\s+:\s+(\d+)/);
1280
            $DI = $1 if (/Packets dropped in hook sink\s+:\s+(\d+)/);
1281
            $DO = $1 if (/Packets dropped in hook source\s+:\s+(\d+)/);
1282
            $DF = $1 if (/Packets dropped in hook forward\s+:\s+(\d+)/);
1283
        }
1284
        print "ParsedInput.value $PI\n";
1285
        print "ParsedOutput.value $PO\n";
1286
        print "ParsedForward.value $PF\n";
1287
        print "DroppedInput.value $DI\n";
1288
        print "DroppedOutput.value $DO\n";
1289
        print "DroppedForward.value $DF\n";
1290
    }
1291
    elsif ( $mode eq 'ids' ) {
1292
        my ( $Active, $Recycled, $Searches, $New, $Collisions ) =
1293
          ( 'U', 'U', 'U', 'U', 'U' );
1294
        print "# Sending \"ids pattern stats\"\n" if $MUNIN_DEBUG;
1295
        my @lines = $telnet->cmd( String => 'ids pattern stats' );
1296
        foreach (@lines) {
1297
            $Active     = $1 if (/number of active patterns\s+:\s+(\d+)/);
1298
            $Recycled   = $1 if (/number of recycled patterns\s+:\s+(\d+)/);
1299
            $Searches   = $1 if (/number of pattern searches\s+:\s+(\d+)/);
1300
            $New        = $1 if (/number of new patterns\s+:\s+(\d+)/);
1301
            $Collisions = $1 if (/number of hash collisions\s+:\s+(\d+)/);
1302
        }
1303
        print "Active.value $Active\n";
1304
        print "Recycled.value $Recycled\n";
1305
        print "Searches.value $Searches\n";
1306
        print "New.value $New\n";
1307
        print "Collisions.value $Collisions\n";
1308
    }
1309
    elsif ( $mode eq 'atm' ) {
1310
        my ( $RxO, $RxC, $RxE, $TxO, $TxC, $TxE ) =
1311
          ( 'U', 'U', 'U', 'U', 'U', 'U' );
1312
        print "# Sending \"atm debug gstats\"\n" if $MUNIN_DEBUG;
1313
        my @lines = $telnet->cmd( String => 'atm debug gstats' );
1314
        foreach (@lines) {
1315
            $RxO = $1 if (/received octets\s+=\s+(\d+)/);
1316
            $RxC = $1 if (/received cells\s+=\s+(\d+)/);
1317
            $RxE = $1 if (/errors on the input\s+=\s+(\d+)/);
1318
            $TxO = $1 if (/transmitted octets\s+=\s+(\d+)/);
1319
            $TxC = $1 if (/transmitted cells\s+=\s+(\d+)/);
1320
            $TxE = $1 if (/errors on output\s+=\s+(\d+)/);
1321
        }
1322
        print "RxOctets.value $RxO\n";
1323
        print "RxCells.value $RxC\n";
1324
        print "RxErrors.value $RxE\n";
1325
        print "TxOctets.value $TxO\n";
1326
        print "TxCells.value $TxC\n";
1327
        print "TxErrors.value $TxE\n";
1328
    }
1329
    elsif ( $mode eq 'conntrack' ) {
1330
        print "# Sending \"connection stats\"\n" if $MUNIN_DEBUG;
1331
        my @lines = $telnet->cmd( String => 'connection stats' );
1332
        foreach (@lines) {
1333
            if (/^Number of (.*) connections\s+:\s+(\d+)/) {
1334
                my $field = $1;
1335
                my $value = $2;
1336
                $field =~ s/\s+//g;
1337
                $field = 'non' if ( $field eq "nonTCP/UDP/ICMP" );
1338
                print "$field.value $value\n";
1339
            }
1340
        }
1341
    }
1342
    elsif ( $mode eq 'dhcpclient' ) {
1343
        print "# Sending \"dhcp client debug stats\"\n" if $MUNIN_DEBUG;
1344
        my @lines = $telnet->cmd( String => 'dhcp client debug stats' );
1345
        foreach (@lines) {
1346
            chomp;
1347
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1348
            if (   /(Corrupted) packet recv\s+:\s+(\d+)/
1349
                or /(\S+)\s+recv\s+:\s+(\d+)/
1350
                or /(\S+)\s+sent\s+:\s+(\d+)/
1351
                or /Pure BOOTP (REPLIES)\s+:\s+(\d+)/
1352
                or /(Other) message types\s+:\s+(\d+)/
1353
                or /Packet\s+sent (failures)\s+:\s+(\d+)/ )
1354
            {
1355
                print "$1.value $2\n";
1356
            }
1357
        }
1358
    }
1359
    elsif ( $mode eq 'dhcprelay' ) {
1360
        print "# Sending \"dhcp relay debug stats\"\n" if $MUNIN_DEBUG;
1361
        my @lines = $telnet->cmd( String => 'dhcp relay debug stats' );
1362
        foreach (@lines) {
1363
            if (/(\S+\s+\S).*:\s+(\d+)/) {
1364
                my $field = $1;
1365
                my $value = $2;
1366
                $field =~ s/\s+//g;
1367
                $field = lc $field;
1368
                print "$field.value $value\n";
1369
            }
1370
        }
1371
    }
1372
    elsif ( $mode eq 'dhcpserver' ) {
1373
        print "# Sending \"dhcp server debug stats\"\n" if $MUNIN_DEBUG;
1374
        my @lines = $telnet->cmd( String => 'dhcp server debug stats' );
1375
        foreach (@lines) {
1376
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1377
            if (   /(Corrupted) packet recv\s+:\s+(\d+)/
1378
                or /^(\S+)\s+:\s+(\d+)/
1379
                or /Pure (BOOTP) REQUESTS\s+:\s+(\d+)/
1380
                or /(Other) message types\s+:\s+(\d+)/
1381
                or /(\S+) sent\s+:\s+(\d+)/
1382
                or /Packet sent (failures)\s+:\s+(\d+)/
1383
                or /Relay agent options (dropped)\s+:\s+(\d+)/ )
1384
            {
1385
                print "$1.value $2\n";
1386
            }
1387
        }
1388
    }
1389
    elsif ( $mode eq 'dns' ) {
1390
        print "# Sending \"dns server debug stats\"\n" if $MUNIN_DEBUG;
1391
        my @lines = $telnet->cmd( String => 'dns server debug stats' );
1392
        my @kw =
1393
          qw(corrupted resolved negative forwarded external spoofed discard spurious unknown);
1394
        foreach (@lines) {
1395
            foreach my $kw (@kw) {
1396
                if (/$kw.*:\s+(\d+)/i) {
1397
                    print "$kw.value $1\n";
1398
                }
1399
            }
1400
        }
1401
    }
1402
    elsif ( $mode eq 'igmphost' ) {
1403
        print "# Sending \"igmp host debug stats\"\n" if $MUNIN_DEBUG;
1404
        my @lines = $telnet->cmd( String => 'igmp host debug stats' );
1405
        my @kw = qw(toosmall toolong badchecksum badttl norouter
1406
          v1membershipq v2membershipq v3membershipq
1407
          badqueries failing reportsreceived
1408
          invalidmembership receivedforour
1409
          reportstransmitted v3membershipr);
1410
        foreach (@lines) {
1411
            chomp;
1412
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1413
            if (/(.*)\s+:\s+(\d+)/) {
1414
                my $field = lc $1;
1415
                my $value = $2;
1416
                $field =~ s/\s+//g;
1417
                foreach my $kw (@kw) {
1418
                    if ( $field =~ /$kw/ ) {
1419
                        print "$kw.value $value\n";
1420
                    }
1421
                }
1422
            }
1423
        }
1424
    }
1425
    elsif ( $mode eq 'igmpproxy' ) {
1426
        print "# Sending \"igmp proxy debug stats\"\n" if $MUNIN_DEBUG;
1427
        my @lines = $telnet->cmd( String => 'igmp proxy debug stats' );
1428
        my @kw = qw(tooshort toolong badchecksum badttl noroute
1429
          v1queriesr v2queriesr v3queriesr badqueries
1430
          queriesfail v1reportsr v2reportsr v3reportsr
1431
          badreports igmpleavereports badleavereports
1432
          v1queriess v2queriess v3queriess election
1433
          mrdsolicits mrdbad mrdadvertise mrdterminate);
1434
1435
        foreach (@lines) {
1436
            chomp;
1437
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1438
            if (/(.*)\s*:\s+(\d+)/) {
1439
                my $field = lc $1;
1440
                my $value = $2;
1441
                $field =~ s/\s+//g;
1442
                foreach my $kw (@kw) {
1443
                    if ( $field =~ /$kw/ ) {
1444
                        print "$kw.value $value\n";
1445
                    }
1446
                }
1447
            }
1448
        }
1449
    }
1450
    elsif ( $mode eq 'protoip' ) {
1451
        print "# Sending \"ip debug stats proto=ip\"\n" if $MUNIN_DEBUG;
1452
        my @lines = $telnet->cmd( String => 'ip debug stats proto=ip' );
1453
        my %kws = (
1454
            herrors      => 'IP header errors',
1455
            forwarded    => 'Datagrams forwarded',
1456
            fwderrors    => 'Datagram forwarding errors',
1457
            reserrors    => 'Datagram forwarding resource errors',
1458
            noroute      => 'Datagram dropped due to no route',
1459
            fragments    => 'Total Fragments received',
1460
            droppedfrags => 'Fragments dropped due to resources or timeouts',
1461
            reassembled  => 'Datagrams reassembled',
1462
            hostrec      => 'Host datagrams received',
1463
            hostfwd      => 'Host datagrams forwarded',
1464
            hostdrop     => 'Host datagrams dropped due to unknown proto',
1465
            fragged      => 'Datagrams fragmented successfully',
1466
            fragerrs     => 'Datagram fragmentation errors',
1467
            totfrags     => 'Total Datagram fragments created successfully'
1468
        );
1469
        foreach (@lines) {
1470
            chomp;
1471
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1472
            if (/(.*)\s+:\s+(\d+)/) {
1473
                my $field = $1;
1474
                my $value = $2;
1475
                foreach my $kw ( keys %kws ) {
1476
                    if ( $field =~ /$kws{$kw}/ ) {
1477
                        print "$kw.value $value\n";
1478
                    }
1479
                }
1480
            }
1481
        }
1482
    }
1483
    elsif ( $mode eq 'prototcp' ) {
1484
        print "# Sending \"ip debug stats proto=tcp\"\n" if $MUNIN_DEBUG;
1485
        my @lines = $telnet->cmd( String => 'ip debug stats proto=tcp' );
1486
        my @kw = qw(attempts accepts drops established received
1487
          transmitted retransmitted errors);
1488
        foreach (@lines) {
1489
            chomp;
1490
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1491
            foreach my $kw (@kw) {
1492
                if (/\b$kw\b.*:\s+(\d+)/) {
1493
                    print "$kw.value $1\n";
1494
                }
1495
            }
1496
        }
1497
    }
1498
    elsif ( $mode eq 'protoudp' ) {
1499
        print "# Sending \"ip debug stats proto=udp\"\n" if $MUNIN_DEBUG;
1500
        my @lines = $telnet->cmd( String => 'ip debug stats proto=udp' );
1501
        my @kw = qw(received transmitted dropped errors);
1502
        foreach (@lines) {
1503
            foreach my $kw (@kw) {
1504
                if (/$kw.*:\s+(\d+)/) {
1505
                    print "$kw.value $1\n";
1506
                }
1507
            }
1508
        }
1509
    }
1510
    elsif ( $mode eq 'protoicmp' ) {
1511
        print "# Sending \"ip debug stats proto=icmp\"\n" if $MUNIN_DEBUG;
1512
        my @lines = $telnet->cmd( String => 'ip debug stats proto=icmp' );
1513
        my %kws = (
1514
            errors       => 'packet errors',
1515
            unreachable  => 'destination unreachable',
1516
            timeexceed   => 'time exceeded',
1517
            param        => 'param problem',
1518
            quench       => 'source quench',
1519
            redirect     => 'redirect',
1520
            echo         => 'echo',
1521
            echorep      => 'echo reply',
1522
            timestamp    => 'timestamp request',
1523
            timestamprep => 'timestamp reply',
1524
            mask         => 'mask request',
1525
            maskrep      => 'mask reply'
1526
        );
1527
        my $sentrecv = 'U';
1528
        foreach (@lines) {
1529
            chomp;
1530
            print "# Got '$_'\n" if $MUNIN_DEBUG;
1531
            if (/Total ICMP datagrams received/) {
1532
                print "# SentRecv => r\n" if $MUNIN_DEBUG;
1533
                $sentrecv = 'r';
1534
                next;
1535
            }
1536
            if (/Total ICMP datagrams transmitted/) {
1537
                print "# SentRecv => s\n" if $MUNIN_DEBUG;
1538
                $sentrecv = 's';
1539
                next;
1540
            }
1541
            if (/ICMP\s+(.*)\s+:\s+(\d+)/) {
1542
                my $field = $1;
1543
                my $value = $2;
1544
                foreach my $kw ( keys %kws ) {
1545
                    if ( $field =~ /^\s*$kws{$kw}\s*$/ ) {
1546
                        print "${kw}${sentrecv}.value $value\n";
1547
                    }
1548
                }
1549
            }
1550
        }
1551
    }
1552
1553
    print "# Sending \"exit\"\n" if $MUNIN_DEBUG;
1554
    $telnet->print('exit');
1555
    $telnet->close;
1556
    exit 0;
1557
}
1558 a9575c11 Paul Saunders