Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use strict;
- use Net::SNMP;
- use LWP::UserAgent;
- use HTTP::Request::Common qw(POST GET DELETE);
- use Data::Dumper;
- use Net::DNS;
- use JSON;
- my $dns;
- my $dbh;
- my $community = 'public';
- my $t0 = time();
- my @hosts = (
- "wlc#1",
- "wlc#2",
- #etc
- );
- if( ! scalar @hosts ) {
- print "No WLCs found in inventory matching location $loc\n";
- exit 0;
- }
- # get client counts per SSID
- my @meas;
- foreach my $host (@hosts) {
- print "$host\n";
- (my $snmp, my $err) = Net::SNMP::Table->session( -hostname => $host, -community => $community, -timeout => 5, -port => "161", -version => '2c', -translate=>[-octetstring => 0]);
- if( ! $snmp ) {
- print STDERR "Could not open SNMP session to $host\n";
- next;
- }
- my $objApName = $snmp->table("1.3.6.1.4.1.14179.2.2.1.1.3", 6); # get AP names
- my $objApMac = $snmp->table("1.3.6.1.4.1.14179.2.2.1.1.1", 6); # get AP MAC addresses
- my $objApModel = $snmp->table("1.3.6.1.4.1.14179.2.2.1.1.16", 6); # get AP model
- my %apnames; # AP MAC to AP name
- my %apmodels; # AP MAC to model
- my @keys = $objApMac->keys();
- foreach my $i (@keys) {
- my $apname = $objApName->item($i);
- my $apmac = unpack "H*", $objApMac->item($i); # we told Net::SNMP to not translate octets, so translate now
- $apnames{$apmac} = $apname;
- my $apmodel = $objApModel->item($i);
- $apmodel =~ s/^air\-[a-z]+//i; # clean up model
- $apmodel =~ s/\-..*//;
- $apmodels{$apmac} = $apmodel;
- print "AP: $apname MODEL: $apmodel MAC: $apmac\n";
- }
- my $objClientMac = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.1", 6); # get client MAC addresses
- my $objClientIP = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.2", 6); # get client IP addresses
- my $objClientName = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.3", 6); # get client name
- my $objClientSSID = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.7", 6); # get client SSID
- my $objClientProto = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.25", 6); # get client IP addresses
- my $objClientRSSI = $snmp->table("1.3.6.1.4.1.14179.2.1.6.1.1", 6); # get client RSSI
- my $objClientSNR = $snmp->table("1.3.6.1.4.1.14179.2.1.6.1.26", 6); # get client SNR
- my $objClientApMac = $snmp->table("1.3.6.1.4.1.14179.2.1.4.1.4", 6); # get client AP MAC address
- @keys = $objClientIP->keys();
- # get the per client info
- foreach my $i (@keys) {
- my $mac = unpack "H*", $objClientMac->item($i); # decode clinet MAC address since we told Net::SNMP to not translate
- my $apmac = unpack "H*", $objClientApMac->item($i); # decode AP MAC address since we told Net::SNMP to not translate
- my $ip = $objClientIP->item($i);
- my $name = $objClientName->item($i);
- my $ssid = $objClientSSID->item($i);
- my $proto = $objClientProto->item($i);
- my $rssi = $objClientRSSI->item($i);
- my $snr = $objClientSNR->item($i);
- next if $ip eq '0.0.0.0'; # not a valid connection
- next unless $ssid; # not valid
- $mac =~ s/^0x//;
- $proto = proto($proto);
- my $id; # human friendly ID for this client
- if( $name =~ /^host\//i) { # workstation name ?
- $id = $name; # best case, use the client name
- $id =~ s/^host\///i; # get rid of HOST/ prefix
- }
- $id = GetHostName($ip) unless $id; # next best option, reverse DNS lookup
- $id = $ip unless $id; # next best, use IP address
- $id = $mac unless $id; # punt, use MAC address
- $id = lc $id; # lower case
- my $apname = $apnames{$apmac} || $apmac;
- my $apmodel = $apmodels{$apmac} || '?';
- $rssi .= 'i'; # store as integer
- $snr .= 'i'; # ditto
- push @meas, qq(client,SSID=$ssid,ip=$ip,id=$id,wlc=$host,mac=$mac,ap=$apname,apmodel=$apmodel proto="$proto",RSSI=$rssi,SNR=$snr);
- # After 75 client mesaurements, send to InfluxDB and empty @meas
- if( scalar @meas > 75 ) {
- print join "\n", @meas;
- print "\n";
- WriteInflux("yourinfluxserver", "yourdatabase", @meas);
- @meas = ();
- }
- }
- }
- # Get remaining measurements
- if( scalar @meas ) {
- print join "\n", @meas;
- print "\n";
- WriteInflux("yourinfluxserver", "yourdatabase", @meas);
- }
- print "\n";
- print "Run time : ", time() - $t0, " seconds\n";
- print "CPU time (user) : ", (times)[0], " seconds\n";
- print "CPU time (system): ", (times)[1], " seconds\n";
- exit 0;
- ####################
- sub WriteInflux {
- my $server = shift;
- my $db = shift;
- my @dat = @_;
- my $body = join "\n", @dat;
- my $url = "http://$server:8086/write?db=$db&precision=s";
- my $ua = LWP::UserAgent->new;
- my $req = (POST $url, Content=>$body);
- my $res = $ua->request($req);
- print "code: ", $res->code, "\n";
- print "content: ", $res->content, "\n";
- }
- ###############################################################################
- #
- # Translate numeric values of bsnMobileStationProtocol to human readable
- #
- ###############################################################################
- sub proto {
- my $i = shift;
- return 'dot11a' if $i == 1;
- return 'dot11b' if $i == 2;
- return 'dot11g' if $i == 3;
- return 'unknown' if $i == 4;
- return 'mobile' if $i == 5;
- return 'dot11n24' if $i == 6;
- return 'dot11n5' if $i == 7;
- return $i;
- }
- sub GetHostName {
- my $ip = shift;
- return undef unless $ip;
- if( ! $dns ) {
- $dns = Net::DNS::Resolver->new();
- }
- my $reverse = join( '.', reverse( split /\./, $ip )) . '.in-addr.arpa';
- if (my $ap = $dns->query( $reverse, 'PTR' )) {
- for my $pa ($ap->answer) {
- return $pa->ptrdname;
- }
- }
- return undef;
- }
- ###############################################################################
- #
- # This code lets us create a "table" object from data returned by an SNMP walk
- # $oid is the OID to fetch
- # $n is the number of righmost data points to use as an index.
- #
- ###############################################################################
- package Net::SNMP::Table;
- use parent 'Net::SNMP';
- sub table {
- my $self = shift;
- my $oid = shift;
- my $n = shift;
- my $obj = TableItem::new($oid, $n);
- my $res = $self->SUPER::get_table(-baseoid => $oid, -maxrepetitions => 30);
- foreach my $x ( keys %{$res} ) {
- my @tmp = split /\./, $x;
- my $key = join ".", splice(@tmp, -1 * $n);
- $obj->item($key, $res->{$x});
- }
- return $obj;
- }
- sub get {
- my $self = shift;
- my $oid = shift;
- my $res = $self->SUPER::get_request(-varbindlist => [ $oid ]);
- return undef if $res->{$oid} =~ /^noSuch/; # skip odd stuff that sometimes gets returned
- return undef if $res->{$oid} =~ /^0x/; # even odder...
- return $res->{$oid};
- }
- ###############################################################################
- #
- # This is a container for SNMP table data
- #
- ###############################################################################
- package TableItem;
- sub new {
- my $class = shift;
- my $oid = shift;
- my $n = shift;
- my $self = {};
- $self->{oid} = $oid;
- $self->{n} = $n;
- $self->{table} = {};
- bless $self;
- return $self;
- }
- sub keys {
- my $self = shift;
- return keys %{$self->{table}};
- }
- sub item {
- my $self = shift;
- my $key = shift;
- my $data = shift;
- $self->{table}->{$key} = $data if defined $data;
- return $self->{table}->{$key};
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement