Wireshark:UARTによるリモートキャプチャ

Wireshark:UARTによるリモートキャプチャ

簡単に言うと:tcpdumpUARTを介してリモート出力をローカルに正しく送信する方法はwireshark

組み込みデバイスを通過するパケットをキャプチャしようとしていますが、デバイスには何もインストールできません。幸い、シリアルポートでgettyが開き、tcpdumpがインストールされました。残念ながら、SSH、dumpcap、tsharkはありません。

ストレートチューブ形

まず、ttyを構成し、データをワイヤーシャークに接続してみました。

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は、入力が有効なlibpcap形式ではないと文句を言います。もちろん、コマンドがエコーされているので、それを削除できませんでした。

raw PySerialを使う

そのため、パイプラインの動作を制御するためにPythonスクリプトを作成することにしました。

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

スクリプトが正しく終了する方法に関するいくつかの問題を取り除き、これは私が思ったほど良くありませんでした。 Wiresharkはしばらく満足していましたが、すぐに入力が破損し、ロギングが中断されました。私の考えでは、これはホストシステムのttyがまだいくつかの特殊文字(改行やキャリッジリターンなど)を変換しているためだと思います。

愚かな:PySerialによる16進ダンプ

だから私はこれが悪いことを知っていますが、他のアイデアがなかったので、これは私が思いついたものです:

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

残念ながら、以前のバージョンよりも少し長く動作しますが、フレームが少し大きすぎると、Wiresharkはフレームが大きすぎて長さが本当に途方もない(例:-1562980309832)という問題を表示します。録音が停止します。

助けてください! :)

私はtcpdumpオプションを試してみましたが、-s少量でも機能しないことがわかります。

私もピココムのパイプを試してみましたが、役に立ちませんでした。

したがって、アイデアを持っているか動作するUARTトンネリングソフトウェアを持っているか、sttyの(無効な)使用についての意見がある場合、またはPythonスクリプトの改善があれば、とても嬉しいです!

Wiresharkは2.2.5、tcpdumpは4.5.0、libpcapは1.5.0です。

ベストアンサー1

いよいよ実際に動作するようになりました。完璧な設定ではありませんが、少なくとも動作するので、後で誰かに役立つことがあります。

上記のPythonスクリプトを使用しました。pyシリアルポートUARTを介してtcpdumpを起動し、hexdumpを使用すると、バイナリデータはtty転写規則によって変更されずにリンクを通過できます。その後、Pythonスクリプトはデータを再変換してWiresharkにパイプします。以下のスクリプトはその結果ですが、問題のスクリプトと比較して-v同じ行を圧縮しようとしないように hexdump にオプションを追加しました。

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

おすすめ記事