#compdef netstat local Wopt Xopt nopt="[don't resolve addresses to names]" local lopt='[show only listening sockets]' local zopt='-z[reset statistic counters after displaying them]' local popt='(-f)-p+[filter by protocol]:protocol:compadd -a plist' local Iopt='(-i)-I+[show information about the specified interface]:interface:_net_interfaces' local set sel tblopt local -A sets local -a Mopts families flist plist args sockets extend interval verbose local -a {sel_,}{bpf,dhcp,groups,interfaces,masquerade,media,memory,multicast,pcb,queues,rdomains,routing,statistics,wireless} case $OSTYPE in linux-gnu) families=( '(-4 --inet)'{-4,--inet} '(-6 --inet)'{-4,--inet6} '(-A --protocol)'{-A+,--protocol=}':protocol:_sequence compadd - inet inet6 unix ipx ax25 netrom ddp bluetooth' --unix -x --ip --tcpip --ax25 --x25 --rose --ash --bluetooth --ipx --netrom --ddp --appletalk --econet --ec ) extend=( \*{-e,--extend}'[show additional information]' ) verbose=( '(-v --verbose)'{-v,--verbose}'[show what is going on]' ) args=( '(-c --continuous)'{-c,--continuous}'[repeat information every second]' '!(-n --numeric)'{-N,--symbolic} '(-n --numeric)'{-n,--numeric}"$nopt" --numeric-hosts --numeric-ports --numeric-users '1: :_guard "[0-9]#" "repeat interval (seconds)"' - '(help)' '(- 1)'{-h,--help}'[display usage information]' '(- 1)'{-V,--version}'[display version information]' ) sets=( routing '(--route|-[^-]#r*)' groups '(--groups|-[^-]#g*)' interfaces '(--interfaces|-[^-]#[iI]*)' statistics '(--statistics|-[^-]#s*)' masquerade '(--masquerade|-[^-]#M*)' ) sel_routing=( '(-r --route)'{-r,--route}'[display routing table]' ) sel_interfaces=( '(-I --interfaces)-i[display interface table]' '(-i -I --interfaces)'{--interface=-,-I=-}'[display interface table]::interface:_net_interfaces' ) sel_groups=( '(-g --groups)'{-g,--groups}'[display multicast group memberships]' ) sel_masquerade=( '(-M --masquerade)'{-M,--masquerade}'[display masqueraded connections]' ) [[ -e /proc/net/ip_masquerade ]] || sel_masquerade=( \!${^sel_masquerade} ) sel_statistics=( '(-s --statistics -c --continuous -n --numeric --numeric-hosts --numeric-ports --numeric-users)'{-s,--statistics}'[display networking statistics]' ) sockets=( $families $verbose --tcp -t --udp -u --udplite -U --sctp -S --raw -w '(-2 --l2cap)'{-2,--l2cap} '(-f --rfcomm)'{-f,--rfcomm} '(-a --all -l --listening)'{-l,--listening}$lopt '(-a --all -l --listening)'{-a,--all}'[show all sockets]' --symbolic -N --extend -e '(--timers -o)'{--timers,-o}'[show information on networking timers]' '(--program -p)'{--program,-p}'[show process id and program name for sockets]' '(--wide -W)'{--wide,-W}"[don't truncate IP addresses in output]" '(-Z --context)'{-Z,--context}'[display SELinux security context for sockets]' ) routing=( $families $extend $verbose '-C[display routing cache instead of FIB]' ) interfaces=( $extend $verbose '(-a --all)'{-a,--all}'[show interfaces that are not up]' ) groups=() masquerade=( $extend ) statistics=( $families ) ;; solaris*|darwin*|dragonfly*|freebsd*) families=( '(-p -4 -6)-f+[specify address family]:address family:compadd -a flist' ) ;| freebsd*) families+=( '(-6 -f)-4[show IPv4 only]' '(-4 -f)-6[show IPv6 only]' ) ;| (open|net)bsd*) popt='(-f)-p+[filter by protocol]:protocol:compadd - ${(M)${(f)"$() sets+=( dcache '-[^-]#d*' ) sel_dcache=( '-d[display the destination cache entry table]' ) dcache=( $families ) args=( '-T+[specify time format]:time format:((u\:seconds\ since\ epoch d\:standard\ date\ format))' ) sockets+=( '-u[list user, pid and program that created network endpoint]' '-k[show only sockets with kernel data path bypass enabled]' '-L[only show state of sockets using SO_REUSEPORT load balancing]' ) ;& solaris*) args=( -A '-*' $args ) interval=( '1: :_guard "[0-9]#" "repeat interval (seconds)"' '2: :_guard "[0-9]#" "count"' ) sets+=( dhcp '-[^-]#D*' media '-[^-]#p*' multicast '-[^-]#M*' ) sel_media=( '-p[display net to media tables]' ) sel_memory=( '-m[display STREAMS memory statistics]' ) sel_multicast=( '-M[display multicast routing tables]' ) sel_dhcp=( '-D[display status of DHCP configured interfaces]' ) sockets+=( $verbose '-R[show extended security attributes]' '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' ) routing+=( $verbose '*-f+[filter routing table]:rule:_values -S \: "filter rule" $flist "af[specify address family]\:family\:(inet inet6 unix)" "outif[specify output interface]\:interface\:_net_interfaces" "dst[specify destination IP]\:IP address" "flags[select routes tagged with flags]\:flags"' \ '-a[show state of all routing tables]' '-R[show extended security attributes]' ) groups+=( $families -n$nopt $verbose ) interfaces+=( $interval '-a[show state of all interfaces]' ) statistics+=( '-P[specify protocol]:protocol:(ip ipv6 icmp icmpv6 igmp udp tcp rawip)' ) media=( -n$nopt $families ) memory+=( $verbose $interval ) multicast+=( -n$nopt $families '-s[show per protocol statistics]' ) dhcp=( $families $Iopt ) ;; darwin*) sets+=( queues '-[^-]#q*' ) sel_queues=( '*-q[display network interface send queue statistics]' ) sel_memory=( \*$sel_memory ) sockets+=( '-l[show full IPv6 address]' '-W[avoid truncating addresses]' ) routing+=( '-l[show mtu and use wider display]' ) interfaces+=( '(-x)-R[show reachability information]' '-S[show interface link status and state]' '(-R)-x[show extended reachability information]' ) queues=( $Iopt '-c+[limit statistics to specified queue]:queue' ) groups+=( $families '*-v[show link-layer memberships; repeat for timers and counters]' ) ;; dragonfly*) plist+=( carp ) sockets+=( '-P[show additional protocol-specific information]' '-c+[access cpu specific route table]:cpu' ) interfaces+=( $zopt '-B[show maximum buffer sizes instead of current buffer usage]' '-t[show the contents of watchdog timers]' '(-a -B -b -d -h -n -t -w)*-s[show protocol statistics; repeat to suppress those with zero counters]' ) routing+=( '-A[show contents of internal Patricia tree structures]' '-a[show protocol-cloned routes]' ) ;; openbsd*) sets+=( wireless '-W*' rdomains '-R' ) sel_rdomains=( '-R[show all rdomains with associated interfaces and routing tables]' ) sel_wireless=( '-W+[display per-interface IEEE 802.11 wireless statistics]:interface' ) flist+=( local mpls ) tblopt='-T+[select an alternate routing table to query]:routing table:_routing_tables' sockets+=( -l$lopt $tblopt '-B[show buffer sizes for TCP sockets]' ) routing+=( $Mopts $tblopt '-A[show the internal addresses of the routing table]' '-F[only show routes with gateway in the same address family as the destination]' ) interfaces+=( '-c+[show specified number of updates, then exit]:count' '-e[show only the number of errors on the interface]' '-q[only show interfaces that have seen packets]' ) statistics+=( $popt '-r[display routing statistics]' ) groups+=( -n$nopt ) pcb+=( $Mopts $verbose ) ;; netbsd*) popt='(-f)-p+[filter by protocol]:protocol:compadd - ${(M)${(f)"$(.*) sockets+=( '-c[show TCP stack used for each session]' '-C[show TCP congestion control algorithm and diagnostic]' ) ;& freebsd<11->.*) routing+=( '-F+[show specified routing table]:routing table' ) bpf=( '-z[reset statistic counters after displaying them]' ) statistics+=( $bpf[-1] ) ;& freebsd*) flist+=( pfkey netgraph ng link ) plist+=( sctp ipsec6 pfkey ) sets+=( netisr '-[^-]#Q*' ) sel_netisr=( '-Q[display netisr(9) statistics]' ) sockets+=( '-R[show flowid and flowtype for each socket]' '-T[show diagnostic information from the TCP control block]' '-x[show socket buffer and TCP timer statistics]' ) interfaces+=( $popt $Mopts $Iopt $Wopt '-q+[exit after specified number of outputs]:number' ) bpf+=( $Iopt $zopt ) ;; esac # Ignore display specific options except the default (socket) display until a # display has been selected. This is not strictly correct (options can be in # any order) but makes the completion much more useful. Descriptions for # options that select a specific display (option set) typically start with # "display" to set them apart from other options. sock='' for set in ${(k)sets}; do sel=sel_$set if [[ -z $words[(r)$~sets[$set]] ]]; then ign='!' else sock='!' ign='' fi args+=( - "$set" ${(P)sel} ${ign}${(P)^set} ) done args+=( - sockets ${sock}${sockets} ) _arguments -s -S $args