idofront / PacketBuilder

MIT License
1 stars 0 forks source link

nsec 精度の pcap 形式に対応する #7

Open idofront opened 3 months ago

idofront commented 3 months ago

現在 usec 精度までしか対応していないが,pcap のファイルフォーマットを変更することで nsec 精度に対応する.

idofront commented 3 months ago

以下,ChatGPT の回答を転記


libpcap を使用して nanosecond(ナノ秒)精度でパケットを保存するには、pcap_open_dead_with_tstamp_precision() 関数を使用して、タイムスタンプ精度を指定する必要があります。デフォルトでは、libpcap はマイクロ秒精度(PCAP_TSTAMP_PRECISION_MICRO)を使用しますが、これをナノ秒精度(PCAP_TSTAMP_PRECISION_NANO)に設定することで対応できます。

以下は、nanosec 精度で Ethernet フレームを保存する方法の例です。

#include <pcap.h>

void save_ethernet_frame_with_nanosec_precision(const u_char *frame, int frame_length) {
    pcap_t *pcap_handle;
    pcap_dumper_t *dumper;
    pcap_pkthdr header;

    // 擬似的な pcap ハンドルを作成 (Ethernet, 65535 は最大のスナップレングス, ナノ秒精度)
    pcap_handle = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, 65535, PCAP_TSTAMP_PRECISION_NANO);
    if (pcap_handle == nullptr) {
        fprintf(stderr, "Failed to open pcap handle\n");
        return;
    }

    // ダンプファイルを開く
    dumper = pcap_dump_open(pcap_handle, "output_nanosec.pcap");
    if (dumper == nullptr) {
        fprintf(stderr, "Failed to open dump file: %s\n", pcap_geterr(pcap_handle));
        pcap_close(pcap_handle);
        return;
    }

    // パケットヘッダーの設定(例: 現在の時刻、フレーム長)
    struct timeval tv;
    gettimeofday(&tv, nullptr);
    header.ts.tv_sec = tv.tv_sec;   // 秒部分
    header.ts.tv_usec = tv.tv_usec * 1000; // マイクロ秒をナノ秒に変換

    header.caplen = frame_length;  // キャプチャしたフレームの長さ
    header.len = frame_length;     // 実際のフレームの長さ

    // フレームをダンプファイルに書き込む
    pcap_dump((u_char *)dumper, &header, frame);

    // 終了処理
    pcap_dump_close(dumper);
    pcap_close(pcap_handle);
}

重要なポイント:

これにより、パケットのタイムスタンプがナノ秒精度で保存されるようになります。