/[baselayout]/trunk/net-scripts/net/iwconfig.sh
Gentoo

Contents of /trunk/net-scripts/net/iwconfig.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2091 - (show annotations) (download) (as text)
Wed Jun 14 21:13:31 2006 UTC (7 years, 10 months ago) by uberlord
File MIME type: text/x-sh
File size: 25455 byte(s)
    {start,stop}_volumes moved to rc and halt.sh respectively.

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