Skip to content
This repository has been archived by the owner on Mar 2, 2019. It is now read-only.

Commit

Permalink
backend: generate events on ARP traffic for frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
micolous committed Mar 10, 2013
1 parent bf475f4 commit 21dfd89
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/example/tollgate/backend.ini
Expand Up @@ -55,6 +55,10 @@ ipmacset_prefix = p2m_
; commands it tries to run.
debug = yes

; Should tollgate-backend sniff for ARP traffic on the network and generate
; events for it?
generate_arp_events = yes

[captive]
; Enable support for the captive mode.
enable = yes
Expand Down
49 changes: 47 additions & 2 deletions tollgate/backend/iptables.py
Expand Up @@ -20,8 +20,13 @@
from os.path import exists, join, isfile
from sys import exit
from re import compile as re_compile
import dbus, dbus.service, dbus.glib, glib
import dbus, dbus.service, dbus.glib, glib, sys, gobject
from dbus.mainloop.glib import DBusGMainLoop
from threading import Thread
try:
from scapy import all as scapy
except:
scapy = None

DEBUG = False

Expand Down Expand Up @@ -546,6 +551,30 @@ def ip4pf_add(self, ip, protocol, port, external_port):
'--state', 'NEW',
'-j', 'ACCEPT',
)

@dbus.service.signal(dbus_interface=DBUS_INTERFACE, signature='ss')
def on_arp_packet(self, mac, ip):
pass


class ArpPacketSniffer(object):
def __init__(self, dev, api):
self.dev = dev
self.api = api

def start(self):
#print 'sniffer: start on %r!' % self.dev
# only sniff ARP packets
scapy.sniff(iface=self.dev, prn=self.handle_packet, filter='arp', store=0)

def handle_packet(self, packet):
if scapy.ARP in packet and packet[scapy.ARP].op in (1, 2):
# who-has or is-at
# fire event on api for handling
self.api.on_arp_packet(packet[scapy.ARP].hwsrc, packet[scapy.ARP].psrc)

# source address
#print 'sniffer: src=%r, ip=%r' % (packet[scapy.ARP].hwsrc, packet[scapy.ARP].psrc)


def setup_dbus():
Expand All @@ -555,11 +584,27 @@ def setup_dbus():
return name

def boot_dbus(daemonise, name, pid_file=None):
PortalBackendAPI(name)
# die early if scapy isn't available and arp events are requested
assert (scapy or not GENERATE_ARP_EVENTS), 'scapy must be installed in order to capture arp events.'

api = PortalBackendAPI(name)
loop = glib.MainLoop()
if daemonise:
assert pid_file, 'Running in daemon mode means pid_file must be specified.'
from daemon import daemonize

# parent process drops here, child lives on
daemonize(pid_file)


if GENERATE_ARP_EVENTS:
# fork off a loop to handle arp packets
sniffer = ArpPacketSniffer(str(INTERN_IFACE), api)
# this means it will be called again if it dies
gobject.threads_init()
Thread(target=sniffer.start).start()
#glib.timeout_add(1000, sniffer.start)


loop.run()

7 changes: 4 additions & 3 deletions tollgate/backend/tollgate_backend.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
"""tollgate backend service
Copyright 2008-2012 Michael Farrell <http://micolous.id.au/>
Copyright 2008-2013 Michael Farrell <http://micolous.id.au/>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
Expand Down Expand Up @@ -39,7 +39,8 @@
'limit_rule_prefix': 'p2l_',
'ipset_prefix': 'p2i_',
'ipmacset_prefix': 'p2m_',
'debug': True
'debug': True,
'generate_arp_events': True
},
'captive': {
'enable': True,
Expand Down Expand Up @@ -104,6 +105,7 @@ def main(daemon_enable, pid_file, settings_file=SETTINGS_FILE):
iptables.REJECT_MODE = config.get('tollgate', 'reject_mode')
iptables.REJECT_TCP_RESET = config.getboolean('tollgate', 'reject_reset_tcp')
iptables.DEBUG = config.getboolean('tollgate', 'debug')
iptables.GENERATE_ARP_EVENTS = config.getboolean('tollgate', 'generate_arp_events')

iptables.CAPTIVE_ENABLED = config.getboolean('captive', 'enable')
iptables.CAPTIVE_PORT = config.getint('captive', 'port')
Expand Down Expand Up @@ -153,7 +155,6 @@ def main(daemon_enable, pid_file, settings_file=SETTINGS_FILE):
print "Setting blacklist hosts..."
parse_hostlist(blacklist_hosts, iptables.add_blacklist)


print "Starting DBUS Server (only debug messages will appear now)"
try:
iptables.boot_dbus(daemon_enable, b, pid_file)
Expand Down

0 comments on commit 21dfd89

Please sign in to comment.