about summary refs log tree commit diff
path: root/Completion/Unix/Command/_tcpdump
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2017-08-16 23:47:55 +0200
committerOliver Kiddle <opk@zsh.org>2017-08-16 23:47:55 +0200
commitb1a1a342504f8013907244c3a2728571e7839543 (patch)
treea79623410f1702ad218b7a6eda3d3ba414393948 /Completion/Unix/Command/_tcpdump
parentf80fe2dfe9dffc512fe76931879087a3ed6d6fa8 (diff)
downloadzsh-b1a1a342504f8013907244c3a2728571e7839543.tar.gz
zsh-b1a1a342504f8013907244c3a2728571e7839543.tar.xz
zsh-b1a1a342504f8013907244c3a2728571e7839543.zip
41556: complete BPF (libpcap) filters
Diffstat (limited to 'Completion/Unix/Command/_tcpdump')
-rw-r--r--Completion/Unix/Command/_tcpdump177
1 files changed, 104 insertions, 73 deletions
diff --git a/Completion/Unix/Command/_tcpdump b/Completion/Unix/Command/_tcpdump
index 2c1d82226..4b9950fa5 100644
--- a/Completion/Unix/Command/_tcpdump
+++ b/Completion/Unix/Command/_tcpdump
@@ -1,17 +1,25 @@
 #compdef tcpdump
 
-typeset -A opt_args
+local args ret=1
+local root
+(( EUID )) && root='!'
 
-_interfaces() {
-  local disp expl sep
-  _description interfaces expl 'network interface'
-  _net_interfaces "$expl[@]"
-  if zstyle -t ":completion:${curcontext}:interfaces" verbose; then
-    zstyle -s ":completion:${curcontext}:interfaces" list-separator sep || sep=--
-    disp=( "any $sep capture on all interfaces" )
-    compadd "$expl[@]" -ld disp any
+_tcpdump_interfaces() {
+  local disp expl sep interfaces
+  [[ $OSTYPE != openbsd* ]] &&
+      interfaces=( ${${${${(f)"$(_call_program interfaces tcpdump -D)"}#<->.}//[()]/}/ /:} )
+  if (( $#interfaces )); then
+    _describe -t interfaces 'network interface' interfaces
   else
-    compadd "$expl[@]" any
+    _description interfaces expl 'network interface'
+    _net_interfaces "$expl[@]"
+    if zstyle -t ":completion:${curcontext}:interfaces" verbose; then
+      zstyle -s ":completion:${curcontext}:interfaces" list-separator sep || sep=--
+      disp=( "any $sep capture on all interfaces" )
+      compadd "$expl[@]" -ld disp any
+    else
+      compadd "$expl[@]" any
+    fi
   fi
 }
 
@@ -40,43 +48,50 @@ _esp_secrets () {
 }
 
 _packet_types () {
+  local -a types
   types=(
-    'cnfp[Cisco NetFlow protocol]'
-    'rpc[Remote Procedure Call]'
-    'rtp[Real-Time Applications protocol]'
-    'rtcp[Real-Time Applications control protocol]'
-    'vat[Visual Audio Tool]'
-    'wb[distributed White Board]'
+    'cnfp:Cisco NetFlow protocol'
+    'rpc:Remote Procedure Call'
+    'rtp:Real-Time Applications protocol'
+    'rtcp:Real-Time Applications control protocol'
+    'vat:Visual Audio Tool'
+    'wb:distributed White Board'
   )
   if [[ $OSTYPE = openbsd* ]]; then
     types+=(
-      'sack[RFC 2018 TCP Selective Acknowledgements Options]'
-      'vrrp[Virtual Router Redundancy Protocol]'
-      'tcp[Transmission Control Protocol]'
+      'sack:RFC 2018 TCP Selective Acknowledgements Options'
+      'vrrp:Virtual Router Redundancy Protocol'
+      'tcp:Transmission Control Protocol'
     )
   else
     types+=(
-      'aodv[Ad-hoc On-demand Distance Vector protocol]'
-      'carp[Common Address Redundancy Protocol]'
-      'radius[RADIUS]'
-      'snmp[Simple Network Management Protocol]'
-      'tftp[Trivial File Transfer Protocol]'
-      'vxlan[Virtual eXtensible Local Area Network]'
-      'zmtpl[ZeroMQ Message Transport Protocol]'
+      'aodv:Ad-hoc On-demand Distance Vector protocol'
+      'carp:Common Address Redundancy Protocol'
+      'radius:RADIUS'
+      'snmp:Simple Network Management Protocol'
+      'tftp:Trivial File Transfer Protocol'
+      'vxlan:Virtual eXtensible Local Area Network'
+      'zmtpl:ZeroMQ Message Transport Protocol'
     )
   fi
-  _values 'Packets type' $types
+  _describe -t packet-types 'packet type' types
+}
+
+_time_stamp_types () {
+  local vals
+  vals=( ${${${(ps:\n  :)"$(_call_program time-stamp-types tcpdump -J ${(kv)opt_args[(i)-i|--interface]} 2>&1)"}[2,-1]:#*cannot be set*}/ /:} )
+  _describe -t time-stamp-types "time stamp type" vals
 }
 
 _data_link_types () {
-	if (( $+opt_args[-i] )); then
-		vals=( ${${${(s:  :)"$(_call_program data-link-types tcpdump -L -i $opt_args[-i] 2>&1)"}[2,-1]}/ /:} )
-		_describe -t data-link-types "data link types ($opt_args[-i])" vals && ret=0
-	else
-		_values "Data link types (general)" \
-			"EN10MB" \
-			"LINUX_SLL"
-	fi
+  local vals expl
+  if (( $+opt_args[(i)-i|--interface] )); then
+    vals=( ${${${(s:  :)"$(_call_program data-link-types tcpdump -L ${(kv)opt_args[(i)-i|--interface]} 2>&1)"}[2,-1]}/ /:} )
+    _describe -t data-link-types "data link type (${(v)opt_args[(i)-i|--interface]})" vals
+  else
+    _wanted data-link-types expl "data link type (general)" \
+        compadd EN10MB LINUX_SLL
+  fi
 }
 
 _bpf_filter () {
@@ -84,79 +99,95 @@ _bpf_filter () {
 
 args=(
   '-A[print each packet in ASCII]'
-  '-c[exit after receiving specified number of packets]:number of packets'
+  '-c+[exit after receiving specified number of packets]:number of packets'
   '(-ddd)-d[dump the compiled packet-matching code in a human readable form]'
   '(-ddd)-dd[dump packet-matching code as a C program fragment]'
   '(-d -dd)-ddd[dump packet-matching code as decimal numbers (preceded with a count)]'
   "-E[decrypting IPsec ESP packets]:spi@ipaddr::algo\:secret:_esp_secrets"
   '-e[print the link-level header on each dump line]'
-  '-F[input file for the filter expression]:filter expression file:_files'
+  '-F+[specify input file for the filter expression]:filter expression file:_files'
   "-f[print 'foreign' IPv4 addresses numerically]"
   '-l[make stdout line buffered]'
   "-N[don't print domain name qualification of host names]"
-  "-n[don't convert addresses to names]"
+  "(-nn)-n[don't convert addresses to names]"
   "-O[don't run the packet-matching code optimizer]"
-  "-p[don't put the interface into promiscuous mode]"
+  '(-p --no-promiscuous-mode)'{-p,--no-promiscuous-mode}"[don't put the interface into promiscuous mode]"
   '-q[quick (quiet?) output]'
-  '-r[read packets from file]:input file:_files'
-  '-S[print absolute TCP sequence numbers]'
-  '-s[specify number of bytes of data to snarf from each packet]:number of bytes to snap'
-  '-T[interpret captured packets as specified type]:packet type:_packet_types'
+  '-r+[read packets from file]:input file:_files'
+  '(-S --absolute-tcp-sequence-numbers)'{-S,--absolute-tcp-sequence-numbers}'[print absolute TCP sequence numbers]'
+  '-T+[interpret captured packets as specified type]:packet type:_packet_types'
   "(-tt -ttt -tttt -ttttt)-t[don't print a timestamp on each dump line]"
   '(-t -ttt -tttt -ttttt)-tt[print an unformatted timestamp on each dump line]'
   '(-vv -vvv)-v[slightly more verbose output]'
   '(-v -vvv)-vv[more verbose output]'
-  '-w[write the raw packets to file]:output file:_files'
+  '-w+[write the raw packets to file]:output file:_files'
   '-X[print each packet (minus its link level header) in hex and ASCII]'
   '-x[print each packet (minus its link level header) in hex]'
-  '-y[set the data link type to use while capturing packets]:data link type:_data_link_types'
-  '*:BPF filter:_bpf_filter'
+  '(-y --linktype)'{-y+,--linktype=}'[set the data link type to use while capturing packets]: :_data_link_types'
 )
 
 if [[ $OSTYPE = openbsd* ]]; then
-  args+=(
+  args=(
+    '-i+[specify interface]:interface:_tcpdump_interfaces'
+    - listd
+    '-L[list data link types for the interface]'
+    - capture
+    ${(R)args:#(|\*)(|\(*\))--*} # removes any long-options
     '(-n)-a[attempt to convert network and broadcast addresses to names]'
     '-D[select packet flowing in specified direction]:direction:(in out)'
     '-I[print the interface on each dump line]'
     '-o[print a guess of the possible operating system(s)]'
+    '-s+[specify amount of data to snarf from each packet]:length (bytes) [116]'
     '(-t -tt -tttt -ttttt)-ttt[print day and month in timestamp]'
     '(-t -tt -ttt -ttttt)-tttt[print timestamp difference between packets]'
     '(-t -tt -ttt -tttt)-ttttt[print timestamp difference since the first packet]'
   )
 else
-  args+=(
-    '-B[specify the capture buffer size in KiB]:capture buffer size'
+  args=(
+    '(-i --interface -D --list-interfaces)'{-i+,--interface=}'[specify interface]:interface:_tcpdump_interfaces'
+    - listt
+    '(-J --list-time-stamp-types)'{-J,--list-time-stamp-types}'[list supported time stamp types]'
+    - listd
+    '(-L --list-data-link-types)'{-L,--list-data-link-types}'[list data link types for the interface]'
+    - capture
+    $args
+    '(-B --buffer-size)'{-B+,--buffer-size=}'[set the operating system capture buffer size]:size (kiB)'
     '-b[print the AS number in BGP packets in ASDOT notation]'
-    '-C[specify output file size in MB (10e6 bytes)]:output file size'
-    '(-* *)'-D'[print the list of the network interfaces available on the system]'
-    '-G[specify the interval to rotate the dump file in seconds]:dump file rotate seconds'
+    '-C+[specify output file size]:output file size (MB)'
+    '(-)'{-D,--list-interfaces}'[print the list of the network interfaces available on the system]'
+    '-G+[rotate dump file specified with -w at specified interval]:interval (seconds)'
     '-H[attempt to detect 802.11s draft mesh headers]'
-    '(-* *)-h[print version strings and a usage message]'
+    '(- *)'{-h,--help}'[display help information]'
+    '(- *)--version[display version information]'
+    '(-I --monitor-mode)'{-I,--monitor-mode}'[put the Wi-Fi interface in monitor mode]'
+    '--immediate-mode[deliver packets to tcpdump as soon as they arrive without buffering]'
     '-I[put the interface in monitor mode]'
-    '(-* *)-J[list the supported timestamp types]'
-    '-j[set the timestamp type]:timestamp type'
-    "-K[don't attempt to verify checksums]"
-    '*-m[load SMI MIB module definitions]:SMI MIB module definitions:_files'
-    '-M[shared secret for validating the digests in TCP segments with the TCP-MD5 option]:secret'
-    '-R[assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829)]'
-    '(-t -tt -tttt)-ttt[print a delta (in micro-seconds) between current and previous line on each dump line]'
-    '(-t -tt -ttt)-tttt[print a timestamp in default format proceeded by date on each dump line]'
-    '(-t -tt -ttt -tttt)-ttttt[print a delta (micro-second resolution) since the first line on each dump line]'
-    '-U[make output packet-buffered when saving to file (-w)]'
+    '(-j --time-stamp-type)'{-j+,--time-stamp-type=}'[set the time stamp type for the capture]: :_time_stamp_types'
+    '--time-stamp-precision=[set the time stamp precision for the capture]:precision [micro]:(micro nano)'
+    '(-K --dont-verify-checksums)'{-K,--dont-verify-checksums}"[don't verify IP, TCP, or UDP checksums]"
+    '*-m+[load SMI MIB module definitions]:SMI MIB module definition:_files'
+    "(-n)-nn[don't convert protocol and port numbers to names]"
+    '-M+[specify shared secret for validating the digests in TCP segments with the TCP-MD5 option]:secret'
+    '(-# --number)'{-\#,--number}'[print an optional packet number at the beginning of the line]'
+    '(-O --no-optimize)'{-O,--no-optimize}"[don't run the packet-matching code optimizer]"
+    '(-s --snapshot-length)'{-s+,--snapshot-length=}'[specify amount of data to snarf from each packet]:length (bytes) [65535]'
+    '(-t -tt -tttt -ttttt)-ttt[print a delta (in micro-seconds) on each line since previous line]'
+    '(-t -tt -ttt -ttttt)-tttt[print a timestamp in default format preceded by date on each dump line]'
+    '(-t -tt -ttt -tttt)-ttttt[print a delta (in micro-seconds) on each line since first line]'
+    '(-U --packet-buffered)'{-U,--packet-buffered}'[make output packet-buffered when saving to file (-w)]'
     '-u[print undecoded NFS handles]'
-    '-V[Read a list of filenames from file]:file:_files'
+    '-V+[read a list of filenames from specified file]:file:_files'
     '(-v -vv)-vvv[most verbose output]'
-    '-W[limit the number of created files (-C)]:number of files'
+    '-W+[limit the number of created files (-C)]:number of files'
     '(-X)-XX[print each packet, including its link level header, in hex and ASCII]'
     '(-x)-xx[print each packet, including its link level header, in hex]'
-    '-Z[drops privileges (if root) and changes user ID (along with primary group)]:user:_users'
-    '-z[command to run after file rotation]:command:_command_names'
+    "${root}(-Z --relinquish-privileges)"{-Z+,--relinquish-privileges=}'[drop privileges and run as specified user]:user:_users'
+    '-z+[specify command to run on files (with -C or -G)]:command:_command_names -e'
   )
 fi
+[[ $OSTYPE = freebsd* ]] && args+=(
+  '-R[assume ESP/AH packets to be based on old specification (RFC1825 to RFC1829)]'
+)
 
-_arguments : \
-  '-i[interface]:interface:_interfaces' \
-  - optL \
-  '-L[list the known data link types for the interface]' \
-  - default \
-  $args
+_arguments -s $args \
+  '*::BPF filter:= _bpf_filters'