Search code examples
pythonraspberry-piscapysystemd

Using scapy sniff on reboot in Raspberrypi (Systemd)


TL;DR: Why does Scapy's sniff not run at reboots from systemd?

I have the following code running on my RPI3 that specifically looks for network requests. This uses the inbuilt ETH0 wifi:

monitorConnections.py

def arp_detect(pkt):

    print("Starting ARP detect")
    logging.debug('Starting ARP detect')

    if pkt.haslayer(ARP):


        if pkt[ARP].op == 1: #network request
            PHONE_name = "Unknown"
            PHONE_mac_address = ""

            if pkt[ARP].hwsrc in known_devices.keys():
                print ("Known Phone Detected")
                logging.debug('Known Phone Detected')

                # Grab name and mac address
                PHONE_mac_address = pkt[ARP].hwsrc
                PHONE_name = known_devices[PHONE_mac_address]

                print ('Hello ' + PHONE_name)
                logging.debug('Hello ' + PHONE_name)

            else:
                # Grab mac address, log these locally

                print ("Unknown Phone Detected")
                logging.debug('Unknown Phone Detected')

                PHONE_mac_address = pkt[ARP].hwsrc

        print (pkt[ARP].hwsrc)

print("Start!")
print (sniff(prn=arp_detect, filter="arp", store=0))

When I run this via the command

python2 monitorConnections.py

This runs as designed, however I have been trying to put this in a daemon, conscious that it needs to run after the internet connection has been established. I have the following setting in my service:

MonitorConnections.service

[Unit]
Description=Monitor Connections
Wants=network-online.target
After=network.target network-online.target sys-subsystem-net-devices-wlan0.device sys-subsystem-net-devices-eth0.device

[Service]
Type=simple
ExecStart=/usr/bin/python2 -u monitorConnections.py
ExecStop=pkill -9 /usr/bin/autossh
WorkingDirectory=/home/pi/Shared/MonitorPhones
Restart=always
User=root

StandardOutput=console
StandardError=console

[Install]
WantedBy=multi-user.target

In order to find the services that I need my script to run after, I ran this command:

systemctl list-units --no-pager

To find the following services to add to my service under 'After' - these corresspond with the ethernet services (I imagine!)

sys-subsystem-net-devices-wlan0.device
sys-subsystem-net-devices-eth0.device

As far as I can tell, this is running successfully. When I save everything and run the following:

sudo systemctl daemon-reload
sudo systemctl restart monitorConnections

This kickstarts the script beautifully. I have then set my script to run at reboot like so:

sudo systemctl enable monitorConnections

And reboot, I can see that it runs the print statement "Start", however then does not seem to run anything within the 'sniff' command, however when running

sudo systemctl -l status monitorConnections

I can see that the script is active - so it has not errored!

My question: Why is it that scapy's sniff does not seem to run at reboot? Have I missed something out

I'm honestly at the end of my wits as to what is wrong - any help about this would be greatly appreciated!


Solution

  • RPI3's wifi driver does not have monitoring mode. After weeks of debugging, this was narrowed down to be the issue. I hope this helps someone else.