私が書いているパケット キャプチャ ユーティリティで問題が発生しています。現在、pcapy を使用してライブ バイトストリームを開き、dpkt を使用してパケットをデコードしています。dpkt.Writer オブジェクトで動作する .pcap ファイルにもパケットを書き込みたいのですが、pcap ファイルに記録されるタイムスタンプは、ライターがパケットを pcap ファイルに書き込んだときのものであり、ネットワーク インターフェイスがまたはカーネルがメッセージを受信しました。
ドキュメントから、書き込み時にライターが使用する ts を提供できることは理解していますが、受信したパケットのヘッダーからそれを抽出する方法がわかりません。ファイルの読み取りからタイムスタンプを出力する方法を示す例から、バイトストリームから受け取ったタプルの最初の値を単純に出力できるように見えますが、そうすると次のエラーが発生します。
TypeError: int() 引数は、「Pkthdr」ではなく、文字列、バイトのようなオブジェクト、または数値でなければなりません
エラーは明らかです。間違いなく Pkthdr オブジェクトでタイムスタンプ属性を見つける必要がありますが、「ヘッダー」を解析する方法を説明するドキュメント/例が pcapy プロジェクトまたは dpkt のいずれにも見つかりません。
ライブ キャプチャに pypcap ライブラリも使用しようとしましたが、出力は同じです。dpkt はまだ python3 を完全にサポートしていない可能性があることを読んだので、python 2.7.5 でも同じコードを試みましたが、どちらのバージョンでも同じ結果になりました
#!/usr/bin/env python3.6
import pcapy
import dpkt
cap = pcapy.open_live("eth0", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
(header,packet) = cap.next()
writer.writepkt(packet, header)
print('packet printed')
pcap のタイムスタンプが書き込み時のものであることを証明するために、同じパケットを再度書き込む前にスリープ期間を追加しました。2 つのヘッダーのタイムスタンプに約 1 秒の差があることがわかります。
#!/usr/bin/env python3.6
import pcapy
import dpkt
import time
cap = pcapy.open_live("em2", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
(header,packet) = cap.next()
writer.writepkt(packet, )
time.sleep(1)
writer.writepkt(packet, )
print('packet printed')
私は pcapy にも dpkt にもあまり依存していないので、より良い方法があればこれらのライブラリのいずれかを切り替えても構わないと思っていますが、もう少し経験のある人が掘り下げる方法を教えてくれるのではないかと感じています。 Pkthdr オブジェクト、タイムスタンプを str として抽出し、pcap への書き込み時に「ts」引数として挿入します。
ts = %unpack from header%
writer.writepkt(packet, ts)
編集: pcapy モジュールの pkthdr オブジェクトのソース コードを調べたところ、便利なものが見つかりました: オブジェクトからタイムスタンプを取得するための「getts」という関数があるようです:
static PyMethodDef p_methods[] = {
{"getts", (PyCFunction) p_getts, METH_VARARGS, "get timestamp tuple
(seconds, microseconds) since the Epoch"},
{"getcaplen", (PyCFunction) p_getcaplen, METH_VARARGS, "returns the length
of portion present"},
{"getlen", (PyCFunction) p_getlen, METH_VARARGS, "returns the length of
the packet (off wire)"},
{NULL, NULL} /* sentinel */
};
私のpythonコードでは、次のように関数を呼び出しました:
timestamp = header.getts()
そして、ヘッダーの秒とマイクロ秒を含むタプルを返しました (例: (1555710256, 942645))。次のステップは、これを単一の数値に連結し、dpkt ライター ts に入力することです。うまくいけばすぐに実際の例を投稿します