How can I capture network packets per PID? [closed]
Asked Answered
A

5

35

Anyone know an easy way to ask Linux to "display every internet packet to/from google chrome" or "display every internet packet to/from telnet process with PID 10275"?

The telnet example is not too useful, since I can just use wireshark or tcpdump to see all TCP conversations involving port 23. That and nobody uses telnet anymore. But sniffing all packets to/from complex applications which use many ports seems like a useful thing.

I found some related answers exploring different ways to corroborate ports and PIDs (or programs names) and such, but nothing about packets

Looks like someone might have been willing to pay for this answer a while back:

NetHogs is useful for quickly seeing what programs are creating traffic over an interface, but it doesn't have a way to capture packets.

Ascendancy answered 20/10, 2011 at 21:33 Comment(5)
Hrm, should I ask on serverfault instead?Ascendancy
This probably belongs on SuperUser, actually. An interesting question. You could use WireShark to filter out HTTP requests, but you'd have to hook into the kernel drivers to filter packets based on PIDsGrolier
It's a bit of a complex issue - sockets aren't owned by PIDs; you can pass them from one process to another. If process A opens a socket, it can pass it over to process B then exit - if you're filtering on process A's PID, what happens now?Girl
I was going to suggest using dtrace to watch syscalls like write, send, sendto, but AFAIK dtrace hasn't made it to Linux. Perhaps you can use a similar syscall logging tool?Elastic
since 2024, you can use github.com/mozillazg/ptcpdump to capturing network packets per PID on linux 5.2+.Janeyjangle
G
21

Not directly a tcpdump, but can give you info about the network traffic, check https://bytefreaks.net/gnulinux/how-to-capture-all-network-traffic-of-a-single-process

strace -f -e trace=network -s 10000 <PROCESS WITH ARGUMENTS>;

If the process is already started and you know its PID you can use the following 1

strace -f -e trace=network -s 10000 -p <PID>;

Another alternative is more complex, using network namespaces, check the above link or use the tool nsntrace, but either can only work on new process, you can not change existent process network namespaces (AFAIK)

UPDATE: you can also install the tool bpfcc-tools (search for your distro, many have it included already) and use the command sudo tcptracer-bpfcc -v -p (PID) While this will not show the packets, it will list network connections for that pid. You can remove the -p (PID) to list all connections per process. This may be useful for those tracking short live connections, not the network payload.

Gayla answered 8/3, 2019 at 20:43 Comment(4)
You can move process to another chroupJudicator
@Judicator any reference how to do that is always usefulGayla
kernel.org/doc/html/v4.18/admin-guide/cgroup-v2.html A process can be migrated into a cgroup by writing its PID to the target cgroup’s “cgroup.procs” fileJudicator
Another link that explains practical commands to manipulate cgroup v2 kernel.org/doc/html/v5.9/admin-guide/cgroup-v1/…Judicator
W
3

In my case I wanted to capture syslog traffic but only from rsyslog. It only had one listening port under lsof -p $(pidof rsyslog) and always used that as the source port, so I was able to get the packets using:

tcpdump -i eth0 -A "host 10.0.0.100 and dst port 514 and src port $(lsof -i 4 -a -p `pidof rsyslogd` | grep -Po '(?<=\*:)[0-9]*') and udp"

The grep uses a positive lookbehind assertion to turn the *:portnumber into just the port number.

Woolgathering answered 9/11, 2018 at 0:5 Comment(0)
I
2

I would use lsof -i to get the port numbers associated with the application I want. The code would be like this:

process=firefox
for _port in `lsof -i | grep $process | cut -d' ' -f18 | cut -d: -f2 | cut -d'-' -f1`
do
    port=$_port
    [[ "$_port" == +([a-zA-Z]) ]] && port=`cat /etc/services  | grep '^$_port' | cut -d' ' -f12 | cut -d'/' -f1 | uniq | head -n 1`

    echo "tcpdump -w ${port}.pcap port $port &"
    tcpdump -w ${port}.pcap port $port &
done

Note that the output of the commands might be different on different versions/distributions. Therefore, you'd better check the right fileds are cut before using the script.

Also, this script does not monitor the ports that are opened later. For that, I would consider a more complicated script that checks ports regularly (using something like watch)

And remember to kill all of the tcpdump processes afterwards.

Iconography answered 22/10, 2011 at 8:36 Comment(0)
R
0

https://github.com/comboshreddies/py-strace2pcap

do 
strace -f -yy -xx -ttt -T | ./py-strace2pcap.py record_file.pcap
Rooseveltroost answered 8/3 at 11:53 Comment(0)
M
-4

Tcpdump can tell you the PID/process a packet comes from/to.
Throw '-k NP' in your options.

Version supported: tcpdump version 4.3.0 -- Apple version 56

Menell answered 21/5, 2014 at 8:1 Comment(4)
Question was asked for Linux. There is no such option in Linux's tcpdump which shows the PID info.Slusher
tcpdump 4.9.2 doesn't have -k option neither, on Linux.Enriqueenriqueta
2022 update: tcpdump 4.9.3 (rhel8) still doesn't have -k.Polycotyledon
Is this answer targeting macOS platform?Rathbun

© 2022 - 2024 — McMap. All rights reserved.