Update netstat-tulp.sh

This commit is contained in:
2026-09-21 18:17:35 +03:00
parent 9154ec1078
commit 7e10dc90b4
+126 -79
View File
@@ -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