ScanTool do MikroTika

1 październik 2008 | Kategorie: Administracja, Perl, WiFi

Skrypt ten wykrywa urządzenia z zainstalowanym systemem MikroTik, nawet gdy urządzenie nie ma ustawionego adresu IP. Po uruchomieniu, na konsoli otrzymujemy:

root@XXXXX:~# ./tools/scan-mikrotik.pl
MAC Address        IP Address       Identity                         Version
00:00:5E:80:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.27
00:02:6F:22:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.8.21
00:0F:CB:B0:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.27
00:02:6F:37:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.6
00:30:05:01:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.27
00:0F:CB:B0:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.6
00:40:CA:15:XX:XX  192.168.XXX.XXX  MT-XXXX                          2.9.6
root@XXXXX:~#
#!/usr/bin/perl -w
 
###############################################################################
#
# scan_mikrotik v.1.0.0
#
# scan utility for mikrotik
#
# panther@mindc.net
# 2008-04-14
###############################################################################
 
use strict;
use IO::Socket;
use Data::Dumper;
use Time::HiRes qw( usleep );
 
use constant MT_PORT => 5678;
use constant FORMAT => "%-17s  %-15s  %-32s %-16s\n";
 
my %LADDR;
my $mikrotik = { };
 
foreach( `/sbin/ip a`) {
    $LADDR{$2} = $1 if m/inet\s+(\S+)\/.*\s(eth\d+)(\s|:)/;
}
 
printf FORMAT,'MAC Address','IP Address','Identity','Version';
 
if (fork) {
    my $socket = IO::Socket::INET->new(
                    Proto => 'UDP',
                    LocalPort => MT_PORT,
                    LocalAddr => inet_ntoa(INADDR_ANY),
                    Reuse => 1
                ) or die "cannot bind socket $!\n";
 
    local $SIG{ALRM} = sub { close $socket;end() };
 
    eval {
        alarm 3;
        while ( $socket->recv(my $data,1024) ) {
            #my @datas = unpack("L1 H8 H12 H8 Z* H6 Z* H6 Z* H22 Z8",$data); #segmentation fault
            my @datas = unpack("L1 H8 H12 H8 Z* H6 Z*",$data);
            next if $datas[1] ne '00010006';
            my ($port, $ipaddr) = sockaddr_in($socket->peername);
            $mikrotik->{$datas[2]}{'mac'} = uc join(':',unpack('H2' x 6,pack("H12",$datas[2])));
            $mikrotik->{$datas[2]}{'ipaddr'} = join('.',unpack('C4',$ipaddr));
            $mikrotik->{$datas[2]}{'identity'} = $datas[4];
            $mikrotik->{$datas[2]}{'version'} = $datas[6];
        }
        alarm 0;
    };
    close $socket;
    end();
 
} else {
    foreach my $dev ( keys %LADDR ) {
        unless (fork) {
            my $socket = IO::Socket::INET->new(
                            Proto => 'UDP',
                            PeerPort => MT_PORT,
                            PeerAddr => inet_ntoa(INADDR_BROADCAST),
                            LocalAddr => $LADDR{$dev},
                            LocalPort => MT_PORT,
                            Broadcast => 1,
                            Reuse => 1
                        ) or die "cannot bind socket $!\n";
#           for (1..3) {
#               usleep(300000);
                $socket->send(pack("H8",0));
#           }
            close $socket;
            exit;
        }
    }
}
 
1 while ( wait() != -1);
 
exit;
 
sub end {
    foreach ( keys %$mikrotik ) {
        printf FORMAT,
                $mikrotik->{$_}{'mac'},
                $mikrotik->{$_}{'ipaddr'},
                $mikrotik->{$_}{'identity'},
                $mikrotik->{$_}{'version'};
    }
    exit;
}
Nie ma jeszcze komentarzy.