プログラミングでメシが食えるか!?

パケットキャプチャのファイルフォーマット

»

マニアックな話題ですが、tcpdump,wiresharkなどのパケットキャプチャで扱うPCAP形式のファイルの説明でも書いてみましょう。たまたまちょっと調べましたので。意外と解説が見あたらないものです。。

まず、ファイルの先頭にヘッダ情報があります。

#define TCPDUMP_MAGIC 0xa1b2c3d4
#define PCAP_VERSION_MAJOR   2
#define PCAP_VERSION_MINOR   4
#define DLT_EN10MB      1       /* Ethernet (10Mb) */

struct pcap_file_header {
    uint32_t magic;
    uint16_t version_major;
    uint16_t version_minor;
    int32_t thiszone;
    uint32_t sigfigs;
    uint32_t snaplen;
    uint32_t linktype;
};

magic:TCPDUMP_MAGIC
version_major:PCAP_VERSION_MAJOR
version_minor:PCAP_VERSION_MINOR
thiszone:timezone
snaplen:2048とか書き込む予定の最大サイズを入れておけば良いのかな?
sigfigs:0
linktype:DLT_EN10MB

イーサネットなら、こんな感じの値をセットすれば良さそうです。

その後はパケットデータが続くだけなのですが、パケット1つごとにヘッダがつきます。サイズと時刻ですね。

struct pcap_pkthdr {
        struct timeval ts; /* タイムスタンプ */
        uint32_t caplen; /* 得られたパケットの長さ */
        uint32_t len; /* 元々のパケットの長さ */
}ph;

ts:gettimeofday()すればOK
caplen,lenはパケットのサイズを指定すればOKみたい

このヘッダをつけて生のパケットデータを書けばOKです。

※間違えていたら是非ご指摘くださいませ!

PCAP形式のファイルは、普通はlibpcapを使って扱うのだと思いますが、自分で直接読み書きしたくなったもので、調べてみました。非常にシンプルなファイルなので、単純にパケットの量+ヘッダのサイズ分のファイルになり、全パケットをキャプチャすると結構巨大なファイルになります。

今日はとても技術的な話題でした!

Comment(3)

コメント

参考になりました。ありがとうございます。

大野さま、コメントありがとうございます。
いくつかのフィールドが、本当にそんなデータで良いのか怪しいのですが、、とりあえずWiresharkなどでそれらしく表示されています。。

pcap_pkthdrのstruct timevalは64ビット環境でビルドするとデータサイズが変わってしまい、使えないことに気がつきました。
下記のように、32ビット整数を使うようにしましょう。。

struct pcap_pkthdr {
uint32_t ts_sec; /* タイムスタンプ(s) */
uint32_t ts_usec; /* タイムスタンプ(us) */
uint32_t caplen; /* 得られたパケットの長さ */
uint32_t len; /* 元々のパケットの長さ */
};

コメントを投稿する