fix solo2 ethernet problem in some Gigabit switches
[vuplus_openvuplus_3.0] / meta-openvuplus / recipes-connectivity / wpa-supplicant / wpa-supplicant-0.7.3 / functions.sh
1 #!/bin/sh
2
3 #####################################################################
4 ## Purpose
5 # This file contains common shell functions used by scripts of the
6 # wpasupplicant package to allow ifupdown to manage wpa_supplicant.
7 # It also contains some functions used by wpa_action(8) that allow
8 # ifupdown to be managed by wpa_cli(8) action events.
9 #
10 # This file is provided by the wpasupplicant package.
11
12 #####################################################################
13 # Copyright (C) 2006 - 2009 Debian/Ubuntu wpasupplicant Maintainers 
14 # <pkg-wpa-devel@lists.alioth.debian.org>
15 #
16 # This program is free software; you can redistribute it and/or
17 # modify it under the terms of the GNU General Public License
18 # as published by the Free Software Foundation; either version 2
19 # of the License, or (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 #
26 # On Debian GNU/Linux systems, the text of the GPL license,
27 # version 2, can be found in /usr/share/common-licenses/GPL-2.
28
29 #####################################################################
30 ## global variables
31 # wpa_supplicant variables
32 WPA_SUP_BIN="/usr/sbin/wpa_supplicant"
33 WPA_SUP_PNAME="wpa_supplicant"
34 WPA_SUP_PIDFILE="/var/run/wpa_supplicant.${WPA_IFACE}.pid"
35
36 # wpa_cli variables
37 WPA_CLI_BIN="/usr/sbin/wpa_cli"
38 WPA_CLI_PNAME="wpa_cli"
39 WPA_CLI_PIDFILE="/var/run/wpa_action.${WPA_IFACE}.pid"
40 WPA_CLI_TIMESTAMP="/var/run/wpa_action.${WPA_IFACE}.timestamp"
41 WPA_CLI_IFUPDOWN="/var/run/wpa_action.${WPA_IFACE}.ifupdown"
42
43 # sendsigs omission interface, present in initscripts (>= 2.86.ds1-48)
44 if [ -d /lib/init/rw/sendsigs.omit.d/ ]; then
45         # Debian
46         WPA_SUP_OMIT_PIDFILE="/lib/init/rw/sendsigs.omit.d/wpasupplicant.wpa_supplicant.${WPA_IFACE}.pid"
47 elif [ -d /var/run/sendsigs.omit.d/ ]; then
48         # Ubuntu, see https://launchpad.net/bugs/181541 for status
49         WPA_SUP_OMIT_PIDFILE="/var/run/sendsigs.omit.d/wpasupplicant.wpa_supplicant.${WPA_IFACE}.pid"
50 else
51         WPA_SUP_OMIT_PIDFILE=
52 fi
53
54 # default ctrl_interface socket directory
55 if [ -z "$WPA_CTRL_DIR" ]; then
56         WPA_CTRL_DIR="/var/run/wpa_supplicant"
57 fi
58
59 # verbosity variables
60 if [ -n "$IF_WPA_VERBOSITY" ] || [ "$VERBOSITY" = "1" ]; then
61         TO_NULL="/dev/stdout"
62         DAEMON_VERBOSITY="--verbose"
63 else
64         TO_NULL="/dev/null"
65         DAEMON_VERBOSITY="--quiet"
66 fi
67
68 #####################################################################
69 ## wpa_cli wrapper
70 # Path to common ctrl_interface socket and iface supplied.
71 # NB: WPA_CTRL_DIR cannot be used for interactive commands, it is
72 # set only in the environment that wpa_cli provides when processing
73 # action events.
74 #
75 wpa_cli () {
76         "$WPA_CLI_BIN" -p "$WPA_CTRL_DIR" -i "$WPA_IFACE" "$@"
77
78         return "$?"
79 }
80
81 #####################################################################
82 ## verbose and stderr message wrapper
83 # Ensures a standard and easily identifiable message is printed by
84 # scripts using this function library.
85 #
86 # log           Log a message to syslog when called non-interactively
87 #               by wpa_action
88 #
89 # verbose       To stdout when IF_WPA_VERBOSITY or VERBOSITY is true
90 #
91 # action        Same as verbose but without newline
92 #               Useful for allowing wpa_cli commands to echo result
93 #               value of 'OK' or 'FAILED'
94 #
95 # stderr        Echo warning or error messages to stderr
96 #
97 # NB: when called by wpa_action, there is no redirection (verbose)
98 #
99 wpa_msg () {
100         if [ "$1" = "log" ]; then
101                 shift
102                 case "$WPA_ACTION" in
103                         "CONNECTED"|"DISCONNECTED")
104                                 [ -x /usr/bin/logger ] || return
105                                 if [ "$#" -gt 0 ]; then
106                                         logger -t "wpa_action" "$@"
107                                 else
108                                         logger -t "wpa_action"
109                                 fi
110                                 ;;
111                         *)
112                                 [ "$#" -gt 0 ] && echo "wpa_action: $@"
113                                 ;;
114                 esac
115                 return
116         fi
117         
118         case "$1" in 
119                 "verbose")
120                         shift
121                         echo "$WPA_SUP_PNAME: $@" >$TO_NULL
122                         ;;
123                 "action")
124                         shift
125                         echo -n "$WPA_SUP_PNAME: $@ -- " >$TO_NULL
126                         ;;
127                 "stderr")
128                         shift
129                         echo "$WPA_SUP_PNAME: $@" >/dev/stderr
130                         ;;
131                 *)
132                         ;;
133         esac
134 }
135
136 #####################################################################
137 ## validate daemon pid files
138 # Test daemon process ID files via start-stop-daemon with a signal 0
139 # given the exec binary and pidfile location.
140 #
141 # $1    daemon
142 # $2    pidfile
143 #
144 # Returns true when pidfile exists, the process ID exists _and_ was
145 # created by the exec binary.
146 #
147 # If the test fails, but the pidfile exists, it is stale
148 #
149 test_daemon_pidfile () {
150         local DAEMON
151         local PIDFILE
152         
153         if [ -n "$1" ]; then
154                 DAEMON="$1"
155         fi
156         
157         if [ -f "$2" ]; then
158                 PIDFILE="$2"
159         fi
160         
161         if [ -n "$DAEMON" ] && [ -f "$PIDFILE" ]; then
162                 if start-stop-daemon --stop --quiet --signal 0 \
163                         --exec "$DAEMON" --pidfile "$PIDFILE"; then
164                         return 0
165                 else
166                         rm -f "$PIDFILE"
167                         return 1
168                 fi
169         else
170                 return 1
171         fi
172 }
173
174 # validate wpa_supplicant pidfile
175 test_wpa_supplicant () {
176         test_daemon_pidfile "$WPA_SUP_BIN" "$WPA_SUP_PIDFILE"
177 }
178
179 # validate wpa_cli pidfile
180 test_wpa_cli () {
181         test_daemon_pidfile "$WPA_CLI_BIN" "$WPA_CLI_PIDFILE"
182 }
183
184 #####################################################################
185 ## daemonize wpa_supplicant
186 # Start wpa_supplicant via start-stop-dameon with all required
187 # options. Will start if environment variable WPA_SUP_CONF is present
188 #
189 # Default options:
190 # -B    dameonize/background process
191 # -D    driver backend ('wext' if none given)
192 # -P    process ID file
193 # -C    path to ctrl_interface socket directory
194 # -s    log to syslog
195 #
196 # Conditional options:
197 # -c    configuration file
198 # -W    wait for wpa_cli to attach to ctrl_interface socket
199 # -b    bridge interface name
200 # -f    path to log file
201 #
202 init_wpa_supplicant () {
203         [ -n "$WPA_SUP_CONF" ] || return 0
204
205         local WPA_SUP_OPTIONS
206         WPA_SUP_OPTIONS="-s -B -P $WPA_SUP_PIDFILE -i $WPA_IFACE"
207
208         if [ -n "$WPA_ACTION_SCRIPT" ]; then
209                 if [ -x "$WPA_ACTION_SCRIPT" ]; then
210                         WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -W"
211                         wpa_msg verbose "wait for wpa_cli to attach"
212                 else
213                         wpa_msg stderr "action script \"$WPA_ACTION_SCRIPT\" not executable"
214                         return 1
215                 fi
216         fi
217
218         if [ -n "$IF_WPA_BRIDGE" ]; then
219                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -b $IF_WPA_BRIDGE"
220                 wpa_msg verbose "wpa-bridge $IF_WPA_BRIDGE"
221         fi
222
223         if [ -n "$IF_WPA_DRIVER" ]; then
224                 wpa_msg verbose "wpa-driver $IF_WPA_DRIVER"
225                 case "$IF_WPA_DRIVER" in
226                         hostap|ipw|madwifi|ndiswrapper)
227                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -D nl80211,wext"
228                                 wpa_msg stderr "\"$IF_WPA_DRIVER\" wpa-driver is unsupported"
229                                 wpa_msg stderr "using \"nl80211,wext\" wpa-driver instead ..."
230                                 ;;
231                         *)
232                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -D $IF_WPA_DRIVER"
233                                 ;;
234                 esac
235         else
236                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -D nl80211,wext"
237                 wpa_msg verbose "wpa-driver nl80211,wext (default)"
238         fi
239
240         if [ -n "$IF_WPA_DEBUG_LEVEL" ]; then
241                 case "$IF_WPA_DEBUG_LEVEL" in
242                         3)
243                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -t -ddd"
244                                 ;;
245                         2)
246                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -t -dd"
247                                 ;;
248                         1)
249                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -t -d"
250                                 ;;
251                         0)
252                                 # wpa_supplicant default verbosity
253                                 ;;
254                         -1)
255                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -q"
256                                 ;;
257                         -2)
258                                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -qq"
259                                 ;;
260                 esac
261                 wpa_msg verbose "using debug level: $IF_WPA_DEBUG_LEVEL"
262         fi
263
264         if [ -n "$IF_WPA_LOGFILE" ]; then
265                 # custom log file
266                 WPA_SUP_OPTIONS="$WPA_SUP_OPTIONS -f $IF_WPA_LOGFILE"
267                 WPA_SUP_LOGFILE="$IF_WPA_LOGFILE"
268                 wpa_msg verbose "logging to $IF_WPA_LOGFILE"
269         fi
270
271         wpa_msg verbose "$WPA_SUP_BIN $WPA_SUP_OPTIONS $WPA_SUP_CONF"
272                 
273         start-stop-daemon --start --oknodo $DAEMON_VERBOSITY \
274                 --name $WPA_SUP_PNAME --startas $WPA_SUP_BIN --pidfile $WPA_SUP_PIDFILE \
275                 -- $WPA_SUP_OPTIONS $WPA_SUP_CONF
276
277         if [ "$?" -ne 0 ]; then
278                 wpa_msg stderr "$WPA_SUP_BIN daemon failed to start"
279                 return 1
280         fi
281
282         if [ -n "$WPA_SUP_OMIT_PIDFILE" ]; then
283                 local WPA_PIDFILE_WAIT
284                 local MAX_WPA_PIDFILE_WAIT
285                 WPA_PIDFILE_WAIT="0"
286                 MAX_WPA_PIDFILE_WAIT="5"
287                 until [ -s "$WPA_SUP_PIDFILE" ]; do
288                         if [ "$WPA_PIDFILE_WAIT" -ge "$MAX_WPA_PIDFILE_WAIT" ]; then
289                                 wpa_msg stderr "timed out waiting for creation of $WPA_SUP_PIDFILE"
290                                 return 1
291                         else
292                                 wpa_msg verbose "waiting for \"$WPA_SUP_PIDFILE\": " \
293                                         "$WPA_PIDFILE_WAIT (max. $MAX_WPA_PIDFILE_WAIT)"
294                         fi
295
296                         WPA_PIDFILE_WAIT=$(($WPA_PIDFILE_WAIT + 1))
297                         sleep 1
298                 done
299                 wpa_msg verbose "creating sendsigs omission pidfile: $WPA_SUP_OMIT_PIDFILE"
300                 cat "$WPA_SUP_PIDFILE" > "$WPA_SUP_OMIT_PIDFILE"
301         else
302                 wpa_msg verbose "sendsigs omission pidfile not created"
303         fi
304
305         local WPA_SOCKET_WAIT
306         local MAX_WPA_SOCKET_WAIT
307         WPA_SOCKET_WAIT="0"
308         MAX_WPA_SOCKET_WAIT="5"
309         until [ -S "$WPA_CTRL_DIR/$WPA_IFACE" ]; do
310                 if [ "$WPA_SOCKET_WAIT" -ge "$MAX_WPA_SOCKET_WAIT" ]; then
311                         wpa_msg stderr "ctrl_interface socket not found at $WPA_CTRL_DIR/$WPA_IFACE"
312                         return 1
313                 else
314                         wpa_msg verbose "waiting for \"$WPA_CTRL_DIR/$WPA_IFACE\": " \
315                                 "$WPA_SOCKET_WAIT (max. $MAX_WPA_SOCKET_WAIT)"
316                 fi
317                 
318                 WPA_SOCKET_WAIT=$(($WPA_SOCKET_WAIT + 1))
319                 sleep 1
320         done
321         
322         wpa_msg verbose "ctrl_interface socket located at $WPA_CTRL_DIR/$WPA_IFACE"
323 }
324
325 #####################################################################
326 ## stop wpa_supplicant process
327 # Kill wpa_supplicant via start-stop-daemon, given the location of
328 # the pidfile or ctrl_interface socket path and interface name
329 #
330 kill_wpa_supplicant () {
331         test_wpa_supplicant || return 0
332
333         wpa_msg verbose "terminating $WPA_SUP_PNAME daemon via pidfile $WPA_SUP_PIDFILE"
334
335         start-stop-daemon --stop --oknodo $DAEMON_VERBOSITY \
336                 --exec $WPA_SUP_BIN --pidfile $WPA_SUP_PIDFILE
337
338         if [ -f "$WPA_SUP_PIDFILE" ]; then
339                 rm -f "$WPA_SUP_PIDFILE"
340         fi
341
342         if [ -f "$WPA_SUP_OMIT_PIDFILE" ]; then
343                 wpa_msg verbose "removing $WPA_SUP_OMIT_PIDFILE"
344                 rm -f "$WPA_SUP_OMIT_PIDFILE"
345         fi
346 }
347
348 #####################################################################
349 ## reload wpa_supplicant process
350 # Sending a HUP signal causes wpa_supplicant to reparse its
351 # configuration file
352 #
353 reload_wpa_supplicant () {
354         if test_wpa_supplicant; then
355                 wpa_msg verbose "reloading wpa_supplicant configuration file via HUP signal"
356                 start-stop-daemon --stop --signal HUP \
357                         --name "$WPA_SUP_PNAME" --pidfile "$WPA_SUP_PIDFILE"
358         else
359                 wpa_msg verbose "cannot $WPA_ACTION, $WPA_SUP_PIDFILE does not exist"
360         fi
361 }
362
363 #####################################################################
364 ## daemonize wpa_cli and action script
365 # If environment variable WPA_ACTION_SCRIPT is present, wpa_cli will
366 # be spawned via start-stop-daemon
367 #
368 # Required options:
369 # -a    action script => wpa_action
370 # -P    process ID file
371 # -B    background process
372 #
373 init_wpa_cli () {
374         [ -n "$WPA_ACTION_SCRIPT" ] || return 0
375
376         local WPA_CLI_OPTIONS
377         WPA_CLI_OPTIONS="-B -P $WPA_CLI_PIDFILE -i $WPA_IFACE"
378
379         wpa_msg verbose "$WPA_CLI_BIN $WPA_CLI_OPTIONS -p $WPA_CTRL_DIR -a $WPA_ACTION_SCRIPT"
380                 
381         start-stop-daemon --start --oknodo $DAEMON_VERBOSITY \
382                 --name $WPA_CLI_PNAME --startas $WPA_CLI_BIN --pidfile $WPA_CLI_PIDFILE \
383                 -- $WPA_CLI_OPTIONS -p $WPA_CTRL_DIR -a $WPA_ACTION_SCRIPT
384
385         if [ "$?" -ne 0 ]; then
386                 wpa_msg stderr "$WPA_CLI_BIN daemon failed to start"
387                 return 1
388         fi
389 }
390
391 #####################################################################
392 ## stop wpa_cli process
393 # Kill wpa_cli via start-stop-daemon, given the location of the
394 # pidfile
395 #
396 kill_wpa_cli () {
397         test_wpa_cli || return 0
398         
399         wpa_msg verbose "terminating $WPA_CLI_PNAME daemon via pidfile $WPA_CLI_PIDFILE"
400         
401         start-stop-daemon --stop --oknodo $DAEMON_VERBOSITY \
402                 --exec $WPA_CLI_BIN --pidfile $WPA_CLI_PIDFILE
403         
404         if [ -f "$WPA_CLI_PIDFILE" ]; then
405                 rm -f "$WPA_CLI_PIDFILE"
406         fi
407
408         if [ -f "$WPA_CLI_TIMESTAMP" ]; then
409                 rm -f "$WPA_CLI_TIMESTAMP"
410         fi
411
412         if [ -L "$WPA_CLI_IFUPDOWN" ]; then
413                 rm -f "$WPA_CLI_IFUPDOWN"
414         fi
415 }
416
417 #####################################################################
418 ## higher level wpa_cli wrapper for variable and set_network commands
419 # wpa_cli_do <value> <type> <variable> [set_network variable] <desc>
420 #
421 # $1    envorinment variable
422 # $2    data type of variable {raw|ascii}
423 # $3    wpa_cli variable, if $3 is set_network, shift and take 
424 #       set_network subvariable
425 # $4    wpa-* string as it would appear in interfaces file, enhances
426 #       verbose messages
427 #
428 wpa_cli_do () {
429         if [ -z "$1" ]; then
430                 return 0
431         fi
432         
433         local WPACLISET_VALUE
434         local WPACLISET_VARIABLE
435         local WPACLISET_DESC
436         
437         case "$2" in
438                 ascii)
439                         # Double quote
440                         WPACLISET_VALUE="\"$1\""
441                         ;;
442                 raw|*)
443                         # Provide raw value
444                         WPACLISET_VALUE="$1"
445                         ;;
446         esac
447         
448         case "$3" in
449                 set_network)
450                         if [ -z "$WPA_ID" ]; then
451                                 return 1
452                         fi
453                         shift
454                         WPACLISET_VARIABLE="set_network $WPA_ID $3"
455                         ;;
456                 *)
457                         WPACLISET_VARIABLE="$3"
458                         ;;
459         esac
460         
461         case "$4" in
462                 *-psk|*-passphrase|*-passwd*|*-wep-key*)
463                         WPACLISET_DESC="$4 *****"
464                         ;;
465                 *)
466                         WPACLISET_DESC="$4 $WPACLISET_VALUE"
467                         ;;
468         esac
469
470         wpa_msg action "$WPACLISET_DESC"
471         
472         wpa_cli $WPACLISET_VARIABLE "$WPACLISET_VALUE" >$TO_NULL
473
474         if [ "$?" -ne 0 ]; then
475                 wpa_msg stderr "$WPACLISET_DESC failed!"
476         fi
477 }
478
479 #####################################################################
480 ## check value data type in plaintext or hex
481 # returns 0 if input consists of hexadecimal digits only, 1 otherwise
482 #
483 ishex () {
484         if [ -z "$1" ]; then 
485                 return 0
486         fi
487         
488         case "$1" in
489                 *[!0-9a-fA-F]*)
490                         # plaintext
491                         return 1
492                         ;;
493                 *)
494                         # hexadecimal
495                         return 0
496                         ;;
497         esac
498 }
499
500 #####################################################################
501 ## sanity check and set psk|passphrase
502 # Warn about strange psk|passphrase values
503 #
504 # $1    psk or passphrase value
505
506 # If psk is surrounded by quotes strip them.
507 #
508 # If psk contains all hexadecimal characters and string length is 64:
509 #       is 256bit hexadecimal
510 # else:
511 #       is plaintext
512 #
513 # plaintext passphrases must be 8 - 63 characters in length
514 # 256-bit hexadecimal key must be 64 characters in length
515 #
516 wpa_key_check_and_set () {
517         if [ "$#" -ne 3 ]; then
518                 return 0
519         fi
520
521         local KEY
522         local KEY_LEN
523         local KEY_TYPE
524         local ENC_TYPE
525         
526         case "$1" in
527                 '"'*'"')
528                         # Strip surrounding quotation marks
529                         KEY=$(echo -n "$1" | sed 's/^"//;s/"$//')
530                         ;;
531                 *)
532                         KEY="$1"
533                         ;;
534         esac
535
536         KEY_LEN="${#KEY}"
537
538         case "$2" in
539                 wep_key*)
540                         ENC_TYPE="WEP"
541                         ;;
542                 psk)
543                         ENC_TYPE="WPA"
544                         ;;
545                 *)
546                         return 0
547                         ;;
548         esac
549
550         if [ "$ENC_TYPE" = "WEP" ]; then
551                 if ishex "$KEY"; then
552                         case "$KEY_LEN" in
553                                 10|26|32|58)
554                                         # 64/128/152/256-bit WEP
555                                         KEY_TYPE="raw"
556                                         ;;
557                                 *)
558                                         KEY_TYPE="ascii"
559                                         ;;
560                         esac
561                 else
562                         KEY_TYPE="ascii"
563                 fi
564
565                 if [ "$KEY_TYPE" = "ascii" ]; then
566                         if [ "$KEY_LEN" -lt "5" ]; then
567                                 wpa_msg stderr "WARNING: plaintext or ascii WEP key has $KEY_LEN characters,"
568                                 wpa_msg stderr "it must have at least 5 to be valid."
569                         fi
570                 fi
571         elif [ "$ENC_TYPE" = "WPA" ]; then
572                 if ishex "$KEY"; then
573                         case "$KEY_LEN" in
574                                 64)
575                                         # 256-bit WPA
576                                         KEY_TYPE="raw"
577                                         ;;
578                                 *)
579                                         KEY_TYPE="ascii"
580                                         ;;
581                         esac
582                 else
583                         KEY_TYPE="ascii"
584                 fi
585
586                 if [ "$KEY_TYPE" = "ascii" ]; then
587                         if [ "$KEY_LEN" -lt "8" ] || [ "$KEY_LEN" -gt "63" ]; then
588                                 wpa_msg stderr "WARNING: plaintext or ascii WPA key has $KEY_LEN characters,"
589                                 wpa_msg stderr "it must have between 8 and 63 to be valid."
590                                 wpa_msg stderr "If the WPA key is a 256-bit hexadecimal key, it must have"
591                                 wpa_msg stderr "exactly 64 characters."
592                         fi
593                 fi
594         fi
595
596         wpa_cli_do "$KEY" "$KEY_TYPE" set_network "$2" "$3"
597 }
598
599 #####################################################################
600 ## formulate a usable configuration from interfaces(5) wpa- lines
601 # A series of wpa_cli commands corresponding to environment variables
602 # created as a result of wpa- lines in an interfaces stanza.
603 #
604 # NB: no-act when roaming daemon is used (to avoid prematurely
605 # attaching to ctrl_interface socket)
606 #
607 conf_wpa_supplicant () {
608         if [ -n "$WPA_ACTION_SCRIPT" ]; then
609                 return 0
610         fi
611
612         if [ "$IF_WPA_DRIVER" = "wired" ]; then
613                 IF_WPA_AP_SCAN="0"
614                 wpa_msg verbose "forcing ap_scan=0 (required for wired IEEE8021X auth)"
615         fi
616
617         if [ -n "$IF_WPA_ESSID" ]; then
618                 # #403316, be similar to wireless tools
619                 IF_WPA_SSID="$IF_WPA_ESSID"
620         fi
621         
622         wpa_cli_do "$IF_WPA_AP_SCAN" raw \
623                 ap_scan wpa-ap-scan
624         
625         wpa_cli_do "$IF_WPA_PREAUTHENTICATE" raw \
626                 preauthenticate wpa-preauthenticate
627                 
628         if [ -n "$IF_WPA_SSID" ] || [ "$IF_WPA_DRIVER" = "wired" ] || \
629                 [ -n "$IF_WPA_KEY_MGMT" ]; then
630                 
631                 case "$IF_WPA_SSID" in
632                         '"'*'"')
633                                 IF_WPA_SSID=$(echo -n "$IF_WPA_SSID" | sed 's/^"//;s/"$//')
634                                 ;;
635                         *)
636                                 ;;
637                 esac
638                 
639                 WPA_ID=$(wpa_cli add_network)
640
641                 wpa_msg verbose "configuring network block -- $WPA_ID"
642                 
643                 wpa_cli_do "$IF_WPA_SSID" ascii \
644                         set_network ssid wpa-ssid
645                 
646                 wpa_cli_do "$IF_WPA_PRIORITY" raw \
647                         set_network priority wpa-priority
648                 
649                 wpa_cli_do "$IF_WPA_BSSID" raw \
650                         set_network bssid wpa-bssid
651                 
652                 if [ -s "$IF_WPA_PSK_FILE" ]; then
653                         IF_WPA_PSK=$(cat "$IF_WPA_PSK_FILE")
654                 fi
655                 
656                 # remain compat with wpa-passphrase-file
657                 if [ -s "$IF_WPA_PASSPHRASE_FILE" ]; then
658                         IF_WPA_PSK=$(cat "$IF_WPA_PASSPHRASE_FILE")
659                 fi
660                 
661                 # remain compat with wpa-passphrase
662                 if [ -n "$IF_WPA_PASSPHRASE" ]; then
663                         IF_WPA_PSK="$IF_WPA_PASSPHRASE"
664                 fi
665         
666                 if [ -n "$IF_WPA_PSK" ]; then
667                         wpa_key_check_and_set "$IF_WPA_PSK" \
668                                 psk wpa-psk
669                 fi
670                 
671                 wpa_cli_do "$IF_WPA_PAIRWISE" raw \
672                         set_network pairwise wpa-pairwise
673                 
674                 wpa_cli_do "$IF_WPA_GROUP" raw \
675                         set_network group wpa-group
676
677                 wpa_cli_do "$IF_WPA_MODE" raw \
678                         set_network mode wpa-mode
679
680                 wpa_cli_do "$IF_WPA_FREQUENCY" raw \
681                         set_network frequency wpa-frequency
682
683                 wpa_cli_do "$IF_WPA_SCAN_FREQ" raw \
684                         set_network scan_freq wpa-scan-freq
685
686                 wpa_cli_do "$IF_WPA_FREQ_LIST" raw \
687                         set_network freq_list wpa-freq-list
688                 
689                 wpa_cli_do "$IF_WPA_KEY_MGMT" raw \
690                         set_network key_mgmt wpa-key-mgmt
691                 
692                 wpa_cli_do "$IF_WPA_PROTO" raw \
693                         set_network proto wpa-proto
694                 
695                 wpa_cli_do "$IF_WPA_AUTH_ALG" raw \
696                         set_network auth_alg wpa-auth-alg
697                 
698                 wpa_cli_do "$IF_WPA_SCAN_SSID" raw \
699                         set_network scan_ssid wpa-scan-ssid
700                 
701                 wpa_cli_do "$IF_WPA_IDENTITY" ascii \
702                         set_network identity wpa-identity
703                 
704                 wpa_cli_do "$IF_WPA_ANONYMOUS_IDENTITY" ascii \
705                         set_network anonymous_identity wpa-anonymous-identity
706                 
707                 wpa_cli_do "$IF_WPA_EAP" raw \
708                         set_network eap wpa-eap
709                 
710                 wpa_cli_do "$IF_WPA_EAPPSK" raw \
711                         set_network eappsk wpa-eappsk
712
713                 wpa_cli_do "$IF_WPA_NAI" ascii \
714                         set_network nai wpa-nai
715
716                 wpa_cli_do "$IF_WPA_PASSWORD" ascii \
717                         set_network password wpa-password
718
719                 wpa_cli_do "$IF_WPA_CA_CERT" ascii \
720                         set_network ca_cert wpa-ca-cert
721
722                 wpa_cli_do "$IF_WPA_CA_PATH" ascii \
723                         set_network ca_path wpa-ca-path
724
725                 wpa_cli_do "$IF_WPA_CLIENT_CERT" ascii \
726                         set_network client_cert wpa-client-cert
727
728                 wpa_cli_do "$IF_WPA_PRIVATE_KEY" ascii \
729                         set_network private_key wpa-private-key
730
731                 wpa_cli_do "$IF_WPA_PRIVATE_KEY_PASSWD" ascii \
732                         set_network private_key_passwd wpa-private-key-passwd
733                 
734                 wpa_cli_do "$IF_WPA_DH_FILE" ascii \
735                         set_network dh_file wpa-dh-file
736
737                 wpa_cli_do "$IF_WPA_SUBJECT_MATCH" ascii \
738                         set_network subject_match wpa-subject-match
739
740                 wpa_cli_do "$IF_WPA_ALTSUBJECT_MATCH" ascii \
741                         set_network altsubject_match wpa-altsubject-match
742
743                 wpa_cli_do "$IF_WPA_CA_CERT2" ascii \
744                         set_network ca_cert2 wpa-ca-cert2
745
746                 wpa_cli_do "$IF_WPA_CA_PATH2" ascii \
747                         set_network ca_path2 wpa-ca-path2
748
749                 wpa_cli_do "$IF_WPA_CLIENT_CERT2" ascii \
750                         set_network client_cert2 wpa-client-cert2
751
752                 wpa_cli_do "$IF_WPA_PRIVATE_KEY2" ascii \
753                         set_network private_key2 wpa-private-key2
754
755                 wpa_cli_do "$IF_WPA_PRIVATE_KEY_PASSWD2" ascii \
756                         set_network private_key_passwd2 wpa-private-key-passwd2
757                 
758                 wpa_cli_do "$IF_WPA_DH_FILE2" ascii \
759                         set_network dh_file2 wpa-dh-file2
760
761                 wpa_cli_do "$IF_WPA_SUBJECT_MATCH2" ascii \
762                         set_network subject_match2 wpa-subject-match2
763
764                 wpa_cli_do "$IF_WPA_ALTSUBJECT_MATCH2" ascii \
765                         set_network altsubject_match2 wpa-altsubject-match2
766                 
767                 wpa_cli_do "$IF_WPA_EAP_METHODS" raw \
768                         set_network eap_methods wpa-eap-methods
769
770                 wpa_cli_do "$IF_WPA_PHASE1" ascii \
771                         set_network phase1 wpa-phase1
772
773                 wpa_cli_do "$IF_WPA_PHASE2" ascii \
774                         set_network phase2 wpa-phase2
775
776                 wpa_cli_do "$IF_WPA_PCSC" raw \
777                         set_network pcsc wpa-pcsc
778
779                 wpa_cli_do "$IF_WPA_PIN" ascii \
780                         set_network pin wpa-pin
781
782                 wpa_cli_do "$IF_WPA_ENGINE" raw \
783                         set_network engine wpa-engine
784
785                 wpa_cli_do "$IF_WPA_ENGINE_ID" ascii \
786                         set_network engine_id wpa-engine-id
787
788                 wpa_cli_do "$IF_WPA_KEY_ID" ascii \
789                         set_network key_id wpa-key-id
790
791                 wpa_cli_do "$IF_WPA_EAPOL_FLAGS" raw \
792                         set_network eapol_flags wpa-eapol-flags
793                 
794                 if [ -n "$IF_WPA_WEP_KEY0" ]; then
795                         wpa_key_check_and_set "$IF_WPA_WEP_KEY0" \
796                                 wep_key0 wpa-wep-key0
797                 fi
798                 
799                 if [ -n "$IF_WPA_WEP_KEY1" ]; then
800                         wpa_key_check_and_set "$IF_WPA_WEP_KEY1" \
801                                 wep_key1 wpa-wep-key1
802                 fi
803
804                 if [ -n "$IF_WPA_WEP_KEY2" ]; then
805                         wpa_key_check_and_set "$IF_WPA_WEP_KEY2" \
806                                 wep_key2 wpa-wep-key2
807                 fi
808
809                 if [ -n "$IF_WPA_WEP_KEY3" ]; then
810                         wpa_key_check_and_set "$IF_WPA_WEP_KEY3" \
811                                 wep_key3 wpa-wep-key3
812                 fi
813                 
814                 wpa_cli_do "$IF_WPA_WEP_TX_KEYIDX" raw \
815                         set_network wep_tx_keyidx wpa-wep-tx-keyidx
816                 
817                 wpa_cli_do "$IF_WPA_PROACTIVE_KEY_CACHING" raw \
818                         set_network proactive_key_caching wpa-proactive-key-caching
819                         
820                 wpa_cli_do "$IF_WPA_PAC_FILE" ascii \
821                         set_network pac_file wpa-pac-file
822                 
823                 wpa_cli_do "$IF_WPA_PEERKEY" raw \
824                         set_network peerkey wpa-peerkey
825                         
826                 wpa_cli_do "$IF_FRAGMENT_SIZE" raw \
827                         set_network fragment_size wpa-fragment-size
828
829                 wpa_cli_do "$IF_WPA_ID_STR" ascii \
830                         set_network id_str wpa-id-str
831                 
832                 wpa_cli_do "$WPA_ID" raw \
833                         enable_network "enabling network block"
834         fi
835 }
836
837 #####################################################################
838 ## Log wpa_cli environment variables
839 wpa_log_env () {
840         wpa_msg log "WPA_IFACE=$WPA_IFACE WPA_ACTION=$WPA_ACTION"
841         wpa_msg log "WPA_ID=$WPA_ID WPA_ID_STR=$WPA_ID_STR WPA_CTRL_DIR=$WPA_CTRL_DIR"
842 }
843
844 #####################################################################
845 ## hysteresis checking
846 # Networking tools such as dhcp clients used with ifupdown can
847 # synthesize artificial ACTION events, particuarly just after a
848 # DISCONNECTED/CONNECTED events are experienced in quick succession.
849 # This can lead to infinite event loops, and in extreme cases has the
850 # potential to cause system instability.
851 #
852 wpa_hysteresis_event () {
853         echo "$(date +%s)" > "$WPA_CLI_TIMESTAMP" 2>/dev/null
854 }
855
856 wpa_hysteresis_check () {
857         if [ -f "$WPA_CLI_TIMESTAMP" ]; then
858                 local TIME
859                 local TIMESTAMP
860                 local TIMEWAIT
861                 TIME=$(date +%s)
862                 # current time minus 4 second event buffer
863                 TIMEWAIT=$(($TIME-4))
864                 # get time of last event
865                 TIMESTAMP=$(cat $WPA_CLI_TIMESTAMP)
866                 # compare values, allowing new action to be processed 
867                 # only if last action was more than 4 seconds ago
868                 if [ "$TIMEWAIT" -le "$TIMESTAMP" ]; then
869                         wpa_msg log "$WPA_ACTION event blocked by hysteresis check"
870                         return 1
871                 fi
872         fi
873
874         return 0
875 }
876
877 #####################################################################
878 ## ifupdown locking functions
879 # A collection of rudimentary locking functions to lock ifup/ifdown
880 # actions.
881 #
882
883 ifupdown_lock () {
884         ln -s lock "$WPA_CLI_IFUPDOWN"
885 }
886
887 ifupdown_locked () {
888         [ -L "$WPA_CLI_IFUPDOWN" ] && return 0
889
890         return 1
891 }
892
893 ifupdown_unlock () {
894         rm -f "$WPA_CLI_IFUPDOWN"
895 }
896
897 #####################################################################
898 ## apply mapping logic and ifup logical interface
899 # Apply mapping logic via id_str or external mapping script, check
900 # state of IFACE with respect to ifupdown and ifup logical interaface
901 #
902 ifup () {
903         local INTERFACES_FILE
904         local IFSTATE_FILE
905         local IFUP_RETVAL
906         local WPA_LOGICAL_IFACE
907
908         if [ -e /etc/network/interfaces ]; then
909                 INTERFACES_FILE="/etc/network/interfaces"
910         else
911                 wpa_msg log "/etc/network/interfaces does not exist, $WPA_IFACE will not be configured"
912                 return 1
913         fi
914
915         if [ -e /etc/network/run/ifstate ]; then
916                 # debian's ifupdown
917                 IFSTATE_FILE="/etc/network/run/ifstate"
918         elif [ -e /var/run/network/ifstate ]; then
919                 # ubuntu's
920                 IFSTATE_FILE="/var/run/network/ifstate"
921         else
922                 unset IFSTATE_FILE
923         fi
924         
925         if [ -z "$IF_WPA_MAPPING_SCRIPT_PRIORITY" ] && [ -n "$WPA_ID_STR" ]; then
926                 WPA_LOGICAL_IFACE="$WPA_ID_STR"
927         fi
928         
929         if [ -z "$WPA_LOGICAL_IFACE" ] && [ -n "$IF_WPA_MAPPING_SCRIPT" ]; then
930                 local WPA_MAP_STDIN
931                 
932                 WPA_MAP_STDIN=$(set | sed -n 's/^\(IF_WPA_MAP[0-9]*\)=.*/echo \$\1/p')
933                 
934                 if [ -n "$WPA_MAP_STDIN" ]; then
935                         WPA_LOGICAL_IFACE=$(eval "$WPA_MAP_STDIN" | "$IF_WPA_MAPPING_SCRIPT" "$WPA_IFACE")
936                 else            
937                         WPA_LOGICAL_IFACE=$("$IF_WPA_MAPPING_SCRIPT" "$WPA_IFACE")
938                 fi
939                 
940                 if [ -n "$WPA_LOGICAL_IFACE" ]; then
941                         wpa_msg log "mapping script result: $WPA_LOGICAL_IFACE"
942                 else
943                         wpa_msg log "mapping script failed."
944                 fi
945         fi
946
947         if [ -z "$WPA_LOGICAL_IFACE" ]; then
948                 if [ -n "$IF_WPA_ROAM_DEFAULT_IFACE" ]; then
949                         WPA_LOGICAL_IFACE="$IF_WPA_ROAM_DEFAULT_IFACE"
950                 else
951                         WPA_LOGICAL_IFACE="default"
952                 fi
953         fi
954
955         if [ -n "$WPA_LOGICAL_IFACE" ]; then
956                 if egrep -q "^iface[[:space:]]+${WPA_LOGICAL_IFACE}[[:space:]]+inet" "$INTERFACES_FILE"; then
957                         : # logical network is defined
958                 else
959                         wpa_msg log "network settings not defined for $WPA_LOGICAL_IFACE in $INTERFACES_FILE"
960                         WPA_LOGICAL_IFACE="default"
961                 fi
962
963                 wpa_msg log "ifup $WPA_IFACE=$WPA_LOGICAL_IFACE"
964
965                 ifupdown_lock
966
967                 if [ -n "$IFSTATE_FILE" ] && grep -q "^$WPA_IFACE=$WPA_IFACE" "$IFSTATE_FILE"; then
968                         # Force settings over the unconfigured "master" IFACE
969                         /sbin/ifup -v --force "$WPA_IFACE=$WPA_LOGICAL_IFACE"
970                 else
971                         /sbin/ifup -v "$WPA_IFACE=$WPA_LOGICAL_IFACE"
972                 fi
973                 IFUP_RETVAL="$?"
974
975                 ifupdown_unlock
976         fi
977
978         wpa_msg log "creating sendsigs omission pidfile: $WPA_SUP_OMIT_PIDFILE"
979         cat "$WPA_SUP_PIDFILE" > "$WPA_SUP_OMIT_PIDFILE"
980
981         return "$IFUP_RETVAL"
982 }
983
984 #####################################################################
985 ## ifdown IFACE
986 # Check IFACE state and ifdown as requested.
987 #
988 ifdown () {
989         wpa_msg log "ifdown $WPA_IFACE"
990
991         ifupdown_lock
992
993         /sbin/ifdown -v "$WPA_IFACE"
994
995         ifupdown_unlock
996
997         wpa_msg log "removing sendsigs omission pidfile: $WPA_SUP_OMIT_PIDFILE"
998         rm -f "$WPA_SUP_OMIT_PIDFILE"
999 }
1000
1001 #####################################################################
1002 ## keep IFACE scanning
1003 # After ifdown, the IFACE may be left "down", and inhibits 
1004 # wpa_supplicant's ability to continue roaming.
1005 #
1006 # NB: use iproute if present, flushing the IFACE first
1007 #
1008 if_post_down_up () {
1009         if [ -x /bin/ip ]; then
1010                 ip addr flush dev "$WPA_IFACE" 2>/dev/null
1011                 ip link set "$WPA_IFACE" up
1012         else
1013                 ifconfig "$WPA_IFACE" up
1014         fi
1015 }