/[baselayout]/trunk/net-scripts/net.modules.d/wpa_supplicant
Gentoo

Contents of /trunk/net-scripts/net.modules.d/wpa_supplicant

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1322 - (show annotations) (download)
Wed Jul 20 06:16:05 2005 UTC (9 years, 1 month ago) by uberlord
File size: 10216 byte(s)
Fixed <wpa_supplicant-0.4 support
1 #!/bin/bash
2 # Copyright (c) 2004-2005 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4
5 # Contributed by Roy Marples (uberlord@gentoo.org)
6
7 # Fix any potential localisation problems
8 # Note that LC_ALL trumps LC_anything_else according to locale(7)
9 wpa_supplicant() {
10 LC_ALL=C /sbin/wpa_supplicant "$@"
11 }
12
13 wpa_cli() {
14 LC_ALL=C /bin/wpa_cli "$@"
15 }
16
17 # char* wpa_supplicant_provides(void)
18 #
19 # Returns a string to change module definition for starting up
20 wpa_supplicant_provides() {
21 echo "wireless"
22 }
23
24 # void wpa_supplicant_depend(void)
25 #
26 # Sets up the dependancies for the module
27 wpa_supplicant_depend() {
28 after macnet
29 before interface
30 }
31
32 # bool wpa_supplicant_check_installed(void)
33 #
34 # Returns 0 if wpa_supplicant is installed, otherwise 1
35 wpa_supplicant_check_installed() {
36 local report="${1:-false}" installed=0
37 if [[ ! -x /sbin/wpa_supplicant ]]; then
38 installed=1
39 ${report} && eerror "For WPA support (wpa_supplicant) support, emerge net-wireless/wpa_supplicant"
40 fi
41 if [[ ! -e /proc/net/packet ]]; then
42 installed=1
43 ${report} && eerror "wpa_supplicant requires Packet Socket (CONFIG_PACKET=y) enabled in the kernel"
44 fi
45 return ${installed}
46 }
47
48 # bool wpa_supplicant_check_depends(void)
49 #
50 # Checks to see if we have the needed functions
51 wpa_supplicant_check_depends() {
52 local f
53
54 for f in interface_exists; do
55 [[ $( type -t ${f} ) == "function" ]] && continue
56 eerror "wpa_supplicant: missing required function ${f}\n"
57 return 1
58 done
59
60 return 0
61 }
62
63 # bool wpa_supplicant_check_extensions(char *interface)
64 #
65 # Checks to see if wireless extensions are enabled on the interface
66 wpa_supplicant_check_extensions() {
67 grep -q "$1: " /proc/net/wireless
68 }
69
70 # char* wpa_supplicant_get_essid(char *interface)
71 #
72 # Gets the current ESSID of iface
73 wpa_supplicant_get_essid() {
74 local i essid
75
76 for (( i=0; i<5; i++ )); do
77 essid=$( wpa_cli -i"$1" status | sed -n -e 's/^ssid=//p' )
78 if [[ -n ${essid} ]]; then
79 echo "${essid}"
80 return 0
81 fi
82 sleep 1
83 done
84
85 return 1
86 }
87
88 # char* wpa_supplicant_get_ap_mac_address(char *interface)
89 #
90 # Returns the MAC address of the Access Point
91 # the interface is connected to
92 wpa_supplicant_get_ap_mac_address() {
93 wpa_cli -i"$1" status | sed -n -e 's/^bssid=\([^=]\+\).*/\U\1/p'
94 }
95
96 # bool wpa_supplicant_associated(char *interface)
97 #
98 # Returns 0 if we're associated correctly or 1 if not
99 # Note that just because we are associated does not mean we are using the
100 # correct encryption keys
101 # We only need this for wpa_supplicant-0.3.x
102 wpa_supplicant_associated() {
103 local -a status=( "$( wpa_cli -i"$1" status | sed -n -e 's/^\(key_mgmt\|wpa_state\|EAP state\)=\([^=]\+\).*/\U\2/p' )" )
104
105 case ${status[0]} in
106 "NONE") [[ ${status[1]} == "ASSOCIATED" ]] ;;
107 "IEEE 802.1X (no WPA)") [[ ${status[2]} == "SUCCESS" ]] ;;
108 *) [[ ${status[1]} == "COMPLETED" ]] ;;
109 esac
110
111 return $?
112 }
113
114 # void wpa_supplicant_kill(char *interface, bool report)
115 #
116 # Kills any existing wpa_supplicant process on the interface
117 wpa_supplicant_kill() {
118 local iface="$1" report="${2:-false}" pidfile
119
120 # Shutdown wpa_cli first, if it's running
121 # This is important as future versions of wpa_supplicant
122 # may send a disconnect message to wpa_cli when it shutsdown
123 pidfile="/var/run/wpa_cli-${iface}.pid"
124 if ! clean_pidfile "${pidfile}" ; then
125 ${report} && ebegin "Stopping wpa_cli on ${iface}"
126 start-stop-daemon --stop --exec /bin/wpa_cli \
127 --pidfile "${pidfile}"
128 ${report} && eend $?
129 fi
130
131 # Now shutdown wpa_supplicant
132 pidfile="/var/run/wpa_supplicant-${iface}.pid"
133 if ! clean_pidfile "${pidfile}" ; then
134 ${report} && ebegin "Stopping wpa_supplicant on ${iface}"
135 start-stop-daemon --stop --exec /sbin/wpa_supplicant \
136 --pidfile "${pidfile}"
137 ${report} && eend $?
138 else
139 # Support wpa_supplicant-0.3.x
140 local pid=$( pgrep -f '^/sbin/wpa_supplicant .* -i'"${iface}"'[ ]*$' )
141 if [[ -n ${pid} ]]; then
142 ${report} && ebegin "Stopping wpa_supplicant on ${iface}"
143 kill -s TERM "${pid}"
144 ${report} && eend 0
145 fi
146 fi
147
148 # If wpa_supplicant exits uncleanly, we need to remove the stale dir
149 [[ -S "/var/run/wpa_supplicant/${iface}" ]] \
150 && rm -f "/var/run/wpa_supplicant/${iface}"
151 }
152
153 # bool wpa_supplicant_associate(char *interface)
154 #
155 # Returns 0 if wpa_supplicant associates and authenticates to an AP
156 # otherwise, 1
157 wpa_supplicant_associate() {
158 local iface="$1" ifvar=$( bash_variable "$1" ) timeout i
159
160 eval timeout=\"\$\{wpa_timeout_${ifvar}:-60\}\"
161 for (( i=0; i<${timeout}; i++ )); do
162 if ${action} ; then
163 service_started "net.${iface}" && return 0
164 else
165 if ! wpa_cli -i"${iface}" status &>/dev/null ; then
166 eend 1 "wpa_supplicant has exited unexpectedly"
167 return 1
168 fi
169 wpa_supplicant_associated "${iface}" && return 0
170 fi
171 sleep 1
172 done
173
174 # Spit out an appropriate error
175 if [[ ${background} != "yes" ]]; then
176 if ${action} ; then
177 eend 1 "Failed to configure ${iface} in the background"
178 else
179 eend 1 "Timed out"
180 fi
181 fi
182
183 # exit without error with wpa_supplicant-0.4.x as we may get kickstarted
184 # when an AP comes in range
185 ${action} && exit 0
186
187 # Kill wpa_supplicant for 0.3.x
188 wpa_supplicant_kill "${iface}"
189 return 1
190 }
191
192 # bool wpa_supplicant_pre_start(char *interface)
193 #
194 # Start wpa_supplicant on an interface and wait for association
195 # Returns 0 (true) when successful, non-zero otherwise
196 wpa_supplicant_pre_start() {
197 local iface="$1" opts timeout action=false
198 local cfgfile="/etc/wpa_supplicant.conf"
199 local actfile="/sbin/wpa_cli.action"
200
201 # We don't configure wireless if we're being called from
202 # the background
203 if ${IN_BACKGROUND} ; then
204 ESSID=$( wpa_supplicant_get_essid "${iface}" )
205 ESSIDVAR=$( bash_variable "${ESSID}" )
206 save_options "ESSID" "${ESSID}"
207 return 0
208 fi
209
210 save_options "ESSID" ""
211
212 # We only work on wirelesss interfaces
213 wpa_supplicant_check_extensions "${iface}" || return 0
214
215 # Kill off any existing wpa_supplicant on this interface
216 # This is so we can re-read the configuration file and clean any stale
217 # directories
218 wpa_supplicant_kill "${iface}" true
219
220 # Check for rf_kill - only ipw supports this at present, but other
221 # cards may in the future
222 if [[ -e "/sys/class/net/${iface}/device/rf_kill" ]]; then
223 if [[ $( < "/sys/class/net/${iface}/device/rf_kill" ) != 0 ]]; then
224 eerror "Wireless radio has been killed for interface ${iface}"
225 return 1
226 fi
227 fi
228
229 # If wireless-tools is installed, try and apply our user config
230 # This is needed for some drivers - such as hostap because they start
231 # the card in Master mode which causes problems with wpa_supplicant.
232 if [[ $( type -t iwconfig_defaults ) == "function" ]]; then
233 iwconfig_defaults "${iface}"
234 iwconfig_user_config "${iface}"
235 fi
236
237 ebegin "Starting wpa_supplicant on ${iface}"
238
239 if [[ ! -f ${cfgfile} ]]; then
240 eend 1 "configuration file ${cfgfile} not found!"
241 return 1
242 fi
243
244 local ctrl_dir=$( sed -n -e 's/[ \t]*#.*//g;s/[ \t]*$//g;s/^ctrl_interface=//p' "${cfgfile}" )
245 if [[ ${ctrl_dir} != "/var/run/wpa_supplicant" ]]; then
246 eerror "${cfgfile} must set"
247 eerror " ctrl_interface=/var/run/wpa_supplicant"
248 eend 1
249 return 1
250 fi
251
252 local ifvar=$( bash_variable "${iface}" )
253 eval opts=\" \$\{wpa_supplicant_${ifvar}\}\"
254 [[ ${opts} != *' -D'* ]] \
255 && ewarn "wpa_supplicant_${ifvar} does not define a driver"
256
257 # Some drivers require the interface to be up
258 interface_up "${iface}"
259
260 version=$( wpa_cli -v | sed -n -e 's/wpa_cli v//p' )
261 version=( ${version//./ } )
262 (( version = version[0] * 1000 + version[1] * 100 + version[2] ))
263
264 # wpa_supplicant 0.4.0 and greater supports wpa_cli actions
265 # This is very handy as if and when different association mechanisms are
266 # introduced to wpa_supplicant we don't have to recode for them as
267 # wpa_cli is now responsible for informing us of success/failure.
268 # The downside of this is that we don't see the interface being configured
269 # for DHCP/static.
270 if [[ ${version} -gt 399 && -x ${actfile} ]]; then
271 opts="${opts} -W -P/var/run/wpa_supplicant-${iface}.pid"
272 action=true
273 [[ ${RC_PARALLEL_STARTUP} == "yes" ]] && background=no
274 fi
275
276 start-stop-daemon --start --exec /sbin/wpa_supplicant \
277 -- ${opts} -B -c/etc/wpa_supplicant.conf -i"${iface}"
278 eend $? || return 1
279
280 # Starting wpa_supplication-0.4.0, we can get wpa_cli to
281 # start/stop our scripts from wpa_supplicant messages
282 if ${action} ; then
283 mark_service_inactive "net.${iface}"
284 ebegin "Starting wpa_cli on ${iface}"
285 start-stop-daemon --start --exec /bin/wpa_cli \
286 -- -a"${actfile}" -i"${iface}" \
287 -P"/var/run/wpa_cli-${iface}.pid" -B
288 eend $? || return 1
289 fi
290
291 # Background wpa_supplication if required
292 if [[ ${background} == "yes" ]]; then
293 if ! ${action} ; then
294 wpa_supplicant_associate "${iface}" \
295 && export IN_BACKGROUND=true \
296 && /etc/init.d/net.${iface} start >/dev/null &
297 fi
298 go_background
299 fi
300
301 eindent
302 veinfo "Waiting for association"
303 eend 0
304
305 wpa_supplicant_associate "${iface}" || return 1
306
307 # Set ESSID for essidnet and report
308 ESSID=$( wpa_supplicant_get_essid "${iface}" )
309 ESSIDVAR=$( bash_variable "${ESSID}" )
310 save_options "ESSID" "${ESSID}"
311
312 local -a status=( "$( wpa_cli -i${iface} status | sed -n -e 's/^\(bssid\|pairwise_cipher\|key_mgmt\)=\([^=]\+\).*/\U\2/p' | tr '[:lower:]' '[:upper:]' )" )
313 einfo "${iface} connected to \"${ESSID//\\\\/\\\\}\" at ${status[0]}"
314
315 if [[ ${status[2]} == "NONE" ]]; then
316 if [[ ${status[1]} == "NONE" ]]; then
317 ewarn "not using any encryption"
318 else
319 veinfo "using ${status[1]}"
320 fi
321 else
322 veinfo "using ${status[2]}/${status[1]}"
323 fi
324 eoutdent
325
326 if ${action} ; then
327 einfo "${iface} configured in the background successfully"
328 exit 0
329 fi
330
331 return 0
332 }
333
334 # bool wpa_supplicant_post_stop(char *iface)
335 #
336 # Stops wpa_supplicant on an interface
337 # Returns 0 (true) when successful, non-zero otherwise
338 wpa_supplicant_post_stop() {
339 ! ${IN_BACKGROUND} && wpa_supplicant_kill "$1" true
340 return 0
341 }

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.20