phaethon / kamene

Network packet and pcap file crafting/sniffing/manipulation/visualization security tool. Originally forked from scapy in 2015 and providing python3 compatibility since then.
GNU General Public License v2.0
864 stars 192 forks source link

Feature Request: allow sniff to check a stop flag in order to terminate sniff programmatically #126

Open thediveo opened 7 years ago

thediveo commented 7 years ago

The sniff function in Scapy for Python 2 supports the parameters stopper= and stopperTimeout (see also https://bitbucket.org/secdev/scapy/wiki/contrib/code/PatchSelectStopperTimeout), which allow the sniff to be terminated programmatically at (almost) any time on demand, even without any captured packet callbacks.

The current sniff() only supports a timeout or ending the capture after a packet has been captured and a callback indicated termination. It is not possible to end sniffing while sniff() is idly waiting.

Using a sniff() in a loop with a short timeout results in much overhead, as the packet capture is constantly started and stopped again. In contrast, stopper= and stopperTimeout= would avoid such repeated overhead, as sniff could check for termination on a constant basis.

SkypLabs commented 6 years ago

Actually, Scapy from SecDev (which supports Python 3 now) doesn't have the parameters stopper and stopperTimeout for the sniff function. The page from the wiki you mentioned in your issue is the description of a patch which has not been implemented. See this issue for further detail.

thediveo commented 6 years ago

Ah, the suggested super-socked code looks very easy and promising. I didn't know it could be like that, thanks for answering my issue even after so long a time!

SkypLabs commented 6 years ago

Actually @TheDiveO, I was looking for a solution to this issue too and I stumbled upon this thread :)

I just published a blog post about a way to address this issue: http://blog.skyplabs.net/2018/03/01/python-sniffing-inside-a-thread-with-scapy/. I hope it will help you.

thediveo commented 6 years ago

@SkypLabs your proposed solution isn't actually addressing my original issue/question: how to properly shut down a sniffing without having to wait for network traffic to be caught. In fact, your proposed solution is exactly what I want to avoid. Especially when deploying BPF there won't be much network activity, so a stop filter will be pretty useless.

However, the issue you linked to in your older post correctly addresses my concern: by creating a SuperSocket, then select.select(..., timeout) on it, which now allows me to check my stop event in a regular interval, even if there is no traffic reaching user space. And that's a clean method, because the thread shuts down itself cleanly, including its resources; compare that to your proposed solution where you even have to remember to clean up the SuperSocket from the main thread that kills the sniffer thread.

Maybe you want to reconsider your proposed solution?

SkypLabs commented 6 years ago

@SkypLabs your proposed solution isn't actually addressing my original issue/question: how to properly shut down a sniffing without having to wait for network traffic to be caught.

I don't see why my solution doesn't address your issue. It allows to stop the sniffing loop programmatically at any time which is what you looked for.

Especially when deploying BPF there won't be much network activity, so a stop filter will be pretty useless.

As said above, you can stop the sniffing loop programmatically at any time with my method. The use of the stop filter is here only to give a chance to the sniffing loop to stop by itself before the timeout.

However, the issue you linked to in your older post correctly addresses my concern: by creating a SuperSocket, then select.select(..., timeout) on it, which now allows me to check my stop event in a regular interval, even if there is no traffic reaching user space.

Using a SuperSocket with a timeout works fine but this method is resource-consuming since you have to check every X seconds if the sniffing loop should be stopped or not.

And that's a clean method, because the thread shuts down itself cleanly, including its resources; compare that to your proposed solution where you even have to remember to clean up the SuperSocket from the main thread that kills the sniffer thread.

It doesn't change anything to let the sniffing loop stop by itself or to force-stop it as we properly close the socket in the end, which is the only resource used by the sniff(...) function. Of course, it's important not to forget to close it, but you can easily do it through the use of a function or a dedicated class which would contain the whole logic of the solution as you should have done it with your SuperSocket. Software architecture was not the purpose of my blog post hence I closed the socket from the main thread in my example.