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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2534 - (show annotations) (download) (as text)
Thu Mar 22 10:14:03 2007 UTC (7 years, 9 months ago) by uberlord
File MIME type: text/x-sh
File size: 11220 byte(s)
Backport fix from trunk to stop wpa_supplicant associating before we are ready, #171273.
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
5 # Fix any potential localisation problems
6 # Note that LC_ALL trumps LC_anything_else according to locale(7)
7 wpa_supplicant() {
8 LC_ALL=C /sbin/wpa_supplicant "$@"
9 }
10
11 wpa_cli() {
12 if [[ -n ${ctrl_dir} ]] ; then
13 LC_ALL=C /bin/wpa_cli -p "${ctrl_dir}" "$@"
14 else
15 LC_ALL=C /bin/wpa_cli "$@"
16 fi
17 }
18
19 # void wpa_supplicant_depend(void)
20 #
21 # Sets up the dependancies for the module
22 wpa_supplicant_depend() {
23 after macnet plug
24 before interface
25 provide wireless
26 functions interface_exists
27 }
28
29 # void wpa_supplicant_expose(void)
30 #
31 # Expose variables that can be configured
32 wpa_supplicant_expose() {
33 variables associate_timeout wpa_supplicant
34 }
35
36 # bool wpa_supplicant_check_installed(void)
37 #
38 # Returns 0 if wpa_supplicant is installed, otherwise 1
39 wpa_supplicant_check_installed() {
40 [[ -x /sbin/wpa_supplicant ]] && return 0
41 ${1:-false} && eerror "For WPA support (wpa_supplicant) support, emerge net-wireless/wpa_supplicant"
42 return 1
43 }
44
45 # bool wpa_supplicant_exists(char *interface)
46 #
47 # Checks to see if wireless extensions are enabled on the interface
48 wpa_supplicant_exists() {
49 # Support new sysfs layout
50 [[ -L /sys/class/net/$1/wiphy || -d /sys/class/net/$1/wireless ]] \
51 && return 0
52
53 [[ ! -e /proc/net/wireless ]] && return 1
54 grep -q "^[ \t]*$1:" /proc/net/wireless
55 }
56
57 # char* wpa_supplicant_get_essid(char *interface)
58 #
59 # Gets the current ESSID of iface
60 wpa_supplicant_get_essid() {
61 local i= essid=
62
63 for (( i=0; i<5; i++ )); do
64 essid=$( wpa_cli -i"$1" status | sed -n -e 's/^ssid=//p' )
65 if [[ -n ${essid} ]] ; then
66 echo "${essid}"
67 return 0
68 fi
69 sleep 1
70 done
71
72 return 1
73 }
74
75 # char* wpa_supplicant_get_ap_mac_address(char *interface)
76 #
77 # Returns the MAC address of the Access Point
78 # the interface is connected to
79 wpa_supplicant_get_ap_mac_address() {
80 wpa_cli -i"$1" status | sed -n -e 's/^bssid=\([^=]\+\).*/\U\1/p'
81 }
82
83 # bool wpa_supplicant_associated(char *interface)
84 #
85 # Returns 0 if we're associated correctly or 1 if not
86 # Note that just because we are associated does not mean we are using the
87 # correct encryption keys
88 wpa_supplicant_associated() {
89 local -a status=()
90 eval status=( $(wpa_cli -i"$1" status \
91 | sed -n -e 's/^\(key_mgmt\|wpa_state\|EAP state\)=\([^=]\+\).*/\U\"\2\"/p')
92 )
93
94 case "${status[0]}" in
95 "NONE")
96 [[ ${status[1]} == "ASSOCIATED" || ${status[1]} == "COMPLETED" ]]
97 ;;
98 "IEEE 802.1X (no WPA)")
99 [[ ${status[2]} == "SUCCESS" ]]
100 ;;
101 *)
102 [[ ${status[1]} == "COMPLETED" ]]
103 ;;
104 esac
105
106 return $?
107 }
108
109 # void wpa_supplicant_kill(char *interface, bool report)
110 #
111 # Kills any existing wpa_supplicant process on the interface
112 wpa_supplicant_kill() {
113 local iface="$1" report="${2:-false}" pidfile=
114
115 # Shutdown wpa_cli first, if it's running
116 # This is important as future versions of wpa_supplicant
117 # may send a disconnect message to wpa_cli when it shutsdown
118 pidfile="/var/run/wpa_cli-${iface}.pid"
119 if [[ -f ${pidfile} ]] ; then
120 ${report} && ebegin "Stopping wpa_cli on ${iface}"
121 start-stop-daemon --stop --exec /bin/wpa_cli --pidfile "${pidfile}"
122 ${report} && eend "$?"
123 fi
124
125 # Now shutdown wpa_supplicant
126 pidfile="/var/run/wpa_supplicant-${iface}.pid"
127 if [[ -f ${pidfile} ]] ; then
128 ${report} && ebegin "Stopping wpa_supplicant on ${iface}"
129 start-stop-daemon --stop --exec /sbin/wpa_supplicant \
130 --pidfile "${pidfile}"
131 ${report} && eend "$?"
132 fi
133
134 # If wpa_supplicant exits uncleanly, we need to remove the stale dir
135 [[ -S "/var/run/wpa_supplicant/${iface}" ]] \
136 && rm -f "/var/run/wpa_supplicant/${iface}"
137 }
138
139 # bool wpa_supplicant_associate(char *interface)
140 #
141 # Returns 0 if wpa_supplicant associates and authenticates to an AP
142 # otherwise, 1
143 wpa_supplicant_associate() {
144 local iface="$1" ifvar=$(bash_variable "$1") timeout=
145 timeout="associate_timeout_${ifvar}"
146 timeout="${!timeout:--1}"
147
148 [[ -z ${actfile} && ${timeout} -lt 0 ]] && timeout="60"
149
150 if [[ ${timeout} == "0" ]] ; then
151 ewarn "WARNING: infinite timeout set for association on ${iface}"
152 elif [[ ${timeout} -lt 0 ]] ; then
153 einfo "Backgrounding ..."
154 exit 0
155 fi
156
157 local i=0
158 while true ; do
159 if [[ -n ${actfile} ]] ; then
160 service_started "net.${iface}" && return 0
161 else
162 if ! wpa_cli -i"${iface}" status &>/dev/null ; then
163 eend 1 "wpa_supplicant has exited unexpectedly"
164 return 1
165 fi
166 wpa_supplicant_associated "${iface}" && return 0
167 fi
168 sleep 1
169 [[ ${timeout} == "0" ]] && continue
170 (( i++ ))
171 [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break
172 done
173
174 # Spit out an appropriate error
175 if [[ -n ${actfile} ]] ; then
176 eend 1 "Failed to configure ${iface} in the background"
177 else
178
179 eend 1 "Timed out"
180 fi
181
182 # exit without error with wpa_supplicant-0.4.x as we may get kickstarted
183 # when an AP comes in range
184 [[ -n ${actfile} ]] && exit 0
185
186 # Kill wpa_supplicant for 0.3.x
187 wpa_supplicant_kill "${iface}"
188 return 1
189 }
190
191 # bool wpa_supplicant_pre_start(char *interface)
192 #
193 # Start wpa_supplicant on an interface and wait for association
194 # Returns 0 (true) when successful, non-zero otherwise
195 wpa_supplicant_pre_start() {
196 local iface="$1" opts= timeout= actfile= cfgfile=
197
198 # We don't configure wireless if we're being called from
199 # the background unless we're not currently running
200 if ${IN_BACKGROUND} ; then
201 if service_started_daemon "net.${iface}" /sbin/wpa_supplicant ; then
202 if wpa_supplicant_exists "${iface}" ; then
203 ESSID=$(wpa_supplicant_get_essid "${iface}")
204 ESSIDVAR=$(bash_variable "${ESSID}")
205 save_options "ESSID" "${ESSID}"
206 metric=2000
207 fi
208 return 0
209 fi
210 fi
211
212 save_options "ESSID" ""
213
214 local ifvar=$(bash_variable "${iface}")
215 opts="wpa_supplicant_${ifvar}"
216 opts=" ${!opts} "
217 [[ ${opts} != *" -D"* ]] \
218 && vewarn "wpa_supplicant_${ifvar} does not define a driver"
219
220 # We only work on wirelesss interfaces unless a driver for wired
221 # has been defined
222 if [[ ${opts} != *" -Dwired "* && ${opts} != *" -D wired "* ]] ; then
223 if ! wpa_supplicant_exists "${iface}" ; then
224 veinfo "wpa_supplicant only works on wireless interfaces"
225 veinfo "unless the -D wired option is specified"
226 return 0
227 fi
228 fi
229
230 # If wireless-tools is installed, try and apply our user config
231 # This is needed for some drivers - such as hostap because they start
232 # the card in Master mode which causes problems with wpa_supplicant.
233 if is_function iwconfig_defaults ; then
234 if wpa_supplicant_exists "${iface}" ; then
235 iwconfig_defaults "${iface}"
236 iwconfig_user_config "${iface}"
237 fi
238 fi
239
240 # Check for rf_kill - only ipw supports this at present, but other
241 # cards may in the future
242 if [[ -e "/sys/class/net/${iface}/device/rf_kill" ]] ; then
243 if [[ $( < "/sys/class/net/${iface}/device/rf_kill" ) != 0 ]] ; then
244 ewarn "Wireless radio has been killed for interface ${iface}"
245 local asc="associate_timeout_${ifvar}"
246 if [[ -n ${!asc} && ${!asc} -ge 0 ]] ; then
247 eerror "As you have ${asc} set to 0 or greater"
248 eerror "we will abort as we cannot associate"
249 return 1
250 fi
251 ewarn "wpa_supplicant will launch, but not associate until"
252 ewarn "wireles radio is re-enabled for interface ${iface}"
253 fi
254 fi
255
256 ebegin "Starting wpa_supplicant on ${iface}"
257
258 cfgfile="${opts##* -c}"
259 if [[ -n ${cfgfile} && ${cfgfile} != "${opts}" ]] ; then
260 [[ ${cfgfile:0:1} == " " ]] && cfgfile="${cfgfile# *}"
261 cfgfile="${cfgfile%% *}"
262 else
263 # Support new and old style locations
264 cfgfile="/etc/wpa_supplicant/wpa_supplicant-${iface}.conf"
265 [[ ! -e ${cfgfile} ]] \
266 && cfgfile="/etc/wpa_supplicant/wpa_supplicant.conf"
267 [[ ! -e ${cfgfile} ]] \
268 && cfgfile="/etc/wpa_supplicant.conf"
269 opts="${opts} -c${cfgfile}"
270 fi
271
272 if [[ ! -f ${cfgfile} ]] ; then
273 eend 1 "configuration file ${cfgfile} not found!"
274 return 1
275 fi
276
277 # Work out where the ctrl_interface dir is if it's not specified
278 local ctrl_dir=$(sed -n -e 's/[ \t]*#.*//g;s/[ \t]*$//g;s/^ctrl_interface=//p' "${cfgfile}")
279 if [[ -z ${ctrl_dir} ]] ; then
280 ctrl_dir="${opts##* -C}"
281 if [[ -n ${ctrl_dir} && ${ctrl_dir} != "${opts}" ]] ; then
282 [[ ${ctrl_dir:0:1} == " " ]] && ctrl_dir="${ctrl_dir# *}"
283 ctrl_dir="${ctrl_dir%% *}"
284 else
285 ctrl_dir="/var/run/wpa_supplicant"
286 opts="${opts} -C${ctrl_dir}"
287 fi
288 fi
289
290 # Support the new style config
291 if [[ ${ctrl_dir} == "DIR"* ]] ; then
292 ctrl_dir=${ctrl_dir##*DIR=}
293 ctrl_dir=${ctrl_dir%% GROUP=*}
294 fi
295
296 save_options ctrl_dir "${ctrl_dir}"
297
298 # Some drivers require the interface to be up
299 interface_up "${iface}"
300
301 # wpa_supplicant 0.4.0 and greater supports wpa_cli actions
302 # This is very handy as if and when different association mechanisms are
303 # introduced to wpa_supplicant we don't have to recode for them as
304 # wpa_cli is now responsible for informing us of success/failure.
305 # The downside of this is that we don't see the interface being configured
306 # for DHCP/static.
307 actfile="/etc/wpa_supplicant/wpa_cli.sh"
308 # Support old file location
309 [[ ! -x ${actfile} ]] && actfile="/sbin/wpa_cli.action"
310 [[ ! -x ${actfile} ]] && unset actfile
311 [[ -n ${actfile} ]] && opts="${opts} -W"
312
313 eval start-stop-daemon --start --exec /sbin/wpa_supplicant \
314 --pidfile "/var/run/wpa_supplicant-${iface}.pid" \
315 -- "${opts}" -W -B -i"${iface}" \
316 -P"/var/run/wpa_supplicant-${iface}.pid"
317 eend "$?" || return 1
318
319 # Starting wpa_supplication-0.4.0, we can get wpa_cli to
320 # start/stop our scripts from wpa_supplicant messages
321 if [[ -n ${actfile} ]] ; then
322 mark_service_inactive "net.${iface}"
323 ebegin "Starting wpa_cli on ${iface}"
324 start-stop-daemon --start --exec /bin/wpa_cli \
325 --pidfile "/var/run/wpa_cli-${iface}.pid" \
326 -- -a"${actfile}" -p"${ctrl_dir}" -i"${iface}" \
327 -P"/var/run/wpa_cli-${iface}.pid" -B
328 eend "$?" || return 1
329 fi
330
331 eindent
332 veinfo "Waiting for association"
333 eend 0
334
335 wpa_supplicant_associate "${iface}" || return 1
336
337 # Only report wireless info for wireless interfaces
338 if wpa_supplicant_exists "${iface}" ; then
339 # Set ESSID for essidnet and report
340 ESSID=$(wpa_supplicant_get_essid "${iface}" )
341 ESSIDVAR=$(bash_variable "${ESSID}")
342 save_options "ESSID" "${ESSID}"
343
344 local -a status=()
345 eval status=( $(wpa_cli -i"${iface}" status | sed -n -e 's/^\(bssid\|pairwise_cipher\|key_mgmt\)=\([^=]\+\).*/\"\U\2\"/p' | tr '[:lower:]' '[:upper:]') )
346 einfo "${iface} connected to \"${ESSID//\\\\/\\\\}\" at ${status[0]}"
347
348 if [[ ${status[2]} == "NONE" ]] ; then
349 if [[ ${status[1]} == "NONE" ]] ; then
350 ewarn "not using any encryption"
351 else
352 veinfo "using ${status[1]}"
353 fi
354 else
355 veinfo "using ${status[2]}/${status[1]}"
356 fi
357 eoutdent
358 else
359 einfo "${iface} connected"
360 fi
361
362 if [[ -n ${actfile} ]] ; then
363 local addr=$(interface_get_address "${iface}")
364 einfo "${iface} configured with address ${addr}"
365 exit 0
366 fi
367
368 metric=2000
369 return 0
370 }
371
372 # bool wpa_supplicant_post_stop(char *iface)
373 #
374 # Stops wpa_supplicant on an interface
375 # Returns 0 (true) when successful, non-zero otherwise
376 wpa_supplicant_post_stop() {
377 if ${IN_BACKGROUND} ; then
378 # Only stop wpa_supplicant if it's not the controlling daemon
379 ! service_started_daemon "net.$1" /sbin/wpa_supplicant 0
380 fi
381 [[ $? == 0 ]] && wpa_supplicant_kill "$1" true
382 return 0
383 }
384
385 # 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