2007-01-24, 13:01
#1
#!/usr/bin/perl #PiFi version 0.31 released under GNU GPL2 #This is Perl program written to make it more simple to connect #to the most common WiFi nets (open, WEP and WPA-PSK). #It uses wirelesstools to scan and connect to WiFi nets. #To be able to connect to WPA-PSK encrypted nets wpa_supplicant is #a dependency. # #This program is written by Rickard Gustafson (rickard.gustafson@gmail.com
use strict; use Math::BigInt; use Getopt::Long qw(:config pass_through); use vars qw($VERSION); $VERSION = 0.31; sub version { print "PiFi version $VERSION\n"; } #Check if valid wifi-inteface. sub valid_if { my ($if) = @_; system("ifconfig $if up"); $_ = `iwconfig $if 2>&1`; # 2>&1 redirect STDERR to STDOUT return /ESSID/; } #Checks ip wpa_supplicant exists in path. sub check_wpa { $_ = `which wpa_supplicant`; return !/which/; } #Scan and parse SSIDs. sub scan_ssid { my ($if) = @_; my @lines = `iwlist $if scan`; my @nets = (); my @ssid = (); my $i = 0; for (0..$#lines) { if (@lines[$_] =~ s/.*ESSID:"(.*)"/$1/) { #Get ssid and stores in first cell of vector. chomp @lines[$_]; @ssid[0] = @lines[$_]; $i++; } if (@lines[$_] =~ s/.*key:(.*)/$1/) { #Gets encryption, if WPA it extends vector with chipper $i++; my $j; if (@lines[$_] =~ /on/) { @ssid[2] = 1; #Field 2 is a boolean for encryption if (@lines[$_+5] =~ /WPA/) { @lines[$_+5] =~ s/.*IE: (.*) Version.*/$1/; #@lines[$_+5] =~ s/.*IE: (.*) Version (.)/$1$2/; does the same but also stores wpa version. chomp @lines[$_+5]; @ssid[3] = @lines[$_+5]; for $j (4..6) { #Gets chippers and other extra output from iwlist. @lines[$_+$j+2] =~ s/.*: (.*)/$1/; chomp @lines[$_+$j+2]; @ssid[$j] = @lines[$_+$j+2]; } } else { @ssid[3] = "WEP"; for $j (4..6) { #These fields are obsolete for WEP but set to zero to not get any missmatching. @ssid[$j] = 0; } } } else { @ssid[2]= 0; for $j (2..6) {#These fields are obsolete but set to zero to not get any missmatching. @ssid[$j] = 0; } } } if (@lines[$_] =~ s/.*=(.*)\/(.*)/$1/) { #Signalstrength chomp @lines[$_]; @ssid[1] = @lines[$_]; $i++; } if ($i == 3) { push @nets, [@ssid]; $i = 0; } } return @nets; } #Returns encryption type from array like an integer. Returns 0 for none, 1 for WEP and 2 for WPA. sub enc_type { #enc_type(@net) my (@net) = @_; if (@net[2] == 0) { return 0; } if (@net[2] == 1 && @net[3] =~ /WEP/) { return 1; } if (@net[2] == 1 && @net[3] =~ /WPA/) { return 2; } } #Print ssid and info from given vector. sub print_ssid { my @nets = @_; my $i; die ("No networks found.") unless ($#nets != -1); for $i (0..$#nets) { my $sig = Math::BigInt -> new($nets[$i][1]); my $stars = "#" x ($sig / 2); my $enc = ($nets[$i][2] == 0) ? "not encypted." : "encrypted with $nets[$i][3]"; printf("Network id: %d\n", $i+1); print "SSID: $nets[$i][0]\n"; printf("This network is %s\n", $enc); printf("Link quality: [%-50s %3d\%]\n", $stars, $sig ); print "-" x 70 . "\n"; } return 0; } #Generates configuration file for wpa_supplicant. sub gen_conf { # gen_conf($ssid, $secret, $file) my ($ssid, $secret, $file) = @_; $_ = `wpa_passphrase $ssid "$secret"`; my @wpa = split /\n/; open(FILE,">$file"); print FILE "ctrl_interface=/var/run/wpa_supplicant\n"; print FILE "ctrl_interface_group=0\n"; print FILE "eapol_version=1\n"; print FILE "ap_scan=1\n"; print FILE "fast_reauth=1\n"; print FILE "\n\n\nnetwork={\n"; #WPA print FILE "scan_ssid=1\n"; print FILE "ssid=\"$ssid\"\n"; print FILE "proto=WPA\n"; print FILE "key_mgmt=WPA-PSK\n"; print FILE "pairwise=CCMP TKIP\n"; print FILE "group=CCMP TKIP WEP104 WEP40\n"; print FILE "@wpa[3]\n"; print FILE "}\n"; close(FILE); return 0; } #Connects to wpa encrypted network with given interface, SSID and PSK. sub wpa_connect { #wpa_connect($iw, $ssid, $secret) my ($iw, $ssid, $secret) = @_; my $file = "/tmp/wpa_supplicant.conf"; gen_conf($ssid, $secret, $file); system("wpa_supplicant -Dwext -i$iw -c$file -B"); #wext is a chipper wpa_supplicant allways is compiled with and probably all drivers works with. unlink($file); return 0; } #Connects to wep encrypted network with ginev interface, SSID and hex-key. sub wep_connect { #wep_connect($iw, $ssid, $key) my ($iw, $ssid, $key) = @_; system("iwconfig $iw mode managed key $key"); system("iwconfig essid $ssid"); return 0; } #Connects to open network with given interface and SSID sub open_connect { #open_connect($iw, $ssid) my ($iw, $ssid) = @_; system("iwconfig $iw essid $ssid"); return 0; } #Escapes quotes in string. sub quote_escape { $_ = @_; s/\"/\\\"/g; return; } #Set IP on given interface with given client. sub ip_dhcp { #ip_dhcp($iw, $client) my ($iw, $client) = @_; system($client $iw); return 0; } #Set IP on given interface with ifconfig and given ip-string. sub ip_static { #ip_static($iw, $ip) my ($iw, $ip) = @_; system("ifconfig $iw $ip"); return 0; } #Function for running as wizard. sub wizard { #Get which interface and checks if valid. print "Enter which interface you want to connect with (eg. ath0 eth1 wifi0): "; my $iw = <STDIN>; chomp $iw; die ("\n$iw does not seem to be a valid WiFi interface please check your spelling.\n") unless ( valid_if($iw) == 1); #Scan and print aviable networks. my @nets = scan_ssid($iw); print_ssid(@nets); #Get network id. print "\nEnter id of SSID you want to connect: "; my $id = <STDIN>; chomp $id; $id--; die ("You want to connect to a WPA encrypted network and wpa_supplicant does not exists in path.\n") if (enc_type(@{$nets[$id]}) == 2 && check_wpa == 0); #Connect to AP. if (enc_type(@{$nets[$id]}) == 0) { open_connect($iw, $nets[$id][0]); } if (enc_type(@{$nets[$id]}) == 1) { print "\nEnter WEP-key: "; my $key = <STDIN>; chomp $key; wep_connect($iw, $nets[$id][0], $key); } if (enc_type(@{$nets[$id]}) == 2) { print "\nEnter WPA-passphrase: "; my $psk = <STDIN>; chomp $psk; $psk = quote_escape($psk); wpa_connect($iw, $nets[$id][0], $psk); } #IP configuration. print "\nTo use DHCP enter your client below.\n"; print "To use static IP enter an ifconfig compatible string.\n"; print "Example: 10.0.0.1, 10.0.0.1 netmask 255.255.255.0, 10.0.0.1 netmask 0xffffff00, 10.0.0.1/24\n"; print "wifi> "; my $adr = <STDIN>; chomp $adr; if ($adr =~ /[dD][hH][cC]/) { ip_dhcp($iw, $adr); } else { ip_static($iw, $adr); } } #Main function. Parses arguments. sub main { my ($wizard,@open, @wep, @wpa, $help, $version); GetOptions ('w|wizard' => \$wizard, 'o|open=s{2}' => \@open, 'wep=s{3}' => \@wep, 'wpa=s{3}' => \@wpa, 'h|help' => \$help, 'v|version' => \$version); if ($#ARGV != -1) { die ("Try -h --help for usage.\n"); } if ((@open && (@wep || @wpa)) || (@wep && @wpa)) { die ("Option open, wep and wpa obsoletes each other. Do not try to combine them!\n") } #Connect to open network. #Helptext: -o --open [inteface ssid] if ($#open != -1) { #valid_if(@ARGV[0]) || die ("Not a valid WiFi interface."); #Seems to be obsolet die ("To few arguments\n") unless ($#open == 1); open_connect(@open); } #Connect to WEP network. #Helptext: --wep [interface ssid key] elsif ($#wep != -1) { #valid_if(@ARGV[0]) || die ("Not a valid WiFi interface."); #Seems to be obsolet die ("To few arguments\n") unless ($#wep == 2); wep_connect(@wep); } #Connect to WPA-PSK. #Helptext: --wpa [interface ssid passphrase] elsif ($#wpa != -1) { #valid_if(@ARGV[0]) || die ("Not a valid WiFi interface."); #Seems to be obsolet die ("To few arguments\n") unless ($#wpa == 2); wpa_connect(@wpa); } #Start PiFi in wizard mode. elsif ($wizard == 1) { wizard(); } #Help. elsif ($help == 1) { print "PiFi usage:\n"; print "-w --wizard\t\t\t\tWizard mode, similar as no option.\n"; print "-o --open [inteface ssid]\t\tConnect to open network\n"; print "--wep [interface ssid key]\t\tConnect to WEP encrypted network.\n"; print "--wpa [interface ssid passphrase]\tConnect to WPA-PSK encrypted network.\n"; print "-v --version\t\t\t\tPrint version.\n"; print "-h --help\t\t\t\tPrint this helpmessage.\n"; } #Version. elsif ($version == 1) { version(); } #If no arguments are passed start as wizard. else { wizard(); } } main();
nilsl@***:~/projects/perl$ perl wlan.pl Error in option spec: "o|open=s{2}" Error in option spec: "wep=s{3}" Error in option spec: "wpa=s{3}"
nilsl@***:~/projects/perl$ perl wlan.pl Error in option spec: "o|open=s{2}" Error in option spec: "wep=s{3}" Error in option spec: "wpa=s{3}"
if (@lines[$_] =~ s/.*=(.*)\/(.*)/$1/ || @lines[$_] =~ s/^Quality:(\d+)/$1/) { #Signalstrength
Du måste vara medlem för att kunna kommentera
Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!
Swish: 123 536 99 96 Bankgiro: 211-4106