iwpick (3405B)
1 #!/bin/bash 2 # Connects to a network 3 # Requires: wpa_supplicant, dhclient and the iwconfig suite 4 5 NETWORKS_FILE=~/.networks 6 newline=" 7 " 8 9 SCANRETRIES=3 10 SCANWAITSEC=3 11 12 ARGV0="$(basename "$0")" 13 14 connect() { 15 iface=$1 16 essid=$2 17 key=$3 18 addr="$4" 19 gw="$5" 20 21 iwconfig $iface essid "$essid" 22 if [ -n "$key" ]; then 23 tmp=$(mktemp) 24 echo -n "$key" | wpa_passphrase "$essid" >> $tmp 2>/dev/null 25 wpa_supplicant -i $iface -c "$tmp" -B 2>&1 > /dev/null 26 rm $tmp 27 fi 28 29 # if no addr then use dhcp 30 if [ -z "$addr" ]; then 31 dhclient $iface >/dev/null & 32 while [ -z "$gw" ]; do 33 pkt="$(tcpdump -vlni $iface -c 1 -Q in udp 2>&1)" 34 addr="$(echo "$pkt" |grep "Your-IP" |tr -d [:space:] |cut -b8-)" 35 dgw="$(echo "$pkt" |grep "Gateway-IP" |tr -d [:space:] |cut -b11-)" 36 egw="$(echo "$pkt" |grep "Default-Gateway" |tr -d [:space:] |cut -d: -f2)" 37 [ -n "$dgw" ] && gw="$dgw" || gw="$egw" 38 done 39 fi 40 [ -n "$addr" ] && ifconfig $iface $addr 2>/dev/null 41 [ -n "$gw" ] && route add default gw $gw 2>/dev/null 42 } 43 44 die() { 45 echo "$ARGV0: $@" 46 exit 1 47 } 48 49 emsg() { 50 echo "$@" > /dev/stderr 51 } 52 53 pickone() { 54 iface="$1" 55 file="$2" 56 retry="$3" 57 #ids=$(iwlist "$iface" scan |grep ESSID |cut -d'"' -f2) 58 scanned="$(iwlist "$iface" scan 2> /dev/null)" 59 rv=$? 60 61 if [ $rv -ne 0 ]; then 62 [ -z "$retry" ] && retry=1 63 emsg "Device busy. Retry in $SCANWAITSEC seconds ($retry/$SCANRETRIES)..." 64 [ $retry -eq $SCANRETRIES ] && exit 1 65 sleep "$SCANWAITSEC" 66 retry="$(echo "$retry + 1" | bc)" 67 pickone "$iface" "$file" "$retry" 68 exit $? 69 fi 70 71 ids="$(echo "$scanned" |grep ESSID | cut -d'"' -f2)" 72 nets="$(cat "$file")" 73 74 oifs="$IFS" 75 IFS="$newline" 76 for net in $nets; do 77 essid="$(echo "$net" |cut -d: -f2)" 78 for id in $ids; do 79 if [ "$id" = "$essid" ]; then 80 echo "$net" 81 return 82 fi 83 done 84 done 85 IFS="$oifs" 86 } 87 88 usage() { 89 echo -n "Usage: $ARGV0 [-hg] [-i <iface>] [-e <essid>] [-k <psk>] [-a <alias>] 90 -i <iface> Network interface 91 -a <alias> Use the specified alias to connect 92 -e <essid> ESSID of the network to connect 93 -k <key> Key of the network to connect 94 -f <file> Networks file 95 -p Connect to a known network 96 -h Show this help 97 " 98 exit 1 99 } 100 101 main() { 102 iface="$(ifconfig -a -s |grep ^wl |head -1 |cut -d ' ' -f1)" 103 file="$NETWORKS_FILE" 104 alias= 105 essid= 106 key= 107 pick=0 108 109 while getopts "inpa:e:k:f:h" o; do 110 case $o in 111 i) iface=$OPTARG;; 112 a) alias=$OPTARG;; 113 e) essid=$OPTARG;; 114 k) key=$OPTARG;; 115 f) file=$OPTARG;; 116 p) pick=1;; 117 h) usage;; 118 esac 119 done 120 121 uid="$(id -u)" 122 if [ "$uid" -ne 0 ]; then 123 [ ! -u "$0" ] && die "You must be root." 124 sudo HOME="$HOME" $0 $@ 125 exit $? 126 fi 127 128 if [ -n "$alias" ]; then 129 net="$(sed -n "/^${alias}:/p" "$file")" 130 [ -z "$net" ] && die "alias '${alias}' not found" 131 elif [ $pick -eq 1 ]; then 132 echo "Looking for a suitable network... " 133 net="$(pickone "$iface" "$file")" 134 [ -z "$net" ] && die "no network found." 135 else 136 usage 137 fi 138 139 essid="$(echo $net |cut -d: -f2)" 140 key="$(echo $net |cut -sd: -f3)" 141 addr="$(echo $net |cut -sd: -f4)" 142 gw="$(echo $net |cut -sd: -f5)" 143 144 echo "Connecting to ${essid}..." 145 146 # If explicitly specified, check if the ESSID do exists 147 valid="$(iwlist $iface scan |grep ESSID |grep -wc "$essid")" 148 [ $valid -eq 0 ] && die "$essid: no network found" 149 ifconfig $iface up 0.0.0.0 150 apps=(wpa_supplicant dhclient) 151 for a in ${apps[@]} 152 do 153 pkill -f "$a" 154 done 155 connect "$iface" "$essid" "$key" "$addr" "$gw" 156 echo "Connected." 157 } 158 159 main "$@"