]> andersk Git - routeradvert-scan.git/commitdiff
Initial commit of routeradvert-scan.
authorAnders Kaseorg <andersk@mit.edu>
Sun, 25 Apr 2010 02:27:46 +0000 (22:27 -0400)
committerAnders Kaseorg <andersk@mit.edu>
Sun, 25 Apr 2010 02:30:51 +0000 (22:30 -0400)
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
routeradvert-scan.py [new file with mode: 0755]

diff --git a/routeradvert-scan.py b/routeradvert-scan.py
new file mode 100755 (executable)
index 0000000..c499484
--- /dev/null
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# routeradvert-scan.py: Scan for rogue IPv6 router advertisements.
+#
+# Copyright © 2010 Anders Kaseorg <andersk@mit.edu>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the “Software”), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import errno
+import math
+import os
+import re
+import signal
+import socket
+import subprocess
+import sys
+import time
+
+# configuration
+interface = 'eth1'
+timeout = 30
+zclass = 'andersk-auto'
+zinstance = '6to4'
+zsig = '%s on %s' % (sys.argv[0], socket.gethostname())
+# end configuration
+
+mac_re = re.compile(r'^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$')
+
+seen_macs = {}
+
+def msg(m):
+    os.spawnlp(os.P_WAIT, 'zwrite', 'zwrite', '-q', '-d', '-c', zclass, '-i', zinstance, '-s', zsig, '-m', m)
+
+def check_gone():
+    now = time.time()
+    next = None
+    for (mac, t) in seen_macs.items():
+        if t < now:
+            del seen_macs[mac]
+            msg('Gone 6to4 router: %s\nCurrent 6to4 routers: %s' % (mac, seen_macs.keys()))
+        elif next is None or next > t:
+            next = t
+    if next is None:
+        signal.alarm(0)
+    else:
+        signal.alarm(int(math.ceil(next - now)))
+
+signal.signal(signal.SIGALRM, lambda signum, frame: check_gone())
+
+p = subprocess.Popen(['tcpdump', '-elnp', '-i', interface, 'icmp6 and (ip6[40] = 134)'], stdout=subprocess.PIPE)
+while True:
+    check_gone()
+    while True:
+        try:
+            line = p.stdout.readline()
+        except IOError, (e, s):
+            if e == errno.EINTR:
+                continue
+        break
+    signal.alarm(0)
+    if line == '':
+        break
+    words = line.split()
+    if len(words) >= 2 and mac_re.match(words[1]):
+        mac = words[1]
+        t = time.time() + timeout
+        if mac in seen_macs:
+            seen_macs[mac] = t
+        else:
+            seen_macs[mac] = t
+            msg('New 6to4 router: %s\n%s\nCurrent 6to4 routers: %s' % (mac, line.rstrip('\n'), seen_macs.keys()))
+    else:
+        print >>sys.stderr, 'Unrecognized line: ', line.rstrip('\n')
This page took 0.087271 seconds and 5 git commands to generate.