]>
git.ipfire.org Git - oddments/cappie.git/blob - cappie/events.py
2 ###############################################################################
5 # Copyright (C) 2010 Michael Tremer #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
26 from constants
import *
30 def __init__(self
, interface
):
31 self
.cappie
= interface
.cappie
32 self
.interface
= interface
33 self
.log
= interface
.log
34 self
.db
= self
.cappie
.db
37 return self
.__class
__.__name
__
39 def addEvent(self
, event
):
40 return self
.cappie
.queue
.add(event
)
43 raise NotImplementedError
46 class EventShell(Event
):
50 def __init__(self
, interface
, script
):
51 Event
.__init
__(self
, interface
)
56 args
= " ".join([self
.script
, self
.interface
.dev
])
59 self
.log
.debug("Running: %s" % args
)
61 p
= subprocess
.Popen(args
,
64 stdin
=open("/dev/null", "r"),
65 stdout
=subprocess
.PIPE
,
66 stderr
=subprocess
.STDOUT
)
68 while p
.poll() is None:
69 time
.sleep(self
.heartbeat
)
70 if (time
.time() - start
) > self
.timeout
:
75 raise EventTimeout
, "Script took too long to return"
77 for line
in p
.stdout
.read().splitlines():
79 self
.log
.debug(" %s" % line
)
81 self
.cappie
.log
.debug("Child process returned with exit code: %s" % \
87 class EventRequestTrigger(Event
):
88 def __init__(self
, interface
, packet
):
89 Event
.__init
__(self
, interface
)
91 self
.db
= interface
.cappie
.db
94 def _updateAddress(self
, mac
, address
):
95 where
= "WHERE mac = '%s' AND address = '%s'" % (mac
, address
)
97 if self
.db
.get("SELECT * FROM addresses %s" % where
):
98 self
.db
.execute("UPDATE addresses SET lastseen='%d' %s" % \
101 self
.db
.execute("INSERT INTO addresses VALUES('%s', '%s', '%d')" % \
102 (mac
, address
, time
.time()))
104 def _updateChanges(self
, *args
):
106 where
= "WHERE address = '%s'" % arg
107 if self
.db
.get("SELECT * FROM changes %s" % where
):
108 self
.db
.execute("UPDATE changes SET lastchange = '%d' %s" % \
109 (time
.time(), where
))
111 self
.db
.execute("INSERT INTO changes VALUES('%s', '%d')" % \
115 mac
= self
.packet
.source_address
116 address
= self
.packet
.source_ip_address
118 self
._updateAddress
(mac
, address
)
119 self
._updateChanges
(mac
, address
)
122 class EventResponseTrigger(EventRequestTrigger
):
126 class EventGarbageCollector(Event
):
127 def __init__(self
, db
, log
):
132 # Remove old addresses
133 self
.db
.execute("DELETE FROM addresses WHERE lastseen >= '%d'" % \
134 (time
.time() - DB_LASTSEEN_MAX
))
139 class EventCheckDuplicate(Event
):
140 def __init__(self
, interface
, packet
):
141 Event
.__init
__(self
, interface
)
145 entries
= self
.db
.query("SELECT * FROM addresses WHERE address = '%s'" % \
146 self
.packet
.source_ip_address
)
151 for entry
in entries
:
152 if self
.packet
.source_address
== entry
.mac
:
153 entries
.remove(entry
)
156 self
.addEvent(EventHandleDuplicate(self
.interface
, self
.packet
))
159 class EventHandleDuplicate(Event
):
160 def __init__(self
, interface
, packet
):
161 Event
.__init
__(self
, interface
)
165 self
.log
.warning("We probably have a mac spoofing for %s" % \
166 self
.packet
.source_address
)
169 class EventCheckFlipFlop(Event
):