Znowu się nudziłem i napisałem sobie mały projekt w PHP, który informuje mnie o kolejce skilli w EVE Online, bez potrzeby logowania się do gry.
Jeśli ktoś będzie zainteresowany źródłem, dorzucę do bloga.
Jeszcze pomyślę o "oklejeniu" tego jakimś javascriptem, aby dane wyglądały jeszcze bardziej "na bieżąco".
14 czerwca 2011
11 czerwca 2011
Ubiquiti cz.2
Dzisiaj rzutem na taśmę skaner do Ubiquiti. W odróżnieniu od Mikrotika, Ubiquiti odpowiada na adres z którego zostało wysłane zapytanie. Ale w tym skrypcie nasłuchujemy na dowolnym adresie, tak jak w skanerze dla Mikrotików.
No i miały być szczegóły techniczne. Skaner rozsyła z portu 50122 na port 10001 paczkę
0x01000000
po broadcaście. Urządzenie wysyła odpowiedź na port 50122.
Trochę dłubaniny było przy zmiennym formacie ramki ale dość łatwo było ominąć ten problem. Pierwszy rodzaj ramki:@s = unpack("H6H2H6H12NH6H12H8(H2n/a*)*", $ramka); $s[0] sygnatura (0x010000) $s[1] nie pamiętam :) $s[2] ?? $s[3] adres MAC $s[4] ?? $s[5] ?? $s[6] ?? $s[7] ?? ( $s[8] typ pola X długość łańcucha (automatycznie wchłaniane przez unpack) $s[9] łańcuch ) ...Drugi rodzaj ramki:
@s = unpack("H6H2H6H12NH6H12H14(H2n/a*)*", $ramka); $s[0] sygnatura (0x010000) $s[1] nie pamiętam :) $s[2] ?? $s[3] adres MAC $s[4] ?? $s[5] ?? $s[6] ?? $s[7] ?? (tutaj długość jest większa o 3 bajty) ( $s[8] typ pola X długość łańcucha (automatycznie wchłaniane przez unpack) $s[9] łańcuch ) ...Zidentyfikowane typy pól:
0x03 - wersja softu 0x0a - uptime 0x0b - nadana nazwa dla urządzenia 0x0c - model urządzenia 0x0d - SSID do którego jest podpięte urządzenie gdy pracuje w trybie klientaNo i skrypt:
#!/usr/bin/perl ############################################################################### # # scan-ubiquiti.pl v1.2.0 # # scan utility for ubiquiti # # 2011-06-11 # przepisano engine na klasyczne sockety # # mindc.net # 2011-03-20 ############################################################################### use strict; use warnings; use Socket; use Time::HiRes qw(gettimeofday); print "scan-ubiquiti.pl v1.2.0 hw ip board sw uptime name ssid -------------------------------------------------------------------------------------------------------- "; my %dev; open my $ph, "-|","ip a"; while ( <$ph> ) { $dev{$2} = $1 if m@\s(\S+)/\d+\s.*(eth\d+)@; } close $ph; my $data = {}; foreach my $saddr ( values %dev ) { my $socket; socket($socket,PF_INET,SOCK_DGRAM,17); setsockopt($socket, SOL_SOCKET, SO_BROADCAST, 1 ); my $sin = sockaddr_in(50122,inet_aton($saddr)); bind($socket,$sin); my $sout = sockaddr_in(10001,INADDR_BROADCAST); send($socket,pack("H8","01000000"),0,$sout); send($socket,pack("H8","01000000"),0,$sout); send($socket,pack("H8","01000000"),0,$sout); close $socket; } my $socket; socket($socket,PF_INET,SOCK_DGRAM,17) or die "socket error - $!"; my $sin = sockaddr_in(50122,INADDR_ANY); bind($socket,$sin); my $rin = ""; vec($rin,fileno($socket),1) = 1; my $end = gettimeofday() + 3; my $timeout = $end - gettimeofday(); my $i = 0; while ( select(my $rout = $rin,undef,undef,$timeout) ) { $timeout = $end - gettimeofday(); my $rtime = ""; my $his = recv($socket,$rtime,1500,0) || die "recv: $!"; my ($port,$hisaddr) = sockaddr_in($his); next if length($rtime) < 8; #skip self my $o = ubiquiti_header(inet_ntoa($hisaddr),$rtime); if ( not exists($data->{$o->{mac}})) { my $sw = parse_sw($o->{sw}); printf("%2d. %17s %-16s %-16s %-4s %6s %-24s %s\n", ++$i, $o->{mac}, $o->{ip}, models($o->{board}), $sw->{sw_version}, sec2human($o->{uptime}), $o->{name}, $o->{ssid} ); } $data->{$o->{mac}}++; } close $socket; print "\n" if keys %$data; exit; sub ubiquiti_header { my $ip = shift; my $frame = shift; my $template = "H6 H2 H6 H12 N H6 H12 H8 (H2n/a*)*"; my @header = unpack($template,$frame); my $signature = shift @header; return undef if $signature ne '010000'; my $t = shift @header; shift @header; my $mac = shift @header; shift @header; shift @header; shift @header; shift @header; if ( $header[0] ne '01' ) { $template = "H6 H2 H6 H12 N H6 H12 H14 (H2n/a*)*"; @header = unpack($template, $frame); $signature = shift @header; return undef if $signature ne '010000'; $t = shift @header; shift @header; $mac = shift @header; shift @header; shift @header; shift @header; shift @header; } my $out = {}; @{$out}{qw(ip mac sw board key uptime ssid)} = ($ip,'','','','',0,''); for ( my $i = 0; $i < @header ; $i += 2 ) { my $type = $header[$i]; my $value = $header[$i+1]; $out->{sw} = $value if $type eq '03'; $out->{board} = $value if $type eq '0c'; $out->{name} = $value if $type eq '0b'; $out->{uptime} = unpack("N",$value) if $type eq '0a'; $out->{ssid} = $value if $type eq '0d'; } $out->{mac} = uc join(":",unpack("(H2)6",pack("H*",$mac))); $out->{frame} = $frame; $out->{structure} = \@header; return $out; } sub sec2human { my $sec = shift; return "" if $sec <= 0; my $w = int($sec / 60 / 60 / 24 / 7); my $d = int($sec / 60 / 60 / 24 % 7); my $h = int($sec / 60 / 60 % 24); my $m = int($sec / 60 % 60); my $s = int($sec % 60); if ( $w ) { return sprintf("%dw%dd",$w,$d); } elsif ( $d ) { return sprintf("%dd%dh",$d,$h); } elsif ( $h ) { return sprintf("%dh%dm",$h,$m); } elsif ( $m ) { return sprintf("%dm%ds",$m,$s); } else { return "${s}s"; } } sub parse_sw { my $sw = shift; return {} unless $sw; my @s = split /\./,$sw; $s[2] = $s[2] || ''; $s[3] = $s[3] || ''; $s[2] =~ s/v//g; my $out = { board => $s[0] || '', chipset => uc $s[1] || '', build => $s[4] || '', date => $s[5] || '', unkn => $s[6] || '' }; $out->{sw_version} = $s[2].".".$s[3] if $s[2] && $s[3]; return $out; } sub models { my $m = shift; return 'NanoBridgeM' if $m eq 'NB5'; return 'WISPStation5' if $m eq 'MS5'; return 'RocketM' if $m eq 'R5N'; return 'AirGridM5' if $m eq 'AG5'; return $m; };
MNDP cz.4
Zaczął mnie irytować ten
tcpdump
. Ogarnąłem się trochę i przepisałem część kodu w zwykłych socketach.
#!/usr/bin/perl ############################################################################### # # scan-mikrotik.pl v2.8.0 # # scan utility for mikrotik # # 2011-06-11 # przepisano engine na klasyczne sockety # # 2011-03-27 # dodano uptime # # mindc.net # 2011-03-20 ############################################################################### use strict; use warnings; use Socket; use Time::HiRes qw(gettimeofday); print "scan-mikrotik.pl v2.8.0 hw ip board sw uptime identity -------------------------------------------------------------------------------- "; my %dev; open my $ph, "-|","ip a"; while ( <$ph> ) { $dev{$2} = $1 if m@\s(\S+)/\d+\s.*(eth\d+)@; } close $ph; my $data = {}; foreach my $saddr ( values %dev ) { my $socket; socket($socket,PF_INET,SOCK_DGRAM,17); setsockopt($socket, SOL_SOCKET, SO_BROADCAST, 1 ); my $sin = sockaddr_in(5678,inet_aton($saddr)); bind($socket,$sin); my $sout = sockaddr_in(5678,INADDR_BROADCAST); send($socket,pack("H8",0),0,$sout); send($socket,pack("H8",0),0,$sout); send($socket,pack("H8",0),0,$sout); close $socket; } my $socket; socket($socket,PF_INET,SOCK_DGRAM,17) or die "socket error - $!"; my $sin = sockaddr_in(5678,INADDR_ANY); bind($socket,$sin); my $rin = ""; vec($rin,fileno($socket),1) = 1; my $end = gettimeofday() + 3; my $timeout = $end - gettimeofday(); my $i = 0; while ( select(my $rout = $rin,undef,undef,$timeout) ) { $timeout = $end - gettimeofday(); my $rtime = ""; my $his = recv($socket,$rtime,1500,0) || die "recv: $!"; my ($port,$hisaddr) = sockaddr_in($his); next if length($rtime) < 5; #skip self my $o = mikrotik_header(inet_ntoa($hisaddr),$rtime); if ( not exists($data->{$o->{mac}})) { printf("%2d. %17s %-16s %-10s %-7s %6s %s\n", ++$i, $o->{mac}, $o->{ip}, $o->{board}, $o->{sw}, sec2human($o->{uptime}), $o->{identity} ); } $data->{$o->{mac}}++; } close $socket; print "\n" if keys %$data; exit; sub mikrotik_header { my $ip = shift; my $buffer = shift; my @header = unpack("H2H2S(H4n/a*)*", $buffer); shift @header; #? shift @header; #? shift @header; #age? my $out = {}; @{$out}{qw(ip mac identity vendor sw board key uptime)} = ($ip,'','','','','','',0); for ( my $i = 0; $i < @header ; $i += 2 ) { my $type = $header[$i]; my $value = $header[$i+1]; $out->{mac} = uc join(":",unpack("(H2)6",$value)) if $type eq '0001'; $out->{identity} = $value if $type eq '0005'; $out->{vendor} = $value if $type eq '0008'; $out->{sw} = $value if $type eq '0007'; $out->{board} = $value if $type eq '000c'; $out->{key} = $value if $type eq '000b'; $out->{uptime} = unpack("L",$value) if $type eq '000a'; # $out->{unknown2} = $value if $type eq '000d'; } return $out; } sub sec2human { my $sec = shift; return "" if $sec <= 0; my $w = int($sec / 60 / 60 / 24 / 7); my $d = int($sec / 60 / 60 / 24 % 7); my $h = int($sec / 60 / 60 % 24); my $m = int($sec / 60 % 60); my $s = int($sec % 60); if ( $w ) { return sprintf("%dw%dd",$w,$d); } elsif ( $d ) { return sprintf("%dd%dh",$d,$h); } elsif ( $h ) { return sprintf("%dh%dm",$h,$m); } elsif ( $m ) { return sprintf("%dm%ds",$m,$s); } else { return "${s}s"; } }
Subskrybuj:
Posty (Atom)