#! /bin/bash . /usr/lib/network/network rfkill_from_name() { local name=$1 for rfkill in /sys/class/rfkill/*; do if [[ "$(cat $rfkill/name)" == $name ]]; then echo $rfkill return 0 fi done echo "none" return 1 } wireless_up() { load_profile "$1" [[ -n "$2" ]] && ESSID="$2" # JP: use the literal ESSID (though currently we only interpret wireless-dbus ESSIDs as regexps) . "$SUBR_DIR/8021x" . "$SUBR_DIR/wireless" # If rfkill is specified, enable device. if [[ -n "$RFKILL_NAME" ]]; then path=$(rfkill_from_name $RFKILL_NAME) if [[ $? -ne 0 ]]; then report_fail "no rfkill switch with the name $RFKILL_NAME"; fi echo 1 > ${path}/state sleep 1 fi # Check if interface exists if [[ ! -e "/sys/class/net/$INTERFACE" ]]; then if ! echo "$INTERFACE" | fgrep -q ":"; then report_fail "interface $INTERFACE does not exist" return 1 fi fi # Kill any lingering wpa_supplicants. report_debug wireless_up stop_wpa "$INTERFACE" stop_wpa "$INTERFACE" # Most drivers (mac80211) need mode set before device is brought up # Drivers generally default to managed, but set this to be sure. if [[ $(iwgetid -sm "$INTERFACE") -ne Managed ]]; then report_debug wireless_up iwconfig "$INTERFACE" mode managed iwconfig "$INTERFACE" mode managed fi report_debug wireless_up ifup set_interface up-old "$INTERFACE" || return 1 quirk prescan && iwlist "$INTERFACE" scan &> /dev/null # bcm43xx if quirk preessid; then # ipw3945 if [[ -n "$AP" ]]; then # JP: enable use of AP # JP: Since I don't undertand why the else block below is an eval, I'm not sure # if this command also needs to be eval'd iwconfig "$INTERFACE" mode managed ap "$AP" else # JP: I don't understand why this needs to be an eval. What's wrong with just: # iwconfig "$INTERFACE" mode managed essid "$ESSID" eval "iwconfig \"$INTERFACE\" mode managed essid \"$ESSID\"" fi fi if checkyesno "${SCAN:-no}"; then report_debug wireless_up scanning local OLDESSID="$ESSID" if [[ -n "$AP" ]]; then ESSID=$(find_ap "$INTERFACE" "$AP") else ESSID=$(find_essid "$INTERFACE" "$ESSID" "$CONNECTION") # JP: we could have left $3 null for default of treating ESSID as literal # but instead we explicitly pass $CONNECTION fi if [[ $? -gt 0 ]]; then report_fail "Wireless network \"$OLDESSID\" not present." return 1 fi fi # Manually set iwconfig options if [[ -n "$IWCONFIG" ]]; then report_debug wireless_up iwconfig "$INTERFACE" $IWCONFIG iwconfig "$INTERFACE" $IWCONFIG fi # Set to 'none' if not set [[ -z "$SECURITY" ]] && SECURITY="none" case "$SECURITY" in wep|none) # 'none' uses iwconfig like wep. Use sane default if WEP_OPTS="" if [[ -z "$WEP_OPTS" ]]; then if [[ "$SECURITY" = "wep" ]]; then if [[ -n "$AP" ]]; then WEP_OPTS="ap \"$AP\" key $KEY" # JP: formerly I had "...key open $KEY"; is it correct to omit the 'open'? else WEP_OPTS="essid \"$ESSID\" key $KEY" # JP: formerly I had "...key open $KEY"; is it correct to omit the 'open'? fi elif [[ "$SECURITY" = "none" ]]; then if [[ -n "$AP" ]]; then WEP_OPTS="ap \"$AP\"" else WEP_OPTS="essid \"$ESSID\"" fi fi fi if quirk "predown"; then # madwifi FS#10585 # ignore quirk nodown---is that appropriate? # this adds a flush call as well---is that appropriate? set_interface forcedown-old "$INTERFACE" fi report_debug wireless_up iwconfig "$INTERFACE" $WEP_OPTS # JP: I don't understand why this needs to be an eval. What's wrong with just: # iwconfig "$INTERFACE" $WEP_OPTS if ! eval "iwconfig \"$INTERFACE\" $WEP_OPTS"; then report_fail "Could not set wireless configuration." return 1 fi if quirk "predown"; then # madwifi FS#10585 set_interface up-old "$INTERFACE" fi report_debug ethernet_up wep_check if ! wep_check "$INTERFACE" "$TIMEOUT"; then report_fail "WEP Association Failed" return 1 fi ;; wpa) # Quirk for broken drivers... http://bbs.archlinux.org/viewtopic.php?id=36384 if quirk "wpaessid"; then if [[ -n "$AP" ]]; then # JP: Since I don't undertand why the else block below is an eval, I'm not sure # if this command also needs to be eval'd iwconfig "$INTERFACE" ap "$AP" else # JP: I don't understand why this needs to be an eval. What's wrong with just: # iwconfig "$INTERFACE" essid "$ESSID" eval "iwconfig \"$INTERFACE\" essid \"$ESSID\"" fi fi local WPA_CONF="${TMPDIR:-/tmp}/wpa.${1// /}" # substitute spaces out # make empty tmp dir with correct permissions, rename it rm -rf "$WPA_CONF" mv -f $(mktemp -d) "$WPA_CONF" || return 1 echo "ctrl_interface=/var/run/wpa_supplicant" >> "$WPA_CONF/wpa.conf" # we know $WPA_CONF now has no spaces, but it may have other nasty chars, so still needs to be quoted echo "ctrl_interface_group=${WPA_GROUP:-wheel}" >> "$WPA_CONF/wpa.conf" # Generate configuration if [[ "${#KEY}" -eq 64 ]]; then echo -e "network={ \nssid=\"$ESSID\" \npsk=$KEY \n}">> "$WPA_CONF/wpa.conf" # JP: formerly I had { \nssid=\"$ESSID\" \nproto=WPA \nkey_mgmt=WPA-PSK \npsk=$KEY \n} # JP: is what's above better? elif ! echo "$KEY" | wpa_passphrase "$ESSID" >> "$WPA_CONF/wpa.conf"; then report_fail "Configuration generation failed." cat "$WPA_CONF/wpa.conf" >&2 return 1 fi # Connect! [[ -z "$WPA_OPTS" ]] && WPA_OPTS="-Dwext" report_debug wireless_up start_wpa "$INTERFACE" "$WPA_CONF/wpa.conf" "$WPA_OPTS" if ! start_wpa "$INTERFACE" "$WPA_CONF/wpa.conf" "$WPA_OPTS"; then report_fail "wpa_supplicant did not start, possible configuration error" return 1 fi report_debug wireless_up wpa_check if ! wpa_check "$INTERFACE" "$TIMEOUT"; then report_fail "WPA Authentication/Association Failed" return 1 fi ;; wpa-config) . "$SUBR_DIR/8021x" [[ -z "$WPA_CONF" ]] && WPA_CONF="/etc/wpa_supplicant.conf" # defaults [[ -z "$WPA_OPTS" ]] && WPA_OPTS="-Dwext" report_debug wireless_up start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_OPTS" if ! start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_OPTS"; then report_fail "wpa_supplicant did not start, possible configuration error" return 1 fi report_debug wireless_up wpa_check if ! wpa_check "$INTERFACE" "$TIMEOUT"; then report_fail "WPA Authentication/Association Failed" return 1 fi ;; esac conn=ethernet checkyesno "${IPROUTE:-no}" && conn=ethernet-iproute if ! "$CONN_DIR/$conn" up "$1"; then wireless_down "$1" YES return 1 fi } # wireless_down PROFILE [ LEAVE ifconfig up? default no ] wireless_down() { local PROFILE="$1" NOETHERNETDOWN="$2" load_profile "$PROFILE" . "$SUBR_DIR/8021x" if ! checkyesno "$NOETHERNETDOWN"; then conn=ethernet checkyesno "${IPROUTE:-no}" && conn=ethernet-iproute "$CONN_DIR/$conn" down "$PROFILE" fi report_debug wireless_down stop_wpa "$INTERFACE" stop_wpa "$INTERFACE" [[ "$SECURITY" == "wpa" ]] && rm -rf "${TMPDIR:-/tmp}/wpa.${PROFILE// /}" # remove tmp wpa config report_debug wireless_down iwconfig "$INTERFACE" essid off key off iwconfig "$INTERFACE" essid off key off &> /dev/null # respects quirk nodown---is that appropriate? # wasn't this already called in ethernet_down? but does the call there respect quirk nodown? # this adds a flush call as well---is that appropriate? set_interface down-old "$INTERFACE" # If rfkill is specified, disable device. if [[ -n "$RFKILL_NAME" ]]; then path=$(rfkill_from_name "$RFKILL_NAME") if [[ $? -ne 0 ]]; then report_fail "no rfkill switch with the name $RFKILL_NAME"; fi echo 0 > "${path}/state" fi } # Returns status of profile - is it still functional? wireless_status() { load_profile $1 if [[ "$(iwgetid -r)" -ne $ESSID ]]; then return 1 elif ! ip link show dev ra0 | fgrep -q "state UP"; then return 1 fi } wireless_$1 "$2" "$3" exit $? # vim: set ts=4 et sw=4: