- #!/usr/bin/ksh93
- #
- # list_active_local_tcp_ports1.ksh - list port numbers of local TCP connections
- #
- # Written by Roland Mainz <roland.mainz@nrubsig.org>
- #
- #
- # simple netstat -n parser
- #
- function netstat_list_connections
- {
- set -o nounset
- nameref data=$1
- compound out=( typeset stdout stderr ; integer res )
- out.stderr="${ { out.stdout="${ LC_ALL='POSIX' /usr/bin/netstat -n ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
- if (( out.res != 0 )) || [[ ${out.stderr} != '' ]] ; then
- return 1
- fi
- typeset -a data.connections
- typeset l
- integer dci=0 # data.connections array index
- while read l ; do
- leftover="${l/~(Elrx)
- (?: # non-capturing group
- #
- # regex group for tcp,udp
- #
- (tcp|tcp6|udp) # Proto
- [[:space:]]+
- ([[:digit:]]+) # Recv-Q
- [[:space:]]+
- ([[:digit:]]+) # Send-Q
- [[:space:]]+
- ([^[:space:]]+) # Local Address
- [[:space:]]+
- ([^[:space:]]+) # Foreign Address
- [[:space:]]+
- ([^[:space:]]+) # State
- |
- #
- # regex for unix
- #
- (unix) # Proto
- [[:space:]]+
- ([[:digit:]]+) # RefCnt
- [[:space:]]+
- (\[.+?\]) # Flags
- [[:space:]]+
- ([^[:space:]]+) # Type
- [[:space:]]+
- ([^[:space:]]*?) # State (optional)
- [[:space:]]+
- ([[:digit:]]+) # I-Node
- (?:
- |
- [[:space:]]+
- ([^[:space:]]+) # Path (optional)
- )
- )
- /X}"
- # If the regex above did not match then .sh.match
- # remains untouched, so we might see data from the
- # previous round.
- # So we check the "leftover" var whether it just
- # contains the dummy value of "X" to indicate a
- # successful regex match
- if [[ "$leftover" == 'X' ]] ; then
- #print -v .sh.match
- if [[ "${.sh.match[1]-}" != '' ]] ; then
- nameref dcn=data.connections[$dci]
- typeset dcn.proto="${.sh.match[1]}"
- typeset dcn.recv_q="${.sh.match[2]}"
- typeset dcn.send_q="${.sh.match[3]}"
- typeset dcn.local_address="${.sh.match[4]}"
- typeset dcn.foreign_address="${.sh.match[5]}"
- typeset dcn.state="${.sh.match[6]}"
- ((dci++))
- elif [[ "${.sh.match[7]-}" != '' ]] ; then
- nameref dcn=data.connections[$dci]
- typeset dcn.proto="${.sh.match[7]}"
- typeset dcn.refcnt="${.sh.match[8]}"
- typeset dcn.flags="${.sh.match[9]}"
- typeset dcn.type="${.sh.match[10]}"
- [[ "${.sh.match[11]}" != '' ]] && typeset dcn.state="${.sh.match[11]}"
- typeset dcn.inode="${.sh.match[12]}"
- [[ "${.sh.match[13]}" != '' ]] && typeset dcn.path="${.sh.match[13]}"
- ((dci++))
- fi
- else
- true
- #printf $"leftover=%q\n" "${leftover}"
- fi
- done <<<"${out.stdout}"
- return 0
- }
- function netstat_list_active_local_tcp_connections
- {
- set -o nounset
- nameref ar=$1
- compound c
- integer port
- integer i
- netstat_list_connections c || return 1
- # print -v c
- [[ -v ar ]] || integer -a ar
- for i in "${!c.connections[@]}" ; do
- nameref n=c.connections[$i]
- # look for only for TCP connections which match
- # 127.0.*.* or IPv6 ::1
- if [[ "${n.proto}" == ~(El)tcp && \
- "${n.local_address}" == ~(Elr)(127\.0\..+|::1):[[:digit:]]+ ]] ; then
- port="${n.local_address##*:}"
- #printf $"port = %d\n" port
- (( ar[port]=1 ))
- fi
- done
- return 0
- }
- function main
- {
- set -o nounset
- compound c=( integer -a ar )
- netstat_list_active_local_tcp_connections c.ar || return 1
- # print -v c
- (( ${#c.ar[@]} > 0 )) && printf $"%d\n" "${!c.ar[@]}"
- return 0
- }
- # main entry point
- main
- exit $?
- # EOF.
list_active_local_tcp_ports1.ksh - list port numbers of local TCP connections
Posted by Anonymous on Mon 27th Feb 2023 10:39
raw | new post
view followups (newest first): list_active_local_tcp_ports1.ksh - list port numbers of local TCP connections by Anonymous
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.