#!/usr/bin/perl my $mode = "adhoc"; my $iwmode = "Ad-Hoc"; my $proto = "80211g"; my $pmode = 3; my $channel = 10; my $essid = "jun_exp"; my $rate = "auto"; my $txpower = "auto"; my $boot_pings = 0; my $save_hassle = 0; my $idempotent = 0; my $rate_alg = "sample"; my $iface_num = -1; my $do_modules = 1; my $do_mon_vdev = 0; sub usage { my $msg = shift; if (defined($msg)) { print "ERROR: $msg\n\n"; } print "Usage: $ARGV[0] [-h] [--help] [-ixM] [-dmpfcertn ]\n"; print " -i Only print commands, don't execute\n"; print " -x Try to save hassle; i.e., don't destroy VAP\n"; print " wlanX device and reset modules\n"; print " -N DO NOT remove/modprobe ath_X modules (i.e., you"; print " might not want this if you have more than"; print " one iface\n"; print " -d Operate on device N (i.e., athN)\n"; print " -m Set the mode: \n"; print " 'Ad-Hoc' or 'adhoc' for ad-hoc mode\n"; print " 'Managed' or 'sta' for ap client mode\n"; print " 'Master' or 'ap' for ap mode\n"; print " 'Monitor' or 'monitor' for monitor mode\n"; print " (default: '$mode')\n"; print " -p Set the protocol:\n"; print " '80211a' or 'a' for 802.11a\n"; print " '80211b' or 'b' for 802.11b\n"; print " '80211g' or 'g' for 802.11g\n"; print " (default: '$proto')\n"; print " -f Set the frequency (either channel/freq works)\n"; print " -c Set the frequency (either channel/freq works)\n"; print " -s Set the rate selection algorithm: \n"; print " 'sample' for SampleRate algorithm\n"; print " 'minstrel' for Minstrel algorithm\n"; print " 'ccaa' for CCAA algorithm\n"; print " (default: 'sample')\n"; print " -e Set the essid\n"; print " (default: '$essid')\n"; print " -r Set the transmit rate\n"; print " (default: '$rate')\n"; print " -t Set the transmit power (may not work)\n"; print " (default: '$txpower')\n"; print " -n The number of broadcast pings you want to send\n"; print " upon completion of changes to test\n"; print " (default: '$boot_pings')\n"; print " -M Create a monitor mode virtual device for the device\n"; print " specified by -d ; useful for capturing\n"; print " while the main interface is live (virtual device\n"; print " will be ath(+10).\n"; print " -h, --help Print this help\n"; exit(-1); } sub mac_addr_from_dev($) { my $device = $_[0]; my $output = `/sbin/ifconfig $device 2>&1`; if ($output =~ /^$device: error/) { return ""; } my @tmp = split(/\s+/, $output); my $mac = $tmp[4]; $mac =~ s/-/:/g; my @hex = split(/:/, $mac); return uc (join ":", @hex[0 .. 5]); } #srand(); #$essid .= "_" . (int(rand(10000))); ## grab args... for ($i = 0; $i < scalar(@ARGV); ++$i) { if ($ARGV[$i] eq '-N') { $do_modules = 0; } elsif ($ARGV[$i] eq '-x') { $save_hassle = 1; } elsif ($ARGV[$i] eq '-i') { $idempotent = 1; } elsif ($ARGV[$i] eq '-M') { $do_mon_vdev = 1; } elsif ($ARGV[$i] eq '-h' || $ARGV[$i] eq '--help') { usage(); } elsif ($ARGV[$i] =~ /^\-/ && ($i+1) < scalar(@ARGV)) { ## one of the args, with argval: my $a = $ARGV[$i++]; my $av = $ARGV[$i]; if ($a eq '-d') { $iface_num = $av; } elsif ($a eq '-s') { $rate_alg = $av; if ($rate_alg eq 'sample') { $rate_alg = 'sample'; } elsif ($rate_alg eq 'minstrel') { $rate_alg = 'minstrel'; } elsif ($rate_alg eq 'ccaa') { $rate_alg = 'ccaa'; } else { die("ERROR: bad rate_alg '$rate_alg'!"); } } elsif ($a eq '-m') { $mode = $av; if ($mode eq 'adhoc' || $mode eq 'Ad-Hoc') { $mode = 'adhoc'; $iwmode = 'Ad-Hoc'; } elsif ($mode eq 'sta' || $mode eq 'Managed') { $mode = 'sta'; $iwmode = 'Managed'; } elsif ($mode eq 'ap' || $mode eq 'Master') { $mode = 'ap'; $iwmode = 'Master'; } elsif ($mode eq 'monitor' || $mode eq 'Monitor') { $mode = 'monitor'; $iwmode = 'Monitor'; } else { die("ERROR: bad mode '$mode'!"); } } elsif ($a eq '-p') { $proto = $av; if ($proto eq '80211a' || $proto eq 'a') { $pmode = 1; } elsif ($proto eq '80211b' || $proto eq 'b') { $pmode = 2; } elsif ($proto eq '80211g' || $proto eq 'g') { $pmode = 3; } else { die("ERROR: invalid protocol '$proto'!"); } } elsif ($a eq '-f' || $a eq '-c') { $channel = $av; } elsif ($a eq '-e') { $essid = $av; } elsif ($a eq '-r') { $rate = $av; } elsif ($a eq '-t') { $txpower = $av; } elsif ($a eq '-n') { $boot_pings = $av; } else { usage("unsupported argument '$ARGV[($i-1)]'!"); } } else { usage("improper argument '$ARGV[$i]'!"); } } #JunPark my $ath = "ath0"; $ip = `/sbin/ifconfig $ath | awk '/inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ {print (substr(\$2,6)); }' -`; chomp($ip); if ($ip eq '') { my $ath = "ath1"; $ip = `/sbin/ifconfig $ath | awk '/inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ {print (substr(\$2,6)); }' -`; chomp($ip); } if ($ip eq '') { my $ath = "eth1"; $ip = `/sbin/ifconfig $ath | awk '/inet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/ {print (substr(\$2,6)); }' -`; chomp($ip); } my @newip = split(/\./, $ip); print "ip0=$newip[0], ip1=$newip[1], ip2=$newip[2], ip3=$newip[3]\n"; $ip = "10" . "." . $newip[1] . "." . $newip[2] . "." . $newip[3]; $mac = mac_addr_from_dev($ath); print "ath=$ath, ip=$ip, mac=$mac\n"; #JunPark ## figure out our interface, ip, mac # my ($ip,$mac); # open(IFF,"/var/emulab/boot/ifmap") # or die("ERROR: could not open emulab node ifmap file!\n"); #while (my $line = ) { # chomp($line); # # if ($line =~ /\w+(\d+)\s+(\d+\.\d+\.\d+\.\d+)\s+([0-9a-fA-F]+)/) { # if ($iface_num < 0) { # $iface_num = $1; # $ip = $2; # $mac = $3; # # last; # } # else { # if ($1 eq "$iface_num") { # $ip = $2; # $mac = $3; # # last; # } # } # } # # print "DEBUG: if=$iface_num, ip=$ip, mac=$mac\n"; #} # #close(IFF); #if ($iface_num < 0) { # print "ERROR: could not extract device info from /var/emulab/boot/ifmap!\n"; # exit(-2); #} $iface_num = 0; # JunPark my $ath = "ath$iface_num"; my $wifi = "wifi$iface_num"; #$save_hassle = 0; if ($save_hassle) { ## figure out our current state... my $iwconfig = "/usr/local/sbin/iwconfig"; my @output = `$iwconfig $ath`; foreach my $o (@output) { if ($o =~ /\s+Mode:([\w\d_\-]+)\s+Frequency.+/) { #print "DEBUG: found current mode '$1'\n"; if ($iwmode ne $1) { $save_hassle = 0; print "WARNING: forcing a complete reset; current mode=$1; new=$iwmode!\n"; } } #print "trying '$o'\n"; } } ## figure out our network: my ($netmask,$network,$nmac); #$ip = "10.1.1.2"; $netmask = "255.0.0.0"; #my ($ap_mac); #open(IFC,"/var/emulab/boot/tmcc/ifconfig") # or die("couldn't open /var/emulab/boot/tmcc/ifconfig!\n"); # #while ($line = ) { # chomp($line); # if ($nmac eq '' && $line =~ /INTERFACE IFACETYPE=ath INET=(\d+\.\d+\.\d+\.\d+)\s+MASK=(\d+\.\d+\.\d+\.\d+)\s+MAC=([\d\w]+)/) { # if ($1 eq $ip) { # $netmask = $2; # $nmac = $3; # #last; # } # #print "DEBUG: matched '$line'\n"; # } # elsif ($line =~ /INTERFACE_SETTING MAC=([\d\w]+) KEY=\'(\w+)\' VAL=\'([\w\d]+)\'/) { # my $imac = $1; # my $ikey = $2; # my $ival = $3; # # if ($imac eq $nmac && $ikey eq 'accesspoint') { # $ap_mac = $ival; # ## fix it for iwconfig, sigh... # my $ts = ''; # for (my $lpc = 0; $lpc < 11; ) { # $ts .= "" . (substr($ap_mac,$lpc,2)) . ":"; # $lpc = $lpc + 2; # } # chop($ts); # $ap_mac = $ts; # print "DEBUG: ap_mac=$ap_mac\n"; # } # } # #} #close(IFC); ### compute the network... #my @ipo = split(/\./,$ip); #my @nmo = split(/\./,$netmask); # #if (scalar(@ipo) == scalar(@nmo)) { # $network = ""; # for (my $i = 0; $i < scalar(@ipo); ++$i) { # my $no = int($ipo[$i]) & int($nmo[$i]); # $network .= "$no."; # } # chop($network); #} #else { # die("couldn't compute netmask!\n"); #} ## Notify the user... if (!$save_hassle) { print "WLANCONFIG: iface=$wifi; mode=$mode\n"; } print "IWPRIV: proto=$proto ($pmode)\n"; if (!$save_hassle) { print "IFCONFIG: iface=$ath; ip=$ip; netmask=$netmask; network=$network\n"; } print "IWCONFIG: mode=$iwmode; essid=$essid; channel=$channel; rate=$rate; txpower=$txpower"; if ($mode eq 'sta' && $ap_mac ne '') { print "; ap=$ap_mac\n"; } else { print "\n"; } print "PINGCONFIG: reboot_pings=$boot_pings\n"; ## generate our command set to "reboot" the device my @commands = (); my $i = 0; if (!$save_hassle) { $commands[$i++] = "sudo /sbin/ifconfig $ath down"; $commands[$i++] = "sudo /sbin/ifconfig $wifi down"; $commands[$i++] = "sudo /usr/local/bin/wlanconfig $ath destroy"; if ($do_modules) { ## also reboot the kernel modules: $commands[$i++] = "sudo /sbin/rmmod ath_pci ath_rate_sample ath_rate_minstrel ath_rate_ccaa ath_hal"; $commands[$i++] = "sudo /sbin/rmmod wlan_scan_ap wlan_scan_sta wlan"; $commands[$i++] = "sudo /sbin/modprobe ath_pci autocreate=none ratectl=$rate_alg"; } $commands[$i++] = "sudo /usr/local/bin/wlanconfig $ath create wlandev $wifi wlanmode $mode"; } if (!$save_hassle) { $commands[$i++] = "sudo /usr/local/sbin/iwpriv $ath mode $pmode"; } $commands[$i] = "sudo /usr/local/sbin/iwconfig $ath essid $essid channel $channel rate $rate txpower $txpower mode $iwmode"; if ($mode eq 'sta' && $ap_mac ne '') { $commands[$i] .= " ap $ap_mac"; } ++$i; if (!$save_hassle) { $commands[$i++] = "sudo /sbin/ifconfig $ath inet $ip netmask $netmask"; } if ($boot_pings > 0) { $commands[$i++] = "sudo /bin/ping -i 0.1 -c $boot_pings -b $network"; } if ($do_mon_vdev) { $athmon = "ath" . ($iface_num + 10); $commands[$i++] = "sudo /usr/local/bin/wlanconfig $athmon create wlandev $wifi wlanmode monitor"; $commands[$i++] = "sudo /sbin/ifconfig $athmon up"; } my $rretval = 0; for ($i = 0; $i < scalar(@commands); ++$i) { print "COMMAND: '" . $commands[$i] . "' ... "; if (!$idempotent) { my $retval = system($commands[$i]); if ($retval == 0) { print "ok\n"; } else { $rrteval |= $retval; print "error\n"; #exit(-3); } } else { print "noexec\n"; } } exit $rretval;