Archive for August, 2014

26
Aug
14

Finding the process of a listening socket

I had a irc user today asked me how they can find the process id of a listening port.  The obvious answer is to use netstat -lnap; however there are occasions when this will show a dash instead of the process ID.  This occurs when some kernel module spawned the PID that owns the socket.  RPC behaves in this manner and the simplest way to find the pid in that case is to use rpcinfo -p. our as pointed out in the initial irc chat you can use the nmap rpcinfo nse script as follows.

nmap -sU -p 111 --script rpcinfo localhost

however i suggested that is should be possible to find these PID’s by parsing the proc file system. using the netstat -e switch we get the inode of the listening socket and with a bit of hacking i came up with the following test code.

#!/bin/sh
INODE=304
for i in /proc/*/fd/*
do
   SOCKET_INODE=$(stat -c %N ${i} 2>/dev/null | awk -F\: '/socket:\[[0-9]+\]/ {gsub(/[\[\]]/, "", $NF);print $NF}')
   [ "${SOCKET_INODE%?}" == "${INODE}" ] && awk -F\/ '{print $3}'<<< ${i}
done

Unfortunately i don’t have a machine that shows these symptoms and the user disconnected from IRC before i could get them to check. However i think this could be reasonably expanded to the following.

netstat -lnptue | awk '{if ($NF == "-")print $0}' | while read CONNECTION
do
	CONN_TOKENS=($CONNECTION)
	LOCAL_ADDRESS=${CONN_TOKENS[3]}
	INODE=${CONN_TOKENS[7]}
	for i in /proc/*/fd/*
	do
		SOCKET_INODE=$(stat -c  %N ${i} 2>/dev/null | awk -F\: '/socket:\[[0-9]+\]/ {gsub(/[\[\]]/, "", $NF);print $NF}')
		if [ "${SOCKET_INODE%?}"  == "${INODE}"]
		then
			PID=$(awk -F\/ '{print $3}'<<< ${i})
			echo "${LOCAL_ADDRESS}: ${PID}"
		fi
	done
done

This is very inefficient as we scan the whole of proc for every entry we find but i will leave it as an exercise for the reader to optimise. Not sure if this is of any use other then my own curiosity so please feel free to leave feedback.