Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: completion for tcpdump filters
- X-seq: zsh-workers 41556
- From: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- To: Zsh workers <zsh-workers@xxxxxxx>
- Subject: PATCH: completion for tcpdump filters
- Date: Wed, 16 Aug 2017 19:11:02 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1502903464; bh=yrYf25RBatqNwQ97yz5DRqUm9jbPRvF4BMzppn4ye5s=; h=From:To:Subject:Date:From:Subject; b=Rq58DvvXdSE2Qz8/NJo5CHtDAhjy4nfecVVqOG+qk9OKT6zAe4Xr9b+8ciBoP8nB/HNVeVV1arF6Yzyu+sj7rwjpSIJw8yGmHQhmMHIpHVGsulC5a+vV2Rqa00tozyJbL5dXZnwQ/PhqhpsaQXceDPT9PZPf52rZUfukXKAsWPBABOkrHXq+Q0nRrI7Gwko69CabkvBagSSogE/C5vZOx9rHuytHOHz+YxdJ7xbh5gPy9FA23j37m+WcUoWulmVTuPI2Ukmkb1TsAozt+S3HzZMIjBCwFwcP57vcvTDrkbp9gzsBPEoczhHI6JLWqtrCN/3wHxNnqhK0r00TBm8TPw==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
This adds a completion function for BPF (libpcap) filters which is
what tcpdump uses. Aside from tcpdump, this also gets used for
Solaris' snoop and a new ngrep completion. I also updated a few
options for _tcpdump and cleaned up _snoop.
This makes use of _regex_arguments because it's a good fit for this
particular problem. The filters can't be fully described by a type-3
(regular) grammar but setting and checking variables in the guards and
taking advantage of the naive backtracking regex parsing algorithm
allows it to do the job. If you break it, _regex_arguments' fallback
is to print "parse failed before current word". This isn't especially
useful from a completion standpoint. Perhaps _regex_arguments could
indicate such errors back via a return status or variable. In the case
of BPF filters, it could strip off the beginning of $words, perhaps up
to the next 'and'/'or', and try again.
Also of note is that _regex_arguments strips quotes from
$words[1,CURRENT-1] but not from $PREFIX. So in some cases patterns
need to allow for backslashes but not others.
Finally, I can't get it to work without an initial word in $words
(normally the command name) that it immediately skips over. This looks
like a bug but I need to investigate further.
Oliver
diff --git a/Completion/Solaris/Command/_snoop b/Completion/Solaris/Command/_snoop
index f734c2fb1..77798a730 100644
--- a/Completion/Solaris/Command/_snoop
+++ b/Completion/Solaris/Command/_snoop
@@ -1,87 +1,32 @@
#compdef snoop
-_snoop() {
- local -a t_opt exp
+local -a args
-t_opt=(
- "r"\:"time relative to first packet"
- "a"\:"absolute time"
- "d"\:"delta time - time since receiving previous packet"
+[[ $OSTYPE = solaris2.<11-> ]] && args=(
+ '-I+[capture packets from specified interface]:interface:_net_interfaces'
)
-
-exp=(
- "ether"
- "ethertype"
- "host"
- "from"
- "to"
- "ip"
- "ip6"
- "arp"
- "rarp"
- "pppoe"
- "pppoed"
- "pppoes"
- "vlan"
- "vlan-id"
- "broadcast"
- "multicast"
- "bootp"
- "dhcp"
- "dhcp6"
- "apple"
- "decnet"
- "greater"
- "less"
- "udp"
- "tcp"
- "icmp"
- "icmp6"
- "ah"
- "esp"
- "net"
- "port"
- "rpc"
- "zone"
- "ldap"
- "gateway"
- "nofrag"
- ">"
- ">="
- "<"
- "<="
- "="
- "!="
- "and"
- "or"
- "not"
- "slp"
- "sctp"
- "ospf"
-)
-
- _arguments \
- '-a[generate audio signal on receiving packets]' \
- '-c[quit after capturing maxcount packets]:maxcount' \
- '-d[capture packets from specified device]:device:_net_interfaces' \
- '-i[display packets previously captured to file]:file:_files' \
- '-n[use file as IP address-to-name mapping table]:file:_files' \
- '-o[save captured packets to file]:file:_files' \
- '-p[display one or more packets from captured file]:first packet number [ , last packet number]' \
- '-q[do not display packet counter when capturing to file]' \
- '-r[do not resolve IP addresses to names]' \
- '-s[truncate each packet after snaplen bytes]:snaplen' \
- '-t[time-stamp presentation]:time-stamp mode:(($t_opt))' \
- '-C[list code generated from filter expression]' \
- '-D[display number of packets dropped on the summary line]' \
- '-N[create IP-address-to-name mapping table file (used with -i)]' \
- '-I[capture packets from specified interface]:interface:_net_interfaces' \
- '-P[capture packets in non-promiscuous mode]' \
- '-S[display size of the entire link layer frame in bytes]' \
- '-V[verbose summary mode]' \
- '-v[verbose mode]' \
- '-x[display offset and length of packet in HEX and ASCII]:offset [ , length]' \
- '*:expression:(($exp))' \
-}
-
-_snoop "$@"
+_arguments -s -S -A "-*" \
+ '-a[generate audio signal on receiving packets]' \
+ '-c+[quit after capturing specified number of packets]:number of packets' \
+ '-d+[capture packets from specified device]:device:_net_interfaces' \
+ '-i+[display packets previously captured to file]:file:_files' \
+ '-n+[use file as IP address-to-name mapping table]:file:_files' \
+ '-o+[save captured packets to file]:file:_files' \
+ '-p+[display one or more packets from captured file]:first packet number [ , last packet number]' \
+ "-q[don't display packet counter when capturing to file]" \
+ "-r[don't resolve IP addresses to names]" \
+ '-s[truncate each packet after specified number of bytes]:length (bytes)' \
+ '-t+[specify time-stamp presentation]:time-stamp mode:((
+ r\:relative\ to\ first\ packet
+ a\:absolute
+ d\:delta\ -\ since\ previous\ packet
+ ))' \
+ '-C[list code generated from filter expression]' \
+ '-D[display number of packets dropped on the summary line]' \
+ '-N[create IP-address-to-name mapping table file (used with -i)]' \
+ '-P[capture packets in non-promiscuous mode]' \
+ '-S[display size of the entire link layer frame in bytes]' \
+ '-V[verbose summary mode]' \
+ '-v[verbose mode]' \
+ '-x+[display offset and length of packet in HEX and ASCII]:offset [ , length]' \
+ '*::expression:= _bpf_filters'
diff --git a/Completion/Unix/Command/_ngrep b/Completion/Unix/Command/_ngrep
new file mode 100644
index 000000000..924597826
--- /dev/null
+++ b/Completion/Unix/Command/_ngrep
@@ -0,0 +1,33 @@
+#compdef ngrep
+
+_arguments -s -S \
+ '(- 1 *)-h[display help information]' \
+ '(- 1 *)-V[display version information]' \
+ "-q[be quiet (don't print packet reception hash marks)]" \
+ '-e[show empty packets]' \
+ '-i[ignore case]' \
+ '-v[invert match]' \
+ "-R[don't do privilege revocation logic]" \
+ '(-W)-x[print in alternate hexdump format]' \
+ '-X[interpret match expression as hexadecimal]' \
+ '-w[word-regex (expression must match as a word)]' \
+ "-p[don't go into promiscuous mode]" \
+ '-l[make stdout line buffered]' \
+ '-D[replay pcap_dumps with their recorded time intervals]' \
+ '-t[print timestamp every time a packet is matched]' \
+ '-T[print delta timestamp every time a packet is matched specify twice for delta from first match]' \
+ "-M[don't do multi-line match (do single-line match instead)]" \
+ '(-d -s)-I+[read packet stream from pcap format file]:file:_files' \
+ '-O+[dump matched packets in pcap format file]:file:_files' \
+ '-n+[look at only specified number of packets]:packets' \
+ '-A+[dump specified number of context packets after a match]:packets' \
+ '(-I)-s+[set the bpf caplen]:length (bytes) [65535]' \
+ '-S+[set the upper limit on size of packets matched]:size (bytes)' \
+ '(-x)-W+[set the dump format]:packet display format:(normal byline single none)' \
+ '-c+[force the column width to the specified size]:columns' \
+ '-P+[set the non-printable display char to what is specified]:character [.]' \
+ '-F+[read the bpf filter from the specified file]:file:_files' \
+ '-N[show sub protocol number]' \
+ '(-I)-d+[use specified device instead of the pcap default]:interface:_net_interfaces' \
+ '1: :_guard "^-*" pattern' \
+ '*::expression:_bpf_filters'
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'
diff --git a/Completion/Unix/Type/_bpf_filters b/Completion/Unix/Type/_bpf_filters
new file mode 100644
index 000000000..c62481e09
--- /dev/null
+++ b/Completion/Unix/Type/_bpf_filters
@@ -0,0 +1,215 @@
+# spaces are valid instead of word ends, perhaps better to just do compset -q
+
+local -a networks fields dirs protos relop
+local -A subtypes flags
+local values dir wlantype skip repeat=1 packet proto=0
+local suf=']'
+
+local WORD=$'[^ \0]##[ \0]##'
+
+networks=(
+ /$'[^/ \0]#'/
+ \(
+ /$'[ \0]'/ ': _message -e networks network'
+ /$'mask[ \0]'/ ':masks:mask:(mask)'
+ /$WORD/ ':netmasks:netmask:'
+ \|
+ /// /$WORD/ ': _message -e masks "netmask length (bits)"'
+ \)
+)
+subtypes=(
+ mgt 'assoc-req assoc-resp reassoc-req reassoc-resp probe-req probe-resp beacon atim disassoc auth deauth'
+ ctl 'ps-poll rts cts ack cf-end cf-end-ack'
+ data 'data data-cf-ack data-cf-poll data-cf-ack-poll null cf-ack cf-poll cf-ack-poll qos-data qos-data-cf-ack qos-data-cf-poll qos-data-cf-ack-poll qos qos-cf-poll and qos-cf-ack-poll'
+)
+flags=(
+ len len
+ tcp 'tcp-fin tcp-syn tcp-rst tcp-push tcp-ack tcp-urg'
+ icmp 'icmp-echoreply icmp-unreach icmp-sourcequench icmp-redirect icmp-echo icmp-routeradvert icmp-routersolicit icmp-timxceed icmp-paramprob icmp-tstamp icmp-tstampreply icmp-ireq icmp-ireqreply icmp-maskreq icmp-maskreply'
+)
+
+case $OSTYPE in
+ solaris*)
+ fields=( ipaddr etheraddr atalkaddr ethertype rpc nofrag inet inet6 vlan-id )
+ protos=( bootp dhcp dhcp6 apple pppoe ldap slp ospf )
+ dirs=( from to )
+ relop=( \^ % )
+ ;|
+ solaris2.<11->)
+ fields+=( zone )
+ ;|
+ (free|open)bsd*) # pf(4) specific filters
+ fields=( ifname on rnr rulenum srnr subruleset reason ruleset rset action )
+ ;|
+ ^(solaris|openbsd)*)
+ protos+=( mpls netbeui iso geneve aarp ipx llc )
+ ;|
+ ^openbsd*)
+ protos+=( ah esp sctp pppoed pppoes )
+ ;|
+ ^solaris*)
+ protos+=( fddi wlan atalk stp lat moprc mopdl )
+ relop=( '>>' '<<' )
+ ;;
+esac
+
+compquote suf
+
+# the regex is essentially:
+# ( [not]* ( expression | [protocol]? [standalone-field | direction field ]? ) and|or ) *
+# the proto variable ensures that and/or is not allowed if there is no
+# protocol or field: it is one, the other or both but not neither
+
+_regex_arguments _bpf /$'[^\0]#\0'/ \( \
+ /$'(not[ \0]#|![ \0]#|(\\\\|)\\([ \0]#)'/ ':operators:operator:(not ()' \# \
+ \(\
+ \(\
+ \(\
+ /"(0x[0-9a-f]##|[0-9]##|${(j.|.)${=flags}})"$'[ \0]#'/ -'((repeat != 2))' ":expressions:expression:compadd ${=flags[$packet]}" \
+ \|\
+ /'[a-z]##(\\|)\[[^\]]##(\\|)\]'$'[ \0]#'/ \
+ \|\
+ /'[a-z]##(\\|)\[[^:\]]##:'/ /'[]'/ ':sizes:field size (bytes):compadd -S "$suf" 1 2 4' \
+ \|\
+ /'tcp(\\|)\['/ -packet=tcp \
+ /'[]'/ ':offsets:header offset:compadd -S "$suf " tcpflags' \
+ \|\
+ /'icmp(\\|)\['/ -packet=icmp \
+ /'[]'/ ':offsets:header offset:compadd -S "$suf " icmptype icmpcode' \
+ \|\
+ /'[a-z]##(\\|)\['/ /'[]'/ ':offsets:offset:' \
+ \)\
+ \(\
+ /$'(\\\\|)([<>=!](\\\\|)[<>=]|[<>&|=+*/%^-])[ \0]#'/ -'repeat=0' ":operators:operator:(+ - = != < > <= >= & | $relop and or)" \
+ // ': _message -e expressions expression' \
+ \|\
+ // -'repeat=2' \
+ \)\
+ \) \# \
+ // -'(( repeat == 2))' \
+ // -'repeat=1' \
+ \|\
+ /$'ether[ \0]proto[ \0]'/ \
+ /$WORD/ ':protocols:protocol:(\ip \ip6 \arp \rarp \atalk \aarp \dec \net \sca \lat \mopdl \moprc \iso \stp \ipx \netbeui)' \
+ \|\
+ /$'(less|greater)[ \0]'/ ':fields:field:(less greater)' \
+ /$WORD/ ':numbers:length (bytes):' \
+ \|\
+ \(\
+ /$'(tcp|udp|icmp|ether|ip|ip6|arp|rarp|decnet|bootp|dhcp|dhcp6|apple|pppoe|pppoed|ldap|ah|esp|slp|sctp|ospf|iso|clnp|esis|isis|atalk|aarp|iso|stp|ipx|netbeui|lat|moprc|mopdl)[ \0]'/ ":protocols:protocol qualifier:(tcp udp icmp ether tr ip ip6 arp rarp decnet $protos)" \
+ \| /$'((fddi|tr|wlan)[ \0]|)'/ '-(( ++proto ))' \) \
+ \(\
+ /$'mpls[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e labels "label number"' \
+ \|\
+ /$'geneve[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e vnis "vni"' \
+ \|\
+ /$'pppoes[ \0]'/ \
+ /$'((0x|)[0-9a-f]##[ \0]|)'/ ': _message -e session-ids "session id"' \
+ \|\
+ /$'proto[ \0]'/ ':fields:field:(proto)' \
+ /$WORD/ ':protocols:protocol:(\icmp \icmp6 \igmp \igrp \pim \ah \esp \vrrp \udp \tcp)' \
+ \|\
+ /$'(broad|multi)cast[ \0]'/ ':fields:field:(broadcast multicast)' \
+ \|\
+ /$'type[ \0]'/ ':fields:field:(type)' \
+ /$WORD/ -'wlantype=${match%?}' ':wlan-types:wlan type:(mgt ctl data)' \
+ \(\
+ /$'subtype[ \0]'/ ':fields:field:(subtype)' \
+ /$WORD/ ':subtypes:subtype:compadd ${=subtypes[$wlantype]:-$subtypes}' \
+ \| \)\
+ \|\
+ /$'protochain[ \0]'/ ':fields:field:(protochain)' \
+ /$WORD/ ':protocols:protocol:' \
+ \|\
+ /$'vlan-id[ \0]'/ \
+ /$WORD/ ':vlans:vlan:' \
+ \|\
+ /$'vlan[ \0]'/ ':fields:field:(vlan)' \
+ \( /$WORD/ ': _message -e vlans vlan' \| \) \
+ \|\
+ \(\
+ /$'(ra|ta|addr[1-4]|inbound|outbound)[ \0]'/ ":directions:direction qualifier:(src dst inbound outbound ra ta addr1 addr2 addr3 addr4 $dirs)" \
+ \|\
+ /$'(src|from|dst|to)[ \0]'/ -'values=${values:-hosts};dir=$match' \
+ \(\
+ /$'(or|and)[ \0]'/ ':operators:operator:(or and)' \
+ /$'(src|dst)[ \0]'/ ':directions:direction qualifier:compadd ${${${${dir%?}:/dst/to}:/(src|from)/dst}:/to/src}' \
+ \| \)\
+ \| \)\
+ \(\
+ /$'(host|gateway)[ \0]'/ ":fields:field:(host gateway $fields)" \
+ /$WORD/ -values=hosts ':hosts:host:_hosts' \
+ \|\
+ /$'inet(6|)[ \0]'/ \
+ \( /$'host[ \0]'/ ':fields:field:(host)' \| \) \
+ /$WORD/ -values=hosts ':hosts:host:_hosts' \
+ \|\
+ /$'ethertype[ \0]'/ \
+ /$WORD/ ':numbers:number:' \
+ \|\
+ /$'(ipaddr|etheraddr|atalkaddr)[ \0]'/ \
+ /$WORD/ ':addresses:address:' \
+ \|\
+ /$'llc[ \0]'/\
+ /$'((s|u|rr|rnr|rej|ui|ua|disc|sabme|test|xid|frmr)[ \0]|)'/ ':types:type:(s u rr rnr rej ui ua disc sabme test xid frmr)' \
+ \|\
+ /$'(ifname|on)[ \0]'/ \
+ /$WORD/ ':interfaces:interface:_net_interfaces' \
+ \|\
+ /$'(rnr|rulenum|srnr|subruleset)[ \0]'/ \
+ /$WORD/ ':rules:rule number:' \
+ \|\
+ /$'reason[ \0]'/ \
+ /$WORD/ ':reasons:reason:(match bad-offset fragment short normalize memory)' \
+ \|\
+ /$'(rset|ruleset)[ \0]'/ \
+ /$WORD/ ':rule-sets:rule set:' \
+ \|\
+ /$'action[ \0]'/ \
+ /$WORD/ ':actions:action:(pass block nat rdr binat scrub)' \
+ \|\
+ /$'rpc[ \0]'/ \
+ \(\
+ /$'[^, \0]##[ \0]'/ ':programs:rpc program:compadd -qS, - ${${(f)"$(</etc/rpc)"}%%[[:blank:]#]*}' \
+ \|\
+ /$'[^, \0]##,[^, \0]##,'/ /$'[^, \0]##[ \0]'/ ':procedures:procedure:' \
+ \|\
+ /$'[^, \0]##,'/ /$'[^, \0]##[ \0]'/ ':versions:version:' \
+ \)\
+ \|\
+ /$'zone[ \0]'/ \
+ /$WORD/ ':zones:zone:_zones' \
+ \|\
+ /$'port[ \0]'/ ':fields:field:(port)' \
+ /$WORD/ -values=ports ':ports:port:_ports' \
+ \|\
+ /$'portrange[ \0]'/ -values=portranges ':fields:field:(portrange)' \
+ /$'[^ \0-]##-'/ ':ports:port:_ports -S-' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ /$'net[ \0]'/ -values='networks' ':fields:field:(net)' \
+ $networks \
+ \|\
+ // -'[[ $values = hosts ]]' \
+ /$WORD/ ':hosts:host:_hosts' \
+ \|\
+ // -'[[ $values = ports ]]' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ // -'[[ $values = networks ]]' \
+ $networks \
+ \|\
+ // -'[[ $values = portranges ]]' \
+ /$'[^ \0-]##-'/ ':ports:port:_ports -S-' \
+ /$WORD/ ':ports:port:_ports' \
+ \|\
+ // -'(( ++proto ))' \
+ \)\
+ \)\
+ \)\
+ // -'(( proto < 2 ))' \
+ /$'(and|or|&&|\\|\\||\\))[ \0]'/ -proto=0 ':operators:operator:compadd and or \)' \) \#
+
+_bpf "$@"
Messages sorted by:
Reverse Date,
Date,
Thread,
Author