Finding a process ID given a socket and inode in Python 3
The following code accomplishes the original goal:
def find_pid(inode):
# get a list of all files and directories in /proc
procFiles = os.listdir("/proc/")
# remove the pid of the current python process
procFiles.remove(str(os.getpid()))
# set up a list object to store valid pids
pids = []
for f in procFiles:
try:
# convert the filename to an integer and back, saving the result to a list
integer = int(f)
pids.append(str(integer))
except ValueError:
# if the filename doesn't convert to an integer, it's not a pid, and we don't care about it
pass
for pid in pids:
# check the fd directory for socket information
fds = os.listdir("/proc/%s/fd/" % pid)
for fd in fds:
# save the pid for sockets matching our inode
if ('socket:[%d]' % inode) == os.readlink("/proc/%s/fd/%s" % (pid, fd)):
return pid
How to find more information about the file descriptor?
Since you are using strace
I assume you are on Linux and you know the process id. In that case you can find a lot of info in /proc
. Here is an example of what to do.
Do ls -l /proc/<pid>/fd
. There will be an entry corresponding to the fd you are interested in and that fd should be a socket as such:
$ ls -l /proc/3311/fd
total 0
lrwx------ 1 alanau alanau 64 Sep 24 20:37 0 -> /dev/pts/0
lrwx------ 1 alanau alanau 64 Sep 24 20:37 1 -> /dev/pts/0
lrwx------ 1 alanau alanau 64 Sep 24 20:37 2 -> /dev/pts/0
lrwx------ 1 alanau alanau 64 Sep 24 20:37 3 -> socket:[23182]
In the above example, 3
is the socket of interest. The number after socket
is the inode number, 23182
in this case.
Now look in the file /proc/net/tcp
to find that inode:
$ cat /proc/net/tcp | grep 23182
2: 0F02000A:C43B 8EDC3AD8:0050 01 00000000:00000000 00:00000000 00000000 1000 0 **23182** 1 0000000000000000 23 0 0 10 -1
The first line of /proc/net/tcp
tells you what each field represents:
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
So in this example, the remote address is 8EDC3AD8:0050
. That's the ip_addres:port_number in hex and network byte ordering. If you convert that to decimal it is 216.58.220.142:80
.
Which tells you it is in fact a TCP connection to port 80 of google.com!
If you don't find the inode number in /proc/net/tcp
then try the other protocols in the directory, probably /proc/net/udp
.
with root, open other process socket and get tcp_info with python?
There's no python tool that I know of which does what you're asking for, nor is there an easy way I can think of involving parsing the proc directory yourself. As such, you could either implement a pure python version of the ss command yourself (or at least figure out how it calculates RTT from information in /proc/<pid>/net/*), or parse its' output. I'm more of a bash person so this is what I threw together to get a list of (RTT,PID) pairs:
#!/usr/bin/python
from subprocess import check_output as co
co("ss -tp > ss.out", shell=True)
rtts = co("cat ss.out | grep ESTAB | awk '{print $4}' | xargs -I {} ss -i 'src {}' | grep \"rtt:\" | awk '{print $4}' | cut -d : -f 2 | cut -d / -f 1", shell=True)
pids = co("cat ss.out | grep ESTAB | awk '{print $6}' | cut -d , -f 2", shell=True)
print zip(rtts.split('\n'), pids.split('\n'))
In the ss command the -t means show TCP connections and the -p means print process (PID) info. Using the -e option you could also get the inode number, which you can use to determine the file descriptor numbers in /proc/XXXX/fd/. For instance I have process 31117 running on my machine with file descriptor number 11 corresponding to a socket with inode number 31159:
# ls -lah /proc/31117/fd/11
lrwx------ 1 root root 64 Dec 10 19:08 /proc/31117/fd/11 -> socket:[31159]
The reason you cannot "open" a socket file like /proc/pid/fd/4 is because these are all links which point to non-existent files. The only information you can get from them is the name (inode number) of the socket.
with root, open other process socket and get tcp_info with python?
There's no python tool that I know of which does what you're asking for, nor is there an easy way I can think of involving parsing the proc directory yourself. As such, you could either implement a pure python version of the ss command yourself (or at least figure out how it calculates RTT from information in /proc/<pid>/net/*), or parse its' output. I'm more of a bash person so this is what I threw together to get a list of (RTT,PID) pairs:
#!/usr/bin/python
from subprocess import check_output as co
co("ss -tp > ss.out", shell=True)
rtts = co("cat ss.out | grep ESTAB | awk '{print $4}' | xargs -I {} ss -i 'src {}' | grep \"rtt:\" | awk '{print $4}' | cut -d : -f 2 | cut -d / -f 1", shell=True)
pids = co("cat ss.out | grep ESTAB | awk '{print $6}' | cut -d , -f 2", shell=True)
print zip(rtts.split('\n'), pids.split('\n'))
In the ss command the -t means show TCP connections and the -p means print process (PID) info. Using the -e option you could also get the inode number, which you can use to determine the file descriptor numbers in /proc/XXXX/fd/. For instance I have process 31117 running on my machine with file descriptor number 11 corresponding to a socket with inode number 31159:
# ls -lah /proc/31117/fd/11
lrwx------ 1 root root 64 Dec 10 19:08 /proc/31117/fd/11 -> socket:[31159]
The reason you cannot "open" a socket file like /proc/pid/fd/4 is because these are all links which point to non-existent files. The only information you can get from them is the name (inode number) of the socket.
Using /proc/ pid , how can I identify a network port number's application?
NOTE: Added another answers as lsof
was not satisfactory.
This should work:
#! /bin/bash
port=56474
hex_port=$(echo "obase=16; $port" | bc )
inode=$(cat /proc/net/tcp | grep ":$hex_port" | awk '{print $10}')
for i in $(ps axo pid); do
ls -l /proc/$i/fd 2> /dev/null | grep -q ":\[$inode\]" && echo $i
done
Explanation:
Once we have the port number converted to Hexadecimal, we can get the inode number from /proc/net/tcp (10th field), then we loop through /proc/pids/fd and find a symlink pointing to the inode.
Related Topics
How to Use Watir to Scrape Data from a Website on a Linux Server Without Monitor
How to Use Sed to Change File Extensions
How to Change Perf_Event_Open Max Sample Rate
Can an Interrupt Handler Be Preempted
How to Catch the L3-Cache Hits and Misses by Perf Tool in Linux
Can Malloc_Trim() Release Memory from the Middle of the Heap
Let Non-Root User Write to Linux Host in Docker
Errors in Make File:*** Missing Separator. Stop
How to Flush Cache of Hard-Disk and Flash-Disk (Or Filesystem) from Command Line
Check If There Is an Stdout Redirection in Bash Script
Run Jenkins Jobs on Linux Under a User
Module Compiling:Asm/Linkage.H File Not Found
How to Redirect Nohup Output to a Specified File
Linux Command to Replace String in Large File with Another String
Linker Cannot Find Symbols, But Libraries Are Read and Symbols Exist