Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Info about PID/user/program that's sending/receiving bytes. #170

Open
Jasha10 opened this issue May 2, 2023 · 12 comments
Assignees
Labels
enhancement New feature, request, or improvement

Comments

@Jasha10
Copy link

Jasha10 commented May 2, 2023

Is your feature request related to a problem? Please describe.
Information on what PID/user/program is responsible for each connection

Describe the solution you'd like
In the list of connections, it would be nice to see what local program is responsible for the bytes sent/received.

Additional context
The program nethogs implements this functionality: it displays a PID/username/program next to information about bytes sent/received.

Is this something that could be implemented for sniffnet?

@GyulyVGC
Copy link
Owner

GyulyVGC commented May 3, 2023

Hi @Jasha10, thanks for this suggestion.
It's definitely something that I'd like to do!

Currently I'm working to introduce some major changes which will be released in the next month or so (v1.2).

I had in mind to try adding PIDs in v1.3.
It's not so straightforward since it's a platform-dependent feature, but I'll try to give it a go.

EDIT: the implementation of PIDs identification is shifting because I'm giving precedence to other features, as described in the project roadmap.

@GyulyVGC GyulyVGC added the enhancement New feature, request, or improvement label May 3, 2023
@GyulyVGC GyulyVGC added this to the v1.3.0 milestone May 3, 2023
@XOR-op
Copy link

XOR-op commented May 28, 2023

Hi @GyulyVGC, finding PID of connections for cross-platform application is challenging, so I want to share my experiences.

The nethogs' behavior heavily relies on /proc and Linux only, so I don't think you should go to reference it. Instead, there is a cross-platform finding-process Go implementation from Clash, including all platforms sniffnet supports. And here is my implementation from BoltConn written in Rust, but only for MacOS and Linux.

Specifically, to find PID for a connection on MacOS, we must use undocumented APIs and perform a weird parsing on a big chunk of raw bytes (I still don't know why but it just works). Also, the performance overhead is another factor you should consider. With my implementation, a PID lookup on Linux takes 6000-8000us, while 300-400us on MacOS.

Hope my experiences could help you implement this feature in sniffnet.

@GyulyVGC
Copy link
Owner

Thank you very much @XOR-op
Some month ago I started trying getting PIDs on MacOS and then gave up.
In particular, what I wanted to retrieve are not just PIDs but also process names.
I thought that using sudo lsof -i -P | grep LISTEN | grep :$PORT could be a good starting point to see if I could get something interesting, but it doesn't output what I expected (i.e. all the active sockets).

What I'd like to achieve is to get, for a given connection, the name of the process responsible for it, such that shown by the Activity Monitor native app for macOS.

I'm not too worried about the performance overhead though, since I'm already using dedicated secondary threads to perform rDNS lookups.
The performance overhead could become a problem if we should re-check the process multiple times for a given socket though, if it can change over time (?)

@XOR-op
Copy link

XOR-op commented May 28, 2023

Yes, my implementation supports getting pid, process name, executable path and cmdline of a process by a local port, either TCP or UDP. So it should satisfy your need.

As for the re-check, I don't think we need to re-check a port until its related socket is closed. But I didn't dive into sniffnet's code much. So if sniffnet doesn't hijack a connection, instead just monitor it externally (e.g. scan all opened ports but don't interfere them), it'd be better regularly perform the check.

@GyulyVGC
Copy link
Owner

Sniffnet monitors without interfering and do that not for all the opened ports but those observed (with some packets incoming/outgoing) during the time of the ongoing analysis.

Thank you very much for your suggestions, I may come back to you when I'll be working on the next major release 🙌

@GyulyVGC GyulyVGC self-assigned this Jun 27, 2023
@thewh1teagle
Copy link

thewh1teagle commented Jul 14, 2023

@XOR-op
Do you have implementation I can see?
I tried to implement something like that using combination of netstat
process_sniffer
it's working but it has bad performance and it's not reliable (I think it doesn't catch all the packets)

@GyulyVGC GyulyVGC removed this from the v1.3.0 milestone Aug 23, 2023
@elesiuta
Copy link

process_sniffer it's working but it has bad performance and it's not reliable (I think it doesn't catch all the packets)

Neat, this is similar to a very early prototype of picosnitch where I also used scapy and psutil!

It also hit a wall in terms of performance and reliability, after which I switched to focusing on just Linux and used eBPF instead. This greatly improved things and all the BPF code is at the bottom of the single source file if you're interested in it.

Also, unlike Little Snitch which it's named after, picosnitch is not a firewall and literally just snitches on programs without interfering.

@GyulyVGC
Copy link
Owner

GyulyVGC commented Sep 9, 2023

Further considerations from #370 by @snooppr:

To understand which utility is driving traffic, you have to run the cli with commands, for example, as in the screenshot (lsof -i | grep part of the IP address). How realistic is it to implement this in Sniffnet software?

Без имени In this case, the network activity is created by the Signal software, but I learned about this from the CLI, not from Sniffnet

Rationale: All operating systems have GUI software that displays network activity and the application that creates it, with GNU/Linux problems.

Here is an example of a software utility from Nirsoft that contains less than 300Kb (It is clear and obvious what kind of software creates and drives traffic in Windows OS.).: 111 tcplogview-x64

2 networktrafficview-x64

@thewh1teagle
Copy link

thewh1teagle commented Sep 9, 2023

process_sniffer it's working but it has bad performance and it's not reliable (I think it doesn't catch all the packets)

Neat, this is similar to a very early prototype of picosnitch where I also used scapy and psutil!

It also hit a wall in terms of performance and reliability, after which I switched to focusing on just Linux and used eBPF instead. This greatly improved things and all the BPF code is at the bottom of the single source file if you're interested in it.

Also, unlike Little Snitch which it's named after, picosnitch is not a firewall and literally just snitches on programs without interfering.

eBPF is great for that task. I wonder if Windows had similar ability to wrap recv / send.
It will be very interesting to have that feature in windows

@GyulyVGC
Copy link
Owner

GyulyVGC commented Mar 6, 2024

And here is my implementation from BoltConn written in Rust, but only for MacOS and Linux.

Specifically, to find PID for a connection on MacOS, we must use undocumented APIs and perform a weird parsing on a big chunk of raw bytes (I still don't know why but it just works).

Hey @XOR-op I'm currently working on a library to retrieve PID, process name, and socket used by active processes.

I was wondering if by chance your macOS implementation also works fine on other BSD systems (FreeBSD, NetBSD, OpenBSD), since they seem to not have a proc file system and how they implement it is poorly documented...

@XOR-op
Copy link

XOR-op commented Mar 6, 2024

Hey @GyulyVGC, it may be difficult to directly use the macOS implementation on other BSD systems. However, you could have a look at the freebsd_amd64 implementation from Clash which is written in Go. I did not test this implementation and was uncertain whether this would work. Another approach I suggest is to use CLI tools like ps, netstat for these platforms as a fallback.

@GyulyVGC
Copy link
Owner

And here it is my personal attempt to partially fix this: listeners.

It currently works on macOS, Windows, and Linux.

For the moment only the processes with a TCP socket in LISTEN state are returned, but it could be easily extended to all connection kinds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature, request, or improvement
Projects
None yet
Development

No branches or pull requests

5 participants