Initial commit

master
Markus Koch 2021-08-21 21:51:57 +02:00
commit 6981889ea0
3 changed files with 174 additions and 0 deletions

11
README.MD 100644
View File

@ -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.

72
eth_tcp.py 100755
View File

@ -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)

91
tcp_uart.py 100755
View File

@ -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)