From 7e10dc90b4a081fffec1310e10986a9cec9b08b5 Mon Sep 17 00:00:00 2001 From: Ste Vaidis Date: Mon, 21 Sep 2026 18:17:35 +0300 Subject: [PATCH] Update netstat-tulp.sh --- netstat-tulp.sh | 205 +++++++++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 79 deletions(-) diff --git a/netstat-tulp.sh b/netstat-tulp.sh index 03ba140..e731c9c 100644 --- a/netstat-tulp.sh +++ b/netstat-tulp.sh @@ -1,98 +1,145 @@ #!/bin/ksh -# OpenBSD equivalent-ish to: # -# Linux: netstat -tulpn +# ports # -# Shows listening TCP sockets and UDP sockets together with -# the process using the socket when fstat can identify it. +# Show network sockets with their owning processes. +# +# Similar idea to Linux: +# +# netstat -tulpn +# +# OpenBSD implementation using: +# +# fstat +# ps +# +# Run as root for complete information. # -# Best run as root for complete process information. -printf "%-5s %-7s %-8s %-22s %-22s %s\n" \ - "PROTO" "PID" "USER" "LOCAL ADDRESS" "FOREIGN ADDRESS" "PROCESS" - -printf "%-5s %-7s %-8s %-22s %-22s %s\n" \ - "-----" "-------" "--------" "----------------------" \ - "----------------------" "-------" # ------------------------------------------------------------ -# TCP listening sockets +# Header # ------------------------------------------------------------ -netstat -an -f inet 2>/dev/null | -awk '$1 ~ /^tcp/ && $6 == "LISTEN" { - print $1, $4, $5 -}' | -while read proto local foreign -do - # Extract port from local address. - port="${local##*.}" +printf "%-5s %-28s %-8s %-12s %s\n" \ + "PROTO" \ + "LOCAL ADDRESS" \ + "PID" \ + "USER" \ + "COMMAND" - # Try to find the process owning this socket. - owner="$( - fstat 2>/dev/null | - awk -v port="$port" ' - $0 ~ ("\\*:" port "([^0-9]|$)") || - $0 ~ ("\\." port "([^0-9]|$)") { - print $1, $2, $3 - exit +printf "%-5s %-28s %-8s %-12s %s\n" \ + "-----" \ + "----------------------------" \ + "--------" \ + "------------" \ + "-------" + + +# ------------------------------------------------------------ +# Read Internet sockets from fstat +# ------------------------------------------------------------ + +fstat 2>/dev/null | +awk ' + # + # We only want IPv4/IPv6 Internet sockets. + # + $5 == "internet" || $5 == "internet6" { + + user = $1 + process = $2 + pid = $3 + family = $5 + type = $6 + proto = $7 + + # + # Ignore raw sockets. + # + if (type != "stream" && type != "dgram") + next + + # + # Only TCP and UDP. + # + if (proto != "tcp" && proto != "udp") + next + + + # + # Determine tcp4/tcp6/udp4/udp6. + # + if (family == "internet6") + proto = proto "6" + else + proto = proto "4" + + + # + # Find the local address. + # + # fstat output contains a kernel socket pointer before + # TCP addresses, for example: + # + # tcp 0xffff800001058140 *:22 + # + # UDP normally looks like: + # + # udp 192.168.0.2:37163 <-> ... + # + # Search fields after the protocol for the first field + # containing ":". + # + + local = "-" + + for (i = 8; i <= NF; i++) { + + if ($i ~ /:/) { + local = $i + break } - ' + } + + + # + # Print fields separated by tabs so the shell can + # safely parse them. + # + printf "%s\t%s\t%s\t%s\n", + proto, + local, + pid, + user + } +' | +while IFS=' ' read proto local pid user +do + + # -------------------------------------------------------- + # Get complete command line from PID. + # -------------------------------------------------------- + + command="$( + ps -p "$pid" -o args= 2>/dev/null )" - if [ -n "$owner" ]; then - set -- $owner - - user="$1" - process="$2" - pid="$3" - else - user="-" - process="-" - pid="-" + if [ -z "$command" ]; then + command="-" fi - printf "%-5s %-7s %-8s %-22s %-22s %s\n" \ - "$proto" "$pid" "$user" "$local" "$foreign" "$process" -done + # -------------------------------------------------------- + # Output + # -------------------------------------------------------- -# ------------------------------------------------------------ -# UDP sockets -# ------------------------------------------------------------ + printf "%-5s %-28s %-8s %-12s %s\n" \ + "$proto" \ + "$local" \ + "$pid" \ + "$user" \ + "$command" -netstat -an -f inet 2>/dev/null | -awk '$1 ~ /^udp/ { - print $1, $4, $5 -}' | -while read proto local foreign -do - port="${local##*.}" - - owner="$( - fstat 2>/dev/null | - awk -v port="$port" ' - $0 ~ ("\\*:" port "([^0-9]|$)") || - $0 ~ ("\\." port "([^0-9]|$)") { - print $1, $2, $3 - exit - } - ' - )" - - if [ -n "$owner" ]; then - set -- $owner - - user="$1" - process="$2" - pid="$3" - else - user="-" - process="-" - pid="-" - fi - - printf "%-5s %-7s %-8s %-22s %-22s %s\n" \ - "$proto" "$pid" "$user" "$local" "$foreign" "$process" -done +done \ No newline at end of file