ether2any/tunnel/rfc1149/rfc1149.py

149 lines
4.4 KiB
Python
Executable File

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2011 Sebastian Lohff <seba@seba-geek.de>
# Licensed under GPL v3 or later
import pyudev
import subprocess
import scapy
from scapy.all import IP
import sys
import tempfile
import threading
from zlib import crc32
from conf import Conf
sys.path.append("../../../")
from ether2any import Ether2Any
class UdevReader(threading.Thread):
def __init__(self, dev):
threading.Thread.__init__(self)
self.daemon = True
self.context = pyudev.Context()
self.dev = dev
self.mountpoint = Conf.get("mountpoint")
self.attrs = Conf.get("udevAttrs")
def isUsableDevice(self, device):
for k, v in self.attrs.items():
try:
if not device[k] == v:
print device[k]
return False
except KeyError:
return False
return True
def readPacket(self):
print " ** Decoding packet"
p = subprocess.Popen("find %s -iname '*jpg' -printf '%%C@ %%p\n'|sort -n|tail -n 1|awk {'print $2'}" % (self.mountpoint,), shell=True, stdout=subprocess.PIPE)
if p.wait() != 0:
return False
imgName = p.stdout.read().strip()
if imgName == "":
print " !! Error: No suitable image found"
return False
print " ++ Using image %s" % imgName
print " ++ Attempting convert + tesseract decoding"
imgFile, txtFile = tempfile.mktemp(suffix=".tif"), tempfile.mktemp()
p = subprocess.Popen("convert %(input)s -colorspace Gray -white-threshold 45%% %(tmpImg)s ; tesseract %(tmpImg)s %(output)s nobatch tessconf/hex" % {'input': imgName, 'tmpImg': imgFile, 'output': txtFile}, shell=True)
if p.wait() != 0:
print " !! Error executing convert/tesseract command"
return False
output = None
try:
outFile = open(txtFile + ".txt", "r")
output = outFile.read()
outFile.close()
except IOError:
print " !! Could not open tesseract output file"
return False
output = output.replace("\n", "").replace(" ", "")
if len(output) % 2 != 0:
print " !! Output of tesseract is not byte aligned"
return False
if len(output) < 10:
print " !! Output of tesseract is not long enough"
return False
packet = "".join(map(lambda x: chr(int(output[x:x+2], 16)), xrange(0, len(output[0:-8]), 2)))
checksum = int(output[-8:], 16)
calcedChecksum = crc32(packet) & 0xffffffff
if checksum != calcedChecksum:
print " !! Checksum failed (was 0x%08x, should be 0x%08x)" % (checksum, calcedChecksum)
return False
self.dev.write(packet)
return True
def run(self):
monitor = pyudev.Monitor.from_netlink(self.context)
monitor.filter_by(subsystem='block')
for action, device in monitor:
if self.isUsableDevice(device):
self.devname = device['DEVNAME']
if action == 'add':
print ["/bin/mount", self.devname, self.mountpoint]
p = subprocess.Popen(["/bin/mount", self.devname, self.mountpoint])
ret = p.wait()
if ret == 0:
print " ++ Mounted camera/card (%s) at %s" % (self.devname, self.mountpoint)
if self.readPacket():
print " >> Successfully read packet"
else:
print " !! Error reading packet"
print " ** Releasing camera/card (%s)..." % (self.devname,)
subprocess.Popen(["/bin/umount", "-f", self.devname])
subprocess.Popen("/bin/sync")
print " ** Unmounted"
else:
print " !! Error mounting stick (%s) at %s: Error id %d" % (self.devname, self.mountpoint, ret)
elif action == 'remove':
print " -- Camera/card (%s) removed." % self.devname
class RFC1149(Ether2Any):
def __init__(self):
Ether2Any.__init__(self, tap=False)
network = Conf.get("network", {'mtu': 1500})
self.dev.ifconfig(**network)
self.dev.up()
self.reader = UdevReader(self.dev)
self.reader.start()
def toPrinter(self, packet):
packet = packet.upper()
print packet
def sendToNet(self, packet):
print "packet", repr(packet)
scp = IP(packet)
checksum = crc32(packet) & 0xffffffff
checksumStr = "%08x" % checksum
hexRepr = " ".join(map(lambda x: "%02x" % ord(x), packet[4:])) + " " + " ".join(map(lambda x: checksumStr[x:x+2], range(0, len(checksumStr), 2)))
print " ?>", scp.summary(), " -- hex len", len(hexRepr), "checksum 0x%08x" % checksum
i = ""
while i.lower() not in ("a", "d"):
i = raw_input(" ?? (A)ccept/(D)rop? ")
if i == "a":
# accept the packet!
print " >> Moved one packet to printer"
self.toPrinter(hexRepr)
self.reader.output(hexRepr.replace(" ", ""))
else:
print " -- Dropped"
if __name__ == '__main__':
rfc1149 = RFC1149()
rfc1149.run()