| … | |
… | |
| 56 | # Gets the current ESSID of iface |
56 | # Gets the current ESSID of iface |
| 57 | wpa_supplicant_get_essid() { |
57 | wpa_supplicant_get_essid() { |
| 58 | local i essid |
58 | local i essid |
| 59 | |
59 | |
| 60 | for (( i=0; i<5; i++ )); do |
60 | for (( i=0; i<5; i++ )); do |
| 61 | essid="$( wpa_cli -i$1 status | sed -n -e 's/^ssid=//p' )" |
61 | essid="$( wpa_cli -i"$1" status | sed -n -e 's/^ssid=//p' )" |
| 62 | if [[ -n ${essid} ]]; then |
62 | if [[ -n ${essid} ]]; then |
| 63 | echo "${essid}" |
63 | echo "${essid}" |
| 64 | return 0 |
64 | return 0 |
| 65 | fi |
65 | fi |
| 66 | sleep 1 |
66 | sleep 1 |
| … | |
… | |
| 118 | start-stop-daemon --stop --exec /sbin/wpa_supplicant \ |
118 | start-stop-daemon --stop --exec /sbin/wpa_supplicant \ |
| 119 | --pidfile "${pidfile}" |
119 | --pidfile "${pidfile}" |
| 120 | ${report} && eend "$?" |
120 | ${report} && eend "$?" |
| 121 | else |
121 | else |
| 122 | # Support wpa_supplicant-0.3.x |
122 | # Support wpa_supplicant-0.3.x |
| 123 | local pid=$( pgrep -f '^/sbin/wpa_supplicant .* -i'"${iface}"'[ ]*$' ) |
123 | local pid="$( pgrep -f "^/sbin/wpa_supplicant .* -i${iface}[ ]*$" )" |
| 124 | if [[ -n ${pid} ]]; then |
124 | if [[ -n ${pid} ]]; then |
| 125 | ${report} && ebegin "Stopping wpa_supplicant on ${iface}" |
125 | ${report} && ebegin "Stopping wpa_supplicant on ${iface}" |
| 126 | kill -s TERM "${pid}" |
126 | kill -s TERM "${pid}" |
| 127 | ${report} && eend 0 |
127 | ${report} && eend 0 |
| 128 | fi |
128 | fi |
| … | |
… | |
| 136 | # bool wpa_supplicant_associate(char *interface) |
136 | # bool wpa_supplicant_associate(char *interface) |
| 137 | # |
137 | # |
| 138 | # Returns 0 if wpa_supplicant associates and authenticates to an AP |
138 | # Returns 0 if wpa_supplicant associates and authenticates to an AP |
| 139 | # otherwise, 1 |
139 | # otherwise, 1 |
| 140 | wpa_supplicant_associate() { |
140 | wpa_supplicant_associate() { |
| 141 | local iface="$1" ifvar=$( bash_variable "$1" ) timeout i |
141 | local iface="$1" ifvar="$( bash_variable "$1" )" timeout i |
| 142 | timeout="associate_timeout_${ifvar}" |
142 | timeout="associate_timeout_${ifvar}" |
| 143 | [[ -z ${!timeout} ]] && timeout="wpa_timeout_${ifvar}" |
143 | [[ -z ${!timeout} ]] && timeout="wpa_timeout_${ifvar}" |
| 144 | timeout="${!timeout:--1}" |
144 | timeout="${!timeout:--1}" |
| 145 | |
145 | |
| 146 | if [[ ${timeout} == "0" ]]; then |
146 | if [[ ${timeout} == "0" ]]; then |
| … | |
… | |
| 149 | einfo "Backgrounding ..." |
149 | einfo "Backgrounding ..." |
| 150 | exit 0 |
150 | exit 0 |
| 151 | fi |
151 | fi |
| 152 | |
152 | |
| 153 | while true ; do |
153 | while true ; do |
| 154 | if ${action} ; then |
154 | if [[ -n ${actfile} ]] ; then |
| 155 | service_started "net.${iface}" && return 0 |
155 | service_started "net.${iface}" && return 0 |
| 156 | else |
156 | else |
| 157 | if ! wpa_cli -i"${iface}" status &>/dev/null ; then |
157 | if ! wpa_cli -i"${iface}" status &>/dev/null ; then |
| 158 | eend 1 "wpa_supplicant has exited unexpectedly" |
158 | eend 1 "wpa_supplicant has exited unexpectedly" |
| 159 | return 1 |
159 | return 1 |
| … | |
… | |
| 164 | (( i++ )) |
164 | (( i++ )) |
| 165 | [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break |
165 | [[ ${i} == "${timeout}" || ${i} -gt "${timeout}" ]] && break |
| 166 | done |
166 | done |
| 167 | |
167 | |
| 168 | # Spit out an appropriate error |
168 | # Spit out an appropriate error |
| 169 | if ${action} ; then |
169 | if [[ -n ${actfile} ]] ; then |
| 170 | eend 1 "Failed to configure ${iface} in the background" |
170 | eend 1 "Failed to configure ${iface} in the background" |
| 171 | else |
171 | else |
| 172 | eend 1 "Timed out" |
172 | eend 1 "Timed out" |
| 173 | fi |
173 | fi |
| 174 | |
174 | |
| 175 | # exit without error with wpa_supplicant-0.4.x as we may get kickstarted |
175 | # exit without error with wpa_supplicant-0.4.x as we may get kickstarted |
| 176 | # when an AP comes in range |
176 | # when an AP comes in range |
| 177 | ${action} && exit 0 |
177 | [[ -n ${actfile} ]] && exit 0 |
| 178 | |
178 | |
| 179 | # Kill wpa_supplicant for 0.3.x |
179 | # Kill wpa_supplicant for 0.3.x |
| 180 | wpa_supplicant_kill "${iface}" |
180 | wpa_supplicant_kill "${iface}" |
| 181 | return 1 |
181 | return 1 |
| 182 | } |
182 | } |
| … | |
… | |
| 184 | # bool wpa_supplicant_pre_start(char *interface) |
184 | # bool wpa_supplicant_pre_start(char *interface) |
| 185 | # |
185 | # |
| 186 | # Start wpa_supplicant on an interface and wait for association |
186 | # Start wpa_supplicant on an interface and wait for association |
| 187 | # Returns 0 (true) when successful, non-zero otherwise |
187 | # Returns 0 (true) when successful, non-zero otherwise |
| 188 | wpa_supplicant_pre_start() { |
188 | wpa_supplicant_pre_start() { |
| 189 | local iface="$1" opts timeout action=false cfgfile |
189 | local iface="$1" opts="" timeout="" actfile="" cfgfile="" |
| 190 | local actfile="/sbin/wpa_cli.action" |
|
|
| 191 | |
190 | |
| 192 | # We don't configure wireless if we're being called from |
191 | # We don't configure wireless if we're being called from |
| 193 | # the background unless we're not currently running |
192 | # the background unless we're not currently running |
| 194 | if ${IN_BACKGROUND} ; then |
193 | if ${IN_BACKGROUND} ; then |
| 195 | if service_started_daemon "net.${iface}" /sbin/wpa_supplicant ; then |
194 | if service_started_daemon "net.${iface}" /sbin/wpa_supplicant ; then |
| 196 | if wpa_supplicant_exists "${iface}" ; then |
195 | if wpa_supplicant_exists "${iface}" ; then |
| 197 | ESSID=$( wpa_supplicant_get_essid "${iface}" ) |
196 | ESSID="$( wpa_supplicant_get_essid "${iface}" )" |
| 198 | ESSIDVAR=$( bash_variable "${ESSID}" ) |
197 | ESSIDVAR="$( bash_variable "${ESSID}" )" |
| 199 | save_options "ESSID" "${ESSID}" |
198 | save_options "ESSID" "${ESSID}" |
| 200 | fi |
199 | fi |
| 201 | return 0 |
200 | return 0 |
| 202 | fi |
201 | fi |
| 203 | fi |
202 | fi |
| 204 | |
203 | |
| 205 | save_options "ESSID" "" |
204 | save_options "ESSID" "" |
| 206 | |
205 | |
| 207 | local ifvar=$( bash_variable "${iface}" ) |
206 | local ifvar="$( bash_variable "${iface}" )" |
| 208 | opts="wpa_supplicant_${ifvar}" |
207 | opts="wpa_supplicant_${ifvar}" |
| 209 | opts=" ${!opts} " |
208 | opts=" ${!opts} " |
| 210 | [[ ${opts} != *" -D"* ]] \ |
209 | [[ ${opts} != *" -D"* ]] \ |
| 211 | && vewarn "wpa_supplicant_${ifvar} does not define a driver" |
210 | && vewarn "wpa_supplicant_${ifvar} does not define a driver" |
| 212 | |
211 | |
| … | |
… | |
| 244 | cfgfile="${opts##* -c}" |
243 | cfgfile="${opts##* -c}" |
| 245 | if [[ -n ${cfgfile} && ${cfgfile} != "${opts}" ]]; then |
244 | if [[ -n ${cfgfile} && ${cfgfile} != "${opts}" ]]; then |
| 246 | [[ ${cfgfile:0:1} == " " ]] && cfgfile="${cfgfile# *}" |
245 | [[ ${cfgfile:0:1} == " " ]] && cfgfile="${cfgfile# *}" |
| 247 | cfgfile="${cfgfile%% *}" |
246 | cfgfile="${cfgfile%% *}" |
| 248 | else |
247 | else |
|
|
248 | # Support new and old style locations |
|
|
249 | cfgfile="/etc/wpa_supplicant/wpa_supplicant-${iface}.conf" |
|
|
250 | [[ ! -e ${cfgfile} ]] \ |
|
|
251 | && cfgfile="/etc/wpa_supplicant/wpa_supplicant.conf" |
|
|
252 | [[ ! -e ${cfgfile} ]] \ |
| 249 | cfgfile="/etc/wpa_supplicant.conf" |
253 | && cfgfile="/etc/wpa_supplicant.conf" |
| 250 | opts="${opts} -c/etc/wpa_supplicant.conf" |
254 | opts="${opts} -c${cfgfile}" |
| 251 | fi |
255 | fi |
| 252 | |
256 | |
| 253 | if [[ ! -f ${cfgfile} ]]; then |
257 | if [[ ! -f ${cfgfile} ]]; then |
| 254 | eend 1 "configuration file ${cfgfile} not found!" |
258 | eend 1 "configuration file ${cfgfile} not found!" |
| 255 | return 1 |
259 | return 1 |
| 256 | fi |
260 | fi |
| 257 | |
261 | |
| 258 | local ctrl_dir=$( sed -n -e 's/[ \t]*#.*//g;s/[ \t]*$//g;s/^ctrl_interface=//p' "${cfgfile}" ) |
262 | local ctrl_dir="$( sed -n -e 's/[ \t]*#.*//g;s/[ \t]*$//g;s/^ctrl_interface=//p' "${cfgfile}" )" |
| 259 | if [[ ${ctrl_dir} != "/var/run/wpa_supplicant" ]]; then |
263 | if [[ ${ctrl_dir} != "/var/run/wpa_supplicant" ]]; then |
| 260 | eerror "${cfgfile} must set" |
264 | eerror "${cfgfile} must set" |
| 261 | eerror " ctrl_interface=/var/run/wpa_supplicant" |
265 | eerror " ctrl_interface=/var/run/wpa_supplicant" |
| 262 | eend 1 |
266 | eend 1 |
| 263 | return 1 |
267 | return 1 |
| 264 | fi |
268 | fi |
| 265 | |
269 | |
| 266 | # Some drivers require the interface to be up |
270 | # Some drivers require the interface to be up |
| 267 | interface_up "${iface}" |
271 | interface_up "${iface}" |
| 268 | |
272 | |
| 269 | version=$( wpa_cli -v | sed -n -e 's/wpa_cli v//p' ) |
273 | version="$( wpa_cli -v | sed -n -e 's/wpa_cli v//p' )" |
| 270 | version=( ${version//./ } ) |
274 | version=( ${version//./ } ) |
| 271 | (( version = version[0] * 1000 + version[1] * 100 + version[2] )) |
275 | (( version = version[0] * 1000 + version[1] * 100 + version[2] )) |
| 272 | |
276 | |
| 273 | # wpa_supplicant 0.4.0 and greater supports wpa_cli actions |
277 | # wpa_supplicant 0.4.0 and greater supports wpa_cli actions |
| 274 | # This is very handy as if and when different association mechanisms are |
278 | # This is very handy as if and when different association mechanisms are |
| 275 | # introduced to wpa_supplicant we don't have to recode for them as |
279 | # introduced to wpa_supplicant we don't have to recode for them as |
| 276 | # wpa_cli is now responsible for informing us of success/failure. |
280 | # wpa_cli is now responsible for informing us of success/failure. |
| 277 | # The downside of this is that we don't see the interface being configured |
281 | # The downside of this is that we don't see the interface being configured |
| 278 | # for DHCP/static. |
282 | # for DHCP/static. |
| 279 | if [[ ${version} -gt 399 && -x ${actfile} ]]; then |
283 | if [[ ${version} -gt 399 ]]; then |
| 280 | opts="${opts} -W -P/var/run/wpa_supplicant-${iface}.pid" |
284 | opts="${opts} -W -P/var/run/wpa_supplicant-${iface}.pid" |
| 281 | action=true |
285 | actfile="/etc/wpa_supplicant/wpa_cli.sh" |
|
|
286 | # Support old file location |
|
|
287 | [[ ! -x ${actfile} ]] && actfile="/sbin/wpa_cli.action" |
|
|
288 | [[ ! -x ${actfile} ]] && unset actfile |
| 282 | fi |
289 | fi |
| 283 | |
290 | |
| 284 | eval start-stop-daemon --start --exec /sbin/wpa_supplicant \ |
291 | eval start-stop-daemon --start --exec /sbin/wpa_supplicant \ |
| 285 | --pidfile "/var/run/wpa_supplicant-${iface}.pid" \ |
292 | --pidfile "/var/run/wpa_supplicant-${iface}.pid" \ |
| 286 | -- "${opts}" -B -i"${iface}" |
293 | -- "${opts}" -B -i"${iface}" |
| 287 | eend "$?" || return 1 |
294 | eend "$?" || return 1 |
| 288 | |
295 | |
| 289 | # Starting wpa_supplication-0.4.0, we can get wpa_cli to |
296 | # Starting wpa_supplication-0.4.0, we can get wpa_cli to |
| 290 | # start/stop our scripts from wpa_supplicant messages |
297 | # start/stop our scripts from wpa_supplicant messages |
| 291 | if ${action} ; then |
298 | if [[ -n ${actfile} ]] ; then |
| 292 | mark_service_inactive "net.${iface}" |
299 | mark_service_inactive "net.${iface}" |
| 293 | ebegin "Starting wpa_cli on ${iface}" |
300 | ebegin "Starting wpa_cli on ${iface}" |
| 294 | start-stop-daemon --start --exec /bin/wpa_cli \ |
301 | start-stop-daemon --start --exec /bin/wpa_cli \ |
| 295 | --pidfile "/var/run/wpa_cli-${iface}.pid" \ |
302 | --pidfile "/var/run/wpa_cli-${iface}.pid" \ |
| 296 | -- -a"${actfile}" -i"${iface}" \ |
303 | -- -a"${actfile}" -i"${iface}" \ |
| … | |
… | |
| 305 | wpa_supplicant_associate "${iface}" || return 1 |
312 | wpa_supplicant_associate "${iface}" || return 1 |
| 306 | |
313 | |
| 307 | # Only report wireless info for wireless interfaces |
314 | # Only report wireless info for wireless interfaces |
| 308 | if wpa_supplicant_exists "${iface}" ; then |
315 | if wpa_supplicant_exists "${iface}" ; then |
| 309 | # Set ESSID for essidnet and report |
316 | # Set ESSID for essidnet and report |
| 310 | ESSID=$( wpa_supplicant_get_essid "${iface}" ) |
317 | ESSID="$( wpa_supplicant_get_essid "${iface}" )" |
| 311 | ESSIDVAR=$( bash_variable "${ESSID}" ) |
318 | ESSIDVAR="$( bash_variable "${ESSID}" )" |
| 312 | save_options "ESSID" "${ESSID}" |
319 | save_options "ESSID" "${ESSID}" |
| 313 | |
320 | |
| 314 | local -a status |
321 | local -a status |
| 315 | eval status=( $( wpa_cli -i"${iface}" status | sed -n -e 's/^\(bssid\|pairwise_cipher\|key_mgmt\)=\([^=]\+\).*/\"\U\2\"/p' | tr '[:lower:]' '[:upper:]' ) ) |
322 | eval status=( $( wpa_cli -i"${iface}" status | sed -n -e 's/^\(bssid\|pairwise_cipher\|key_mgmt\)=\([^=]\+\).*/\"\U\2\"/p' | tr '[:lower:]' '[:upper:]' ) ) |
| 316 | einfo "${iface} connected to \"${ESSID//\\\\/\\\\}\" at ${status[0]}" |
323 | einfo "${iface} connected to \"${ESSID//\\\\/\\\\}\" at ${status[0]}" |
| … | |
… | |
| 327 | eoutdent |
334 | eoutdent |
| 328 | else |
335 | else |
| 329 | einfo "${iface} connected" |
336 | einfo "${iface} connected" |
| 330 | fi |
337 | fi |
| 331 | |
338 | |
| 332 | if ${action} ; then |
339 | if [[ -n ${actfile} ]] ; then |
| 333 | local addr=$( interface_get_address "${iface}" ) |
340 | local addr="$( interface_get_address "${iface}" )" |
| 334 | einfo "${iface} configured with address ${addr}" |
341 | einfo "${iface} configured with address ${addr}" |
| 335 | exit 0 |
342 | exit 0 |
| 336 | fi |
343 | fi |
| 337 | |
344 | |
| 338 | return 0 |
345 | return 0 |