Kurz zusammengefasst:Wie leitet man die Ausgabe einer Fernbedienung ordnungsgemäß über UART tcpdump
an eine lokale Steuerung weiter wireshark
?
Ich versuche, Pakete zu erfassen, die durch ein eingebettetes Gerät fließen, auf dem ich nichts installieren kann. Glücklicherweise ist ein Getty auf der seriellen Schnittstelle geöffnet und tcpdump installiert. Leider kein SSH, kein Dumpcap, kein Tshark.
Direktleitung
Ich habe zuerst versucht, das TTY zu konfigurieren und die Daten über Pipes an Wireshark zu übergeben.
stty -F /dev/ttyUSB0 raw
stty -F /dev/ttyUSB0 -echo -echoe -echok
cat /dev/ttyUSB0 | wireshark -k -i -
# On another terminal:
echo "tcpdump -U -s0 -i eth0 -w - 2>/dev/null" > /dev/ttyUSB0
Wireshark beschwert sich, dass die Eingabe kein gültiges Libpcap-Format habe, sicherlich weil der Befehl zurückgesendet wird und ich es nicht geschafft habe, das zu beheben.
Verwenden von reinem PySerial
Daher habe ich beschlossen, ein Python-Skript zu erstellen, um die Funktionsweise der Rohrleitungen zu steuern:
import serial
import sys
import subprocess
import fcntl
def main(args):
with serial.Serial('/dev/ttyUSB0', 115200, timeout=0) as ser:
length = ser.write(b"tcpdump -U -s0 -i eth0 -w - 2> /dev/null\n") + 1
# Discard the echoed command line
while length > 0:
discard = ser.read(length)
length -= len(discard)
# Spawn wireshark
wireshark = subprocess.Popen(
["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
)
# Pipe data from serial to wireshark's input
while True:
data = ser.read(256)
wireshark.stdin.write(data)
try:
wireshark.stdin.flush()
except BrokenPipeError as e:
break
if len(data) > 0: print(data)
# Send "Ctrl+C" to tcpdump
ser.write(b"\x03")
wireshark.wait()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Abgesehen von einigen Problemen mit der korrekten Beendigung des Skripts funktionierte dies nicht so gut, wie ich es mir vorgestellt hatte. Wireshark funktioniert eine Zeit lang einwandfrei, aber schon bald wird die Eingabe beschädigt und die Aufzeichnung stoppt. Ich denke, das liegt daran, dass das TTY auf dem Host immer noch einige Sonderzeichen konvertiert, wahrscheinlich den Zeilenvorschub oder den Wagenrücklauf.
Wird langsam dumm: Hexdump über PySerial
Ich weiß, das klingt blöd, aber da mir keine anderen Ideen eingefallen sind, ist mir Folgendes eingefallen:
import serial
import sys
import subprocess
import binascii
def main(args):
with serial.Serial('/dev/ttyUSB0', 115200, timeout=5) as ser:
# Spawn tcpdump on the host and convert the raw output to stupid hex format
# We need hexdump -C because that's the only format that doesn't mess up with the endianess
length = ser.write(b"tcpdump -U -s256 -i eth0 -w - 2> /dev/null | hexdump -C\n")
# Discard command line that is echoed
discard = ser.readline()
# Spawn wireshark
wireshark = subprocess.Popen(
["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
)
while True:
# Process each line separately
data = ser.readline().decode('ascii')
elements = data.split()
# Remove the address and ascii convertion of hexdump and spaces
hexa = "".join(elements[1:17])
# Convert back hex to binary
real_data = binascii.unhexlify(hexa)
# Feed to the shark
wireshark.stdin.write(real_data)
try:
wireshark.stdin.flush()
except BrokenPipeError as e:
break
# Stop tcpdump
ser.write(b"\x03")
wireshark.wait()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
Obwohl es etwas länger funktioniert als die vorherige Version, zeigt Wireshark leider ein Problem an, wenn die Frames etwas zu groß sind und besagt, dass der Frame zu groß ist und eine tatsächlich lächerliche Länge aufweist (wie -1562980309832), und die Aufzeichnung wird erneut gestoppt.
Bitte helfen Sie! :)
-s
Sie können feststellen, dass ich versucht habe, mit der Option „tcpdump“ zu spielen , aber es hat nicht funktioniert, nicht einmal mit geringen Mengen.
Ich habe auch versucht, die Weiterleitung von Picocom zu übernehmen, jedoch ohne Erfolg.
Wenn Sie also eine Idee oder eine funktionierende UART-Tunneling-Software haben, einen Kommentar zu meinem (inkompetenten) Einsatz von stty abgeben oder eine Verbesserung meiner Python-Skripte vorschlagen möchten, würde ich mich sehr freuen!
Wireshark ist 2.2.5, tcpdump ist 4.5.0 mit libpcap 1.5.0.
Antwort1
Endlich habe ich es wirklich zum Laufen gebracht. Das ist nicht das perfekte Setup, aber zumindest funktioniert es, sodass es vielleicht in Zukunft jemandem helfen kann.
Ich habe ein Python-Skript darüber verwendetPySerialum tcpdump über den UART zu starten und hexdump zu verwenden, damit die Binärdaten die Verbindung durchlaufen können, ohne von den TTY-Transkriptionsregeln geändert zu werden. Dann konvertiert das Python-Skript die Daten zurück und leitet sie an Wireshark weiter. Das folgende Skript ist das Ergebnis. Im Vergleich zu dem aus der Frage habe ich die -v
Option zu hexdump hinzugefügt, damit es nicht versucht, gleiche Zeilen zu komprimieren.
import serial
import sys
import subprocess
import binascii
def main(args):
with serial.Serial('/dev/ttyUSB0', 115200, timeout=5) as ser:
# Spawn tcpdump on the host and convert the raw output to stupid hex format
# We need hexdump -C because that's the only format that doesn't mess up with the endianess
length = ser.write(b"tcpdump -U -s256 -i eth0 -w - 2> /dev/null | hexdump -Cv\n")
# Discard command line that is echoed
discard = ser.readline()
# Spawn wireshark
wireshark = subprocess.Popen(
["wireshark", "-k", "-i", "-"], stdin=subprocess.PIPE
)
while True:
# Process each line separately
data = ser.readline().decode('ascii')
elements = data.split()
# Remove the address and ascii convertion of hexdump and spaces
hexa = "".join(elements[1:17])
# Convert back hex to binary
real_data = binascii.unhexlify(hexa)
# Feed to the shark
wireshark.stdin.write(real_data)
try:
wireshark.stdin.flush()
except BrokenPipeError as e:
break
# Stop tcpdump
ser.write(b"\x03")
wireshark.wait()
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))