ScanTool do Orinoco
Do oprogramowania dla Access Pointów Orinoco AP2000/AP2500, dołączany jest mały programik o nazwie ScanTool (Windows), który pozwala na podstawowe operacje na AP: ustawienie statycznego adresu IP, aktualizację oprogramowania. Pozwala także na wyszukanie “zaginionego” AP, gdy nie znamy jego adresu IP. Potrzebowałem narzędzia, które “znajdzie” mi Orinoco wprost z konsoli, bez dostępu do X+Wine a tym bardziej do Windows. Skrypt jedynie wykrywa Orinoco w lokalnej sieci. Nie pozwala na modyfikacje czegokolwiek. Po uruchomieniu skryptu, na konsoli otrzymujemy:
root@XXXXX:~# ./tools/scan-tool.pl
Dev MAC Address IP Address s/d Uptime System Description
--------------------------------------------------------------------------------
eth2:
00:20:A6:4A:XX:XX 192.168.XXX.XXX s 013:00:12:22 AP-2000 v2.4.11(821)
00:20:A6:4A:XX:XX 192.168.XXX.XXX s 025:19:06:36 AP-2000 v2.4.11(821)
--------------------------------------------------------------------------------
eth0:
00:02:2D:71:XX:XX 10.XXX.XXX.XXX s 014:07:07:49 AP-2000 v2.4.11(821)
00:02:2D:48:XX:XX 10.XXX.XXX.XXX s 005:22:34:29 AP-2000 v2.4.11(821)
root@XXXXX:~#
Skrypt nie zawsze działa poprawnie, gdy na danym interfejsie mamy ustawiony więcej niż jeden adres IP z tej samej podsieci. Po uruchomieniu ./scan-tool.pl -v otrzymamy więcej informacji na konsoli.
#!/usr/bin/perl -w ############################################################################### # # scan_tool v.1.0.0 # # scan utility for orinoco ap # # panther@mindc.net # 2008-04-11 ############################################################################### use strict; use IO::Socket; use Data::Dumper; use Time::HiRes qw( usleep ); use constant ST_BROADCAST => 'ab010000'; use constant ST_STATIC => 'ab03070f'; use constant ST_DYNAMIC => 'ab03040b'; use constant ST_BROADCAST_RESPONSE => 'ac0207ff'; use constant ST_RESPONSE => 'ac0407fe'; use constant ST_ERROR => 'acff0001'; use constant ST_PORT => 2719; use constant FORMAT => "%-4s %-17s %-15s%3s %-12s %sn"; my $LPORT = 1000 + int rand 2000; my %LADDR; my $orinoco = { }; my $param = $ARGV[0] || ''; my $verbose = 0;$verbose = 1 if $param =~ m/^(-v|--verbose)$/; my $debug = 0;$debug = 1 if $param =~ m/^(-d|--debug)$/; foreach( reverse `/sbin/ip a`) { $LADDR{$2} = $1 if m/inets+(S+)/.*s(ethd+)(?:s|:)/; } printf FORMAT,'Dev','MAC Address','IP Address','s/d','Uptime','System Description'; foreach my $dev ( keys %LADDR ) { unless (fork) { if (fork) { my $socket = IO::Socket::INET->new( Proto => 'UDP', PeerPort => ST_PORT, LocalAddr => $LADDR{$dev}, LocalPort => $LPORT, Reuse => 1) or die "cannot bind socket $!n"; local $SIG{ALRM} = sub { close $socket;end($dev) }; eval { alarm 1; while ( $socket->recv(my $data, 612) ) { my ( $signature,$echo,$mac,undef, $ipaddr, $name, $uptime, $sysname, $tftpipaddr, $tftpfilename, $ipsubmask, $ipgw, $ipaddrtype) = unpack("H8 Z32 H12 H4 H8 Z32 N1 Z256 H8 Z256 H8 H8 L1",$data); next if $signature ne ST_BROADCAST_RESPONSE; $mac = uc join(':',unpack('H2' x 6,pack("H12",$mac))); $orinoco->{$mac}{'signature'} = $signature; $orinoco->{$mac}{'echo'} = $echo; $orinoco->{$mac}{'ip'} = join('.',unpack("C4",pack("H8",$ipaddr))); $orinoco->{$mac}{'name'} = $name; $orinoco->{$mac}{'uptime'} = $uptime/100; $orinoco->{$mac}{'desc'} = $sysname; $orinoco->{$mac}{'tftp-ip'} = join('.',unpack("C4",pack("H8",$tftpipaddr))); $orinoco->{$mac}{'tftp-filename'} = $tftpfilename; $orinoco->{$mac}{'mask'} = join('.',unpack("C4",pack("H8",$ipsubmask)));; $orinoco->{$mac}{'gateway'} = join('.',unpack("C4",pack("H8",$ipgw)));; $orinoco->{$mac}{'dhcp'} = $ipaddrtype - 1; } alarm 0; }; close $socket; end($dev); } else { my $socket = IO::Socket::INET->new( Proto => 'UDP', PeerPort => ST_PORT, PeerAddr => inet_ntoa(INADDR_BROADCAST), LocalAddr => $LADDR{$dev}, LocalPort => $LPORT, Broadcast => 1, Reuse => 1) or die "cannot bind socket $!n"; for (1..3) { usleep(200000); $socket->send(pack("H*",ST_BROADCAST . '00' x 608)); } close $socket; exit; } } } 1 while ( wait() != -1); exit; sub end { my $dev = shift; if ( my @aps = keys %$orinoco ) { print '-' x 80,"n"; print "$dev:n"; foreach ( @aps ) { my $d = $orinoco->{$_}{'dhcp'} ? ' d ' : ' s '; my $desc = $orinoco->{$_}{'desc'}; $desc =~ s/(.*)s+SN.*/$1/ unless $verbose; printf FORMAT,'',$_,$orinoco->{$_}{'ip'},$d,uptime($orinoco->{$_}{'uptime'}),$desc; printf FORMAT,'','',$orinoco->{$_}{'mask'},'','',$orinoco->{$_}{'name'} if $verbose; printf FORMAT,'','',$orinoco->{$_}{'gateway'},'','','' if $verbose; print "n" if $verbose; } print Data::Dumper->Dump([$orinoco],[$dev]) if $param =~ m/^(--debug|-d)$/; print "n" unless $verbose; } # else { # printf FORMAT,'','-','-',' - ','-','-'; # } exit; } sub uptime { my $time = shift; return sprintf "%03d:%02d:%02d:%02d", int($time/60/60/24), $time/60/60%24, $time/60%60, $time%60; } |