I usually use fuser command to check pid opening the certain tcp port like the following
fuser 22/tcp //To get pid opening the 22 tcp port
I've got a reference board which running a embedded linux. It have been already opening 22 tcp port for ssh connection. But fuser doesn't display output anything about 22 port. So I tried another ssh daemon to open 322 port then tried to check pid using fuser, it worked fine.
root@imx6qsabreauto:~# netstat -nlt | grep 22
tcp 0 0 0.0.0.0:4224 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:322 0.0.0.0:* LISTEN
tcp 0 0 :::322 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN
root@imx6qsabreauto:~# fuser 322/tcp
351
root@imx6qsabreauto:~# ps -ef | grep 351
root 351 1 0 01:46 ? 00:00:00 /usr/sbin/dropbear -r /etc/dropbear/dropbear_rsa_host_key -p 322 -B
root 379 315 0 02:11 ttymxc3 00:00:00 grep 351
root@imx6qsabreauto:~# fuser 22/tcp
==> This output nothing !!
How can I figure out which process is opening tcp 22 port. (In the board, lsof command is not available and.. netstat doesn't have -p option.)
I you have /proc
mounted and bash
and readlink
both installed,
You can write a small bash script that parses /proc/net/tcp
, and scan /proc/*/fd/
to find the corresponding socket.
I'm not so familiar with embedded linux, but if you cannot find readlink
, it may be included in busybox
.
/proc/net/tcp
is something like
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:4E7A 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 13128 1 ffff8800cf960740 99 0 0 10 0
The local_address
is hex string of HOST:PORT
, so the script searches for :0016
when you want to search tcp 22 port.
Once it founds the row which contains :0016
in local_address
,
the inode
is the corresponding socket number.
Then it searchs for /proc/*/fd/*
which has the socket number using readlink
command.
#!/bin/bash
PORT="$1"
HEX_PORT=$(printf %04X $PORT)
INODE=""
if ! [ "$PORT" ];then
echo "usage $0 [PORT]"
exit
fi
while read num host_port _ _ _ _ _ _ _ inode _; do
if [[ $host_port =~ :"$HEX_PORT"$ ]];then
INODE=$inode
fi
done < /proc/net/tcp
if ! [ "$INODE" ];then
echo "no process using $PORT"
exit
fi
for fn in /proc/[1-9]*/fd/*; do
if [ "$(readlink $fn)" = "socket:[$INODE]" ];then
tmp=${fn%/fd*}
echo ${tmp#/proc/}
fi
done