summary refs log tree commit diff
path: root/Completion/Unix/Command/_route
blob: 06cca8d99f9f40b10841909821f2649dd407e143 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#compdef route

local curcontext="$curcontext" expect ret=1
local -a state state_descr line args families modifiers ignore sub sequential tags
local -A opt_args subcmds once params

subcmds=(
  add     'add a route'
  flush   'remove all routes'
  delete  'delete a specific route'
  change  'change aspects of a route (such as its gateway)'
  get     'lookup route for a destination'
  monitor 'continuously report any changes to the routing information'
)
args=(
  '-n[output addresses numerically]'
  '(-q)-v[verbose output]'
)
modifiers=(
  '-net:interpret destination as a network'
  '-host:interpret destination as a host'
)
params=(
  '-dst'          target  # does this definitely follow
  '(-|)netmask'   netmask
  '(gw|-gateway)' gateway
  metric          metric
  '(mss|window|-(send|recv)pipe)' size:bytes
  '[i-]rtt'       time:ms
  -rttvar         rttvar
  -mtu            mtu
  '(dev|-ifscope|-ifp)'  interface
  -ifa            address
  -expire         time:epoch
  -hopcount       hopcount
  -tag            tag
  -prefixlen      bits
  '-(label|push|pop|swap)' label
  -priority       number  # is it a number
  -secattr        secattr
  '(-iw|-iwmax|-msl)' value
  '-fib'          table
)

case $OSTYPE in
  ^linux*)
    args+=( '(-v)-q[suppress all output]' )
    families=( -inet -inet6 )
    modifiers+=(
      '-dst:distinguish a destination'
      '-gateway:distinguish a gateway address'
      -netmask
      -rtt -rttvar
      -sendpipe -recvpipe
      -mtu -hopcount
      -expire
      '-lock' '-lockrest'
      -i{,nter}face:'indicate destination is directly reachable'
      '-static:manually added route'
      '-nostatic:pretend route added by kernel or daemon'
      '-reject:emit an ICMP unreachable when matched'
      '-blackhole:silently discard packets (during updates)'
      '-proto1:set protocol specific routing flag #1'
      '-proto2:set protocol specific routing flag #2'
    )
    sequential=( target gateway netmask )
  ;|
  *bsd*|darwin*|dragonfly*)
    modifiers+=(
      -link '-ifp' '-ifa' # do these need an argument: interface or address
      '-prefixlen:indicate mask bits'
    )
  ;|
  (net|free)bsd*|darwin*|dragonfly*)
    families+=( -xns )
    modifiers+=( '-xresolve:emit mesg on use (for external lookup)' )
  ;|
  (net|open)bsd*|darwin*|dragonfly*)
    modifiers+=(
      '-cloning:generate a new route on use'
      '-llinfo:validly translate proto addr to link addr'
    )
  ;|
  (net|open|free)bsd*|darwin*|dragonfly*)
    args+=(
      "-d[debug-only mode: don't update routing table]"
      '-t[test-only mode: /dev/null used instead of a socket]'
    )
  ;|
  netbsd*|solaris*)
    args+=( '-f[remove all routes first]' )
  ;|
  (netbsd|darwin|dragonfly)*)
    modifiers+=( '-proxy:make entry a link level proxy' )
  ;|
  (netbsd|openbsd|dragonfly)*)
    subcmds+=( show 'print out the routing table' )
    families+=( -mpls )
  ;|
  (netbsd|darwin)*)
    families+=( -atalk )
  ;|
  (freebsd|darwin)*)
    families+=( -osi )
  ;|
  (openbsd|dragonfly)*)
    modifiers+=( -push -pop -swap )
  ;|
  freebsd*)
    subcmds+=(
      del $subcmds[delete]
      show $subcmds[get]
    )
    args+=(
      '(-6)-4[specify IPv4 address family]'
      '(-4)-6[specify IPv6 address family]'
    )
    families+=( -4 -6 )
    modifiers+=( '-fib:specify a routing table' )
  ;;
  netbsd*)
    subcmds+=( flushall 'remove all routes including the default gateway' )
    args+=(
      "-L[don't show link layer entries in routing table]"
      '-S[print a space when a flag is missing to align flags]'
      '-s[suppress all output from get except for the gateway]'
      '-T[show tags in the route display]'
    )
    modifiers+=(
      '-tag'
      '-noreject:clear reject flag'
      '-noblackhole:clear blackhole flag'
    )
  ;;
  openbsd*)
    subcmds+=( exec 'execute a command with alternate routing table' )
    args+=(
      '-T+[select specified alternate routing table]:table id'
    )
    modifiers+=(
      -sa
      '-label'
      '-priority'
      '-mpath:multiple gateways for a destination exist'
      -mplslabel -in -out
    )
  ;;
  solaris*)
    subcmds+=( show 'display list of routes applied at system startup' )
    args+=(
      '-p[make changes to the route tables persistent across system restarts]'
      '-R+[specify alternate root directory where changes are applied]:directory:_directories'
    )
    modifiers+=(
      "-private:don't advertise this route"
      '-multirt:create the specified redundant route'
      '-setsrc:assign the default source address'
      '-secattr:security attributes'
    )
  ;;
  darwin*)
    modifiers+=( -ifscope )
  ;|
  dragonfly*)
    modifiers+=( -iw -iwmax -msl )
  ;|
  linux*)
    args+=(
      '(H -n)--numeric[output addresses numerically]'
      '(H)*'{-e,--extend}'[display other/more information]'
      '!(H -C --cache)'{-F,--fib}
      '(H -C --cache)'{-C,--cache}'[display routing cache instead of FIB]'
      + '(family)'
      '-A+[use specified address family]:address family:(inet inet6 ax25 netrom ipx ddp x25)'
      -4 -6 --inet --inet6 --ax25 --netrom --ipx --ddp --x25
      + '(H)'
      '(1 *)'{-h,--help}'[display help information]'
      '(1 *)'{-V,--version}'[display version information]'
    )
    subcmds[del]=$subcmds[delete]
    unset 'subcmds[monitor]' 'subcmds[get]' 'subcmds[change]'
    modifiers+=(
      netmask gw metric mss window irtt reject mod dyn reinstate
      'dev:force route to be associated with the specified device'
    )
    sequential=( target interface )
  ;;
esac

print -v sub -f '%s\\:%s' ${(kvq)subcmds}
_arguments -C -s -S "1:command:(($sub))" '*::args:->args' $args && ret=0

[[ -n $opt_args[(i)-[46]] ]] && families=()

if [[ -n $state ]]; then
  if [[ $line[1] = exec ]]; then
    shift words
    (( CURRENT-- ))
    _normal
  elif [[ $line[1] = (flush|monitor) ]]; then
    sequential=()
  fi

  for ((i=2;i<CURRENT;i++)); do
    if [[ -n $expect ]]; then
      sequential=( ${sequential:#$expect} )
      expect=''
      continue
    fi

    expect=${params[(K)$words[i]]}
    if [[ -n $expect ]]; then
      ignore+=( ${(Q)words[i]} )
    else
      if [[ -n ${(M)${families%%:*}:#${(q)words[i]}} ]]; then
        families=()
      elif [[ -n ${(M)${modifiers%%:*}:#${(q)words[i]}} ]]; then
	ignore+=( ${(q)words[i]} )
      elif [[ $words[1] != -lock ]]; then
	shift sequential
      fi
    fi
  done

  [[ -z $expect ]] && tags=( modifiers families )
  _tags values $tags
  while _tags; do
    if _requested values; then
      case ${expect:-$sequential[1]} in
	target)
	  if [[ -z $expect ]]; then
	    _wanted -x targets expl target compadd default && ret=0
	  else
	    _message -e targets target
	  fi
	;;
	interface) _net_interfaces && ret=0 ;;
	size:bytes) _guard "[0-9]#" 'size (bytes)' ;; # _guard usage pointless
	time:ms) _guard "[0-9]#" 'time (ms)' ;;
	time:microseconds) _guard "[0-9]#" 'time (microseconds)' ;;
	time:epoch) _guard "[0-9]#" 'expiration time (seconds since epoch)' ;;
	rttvar) _guard "[0-9]#" 'time variance (microseconds)' ;;
	mtu) _guard "[0-9]#" 'max MTU (bytes)' ;;
	hopcount) _guard "[0-9]#" 'hop count' ;;
	ssthresh) _message -e threshold 'ss threshold' ;;
	bits) _guard "[0-9]#" 'bits' ;;
	*) _guard "[^-]#" "${expect:-$sequential[1]}" ;;
      esac
    fi
    _requested modifiers && _describe -t modifiers modifier modifiers -F ignore && ret=0
    _requested families expl 'address family' compadd -a families && ret=0
    (( ret )) || break
  done
fi

return ret