248 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
| #compdef iw
 | |
| 
 | |
| # Some parameters to hold patterns that will be used later.
 | |
| local xp='[[:xdigit:]][[:xdigit:]]'
 | |
| local -a bssid devices flags fouraddr fouronoff frequency high_throughput ifacename ifacetype ifacetypes
 | |
| local -a matchany matchnum key lladdr lladdrs meshid meshidval ssid value
 | |
| # matches any word
 | |
| matchany=(/$'[^\0]##\0'/)
 | |
| # matches any number
 | |
| matchnum=(/$'[[:digit:]]##\0'/)
 | |
| # matches any BSSID
 | |
| bssid=($matchany ':bssid:BSSID:')
 | |
| # matches any devices
 | |
| devices=( /$'[[:alpha:]]##[[:digit:]]##(\.[[:digit:]]##)#\0'/ ':interfaces:network_interface:_net_interfaces' )
 | |
| # matches the word 'flags' followed by a list of some of the following words: none fcsfail control otherbss cook
 | |
| flags=(/$'flags\0'/ ':flags:flags:(flags)' $matchany ':flags:flags:(none fcsfail control otherbss cook)' \#)
 | |
| # matches the word '4addr' followed by either 'on' or 'off'
 | |
| fouronoff=(/$'(on|off)\0'/ ':4addr:4addr:(on off)')
 | |
| fouraddr=( /$'4addr\0'/ ':4addr:4addr:(4addr)' $fouronoff )
 | |
| # matches any number (description is 'frequency')
 | |
| frequency=($matchnum ':freq:frequency:')
 | |
| # matches one of HT20 HT40+ or HT40-
 | |
| high_throughput=(/$'HT[0-9]##(+|-)#\0'/ ':HT:high throughput:(HT20 HT40+ HT40-)')
 | |
| # matches any name (description is 'name')
 | |
| ifacename=($matchany ':name:name:')
 | |
| # matches the word 'type' followed by one of: managed ibss monitor mesh wds
 | |
| ifacetypes=(/$'(managed|ibss|monitor|mesh|wds)\0'/ ':type:type:(managed ibss monitor mesh wds)')
 | |
| ifacetype=(/$'type\0'/ ':type:type:(type)' $ifacetypes)
 | |
| # matches any word (description is 'key')
 | |
| key=($matchany ':key:key:')
 | |
| # matches a MAC address (i.e. a sequence of six 2-digit numbers separated by spaces), $xp is defined earlier.
 | |
| lladdr=(/"${xp}:${xp}:${xp}:${xp}:${xp}:${xp}"$'\0'/ ':lladdress:link layer (MAC) address:')
 | |
| # as above but with a different description
 | |
| lladdrs=(/"${xp}:${xp}:${xp}:${xp}:${xp}:${xp}"$'\0'/ ':lladdress:link layer (MAC) addresses (use - to match any octet):' \#)
 | |
| # matches the word 'mesh_id' followed by a number
 | |
| meshidval=($matchnum ':meshid:mesh ID:')
 | |
| meshid=(/$'mesh_id\0'/ ':meshid:meshid:(mesh_id)' $meshidval)
 | |
| # matches any word (description 'SSID')
 | |
| ssid=($matchany ':ssid:SSID:')
 | |
| # matches any word (description 'value')
 | |
| value=($matchany ':val:value:')
 | |
| # matches any number (description 'value')
 | |
| numvalue=($matchnum ':val:value:')
 | |
| 
 | |
| # Use the _regex_words function to create a variable containing command words to go after "iw reg"
 | |
| local -a reg_cmds
 | |
| _regex_words regulatory-commands "reg command" \
 | |
|     'g*et:print out the kernels current regulatory domain information'\
 | |
|     's*et:notify the kernel about the current regulatory domain'
 | |
| reg_cmds=("$reply[@]")
 | |
| 
 | |
| # Options for to go after "iw event"
 | |
| local -a event_opts
 | |
| _regex_words event-options "event option" \
 | |
|     '-t:print timestamp' \
 | |
|     '-r:print relative timstamp' \
 | |
|     '-f:print full frame for auth/assoc etc'
 | |
| event_opts=("$reply[@]")
 | |
| 
 | |
| # Commands to go after "iw phy <DEV> wowlan enable"
 | |
| local -a phy_wowlan_enable_cmds
 | |
| _regex_words phy-wowlan-enable-commands "phy WoWLAN enable commands" \
 | |
|     '4*way-handshake:enable WoWLAN with 4way handshake trigger' \
 | |
|     'a*ny:enable WoWLAN with any trigger' \
 | |
|     'd*isconnect:enable WoWLAN with disconnect trigger' \
 | |
|     'e*ap-identity-request:enable WoWLAN with EAP identity request trigger' \
 | |
|     'g*tk-rekey-failure:enable WoWLAN with gtk rekey failure trigger' \
 | |
|     'm*agic-packet:enable WoWLAN with magic packet trigger' \
 | |
|     'p*atterns:MAC address triggers:$lladdrs' \
 | |
|     'r*fkill-release:enable WoWLAN with rfkill release trigger'
 | |
| phy_wowlan_enable_cmds=("$reply[@]")
 | |
| 
 | |
| # Commands to go after "iw phy <DEV> wowlan"
 | |
| local -a phy_wowlan_cmds
 | |
| _regex_words phy-wowlan-commands "phy WoWLAN commands" \
 | |
|     's*how:show WoWLAN status' \
 | |
|     'd*isable:disable WoWLAN' \
 | |
|     'e*nable:enable WoWLAN:$phy_wowlan_enable_cmds'
 | |
| phy_wowlan_cmds=("$reply[@]")
 | |
| 
 | |
| # Some parameters to hold patterns that will be used for "iw phy set" commands
 | |
| # (not perfect, but mostly OK).
 | |
| local -a phy_set_antenna phy_set_channel phy_set_coverage phy_set_frag phy_set_freq phy_set_distance
 | |
| local -a phy_set_name phy_set_netns phy_set_rts phy_set_txpower phy_txpower_opt 
 | |
| phy_set_antenna=($matchany ':antenna:bitmap:')
 | |
| phy_set_channel=($matchnum ':channel:channel (1-14):' $high_throughput)
 | |
| phy_set_coverage=($matchnum ':coverage:coverage class (0-255):')
 | |
| phy_set_distance=($matchnum ':distance:valid values\: 0 - 114750:')
 | |
| phy_set_frag=(/$'([0-9]##|off)\0'/ ':channel:channel (1-14):(1 2 3 4 5 6 7 8 9 10 11 12 13 14 off)')
 | |
| phy_set_freq=($frequency $high_throughput)
 | |
| phy_set_name=($matchany ':name:device name:')
 | |
| phy_set_netns=($matchany ':netns:network namespace:')
 | |
| phy_set_rts=($matchnum ':rts:rts threshold:')
 | |
| phy_txpower_opt=($matchany ':txpower:tx power in mBm:')
 | |
| _regex_words phy-set-txpower "set txpower" \
 | |
|     'a*uto:auto:' \
 | |
|     'f*ixed:fixed:$phy_txpower_opt' \
 | |
|     'l*imit:limit:$phy_txpower_opt'
 | |
| phy_set_txpower=("$reply[@]")
 | |
| 
 | |
| # Commands to go after "iw phy <DEV> set"
 | |
| local -a phy_set_cmds
 | |
| _regex_words phy-set-commands "phy set commands" \
 | |
|     'a*ntenna:set a bitmap of allowed antennas to use for TX and RX:$phy_set_antenna' \
 | |
|     'ch*annel:set channel:$phy_set_channel' \
 | |
|     'co*verage:set coverage class (1 for every 3 usec of air propagation time):$phy_set_coverage' \
 | |
|     'd*istance:set appropriate coverage class for given link distance in meters:$phy_set_distance' \
 | |
|     'fra*g:set fragmentation threshold:$phy_set_frag' \
 | |
|     'fre*q:set frequency/channel the hardware is using, including HT configuration:$phy_set_freq' \
 | |
|     'na*me:rename this wireless device:$phy_set_name' \
 | |
|     'ne*tns:set network namespace:$phy_set_netns' \
 | |
|     'r*ts:set rts threshold:$phy_set_rts' \
 | |
|     't*xpower:specify transmit power level and setting type:$phy_set_txpower'
 | |
| phy_set_cmds=("$reply[@]")
 | |
| 
 | |
| # Commands to go after "iw phy <DEV> interface" 
 | |
| local -a phy_interface_cmds 
 | |
| # This needs work (should not offer meshid, fouraddr of flags more than once, and need to accomodate multiple flag options)
 | |
| phy_interface_cmds=(\( /$'add\0'/ ':add:add a new virtual interface with the given configuration:(add)' $ifacename $ifacetype \
 | |
|     \( $meshid \| $fouraddr \| $flags \) \# \))
 | |
| 
 | |
| # Commands to go after "iw phy <DEV>"
 | |
| local -a phy_cmds
 | |
| _regex_words phy-commands "phy command" \
 | |
|     's*et:set/configure interface properties:$phy_set_cmds' \
 | |
|     'inf*o:show capabilities for the specified wireless device' \
 | |
|     'int*erface:add a new virtual interface with the given configuration:$phy_interface_cmds' \
 | |
|     'w*owlan:WoWLAN commands:$phy_wowlan_cmds'
 | |
| phy_cmds=("$reply[@]")
 | |
| 
 | |
| # Parameters to hold patterns for dev commands
 | |
| local -a dev_cmds_connect dev_cmds_cqm dev_cmds_get dev_cmds_ibss dev_cmds_interface dev_cmds_mesh dev_cmds_scan_options
 | |
| local -a dev_cmds_mpath dev_cmds_offchannel dev_cmds_roc dev_cmds_scan dev_cmds_set dev_cmds_station dev_cmds_survey
 | |
| dev_cmds_connect=($ssid $frequency $bssid $key)
 | |
| dev_cmds_cqm=(/$'rssi\0'/ ':rssi:rssi:(rssi)' $matchnum ':thresh:threshold:' $matchnum ':hysteresis:hysteresis:')
 | |
| dev_cmds_get=(/$'(mesh_param|power_save)\0'/ ':get:parameter:(mesh_param power_save)' $value)
 | |
| # TODO: THIS NEEDS WORK! THE FINAL OPTIONS FOR JOIN NEED WORK
 | |
| # 	dev <devname> ibss join <SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] [beacon-interval <TU>] [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] [key d:0:abcde]
 | |
| dev_cmds_ibss=(\( /$'leave\0'/ ':cmd:command:((leave:"Leave the IBSS cell"))' \| \( /$'join\0'/ ':cmd:command:((join\:"Join an IBSS cell"))' $ssid $frequency \( /$'fixed-freq\0'/ ':opt:option:((fixed-freq\:"fixed frequency (no args)"))' \| $bssid \| /$'beacon-interval\0'/ ':opt:option:((beacon-interval\:"beacon interval (takes single arg)"))' $numvalue \| /$'basic-rates\0'/ ':opt:option:((basic-rates\:"basic rates (comma separated list of rates)"))' $numvalue \| /$'mcast-rate\0'/ ':opt:option:((mcast-rate\:"multicast rate (takes single arg)"))' $numvalue \| $key \) \# \) \))
 | |
| dev_cmds_interface=(/$'add\0'/ ':add:add:(add)' $ifacename $ifacetype \( $meshid \| $fouraddr \| $flags \) \# )
 | |
| dev_cmds_mesh=(\( /$'leave\0'/ ':leave:leave a mesh:(leave)' \| /$'join\0'/ ':join:join a mesh:(join)' \
 | |
|     $matchnum ':meshid:mesh ID:' $matchany ':parameter:mesh parameters [<param>=<value>]*:' \# \))
 | |
| dev_cmds_mpath=(\( /$'(del|get)\0'/ ':mpath:mesh path command:((del\:"remove the mesh path to the given node" \
 | |
| get\:"get information on mesh path to the given node"))' $lladdr \| /$'(new|set)\0'/ ':mpath:mesh path \
 | |
| command:((new\:"create a new mesh path (instead of relying on automatic discovery)" set\:"set an existing mesh \
 | |
| paths next hop"))' $lladdr /$'next_hop\0'/ ':nexthop:next hop:(next_hop)' $lladdr \| /$'dump\0'/ ':mpath:mesh path \
 | |
| command:((dump\:"list known mesh paths"))' \))
 | |
| dev_cmds_offchannel=($frequency $matchnum ':duration:duration:')
 | |
| dev_cmds_roc=(/$'start\0'/ ':start:start:(start)' $frequency $matchnum ':time:time:')
 | |
| dev_cmds_scan_options=(/$'freq\0'/ ':freq:freq:(freq)' $frequency $frequency \# /$'ies\0'/ ':ies:ies:(ies)' $lladdr \( /$'ssid\0'/ ':ssid:ssid:(ssid)' $ssid \# \| /$'passive\0'/ ':opt:passive:(passive)' \))
 | |
| dev_cmds_scan=(\( $dev_cmds_scan_options \| $matchany -'! [[ $match[1] =~ "dump|trigger" ]]' ':opt:option:((-u\:"include unknown data in results"  \:""))' $dev_cmds_scan_options \| /$'dump\0'/ ':cmd:command:((dump\:"dump the current scan results"))' $matchany ':opt:option:((-u\:"include unknown data in results"  \:""))' \| /$'trigger\0'/ ':cmd:command:((trigger\:"trigger a scan on the given frequencies with probing for the given SSIDs (or wildcard if not given) unless passive scanning is requested"))' $dev_cmds_scan_options \))
 | |
| local -a dev_cmds_set_bitrates dev_cmds_set_freq dev_cmds_set_mesh_param
 | |
| local -a dev_cmds_set_monitor dev_cmds_set_peer dev_cmds_set_power_save 
 | |
| local -a dev_cmds_set_type dev_cmds_set_txpower
 | |
| # 	dev <devname> set bitrates [legacy-<2.4|5> <legacy rate in Mbps>*]
 | |
| dev_cmds_set_bitrates=(/$'legacy-*\0'/ ':opt:legacy:(legacy-2.4 legacy-2.5)' $matchnum ':rate:legacy rate in Mbps:')
 | |
| # 	dev <devname> set freq <freq> [HT20|HT40+|HT40-]
 | |
| dev_cmds_set_freq=($frequency $high_throughput)
 | |
| # 	dev <devname> set mesh_param <param>=<value> [<param>=<value>]*
 | |
| dev_cmds_set_mesh_param=( $matchany ':val:param=value:' \# )
 | |
| # 	dev <devname> set monitor <flag>*
 | |
| dev_cmds_set_monitor=( $matchany ':flag:flag:((none\:"no special flags" fcsfail\:"show frames with FCS errors"\
 | |
|    control\:"show control frames" otherbss\:"show frames from other BSSes" cook\:"use cooked mode"))' \# )
 | |
| # 	dev <devname> set peer <MAC address>
 | |
| dev_cmds_set_peer=($lladdr)
 | |
| # 	dev <devname> set power_save <on|off>
 | |
| dev_cmds_set_power_save=(/$'(on|off)\0'/ ':opt:power save mode:(on off)')
 | |
| 
 | |
| _regex_words setcmds "dev set commands" \
 | |
|     '4*addr:set interface 4addr (WDS) mode:$fouronoff'\
 | |
|     'b*itrates:set/clear specified rate masks:$dev_cmds_set_bitrates'\
 | |
|     'c*hannel:set channel:$phy_set_channel'\
 | |
|     'f*req:set frequency:$dev_cmds_set_freq'\
 | |
|     'mesh_param:set mesh parameters:$dev_cmds_set_mesh_param'\
 | |
|     'meshid:set mesh id:$meshidval'\
 | |
|     'mo*nitor:set monitor flags:$dev_cmds_set_monitor'\
 | |
|     'pe*er:set interface WDS peer MAC address:$dev_cmds_set_peer'\
 | |
|     'po*wer_save:set power save on/off:$dev_cmds_set_power_save'\
 | |
|     'tx*power:set transmission power:$phy_set_txpower'\
 | |
|     'ty*pe:set type:$ifacetypes'
 | |
| dev_cmds_set=("$reply[@]")
 | |
| 
 | |
| local -a dev_cmds_station_plink dev_cmds_station_vlan
 | |
| dev_cmds_station_plink=(/$'(open|block)\0'/ ':opt::(open block)')
 | |
| dev_cmds_station_vlan=($matchnum ':val:ifindex:')
 | |
| 
 | |
| local -a dev_cmds_station_set
 | |
| _regex_words stationsetcmds "dev station set commands"\
 | |
|     'plink_action:set peer link action:$dev_cmds_station_plink'\
 | |
|     'vlan:set AP VLAN:$dev_cmds_station_vlan'
 | |
| dev_cmds_station_set=(\( $lladdr \) "$reply[@]")
 | |
| 
 | |
| _regex_words stationcmds "dev station commands" \
 | |
|     'del:remove the given station entry (use with caution!):$lladdr'\
 | |
|     'dump:list all stations known, e.g. the AP on managed interfaces:'\
 | |
|     'get:get information for a specific station:$lladdr'\
 | |
|     'set:set AP VLAN or mesh peer link action:$dev_cmds_station_set'
 | |
| dev_cmds_station=("$reply[@]")
 | |
| 
 | |
| dev_cmds_survey=(/$'dump\0'/ ':dump:list all gathered channel survey data:(dump)')
 | |
| 
 | |
| local -a dev_cmds
 | |
| _regex_words dev-commands "dev commands" \
 | |
|     'co*nnect:join a network:$dev_cmds_connect' \
 | |
|     'cq*m:set connection quality monitor RSSI threshold:$dev_cmds_cqm' \
 | |
|     'de*l:remove this virtual interface' \
 | |
|     'di*sconnect:disconnect from the current network' \
 | |
|     'g*et:retrieve mesh parameter / power save state:$dev_cmds_get' \
 | |
|     'ib*ss:join/leave IBSS cell:$dev_cmds_ibss' \
 | |
|     'inf*o:show information for this interface' \
 | |
|     'int*erface:add an interface:$dev_cmds_interface' \
 | |
|     'l*ink:print information about the current link, if any' \
 | |
|     'me*sh:join/leave a mesh:$dev_cmds_mesh' \
 | |
|     'mp*ath:mesh path commands:$dev_cmds_mpath' \
 | |
|     'o*ffchannel:leave operating channel and go to the given channel for a while:$dev_cmds_offchannel' \
 | |
|     'r*oc:roc:$dev_cmds_roc' \
 | |
|     'sc*an:scan:$dev_cmds_scan' \
 | |
|     'se*t:set interface parameter:$dev_cmds_set' \
 | |
|     'st*ation:station commands:$dev_cmds_station' \
 | |
|     'su*rvey:list all gathered channel survey data:$dev_cmds_survey' 
 | |
| dev_cmds=( $devices "$reply[@]")
 | |
| 
 | |
| # Arguments to _regex_arguments, built up in array $args.
 | |
| local -a args reply
 | |
| # Command word.  Don't care what that is.
 | |
| args=( $matchany )
 | |
| 
 | |
| local -a phydevs
 | |
| phy_devs=( \( $(iw list|grep '^[[:alnum:]]\+'|cut -f 2 -d ' ') \) )
 | |
| phy_cmds=( \( $matchany ":test:test:$phy_devs[*]" \) "$phy_cmds[@]" )
 | |
| 
 | |
| _regex_words commands "iw command" \
 | |
|   'd*ev:commands to control/list the software devices:$dev_cmds' \
 | |
|   'e*vent:monitor events from the kernel:$event_opts' \
 | |
|   'h*elp:print usage for each command' \
 | |
|   'l*ist:list all wireless devices and their capabilities' \
 | |
|   'p*hy:commands to control the physical device:$phy_cmds' \
 | |
|   'r*eg:get/set regulatory domain:$reg_cmds'
 | |
| args+=("$reply[@]")
 | |
| 
 | |
| _regex_arguments _iw "${args[@]}"
 | |
| 
 | |
| _iw "$@"
 | |
| 
 | |
| # Local Variables: 
 | |
| # mode:shell-script
 | |
| # End:             
 |