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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20