#!/bin/bash # etc/wlan/shared # # Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. # -------------------------------------------------------------------- # # linux-wlan # # The contents of this file are subject to the Mozilla Public # License Version 1.1 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or # implied. See the License for the specific language governing # rights and limitations under the License. # # Alternatively, the contents of this file may be used under the # terms of the GNU Public License version 2 (the "GPL"), in which # case the provisions of the GPL are applicable instead of the # above. If you wish to allow the use of your version of this file # only under the terms of the GPL and not to allow others to use # your version of this file under the MPL, indicate your decision # by deleting the provisions above and replace them with the notice # and other provisions required by the GPL. If you do not delete # the provisions above, a recipient may use your version of this # file under either the MPL or the GPL. # # -------------------------------------------------------------------- # # Inquiries regarding the linux-wlan Open Source project can be # made directly to: # # AbsoluteValue Systems Inc. # info@linux-wlan.com # http://www.linux-wlan.com # # -------------------------------------------------------------------- # # Portions of the development of this software were funded by # Intersil Corporation as part of PRISM(R) chipset product development. # # -------------------------------------------------------------------- if [ ! -n "$ECHO" ]; then ECHO=echo fi if [ -x /sbin/modprobe ] ; then MODPROBE=/sbin/modprobe else ${ECHO} "/sbin/modprobe not found." exit 1 fi if [ -x /sbin/wlanctl-ng ] ; then WLANCTL=/sbin/wlanctl-ng else ${ECHO} "/sbin/wlanctl-ng not found." exit 1 fi if [ -x /sbin/wland ] ; then WLAND=/sbin/wland else ${ECHO} "/sbin/wland not found." exit 1 fi if [ -f /proc/sys/kernel/hotplug -a \ -x `cat /proc/sys/kernel/hotplug` -a \ -f /etc/hotplug/wlan.agent ] ; then HAS_HOTPLUG=y else HAS_HOTPLUG=n fi # Source the wlan configuration if [ -f /etc/wlan/wlan.conf ] ; then . /etc/wlan/wlan.conf else ${ECHO} "/etc/wlan/wlan.conf not found." exit 0 fi # Source NSD specific functions # nsd_fwload # nsd_mibset for i in /etc/wlan/shared.* ; do . $i done is_true () { # $1 == string containing a t/f indicator. [ "$1" = "y" -o "$1" = "Y" -o "$1" = "yes" -o "$1" = "YES" \ -o "$1" = "t" -o "$1" = "T" -o "$1" = "true" -o "$1" = "TRUE" ] } wlan_nsdname () { # $1 == wlandev # Writes the given device's name to stdout grep 'nsd name' /proc/net/p80211/$1/wlandev | sed -e 's/.*: \(.*\)_.*/\1/' } wlan_enable () { # $1 == wlandev #=======ENABLE IFSTATE============================= # Bring the device into its operable state $MODPROBE $1 # First, make sure the driver is loaded.... if ! ifconfig $1 > /dev/null 2>&1 ; then ${ECHO} "Error: Device $1 does not seem to be present." ${ECHO} "Make sure you've inserted the appropriate" ${ECHO} "modules or that your modules.conf file contains" ${ECHO} "the appropriate aliase(s)." return 1 fi # Call the nsd script's fwload function, in case the card needs # a firmware load, or could use an optional one. nsdname=`wlan_nsdname $1` if ! ${nsdname}_fwload $1 ; then ${ECHO} "Firmware failed to load for device $1" return 1 fi # Enable the interface result=`$WLANCTL $1 lnxreq_ifstate ifstate=enable` if [ $? = 0 ] ; then eval $result if [ $resultcode != "success" ]; then ${ECHO} "Failed to enable the device, resultcode=" \ $resultcode "." return 1 fi else ${ECHO} "Failed to enable the device, exitcode=" $? "." return 1 fi # Set any NSD specific MIBs ${nsdname}_mibset $1 } wlan_user_mibs () { # $1 == wlandev #=======USER MIB SETTINGS============================= # Set the user specified MIB items. for i in $USER_MIBS ; do result=`$WLANCTL $1 dot11req_mibset "mibattribute=$i"` if [ $? = 0 ] ; then eval $result if [ $resultcode != "success" ] ; then ${ECHO} "Failed to set user MIB $i." return 1 fi else ${ECHO} "Failed to set user MIB $i." return 1 fi done } wlan_source_config () { # $1 == wlandev # XXX what about stray singlequotes. eval 'GOSSID="$SSID_'$1'"' wlan_source_config_for_ssid "$GOSSID" } wlan_source_config_for_ssid () { # $1 == ssid[:bssid] # $2 == bssid (optional) DesiredSSID="$1" DesiredBSSID="$2" if [ -n "$2" ] ; then token_ssid=`echo $1 | sed -ne 's/\(.*\)\(:..:..:..:..:..:..\).*/\1/p'` token_bssid=`echo $1 | sed -ne 's/\(.*\):\(..:..:..:..:..:..\).*/\2/p'` if [ -n "$token_ssid" ] ; then DesiredSSID="$token_ssid" DesiredBSSID="$token_bssid" fi fi if [ -f "/etc/wlan/wlancfg-$DesiredSSID:$DesiredBSSID" ] ; then . "/etc/wlan/wlancfg-$DesiredSSID:$DesiredBSSID" elif [ -f "/etc/wlan/wlancfg-$DesiredSSID" ] ; then . "/etc/wlan/wlancfg-$DesiredSSID" else if [ -n "$1" ] ; then ${ECHO} "Failed to open network config file /etc/wlan/wlancfg-$1, using default." fi . "/etc/wlan/wlancfg-DEFAULT" fi } wlan_disable () { # $1 == wlandev $WLANCTL $1 lnxreq_ifstate ifstate=disable } wlan_ssid_in_list () { # $1 == wlandev, $2 == ssid, $3 == bssid eval 'GOSSID="$SSID_'$1'"' # This "eval" hackery is to allow escapes in GOSSID... cmd="for token in $GOSSID ; do ssid_token=\`echo \"\$token\" | sed -ne 's/\(.*\)\(:..:..:..:..:..:..\).*/\1/p'\` bssid_token=\`echo \"\$token\" | sed -ne 's/\(.*\):\(..:..:..:..:..:..\).*/\2/p'\` if [ -z \"\$ssid_token\" ] ; then ssid_token="\$token" fi if [ -n \"\$bssid_token\" ] ; then if [ \"\$bssid_token\" = \"\$3\" ] ; then return 0 fi elif [ \"\$2\" = \"\$ssid_token\" ] ; then return 0 fi done" eval "$cmd" return 1 } wlan_supports_scan () { # $1 == wlandev if is_true "$WLAN_SCAN" ; then cat /proc/net/p80211/$1/wlandev | grep 'scan' > /dev/null if [ $? = 0 ] ; then return 0 fi fi return 1 } wlan_scan () { # $1 == wlandev # find our allowed SSID list. # XXX what about stray singlequotes. eval 'GOSSID="$SSID_'$1'"' # kick off a quick scan with the broadcast SSID. wlan_scan_one $1 '' '' n if [ $? = 0 -a \ "$GOSSID" = "" ] ; then # if successful and our ssid list is null, return. sleep 1 return 0 fi # otherwise we walk through the list, and scan for eacn in turn. # this "eval" hackery is to allow escapes in GOSSID cmd="for token in $GOSSID ; do ssid_token=\`echo \"\$token\" | sed -ne 's/\(.*\)\(:..:..:..:..:..:..\).*/\1/p'\` bssid_token=\`echo \"\$token\" | sed -ne 's/\(.*\):\(..:..:..:..:..:..\).*/\2/p'\` if [ -z \"\$ssid_token\" ] ; then ssid_token=\"\$token\" fi wlan_scan_one \$1 \"\$ssid_token\" \"\$bssid_token\" if [ \$? = 0 ] ; then sleep 1 return 0 fi done" eval "$cmd" # We got to the end of the list. Maybe try "any" if is_true "$WLAN_ANY" ; then wlan_scan_one $1 sleep 1 return $? fi sleep 1 return 1 } wlan_scan_one () { # $1 == wlandev, [ $2 == ssid, $3 == bssid, $4 == append ] if [ -z "$4" ] ; then append=true else append=false fi numbss=0 result=`$WLANCTL $1 dot11req_scan bsstype=any bssid=ff:ff:ff:ff:ff:ff \ scantype=active probedelay=0 channellist=$ChannelList ssid="$2" \ minchanneltime=$ChannelMinTime maxchanneltime=$ChannelMaxTime append=$append` eval $result if [ $resultcode != 'success' ] ; then ${ECHO} "Scan failed ($resultcode) " return 1 fi ## XXX if numbss == 0, repeat with $2 $3 $4? i=0 bssfound="" # walk through the results and do first-cut matching. while [ $i -lt $numbss ] ; do result=`$WLANCTL $1 dot11req_scan_results bssindex=$i` eval $result if [ -n "$3" ] ; then if [ "$3" = "$bssid" ] ; then bssfound="$bssfound $i" fi elif [ -z "$2" ] ; then # if our ssid is "", then we pick the first entry. bssfound="$bssfound $i" elif [ "$2" = "$ssid" ] ; then bssfound="$bssfound $i" fi i=`expr $i + 1` done if [ -z "$bssfound" ]; then # No BSSs found, bail. return 1 else # Now find the closest bigsignal=0 for i in $bssfound ; do result=`$WLANCTL $1 dot11req_scan_results bssindex=$i` eval $result if [ $bigsignal -lt $signal ]; then bigsignal=$signal bigbssindex=$i fi done result=`$WLANCTL $1 dot11req_scan_results bssindex=$bigbssindex` eval $result return 0 fi } wlan_wep () { # $1 == wlandev #=======WEP=========================================== # Setup privacy if [ ${dot11PrivacyInvoked:-"false"} = "false" ] ; then return 0; fi result=`$WLANCTL $1 dot11req_mibget mibattribute=dot11PrivacyOptionImplemented` if [ $? = 0 ] ; then eval $result eval $mibattribute else ${ECHO} "dot11PrivacyOptionImplemented mibget failed." return 1 fi if [ $dot11PrivacyOptionImplemented = "false" ] ; then ${ECHO} "Cannot enable privacy, dot11PrivacyOptionImplemented=false." return 1 fi # Do we want host-based WEP? result=`$WLANCTL $1 lnxreq_hostwep \ decrypt="${lnxreq_hostWEPDecrypt:-false}" \ encrypt="${lnxreq_hostWEPEncrypt:-false}"` # set up the rest of the parametsrs. if [ $dot11PrivacyOptionImplemented = "true" -a \ $dot11PrivacyInvoked = "true" ] ; then result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKeyID=$dot11WEPDefaultKeyID ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11ExcludeUnencrypted=$dot11ExcludeUnencrypted ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11PrivacyInvoked=$dot11PrivacyInvoked` if [ "${PRIV_GENSTR:-empty}" != "empty" ] ; then if [ ${PRIV_KEY128:-"false"} = "false" ]; then keys=`$PRIV_GENERATOR "$PRIV_GENSTR" 5` else keys=`$PRIV_GENERATOR "$PRIV_GENSTR" 13` fi knum=0 for i in $keys ; do result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKey$knum=$i` knum=`expr $knum + 1` done else result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKey0=$dot11WEPDefaultKey0 ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKey1=$dot11WEPDefaultKey1 ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKey2=$dot11WEPDefaultKey2 ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11WEPDefaultKey3=$dot11WEPDefaultKey3 ` fi else # disable wep explicitly. result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11PrivacyInvoked=$dot11PrivacyInvoked ` result=`$WLANCTL $1 dot11req_mibset \ mibattribute=dot11ExcludeUnencrypted=false ` fi } wlan_adhoc () { # $1 == wlandev #=======IBSS STARTUP================================== startcmd="$WLANCTL $1 dot11req_start " startcmd="$startcmd ssid=$DesiredSSID" startcmd="$startcmd bsstype=independent" startcmd="$startcmd beaconperiod=$BCNINT" startcmd="$startcmd dtimperiod=3" startcmd="$startcmd cfpollable=false" startcmd="$startcmd cfpollreq=false" startcmd="$startcmd cfpperiod=3" startcmd="$startcmd cfpmaxduration=100" startcmd="$startcmd probedelay=100" startcmd="$startcmd dschannel=$CHANNEL" j=1 for i in $BASICRATES ; do startcmd="$startcmd basicrate$j=$i" j=`expr $j + 1` done j=1 for i in $OPRATES ; do startcmd="$startcmd operationalrate$j=$i" j=`expr $j + 1` done results=`$startcmd` # Here's where it runs if [ $? = 0 ]; then eval $results if [ $resultcode != "success" ] ; then ${ECHO} "IBSS not started, resultcode=$resultcode" exit 1 else ${ECHO} "IBSS mode started." fi else ${ECHO} FAILED: $startcmd return 1 fi WLAN_SCHEMESSID="$DesiredSSID" } wlan_infra () { # $1 == wlandev #==== INFRASTRUCURE STARTUP=========================== # XXX TODO: Grok DesiredBSSID sleep 5 results=`$WLANCTL $1 lnxreq_autojoin \ "ssid=$DesiredSSID" \ authtype=${AuthType:="opensystem"} | sed 's/\([^=]*\)=\(.*\)/\1="\2"/'` eval $results if [ ${resultcode:-"failure"} != "success" ] ; then ${ECHO} 'error: Autojoin indicated failure!' return 1; fi WLAN_SCHEMESSID="$DesiredSSID" } wlan_dot11_join () { # $1 == wlandev joincmd="$WLANCTL $1 dot11req_join bssid=$DesiredBSSID" joincmd="$joincmd joinfailuretimeout=1" j=1 for i in $OPRATES ; do joincmd="$joincmd operationalrate$j=$i" j=`expr $j + 1` done results=`$joincmd` eval $results if [ ${resultcode:-"failure"} != "success" ] ; then ${ECHO} "$1: JOIN Failure" ${ECHO} "joincmd=$joincmd" ${ECHO} "results=$results" return 1; fi } wlan_dot11_auth_assoc () { # $1 == wlandev if [ $bsstype = "infrastructure" ] ; then results=`$WLANCTL $1 dot11req_authenticate \ peerstaaddress=$DesiredBSSID \ authenticationtype=$AuthType \ authenticationfailuretimeout=2000` eval $results if [ ${resultcode:-"failure"} != "success" ] ; then ${ECHO} "error: dot11req_authenticate failed, "\ "resultcode=$resultcode" return 1; fi results=`$WLANCTL $1 dot11req_associate \ listeninterval=1000 \ associatefailuretimeout=2000 ` if [ ${resultcode:-"failure"} != "success" ] ; then ${ECHO} 'error: dot11req_associate failed!' return 1; fi fi } wlan_set_ssid_schemefile () { # $1 == SSID # Find the scheme file if [ -r /var/lib/misc/pcmcia-scheme ] ; then # Debian WLAN_SCHEMEFILE="/var/lib/misc/pcmcia-scheme" elif [ -d /var/state/pcmcia ] ; then WLAN_SCHEMEFILE="/var/state/pcmcia/scheme" elif [ -d /var/lib/pcmcia ] ; then WLAN_SCHEMEFILE="/var/lib/pcmcia/scheme" else WLAN_SCHEMEFILE="/var/run/pcmcia-scheme" fi # Collect the current scheme name and save the file if [ -r $WLAN_SCHEMEFILE ] ; then WLAN_SCHEME=`cat $WLAN_SCHEMEFILE` cp $WLAN_SCHEMEFILE /tmp/wlan_scheme_`date +"%T"`.tmp else touch /tmp/wlan_scheme_`date +"%T"`.tmp fi # Set up the string if [ ! "$WLAN_SCHEME" ] ; then WLAN_SCHEME="default" fi WLAN_SCHEME="$WLAN_SCHEME:$1" # Write to schemefile echo $WLAN_SCHEME > $WLAN_SCHEMEFILE } wlan_restore_schemefile () { # Find the scheme file if [ -r /var/lib/misc/pcmcia-scheme ] ; then # Debian WLAN_SCHEMEFILE="/var/lib/misc/pcmcia-scheme" elif [ -d /var/state/pcmcia ] ; then WLAN_SCHEMEFILE="/var/state/pcmcia/scheme" elif [ -d /var/lib/pcmcia ] ; then WLAN_SCHEMEFILE="/var/lib/pcmcia/scheme" else WLAN_SCHEMEFILE="/var/run/pcmcia-scheme" fi TMPFILE=`ls /tmp/wlan_scheme*.tmp | tail -n 1` if [ -r $TMPFILE ] ; then cat $TMPFILE > $WLAN_SCHEMEFILE rm -f $TMPFILE else ${ECHO} "wlan_restore_schemefile: No wlan_scheme\*.tmp file found." fi } wlan_bring_it_up () { # $1 == wlandev # $2 == non-null if wext enabled. #=======ENABLE======================================== # Do we want to init the card at all? eval 'WLAN_ENABLE=$ENABLE_'$1 if ! is_true $WLAN_ENABLE ; then return 1 fi if wlan_enable $1 ; then if [ -z "$2" ] ; then wlan_scan_and_join $1 return $? else ${ECHO} "Bypassing configuration due to wireless extensions" fi else return 1; fi return 1 } wlan_scan_and_join () { #=======MAC STARTUP========================================= wlan_supports_scan $1 if [ $? = 0 ] ; then wlan_scan $1 if [ $? = 0 ] ; then wlan_source_config_for_ssid "$ssid" "$bssid" wlan_user_mibs $1 wlan_wep $1 wlan_join $1 else if is_true $IS_ADHOC ; then # start an IBSS; we didn't find one. wlan_adhoc $1 else return 1 fi fi else wlan_source_config $1 wlan_user_mibs $1 wlan_wep $1 if is_true $IS_ADHOC ; then wlan_adhoc $1 else wlan_infra $1 fi fi return $? } wlan_join () { # $1 == wlandev grep 'autojoin' /proc/net/p80211/$1/wlandev > /dev/null if [ $? = 0 ]; then wlan_infra $1 else wlan_dot11_join $1 wlan_dot11_auth_assoc $1 fi } start_wland () { $WLAND } stop_wland () { killall wland } tmpname () { # $1 == prefix local i=0 local tname=$TMPDIR/${1}_$$ if [ -f ${tname}.tmp ] ; then for i in 0 1 2 3 4 5 6 7 8 9 ; do if [ ! -f ${tname}_${i}.tmp ] ; then echo ${tname}_${i}.tmp return 0 fi done else echo ${tname}.tmp fi return 0 } source_procfile () { # $1 == procfile to source local fname=`tmpname wlan_procfile` cat "$1" > $fname . $fname rm -f $fname } # This is set by the Configure script as part of 'make install' #FIRMWARE_DIR="/usr/share/linux-wlan"