#!/usr/bin/perl -W # # OrinocoTOP v0x01a # Licensed under GPL # # Programik do wyciagania ciekawych informacji z ORINOCO AP2000 ;) # Mozliwe ze dziala takze na AP600 oraz na AP2500 - nie testowane # Zainspirowany outputem z snmpwalk oraz lektura orinoco.mib :) # Firmware, na ktorym sprawdzalem: 2.4.3 oraz 2.4.5 # # 0. To jest w zasadzie wersja Alfa/Beta... # 1. Kod jest bardzo brzydko napisany i praktycznie nieczytelny ;) # 2. Mialo byc napisane przy uzyciu SNMP_Session, ale niestety czas # naglil i nie mialem okazji zrobic tego "tak jakbym chcial" (tm) # 3. Jesli Orinoco zwroci przez SNMP adres "0.0.0.0" jako klienta # ten programik potraktuje takiego klienta jako "WDS" co nie do # konca jest prawda... - wlasciwie to wcale nie jest ;) # 4. Prosilbym o informowanie mnie o wszystkich bledach/uwagach/opiniach/etc # na adres email podany na koncu # 5. Proxim spier.... implementacje SNMP i czesc danych jest niepoprawnie # wyswietlana ( SNR i transfery zwlascza ) # # TODO: typ stacji, statystyki per interface # # Jakub Wartak [vnull@pcnet.com.pl] 2004 # # sciezka do snmpwalk ( z net-snmp, dostepne z http://net-snmp.sf.net ) my $snmpwalk = "/usr/bin/snmpwalk"; # co ile odswiezac? my $delay = 5; use POSIX; #use IPC::Open2; my $OR = $ARGV[0]; my $comm = $ARGV[1]; if ( !defined $OR || !defined $comm) { printf "usage: ./ortop.pl \n\n"; exit(0); } # zaczerpniete z orinoco.mib my $oriStationStatTable = ".1.3.6.1.4.1.11898.2.1.33.1.1"; my $OID = $oriStationStatTable; my $cmd = "$snmpwalk -On -v 2c -c $comm $OR -Cc $OID"; my %db_mac; my %db_ip; my %db_if; my %db_input; my %db_output; my %db_snr; my %db_type; my %last_in; my %last_out; # glowna petla while(1) { %db_mac = (); %db_ip = (); %db_if = (); %db_input = (); %db_output = (); %db_snr = (); %db_type = (); # czytamy to co nam snmpwalk zwroci... open(S, "$cmd |") or die; while() { chomp; &process_line($_); } close S; print "\n\n\n\n"; printf STDOUT ("%-20s %-16s %-6s %-6s %-10s %-10s\n", "MAC", "IP", "IF", "SNR", "IN(kbit/s)", "OUT(kbit/s)"); my $sum_rx = 0; my $sum_tx = 0; while ( ( $i, $mac ) = each %db_mac ) { my $ip = $db_ip{$i}; my $snr = $db_snr{$i}; my $if = $db_if{$i}; my $desc = "${if}_${mac}_${i}"; $rx = $last_in{$desc}; $tx = $last_out{$desc}; if ( ! defined $rx ) { $rx = $tx = "0"; $diff_tx = $diff_rx = "0"; } else { if($rx < 0 || $tx < 0 ) { print "ERROR: $rx $tx\n"; die; } # kilka operacji :> $diff_rx = $db_input{$i} - $rx; $diff_rx = $diff_rx * $delay; $diff_rx = $diff_rx / 1024; $diff_tx = $db_output{$i} - $tx; $diff_tx = $diff_tx * $delay; $diff_tx = $diff_tx / 1024; # nie wiem dlaczego ale czasami wyglada na to # ze Orinoco "przewija" countery :/ # i roznica moze byc ujemna.... zapobiegamy temu # TODO: lepiej to zbadac... if($diff_rx < 0 ) { $diff_rx = 0; $db_input{$i}=0; $rx = 0; } if($diff_tx < 0 ) { $diff_tx = 0; $db_output{$i}=0; $tx = 0; } } #print "drx=$diff_rx (rx=$rx) dtx=$diff_tx (tx=$tx)\n"; my $p = sprintf("%-20s %-16s %-6s %-6s %-10.2f %-10.2f\n", $mac, $ip, $if, $snr, $diff_rx, $diff_tx); print "$p"; $sum_rx += $diff_rx; $sum_tx += $diff_tx; $last_in{$desc} = $db_input{$i}; $last_out{$desc} = $db_output{$i}; } printf STDOUT "TOTAL IN: %.2f kbit/s TOTAL OUT: %.2f kbit/s\n", $sum_rx, $sum_tx; sleep($delay); } 1; sub process_line() { my $l = shift; # btw: wstydze sie tego kodu :P my $skip = "^$oriStationStatTable\."; $l =~ s/$skip//; my @what = split(/\./, $l, 2); my $func = $what[0]; my @tmp = split(/ /, $what[1]); my $index = $tmp[0]; my $name = &func2name($func); my $data = $tmp[3]; if ( $name eq "macaddr" ) { if(defined $db_mac{$index}) { return; } $data = "$tmp[3]:$tmp[4]:$tmp[5]:$tmp[6]:$tmp[7]:$tmp[8]"; $db_mac{$index} = $data; } elsif ( $name eq "ip" ) { if(defined $db_ip{$index}) { return; } if ($data eq "0.0.0.0") { $data = "( WDS )"; } $db_ip{$index} = $data; } elsif ( $name eq "if" ) { if(defined $db_if{$index}) { return; } $db_if{$index} = &if2name($data); } elsif ( $name eq "input" ) { if(defined $db_input{$index}) { return; } $db_input{$index} = $data; } elsif ( $name eq "output" ) { if(defined $db_output{$index}) { return; } $db_output{$index} = $data; } elsif ( $name eq "snr" ) { if(defined $db_snr{$index}) { return; } $db_snr{$index} = $data; } elsif ( $name eq "NIE" ) { return; } # :P :P :P #print "$l\n"; # print "$name $index $data\n"; } # Lame :/ sub if2name() { my $num = shift; if($num eq 1) { return "eth"; } elsif($num eq 2 || $num eq 0) { return "?"; } elsif($num eq 3) { return "wlan1"; } elsif($num eq 4) { return "wlan2"; } } # To tez jest Lame :/ # ostatnia czesc OIDa zamienia na nazwe sub func2name() { my $f = shift; if($f == "1") { return "index"; } elsif($f == "2") { return "macaddr"; } elsif($f == "3") { return "ip"; } elsif($f == "4") { return "if"; } elsif($f == "12") { return "input"; } elsif($f == "16") { return "output"; } elsif($f == "20") { return "snr"; } else { return "NIE"; } # :P } # TheEND