/[baselayout]/branches/baselayout-1_12/net-scripts/net/iwconfig.sh
Gentoo

Contents of /branches/baselayout-1_12/net-scripts/net/iwconfig.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2542 - (show annotations) (download) (as text)
Thu Apr 5 10:07:56 2007 UTC (7 years, 8 months ago) by uberlord
File MIME type: text/x-sh
File size: 25838 byte(s)
eval essid and key settings, #164846
1 # Copyright 2004-2007 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # Contributed by Roy Marples (uberlord@gentoo.org)
4 # Many thanks to all the people in the Gentoo forums for their ideas and
5 # motivation for me to make this and keep on improving it
6
7 # Fix any potential localisation problems
8 # Note that LC_ALL trumps LC_anything_else according to locale(7)
9 iwconfig() {
10 LC_ALL=C /sbin/iwconfig "$@"
11 }
12 iwgetid() {
13 LC_ALL=C /sbin/iwgetid "$@"
14 }
15 iwlist() {
16 LC_ALL=C /sbin/iwlist "$@"
17 }
18 iwpriv() {
19 LC_ALL=C /sbin/iwpriv "$@"
20 }
21
22 # void iwconfig_depend(void)
23 #
24 # Sets up the dependancies for the module
25 iwconfig_depend() {
26 after plug
27 before interface
28 provide wireless
29 functions interface_up interface_down interface_exists
30 }
31
32 # void iwconfig_expose(void)
33 #
34 # Expose variables that can be configured
35 iwconfig_expose() {
36 variables essid mode associate_timeout sleep_scan preferred_aps blacklist_aps
37 }
38
39 # bool iwconfig_check_installed(void)
40 #
41 # Returns 1 if wireless-tools is installed, otherwise 0
42 iwconfig_check_installed() {
43 local report=${1:-false}
44 [[ -x /sbin/iwconfig ]] && return 0
45 ${report} && eerror "For Wireless (802.11) support, emerge net-wireless/wireless-tools"
46
47 if [[ ! -e /proc/net/wireless ]]; then
48 installed="1"
49 if ${report} ; then
50 eerror "iwconfig requires wireless support"
51 eerror "(CONFIG_NET_WIRELESS=y) enabled in the kernel"
52 fi
53 fi
54
55 return 1
56 }
57
58 # bool iwconfig_exists(char *interface)
59 #
60 # Checks to see if wireless extensions are enabled on the interface
61 iwconfig_exists() {
62 # Support new sysfs layout
63 [[ -L /sys/class/net/$1/wiphy || -d /sys/class/net/$1/wireless ]] \
64 && return 0
65
66 [[ ! -e /proc/net/wireless ]] && return 1
67 grep -q "^[ \t]*$1:" /proc/net/wireless
68 }
69
70 # char* iwconfig_get_wep_status(char *interface)
71 #
72 # Echos a string showing whether WEP is enabled or disabled
73 # for the given interface
74 iwconfig_get_wep_status() {
75 local mode= status="disabled"
76
77 if iwconfig "$1" | grep -qE "^ +Encryption key:[*0-9,A-F]" ; then
78 status="enabled"
79 mode=$(iwconfig "$1" | sed -n -e 's/^.*Security mode:\(.*[^ ]\).*/\1/p')
80 [[ -n ${mode} ]] && mode=" - ${mode}"
81 fi
82
83 echo "(WEP ${status}${mode})"
84 }
85
86 # char* iwconfig_get_essid(char *iface)
87 #
88 # Gets the current ESSID of the iface
89 iwconfig_get_essid() {
90 local i= essid=
91
92 for (( i=0; i<5; i++ )); do
93 essid=$( iwgetid --raw "$1" )
94 if [[ -n ${essid} ]] ; then
95 echo "${essid}"
96 return 0
97 fi
98 sleep 1
99 done
100
101 return 1
102 }
103
104 # char* iwconfig_get_ap_mac_address(char *interface)
105 #
106 # Returns the MAC address of the Access Point
107 # the interface is connected to
108 iwconfig_get_ap_mac_address() {
109 iwgetid --raw --ap "$1"
110 }
111
112 # char* iwconfig_get_mode(char *interface)
113 #
114 # Returns the wireless mode in lower case
115 iwconfig_get_mode() {
116 iwgetid --mode "$1" | sed -n -e 's/^.*Mode:\(.*\)/\L\1/p'
117 }
118
119 iwconfig_set_mode() {
120 local iface="$1" mode="$2"
121 [[ ${mode} == $(iwconfig_get_mode "${iface}") ]] && return 0
122
123 # Devicescape stack requires the interface to be down
124 interface_down "${iface}"
125 if ! iwconfig "${iface}" mode "${mode}" ; then
126 eerror "${iface} does not support setting the mode to \"${mode}\""
127 return 1
128 fi
129 interface_up "${iface}"
130 }
131
132 # char* iwconfig_get_type(char *interface)
133 #
134 # Returns the type of interface - the IEEE part
135 iwconfig_get_type() {
136 iwconfig "$1" | sed -n -e 's/^'"$1"' *\([^ ]* [^ ]*\).*/\1/p'
137 }
138
139 # void iwconfig_report(char *interface)
140 #
141 # Output how our wireless interface has been configured
142 iwconfig_report() {
143 local iface="$1" essid= mac= m="connected to"
144
145 essid=$(iwconfig_get_essid "${iface}")
146
147 local wep_status=$(iwconfig_get_wep_status "${iface}")
148 local channel=$(iwgetid --raw --channel "${iface}")
149 [[ -n ${channel} ]] && channel="on channel ${channel} "
150
151 essid="${essid//\\\\/\\\\}"
152 local mode=$(iwconfig_get_mode "${iface}")
153 if [[ ${mode} == "master" ]]; then
154 m="configured as"
155 else
156 mac=$(iwconfig_get_ap_mac_address "${iface}")
157 [[ -n ${mac} ]] && mac=" at ${mac}"
158 fi
159
160 eindent
161 einfo "${iface} ${m} ESSID \"${essid}\"${mac}"
162 einfo "in ${mode} mode ${channel}${wep_status}"
163 eoutdent
164 }
165
166 # char* iwconfig_get_wep_key(char *mac_address)
167 #
168 # Returns the configured WEP key for the given mac address
169 # or the given ESSID. The mac address setting takes precendence
170 iwconfig_get_wep_key() {
171 local mac="$1" key=
172 key="mac_key_${mac//:/}"
173 [[ -z ${!key} ]] && key="key_${ESSIDVAR}"
174 echo "${!key:-off}"
175 }
176
177 # void iwconfig_user_config(char *iface, char *ifvar)
178 #
179 # Applies the user configuration to the interface
180 iwconfig_user_config() {
181 local iface="$1" conf= aconf= ifvar="$2"
182 [[ -z ${ifvar} ]] && ifvar=$(bash_variable "$1")
183
184 # Apply the user configuration
185 conf="iwconfig_${ifvar}"
186 if [[ -n ${!conf} ]]; then
187 aconf=( "${!conf}" )
188 for conf in "${aconf[@]}" ; do
189 if ! iwconfig "${iface}" ${conf} ; then
190 ewarn "${iface} does not support the following configuration commands"
191 ewarn " ${conf}"
192 fi
193 done
194 fi
195
196 conf="iwpriv_${ifvar}[@]"
197 if [[ -n ${!conf} ]]; then
198 aconf=( "${!conf}" )
199 for conf in "${aconf[@]}" ; do
200 if ! iwpriv "${iface}" ${conf} ; then
201 ewarn "${iface} does not support the following private ioctls"
202 ewarn " ${conf}"
203 fi
204 done
205 fi
206 }
207
208 # bool iwconfig_setup_specific(char *iface)
209 #
210 # Sets up our wireless interface to operate in ad-hoc or master mode
211 iwconfig_setup_specific() {
212 local iface="$1" mode="$2" channel= key= dessid=
213 local ifvar=$(bash_variable "$1")
214
215 if [[ -z ${ESSID} ]]; then
216 eerror "${iface} requires an ESSID to be set to operate in ${mode} mode"
217 eerror "adjust the essid_${iface} setting in /etc/conf.d/wireless"
218 return 1
219 fi
220 dessid="${ESSID//\\\\/\\\\}"
221 ESSIDVAR=$(bash_variable "${ESSID}")
222 key=$(iwconfig_get_wep_key)
223
224 iwconfig_set_mode "${iface}" "${mode}"
225
226 # Now set the key
227 if ! eval iwconfig "${iface}" key "${key}" ; then
228 if [[ ${key} != "off" ]]; then
229 ewarn "${iface} does not support setting keys"
230 ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect"
231 fi
232 fi
233
234 # Then set the ESSID
235 if ! eval iwconfig "${iface}" essid "${ESSID}" ; then
236 eerror "${iface} does not support setting ESSID to \"${dessid}\""
237 return 1
238 fi
239
240 channel="channel_${ifvar}"
241 # We default the channel to 3
242 if ! iwconfig "${iface}" channel "${!channel:-3}" ; then
243 ewarn "${iface} does not support setting the channel to \"${!channel:-3}\""
244 return 1
245 fi
246
247 # Finally apply the user Config
248 iwconfig_user_config "${iface}" "${ESSIDVAR}"
249
250 iwconfig_report "${iface}"
251
252 return 0
253 }
254
255 # bool iwconfig_associate_mac(char *iface)
256 #
257 # Returns true if the AP MAC address is valid or not
258 iwconfig_associate_mac() {
259 # Checks if a MAC address has been assigned
260 local mac=$(iwconfig_get_ap_mac_address "$1") i=
261 local -a invalid_macs=(
262 "00:00:00:00:00:00"
263 "44:44:44:44:44:44"
264 "FF:00:00:00:00:00"
265 "FF:FF:FF:FF:FF:FF"
266 )
267
268 [[ -z ${mac} ]] && return 1
269 for i in "${invalid_macs[@]}"; do
270 [[ ${mac} == "${i}" ]] && return 1
271 done
272 return 0
273 }
274
275 # bool iwconfig_associate_quality(char *iface)
276 #
277 # Returns true if the link quality is not 0 or 0.
278 iwconfig_associate_quality() {
279 local quality=$( \
280 sed -n -e 's/^.*'"$1"': *[0-9]* *\([0-9]*\).*/\1/p' \
281 /proc/net/wireless
282 )
283 [[ ${quality} != "0" ]]
284 return "$?"
285 }
286
287 # bool iwconfig_test_associated(char *iface)
288 #
289 # Returns true if the interface has associated with an Access Point
290 iwconfig_test_associated() {
291 local iface="$1" ttype= ifvar=$(bash_variable "$1") x=
292 # Some drivers don't set MAC to a bogus value when assocation is lost/fails
293 # whereas they do set link quality to 0
294
295 # Use sysfs if we can
296 if [[ -e /sys/class/net/${iface}/carrier ]] ; then
297 [[ $(</sys/class/net/"${iface}"/carrier) == "1" ]]
298 return $?
299 fi
300
301 x="associate_test_${ifvar}"
302 ttype=$(echo "${!x:-mac}" | tr '[:upper:]' '[:lower:]')
303 if [[ ${ttype} != "mac" && ${ttype} != "quality" && ${ttype} != "all" ]]; then
304 ewarn " associate_test_${iface} is not set to mac, quality or all"
305 ewarn " defaulting to \"mac\""
306 test="mac"
307 fi
308
309 case "${ttype}" in
310 mac) iwconfig_associate_mac "${iface}" && return 0 ;;
311 quality) iwconfig_associate_quality "${iface}" && return 0 ;;
312 all) iwconfig_associate_mac "${iface}" \
313 && iwconfig_associate_quality "${iface}" && return 0 ;;
314 esac
315
316 return 1
317 }
318
319 # bool iwconfig_wait_for_association(char *iface)
320 #
321 # Waits for a configured ammount of time until
322 # we are assocaited with an Access Point
323 iwconfig_wait_for_association() {
324 local iface="$1" i=0 timeout= ifvar=$(bash_variable "$1")
325 timeout="associate_timeout_${ifvar}"
326 [[ -z ${!timeout} ]] && timeout="sleep_associate_${ifvar}"
327 timeout="${!timeout:-10}"
328
329 [[ ${timeout} == "0" ]] \
330 && vewarn "WARNING: infinite timeout set for association on ${iface}"
331
332 while true; do
333 iwconfig_test_associated "${iface}" && return 0
334 sleep 1
335 [[ ${timeout} == "0" ]] && continue
336 (( i++ ))
337 [[ ${i} == "${timeout}" || ${i} -gt ${timeout} ]] && break
338 done
339 return 1
340 }
341
342 # bool iwconfig_associate(char *interface, char *mac_address, char *wep_required)
343 #
344 # Tries to associate the interface with an Access Point
345 # If we scanned the Access Point we know if we need WEP to associate or not
346 # and if we have a WEP key for the ESSID or not
347 # so we can fail gracefully without even trying to connect
348 iwconfig_associate() {
349 local iface="$1" mode="${2:-managed}"
350 local mac="$3" wep_required="$4" freq="$5" chan="$6" w="(WEP Disabled)"
351 local dessid="${ESSID//\\\\/\\\\}" key=
352
353 iwconfig_set_mode "${iface}" "${mode}"
354
355 if [[ ${ESSID} == "any" ]]; then
356 iwconfig "${iface}" ap any 2>/dev/null
357 dessid="any"
358 unset ESSIDVAR
359 else
360 ESSIDVAR=$(bash_variable "${ESSID}")
361 key=$(iwconfig_get_wep_key "${mac}")
362 if [[ ${wep_required} == "on" && ${key} == "off" ]]; then
363 ewarn "WEP key is not set for \"${dessid}\" - not connecting"
364 return 1
365 fi
366 if [[ ${wep_required} == "off" && ${key} != "off" ]]; then
367 key="off"
368 ewarn "\"${dessid}\" is not WEP enabled - ignoring setting"
369 fi
370
371 if ! eval iwconfig "${iface}" key "${key}" ; then
372 if [[ ${key} != "off" ]]; then
373 ewarn "${iface} does not support setting keys"
374 ewarn "or the parameter \"mac_key_${ESSIDVAR}\" or \"key_${ESSIDVAR}\" is incorrect"
375 return 1
376 fi
377 fi
378 [[ ${key} != "off" ]] && w=$(iwconfig_get_wep_status "${iface}")
379 fi
380
381 if ! eval iwconfig "${iface}" essid "${ESSID}" ; then
382 if [[ ${ESSID} != "any" ]]; then
383 ewarn "${iface} does not support setting ESSID to \"${dessid}\""
384 fi
385 fi
386
387 # Only use channel or frequency
388 if [[ -n ${chan} ]] ; then
389 iwconfig "${iface}" channel "${chan}"
390 elif [[ -n ${freq} ]] ; then
391 iwconfig "${iface}" freq "${freq}"
392 fi
393 [[ -n ${mac} ]] && iwconfig "${iface}" ap "${mac}"
394
395 # Finally apply the user Config
396 iwconfig_user_config "${iface}" "${ESSIDVAR}"
397
398 vebegin "Connecting to \"${dessid}\" in ${mode} mode ${w}"
399
400 if [[ ${ESSID} != "any" ]] && is_function preassociate ; then
401 veinfo "Running preassociate function"
402 eindent
403 ( preassociate "${iface}" )
404 e="$?"
405 eoutdent
406 if [[ ${e} != 0 ]]; then
407 veend 1 "preassociate \"${dessid}\" on ${iface} failed"
408 return 1
409 fi
410 fi
411
412 if ! iwconfig_wait_for_association "${iface}" ; then
413 veend 1
414 return 1
415 fi
416 veend 0
417
418 if [[ ${ESSID} == "any" ]]; then
419 ESSID=$(iwconfig_get_essid "${iface}")
420 iwconfig_associate "${iface}"
421 return $?
422 fi
423
424 iwconfig_report "${iface}"
425
426 if is_function postassociate ; then
427 veinfo "Running postassociate function"
428 eindent
429 ( postassociate "${iface}" )
430 eoutdent
431 fi
432
433 return 0
434 }
435
436 # bool iwconfig_scan(char *iface)
437 #
438 # Fills 3 arrays with information from a wireless scan
439 iwconfig_scan() {
440 local iface="$1" mode= x= ifvar=$(bash_variable "$1")
441
442 # Set any private driver ioctls needed
443 x="iwpriv_scan_pre_${ifvar}"
444 if [[ -n ${!x} ]]; then
445 if ! eval iwpriv "${iface}" "${!x}" ; then
446 ewarn "${iface} does not support the following private ioctls" \
447 ewarn " ${!x}"
448 fi
449 fi
450
451 veinfo "Scanning for access points"
452
453 # Sleep if required
454 x="sleep_scan_${ifvar}"
455 [[ -z ${!x} || ${!x} -gt 0 ]] && sleep "${!x:-2}"
456
457 local error=true i=-1 line=
458 local -a mac=() essid=() enc=() qual=() mode=() freq=() chan=()
459
460 while read line; do
461 error=false
462 case "${line}" in
463 *Address:*)
464 (( i++ ))
465 mac[i]=$(echo "${line#*: }" | tr '[:lower:]' '[:upper:]')
466 qual[i]=0
467 ;;
468 *ESSID:*)
469 essid[i]="${line#*\"}"
470 essid[i]="${essid[i]%*\"}"
471 ;;
472 *Mode:*)
473 mode[i]=$(echo "${line#*:}" | tr '[:upper:]' '[:lower:]')
474 [[ ${mode[i]} == "master" ]] && mode[i]="managed"
475 ;;
476 *'Encryption key:'*)
477 enc[i]="${line#*:}"
478 ;;
479 *Frequency:*)
480 freq[i]="${line#*:}"
481 x="${freq[i]#* }"
482 freq[i]="${freq[i]%% *}${x:0:1}"
483 ;;
484 *Channel:*)
485 chan[i]="${line#*:}"
486 chan[i]="${chan[i]%% *}"
487 ;;
488 *Quality*)
489 qual[i]="${line#*:}"
490 qual[i]="${qual[i]%/*}"
491 qual[i]="${qual[i]//[![:digit:]]/}"
492 qual[i]="${qual[i]:-0}"
493 ;;
494 esac
495 done < <(iwlist "${iface}" scan 2>/dev/null)
496
497 if ${error}; then
498 ewarn "${iface} does not support scanning"
499 x="adhoc_essid_${ifvar}"
500 [[ -n ${!x} ]] && return 0
501 if [[ -n ${preferred_aps} ]]; then
502 [[ ${associate_order} == "forcepreferred" \
503 || ${associate_order} == "forcepreferredonly" ]] && return 0
504 fi
505 eerror "You either need to set a preferred_aps list in /etc/conf.d/wireless"
506 eerror " preferred_aps=( \"ESSID1\" \"ESSID2\" )"
507 eerror " and set associate_order_${iface}=\"forcepreferred\""
508 eerror " or set associate_order_${iface}=\"forcepreferredonly\""
509 eerror "or hardcode the ESSID to \"any\" and let the driver find an Access Point"
510 eerror " essid_${iface}=\"any\""
511 eerror "or configure defaulting to Ad-Hoc when Managed fails"
512 eerror " adhoc_essid_${iface}=\"WLAN\""
513 eerror "or hardcode the ESSID against the interface (not recommended)"
514 eerror " essid_${iface}=\"ESSID\""
515 return 1
516 fi
517
518 # We may need to unset the previous private driver ioctls
519 x="iwpriv_scan_post_${ifvar}"
520 if [[ -n ${!x} ]]; then
521 if ! eval iwpriv "${iface}" "${!x}" ; then
522 ewarn "${iface} does not support the following private ioctls" \
523 ewarn " ${!x}"
524 fi
525 fi
526
527 # Strip any duplicates
528 local i= j= x="${#mac[@]}" y=
529 for (( i=0; i<x-1; i++ )) ; do
530 [[ -z ${mac[i]} ]] && continue
531 for (( j=i+1; j<x; j++)) ; do
532 if [[ ${mac[i]} == "${mac[j]}" ]] ; then
533 if [[ ${qual[i]} -gt ${qual[j]} ]] ; then
534 y="${j}"
535 else
536 y="${j}"
537 fi
538 unset mac[y]
539 unset qual[y]
540 unset essid[y]
541 unset mode[y]
542 unset enc[y]
543 unset freq[y]
544 unset chan[y]
545 fi
546 done
547 done
548 mac=( "${mac[@]}" )
549 qual=( "${qual[@]}" )
550 essid=( "${essid[@]}" )
551 mode=( "${mode[@]}" )
552 enc=( "${enc[@]}" )
553 freq=( "${freq[@]}" )
554 chan=( "${chan[@]}" )
555
556 for (( i=0; i<${#mac[@]}; i++ )); do
557 # Don't like ad-hoc nodes by default
558 [[ ${mode[i]} == "ad-hoc" ]] && (( qual[i]-=10000 ))
559 sortline="${sortline}${qual[i]} ${i}\n"
560 done
561 sortline=( $(echo -e "${sortline}" | sort -nr) )
562
563 for (( i=0; i<${#mac[@]}; i++ )); do
564 (( x=(i * 2) + 1 ))
565 mac_APs[i]="${mac[${sortline[x]}]}"
566 essid_APs[i]="${essid[${sortline[x]}]}"
567 mode_APs[i]="${mode[${sortline[x]}]}"
568 enc_APs[i]="${enc[${sortline[x]}]}"
569 freq_APs[i]="${freq[${sortline[x]}]}"
570 chan_APs[i]="${chan[${sortline[x]}]}"
571 done
572
573 return 0
574 }
575
576 # void iwconfig_scan_report(void)
577 #
578 # Report the results of the scan and re-map any ESSIDs if they
579 # have been configured for the MAC address found
580 iwconfig_scan_report() {
581 local i= k= m= remove=
582 local -a u=()
583
584 [[ -z ${mac_APs} ]] && ewarn " no access points found"
585
586 # We need to do the for loop like this so we can
587 # dynamically remove from the array
588 eindent
589 for ((i=0; i<${#mac_APs[@]}; i++)); do
590 k="(${mode_APs[i]}"
591 [[ ${enc_APs[i]} != "off" ]] && k="${k}, encrypted"
592 k="${k})"
593
594 if [[ -z ${essid_APs[i]} ]]; then
595 veinfo "Found ${mac_APs[i]} ${k}"
596 else
597 veinfo "Found \"${essid_APs[i]//\\\\/\\\\}\" at ${mac_APs[i]} ${k}"
598 fi
599
600 eindent
601
602 m="mac_essid_${mac_APs[i]//:/}"
603 if [[ -n ${!m} ]]; then
604 essid_APs[i]="${!m}"
605 veinfo "mapping to \"${!m//\\\\/\\\\}\""
606 fi
607
608 remove=false
609 # If we don't know the essid then we cannot connect to them
610 # so we remove them from our array
611 if [[ -z ${essid_APs[i]} ]]; then
612 remove=true
613 else
614 for k in "${blacklist_aps[@]}"; do
615 if [[ ${k} == "${essid_APs[i]}" ]]; then
616 vewarn "\"${k//\\\\/\\\\}\" has been blacklisted - not connecting"
617 remove=true
618 break
619 fi
620 done
621 fi
622
623 eoutdent
624
625 ${remove} && u=( "${u[@]}" "${i}" )
626 done
627
628 eoutdent
629
630 # Now we remove any duplicates
631 for ((i=0; i < ${#essid_APs[@]} - 1; i++)); do
632 for ((j=${i} + 1; j <${#essid_APs[@]}; j++)); do
633 [[ ${essid_APs[i]} == "${essid_APs[j]}" ]] && u=( "${u[@]}" "${j}" )
634 done
635 done
636
637 for i in ${u[@]}; do
638 unset essid_APs[i]
639 unset mode_APs[i]
640 unset mac_APs[i]
641 unset enc_APs[i]
642 unset freq_APs[i]
643 unset chan_APs[i]
644 done
645
646 # We need to squash our arrays so indexes work again
647 essid_APs=( "${essid_APs[@]}" )
648 mode_APs=( "${mode_APs[@]}" )
649 mac_APs=( "${mac_APs[@]}" )
650 enc_APs=( "${enc_APs[@]}" )
651 freq_APs=( "${freq_APs[@]}" )
652 chan_APs=( "${chan_APs[@]}" )
653 }
654
655 # bool iwconfig_force_preferred(char *iface)
656 #
657 # Forces the preferred_aps list to associate in order
658 # but only if they were not picked up by our scan
659 iwconfig_force_preferred() {
660 local iface=$1 essid= i=
661
662 [[ -z ${preferred_aps} ]] && return 1
663
664 ewarn "Trying to force preferred in case they are hidden"
665 for essid in "${preferred_aps[@]}"; do
666 local found_AP=false
667 for ((i = 0; i < ${#mac_APs[@]}; i++)); do
668 if [[ ${essid} == "${essid_APs[i]}" ]]; then
669 found_AP=true
670 break
671 fi
672 done
673 if ! ${found_AP} ; then
674 ESSID="${essid}"
675 iwconfig_associate "${iface}" && return 0
676 fi
677 done
678
679 ewarn "Failed to associate with any preferred access points on ${iface}"
680 return 1
681 }
682
683 # bool iwconfig_connect_preferred(char *iface)
684 #
685 # Connects to preferred_aps in order if they were picked up
686 # by our scan
687 iwconfig_connect_preferred() {
688 local iface="$1" essid= i=
689
690 for essid in "${preferred_aps[@]}"; do
691 for ((i=0; i<${#essid_APs[@]}; i++)); do
692 if [[ ${essid} == "${essid_APs[i]}" ]]; then
693 ESSID="${essid}"
694 iwconfig_associate "${iface}" "${mode_APs[i]}" "${mac_APs[i]}" \
695 "${enc_APs[i]}" "${freq_APs[i]}" "${chan_APs[i]}" && return 0
696 break
697 fi
698 done
699 done
700
701 return 1
702 }
703
704 # bool iwconfig_connect_not_preferred(char *iface)
705 #
706 # Connects to any AP's found that are not in
707 # our preferred list
708 iwconfig_connect_not_preferred() {
709 local iface=$1 i= ap= has_preferred=
710
711 for ((i=0; i<${#mac_APs[@]}; i++)); do
712 has_preferred=false
713 for ap in "${preferred_aps[@]}"; do
714 if [[ ${ap} == "${essid_APs[i]}" ]]; then
715 has_preferred=true
716 break
717 fi
718 done
719 if ! ${has_preferred} ; then
720 ESSID="${essid_APs[i]}"
721 iwconfig_associate "${iface}" "${mode_APs[i]}" "${mac_APs[i]}" \
722 "${enc_APs[i]}" "${freq_APs[i]}" "${chan_APs[i]}" && return 0
723 fi
724 done
725
726 return 1
727 }
728
729 # void iwconfig_defaults(char *iface)
730 #
731 # Apply some sane defaults to the wireless interface
732 # incase the user already applied some changes
733 iwconfig_defaults() {
734 local iface="$1"
735
736 # Set some defaults
737 iwconfig "${iface}" txpower auto 2>/dev/null
738 iwconfig "${iface}" rate auto 2>/dev/null
739 iwconfig "${iface}" rts auto 2>/dev/null
740 iwconfig "${iface}" frag auto 2>/dev/null
741
742 # Release the AP forced
743 # Must do ap and then essid otherwise scanning borks
744 iwconfig "${iface}" ap off 2>/dev/null
745 iwconfig "${iface}" essid off 2>/dev/null
746 }
747
748 # void iwconfig_strip_associated(char *iface)
749 #
750 # We check to see which ifaces have associated AP's except for the iface
751 # given and remove those AP's from the scan list
752 # We also remove from the preferred list
753 iwconfig_strip_associated() {
754 local iface="$1" e= a= j=
755 local essid=$(iwconfig_get_essid "${iface}")
756 local -a ifaces=( $( iwconfig 2>/dev/null | grep -o "^\w*" ) )
757
758 for i in "${ifaces[@]}"; do
759 [[ ${i} == ${iface} ]] && continue
760 interface_is_up "${i}" || continue
761 iwconfig_test_associated "${i}" || continue
762 e=$(iwconfig_get_essid "${i}")
763 local -a u=()
764 for ((j=0; j<${#mac_APs[@]}; j++)); do
765 if [[ ${essid_APs[j]} == "${e}" ]]; then
766 ewarn "${e} has already been associated with ${i}"
767 unset essid_APs[j]
768 unset mode_Aps[j]
769 unset mac_APs[j]
770 unset enc_APs[j]
771 unset freq_APs[j]
772 unset chan_APs[j]
773 # We need to squash our arrays so that indexes work
774 essid_APs=( "${essid_APs[@]}" )
775 mode_APs=( "${mode_APs[@]}" )
776 mac_APs=( "${mac_APs[@]}" )
777 enc_APs=( "${enc_APs[@]}" )
778 freq_APs=( "${freq_APs[@]}" )
779 chan_APs=( "${chan_APs[@]}" )
780 break
781 fi
782 done
783 for ((j=0; j<${#preferred_aps[@]}; j++)); do
784 if [[ ${preferred_aps[j]} == "${e}" ]]; then
785 unset preferred_aps[j]
786 preferred_aps=( "${preferred_aps[@]}" )
787 break
788 fi
789 done
790 done
791 }
792
793 # bool iwconfig_configure(char *iface)
794 #
795 # The main startup code
796 # First we bring the interface up, apply defaults, apply user configuration
797 # Then we test to see if ad-hoc mode has been requested and branch if needed
798 # Then we scan for access points and try to connect to them in a predetermined order
799 # Once we're connected we show a report and then configure any interface
800 # variables for the ESSID
801 iwconfig_configure() {
802 local iface="$1" e= x= ifvar=$(bash_variable "$1")
803 local -a essid_APs=() mac_APs=() mode_APs=()
804 local -a enc_APs=() freq_APs=() chan_APs=()
805
806 ESSID="essid_${ifvar}"
807 ESSID="${!ESSID}"
808
809 # Setup ad-hoc mode?
810 x="mode_${ifvar}"
811 x=$(echo "${!x:-managed}" | tr '[:upper:]' '[:lower:]')
812 if [[ ${x} == "ad-hoc" || ${x} == "master" ]]; then
813 iwconfig_setup_specific "${iface}" "${x}"
814 return $?
815 fi
816
817 if [[ ${x} != "managed" && ${x} != "auto" ]]; then
818 eerror "Only managed, ad-hoc, master and auto modes are supported"
819 return 1
820 fi
821
822 # Has an ESSID been forced?
823 if [[ -n ${ESSID} ]]; then
824 iwconfig_set_mode "${iface}" "${x}"
825 iwconfig_associate "${iface}" && return 0
826 [[ ${ESSID} == "any" ]] && iwconfig_force_preferred "${iface}" && return 0
827
828 ESSID="adhoc_essid_${ifvar}"
829 ESSID="${!ESSID}"
830 if [[ -n ${ESSID} ]]; then
831 iwconfig_setup_specific "${iface}" ad-hoc
832 return $?
833 fi
834 return 1
835 fi
836
837 # Do we have a preferred Access Point list specific to the interface?
838 x="preferred_aps_${ifvar}[@]"
839 [[ -n ${!x} ]] && preferred_aps=( "${!x}" )
840
841 # Do we have a blacklist Access Point list specific to the interface?
842 x="blacklist_aps_${ifvar}[@]"
843 [[ -n ${!x} ]] && blacklist_aps=( "${!x}" )
844
845 # Are we forcing preferred only?
846 x="associate_order_${ifvar}"
847 [[ -n ${!x} ]] && associate_order="${!x}"
848 associate_order=$(echo "${associate_order:-any}" \
849 | tr '[:upper:]' '[:lower:]')
850
851 if [[ ${associate_order} == "forcepreferredonly" ]]; then
852 iwconfig_force_preferred "${iface}" && return 0
853 else
854 iwconfig_scan "${iface}" || return 1
855 iwconfig_scan_report
856
857 # Strip AP's from the list that have already been associated with
858 # other wireless cards in the system if requested
859 x="unique_ap_${ifvar}"
860 [[ -n ${!x} ]] && unique_ap="${!x}"
861 unique_ap=$(echo "${unique_ap:-no}" | tr '[:upper:]' '[:lower:]')
862 [[ ${unique_ap} != "no" ]] && iwconfig_strip_associated "${iface}"
863
864 iwconfig_connect_preferred "${iface}" && return 0
865 [[ ${associate_order} == "forcepreferred" \
866 || ${associate_order} == "forceany" ]] \
867 && iwconfig_force_preferred "${iface}" && return 0
868 [[ ${associate_order} == "any" || ${associate_order} == "forceany" ]] \
869 && iwconfig_connect_not_preferred "${iface}" && return 0
870 fi
871
872 e="associate with"
873 [[ -z ${mac_APs} ]] && e="find"
874 [[ ${preferred_only} == "force" || ${preferred_aps} == "forceonly" ]] \
875 && e="force"
876 e="Couldn't ${e} any access points on ${iface}"
877
878 ESSID="adhoc_essid_${ifvar}"
879 ESSID="${!ESSID}"
880 if [[ -n ${ESSID} ]]; then
881 ewarn "${e}"
882 iwconfig_setup_specific "${iface}" ad-hoc
883 return $?
884 fi
885
886 eerror "${e}"
887 return 1
888 }
889
890 # bool iwconfig_pre_start(char *iface)
891 #
892 # Start entry point
893 # First we check if wireless extensions exist on the interface
894 # If they are then we configue wireless
895 iwconfig_pre_start() {
896 local iface="$1" r=0
897
898 # We don't configure wireless if we're being called from
899 # the background
900 ${IN_BACKGROUND} && return 0
901
902 save_options "ESSID" ""
903 interface_exists "${iface}" || return 0
904
905 # We need to bring the interface up, as some cards do not register
906 # in /proc/wireless until they are brought up.
907 interface_up "${iface}"
908
909 if ! iwconfig_exists "${iface}" ; then
910 veinfo "Wireless extensions not found for ${iface}"
911 return 0
912 fi
913
914 iwconfig_defaults "${iface}"
915 iwconfig_user_config "${iface}"
916
917 # Set the base metric to be 2000
918 metric=2000
919
920 # Check for rf_kill - only ipw supports this at present, but other
921 # cards may in the future.
922 if [[ -e "/sys/class/net/${iface}/device/rf_kill" ]]; then
923 if [[ $( < "/sys/class/net/${iface}/device/rf_kill" ) != 0 ]]; then
924 eerror "Wireless radio has been killed for interface ${iface}"
925 return 1
926 fi
927 fi
928
929 einfo "Configuring wireless network for ${iface}"
930
931 # Are we a proper IEEE device?
932 # Most devices reutrn IEEE 802.11b/g - but intel cards return IEEE
933 # in lower case and RA cards return RAPCI or similar
934 # which really sucks :(
935 # For the time being, we will test prism54 not loading firmware
936 # which reports NOT READY!
937 x=$(iwconfig_get_type "${iface}")
938 if [[ ${x} == "NOT READY!" ]]; then
939 eerror "Looks like there was a probem loading the firmware for ${iface}"
940 return 1
941 fi
942
943 # Setup IFS incase parent script has modified it
944 local IFS=$' '$'\n'$'\t'
945
946 if iwconfig_configure "${iface}" ; then
947 save_options "ESSID" "${ESSID}"
948 return 0
949 fi
950
951 eerror "Failed to configure wireless for ${iface}"
952 iwconfig_defaults "${iface}"
953 iwconfig "${iface}" txpower off 2>/dev/null
954 unset ESSID ESSIDVAR
955 interface_down "${iface}"
956 return 1
957 }
958
959 iwconfig_post_stop() {
960 ${IN_BACKGROUND} && return 0
961 interface_exists "${iface}" || return 0
962 iwconfig_defaults "${iface}"
963 iwconfig "${iface}" txpower off 2>/dev/null
964 }
965
966 # vim: set ts=4 :

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20