commit 6981889ea0bd03f59c44b75f237b077ab06eee85 Author: Markus Koch Date: Sat Aug 21 21:51:57 2021 +0200 Initial commit diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..750e80a --- /dev/null +++ b/README.MD @@ -0,0 +1,11 @@ +# Ethernet over TCP over UART + +Scripts to forward an Ethernet interface (in Linux) over TCP and / or UART. + +These are terribly dirty scripts and don't work in all situations. Right now, only standard Ethernet frames are supported. Will add support for larger frames later. + +Still, might be useful as a proof of concept or something. + +## License + +Released into the Public Domain without any restrictions. diff --git a/eth_tcp.py b/eth_tcp.py new file mode 100755 index 0000000..8d9102d --- /dev/null +++ b/eth_tcp.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python + +import sys +import socket +import threading +import socket +import time +import os + +class MacDevReceiver(threading.Thread): + def __init__(self, macdev, ipdev): + self.macdev = macdev + self.ipdev = ipdev + threading.Thread.__init__(self) + + def run(self): + while True: + r=self.macdev.recv(2000) + sys.stdout.write("[TCP] TX %d bytes.\n"%len(r)) + self.ipdev.sendall(r) + +class IpDevReceiver(threading.Thread): + def __init__(self, macdev, ipdev): + self.macdev = macdev + self.ipdev = ipdev + threading.Thread.__init__(self) + + def run(self): + while True: + r = self.ipdev.recv(10000) + if (len(r) <= 1518): + sys.stdout.write("[MAC] TX %d bytes.\n"%len(r)) + self.macdev.send(r) + else: + sys.stdout.write("[MAC] Dropping %d bytes long frame.\n"%len(r)) + + +mode = sys.argv[1] +dev = sys.argv[2] +port = int(sys.argv[3]) + +print("Setting IF to promisc mode...") +os.system("sudo ip link set promisc on dev {}".format(dev)) + +ETH_P_ALL=3 +m=socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL)) +m.bind((dev, 0)) + +# TODO: IP Frames w/ MTU > 1500 +# i = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) +# i.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, True) +# i.send(ip payload) + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +if (mode == "s"): + s.bind(('localhost', port)) + s.listen(1) + print("Waiting for TCP connection on port {}...".format(port)) + conn, addr = s.accept() +else: + s.connect(("localhost", port)) + conn = s + +print("Forwarding data...") + +macdev_r = MacDevReceiver(m, conn) +macdev_r.start() +macdev_s = IpDevReceiver(m, conn) +macdev_s.start() + +while True: + time.sleep(1) diff --git a/tcp_uart.py b/tcp_uart.py new file mode 100755 index 0000000..ea727a2 --- /dev/null +++ b/tcp_uart.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +import socket +import serial +import threading +import sys +import time + +class IpDevReceiver(threading.Thread): + def __init__(self, serdev, ipdev): + self.serdev = serdev + self.ipdev = ipdev + threading.Thread.__init__(self) + + def run(self): + while True: + r = self.ipdev.recv(10000) + +class IpDevReceiver(threading.Thread): + def __init__(self, ipdev, serdev): + self.serdev = serdev + self.ipdev = ipdev + threading.Thread.__init__(self) + + def run(self): + while True: + r = self.ipdev.recv(10000) + l = len(r) + print("[TCP ] RX Frame") + ser.write(l.to_bytes(2, byteorder='little')) + ser.write(r) + +class SerDevReceiver(threading.Thread): + def __init__(self, ipdev, serdev): + self.serdev = serdev + self.ipdev = ipdev + self.buf = [] + self.exp = 0 + threading.Thread.__init__(self) + + def run(self): + while True: + r = self.serdev.read(1) + if (len(r) <= 0): + print(".") + continue + self.buf += r + #print("RX {} bytes. Buffer at {}.".format(len(r), len(self.buf))) + while True: + if (self.exp > 0): + if (len(self.buf) >= self.exp): + print("[UART] Frame RX complete ({} bytes)".format(self.exp)) + self.ipdev.sendall(bytes(self.buf[:self.exp])) + self.buf = self.buf[self.exp:] + self.exp = 0 + else: + #print("Data frame incomplete") + break + elif len(self.buf) >= 2: + self.exp = self.buf[0] + (self.buf[1] << 8) + self.buf = self.buf[2:] + print("[UART] Frame start. Expecting {} bytes".format(self.exp)) + else: + #print("Header still incomplete") + break + + +mode = sys.argv[1] +dev = sys.argv[2] +port = int(sys.argv[3]) + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +if (mode == "s"): + s.bind(('localhost', port)) + s.listen(1) + print("Waiting for TCP connection on port {}...".format(port)) + conn, addr = s.accept() +else: + s.connect(("localhost", port)) + conn = s + +print("Forwarding data...") + +ser = serial.Serial(dev, 1000000, timeout=1) + +serdev_r = SerDevReceiver(conn, ser) +serdev_r.start() +serdev_s = IpDevReceiver(conn, ser) +serdev_s.start() + +while True: + time.sleep(1)