#!/bin/sh prog="ss" usage() { cat >&2 <&2 usage } ############################################################ # parse_filter() { # Very limited implementation: # We only expect to find || inside parentheses # We don't expect to see && - it is implied by juxtaposition # Operator for port comparison is ignored and assumed to be == # Build lists of source ports and source IP addresses where # each entry is surrounded by '|' characters. These lists can # be easily "searched" using the POSIX prefix and suffix # removal operators. in_parens=false sports="|" srcs="|" while [ -n "$1" ]; do case "$1" in \() in_parens=true shift ;; \)) in_parens=false shift ;; \|\|) if ! $in_parens; then not_supported "|| in parentheses" fi shift ;; sport) p="${3#:}" sports="${sports}${p}|" shift 3 ;; src) ip="${2#\[}" ip="${ip%\]}" srcs="${srcs}${ip}|" shift 2 ;; *) usage ;; esac done } # Check if socket has matches in both ok_ips and ok_ports filter_socket() { ok_ips="$1" ok_ports="$2" socket="$3" ip="${socket%:*}" port="${socket##*:}" if [ "$ok_ports" != "|" ] && [ "${ok_ports#*|"${port}"|}" = "$ok_ports" ]; then return 1 fi if [ "$ok_ips" != "|" ] && [ "${ok_ips#*|"${ip}"|}" = "$ok_ips" ]; then return 1 fi return 0 } ss_tcp_established() { if $header; then echo "Recv-Q Send-Q Local Address:Port Peer Address:Port" fi # Yes, lose the quoting so we can do a hacky parsing job # shellcheck disable=SC2048,SC2086 parse_filter $* for i in $FAKE_NETSTAT_TCP_ESTABLISHED; do src="${i%|*}" dst="${i#*|}" if filter_socket "$srcs" "$sports" "$src"; then echo 0 0 "$src" "$dst" fi done if [ -z "$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" ]; then return fi while read -r src dst; do if filter_socket "$srcs" "$sports" "$src"; then echo 0 0 "$src" "$dst" fi done <"$FAKE_NETSTAT_TCP_ESTABLISHED_FILE" } ############################################################ unix_listen() { if $header; then cat <