.pcapファイルについてちょっと調べた
パケットキャプチャではおなじみのpcapファイルについて、調べたのでまとめます。
動機
研究室で取り扱っているpcapファイルを管理するためにpcapパーサーを作ろうと思った。
そのためにpcapファイルの構造を調べたが、知りたい情報のある日本語の解説が見つからなかったので調べてまとめた。
pcapファイルの構造
HTTPパケットの入力の概要
上記ページはHitachiのuCosminexus Stream Data Platform - Application Framework システム構築・運用ガイドである。pcapファイルの構造についてはこちらに書かれてたので参考になった。
図を見た方が早いが、
- Pcapファイル自体のファイルヘッダ(24バイト)
- キャプチャしたパケット
- キャプチャしたパケットのヘッダ(16バイト)
- キャプチャしたパケットのデータ(可変長)
という構造になっているようだ。
Pcapファイル自体のファイルヘッダの構造
Development/LibpcapFileFormat - The Wireshark Wiki
上記のページによると、Pcapファイルのヘッダは下記のようになっているとのこと。
typedef struct pcap_hdr_s { guint32 magic_number; /* magic number */ guint16 version_major; /* major version number */ guint16 version_minor; /* minor version number */ gint32 thiszone; /* GMT to local correction */ guint32 sigfigs; /* accuracy of timestamps */ guint32 snaplen; /* max length of captured packets, in octets */ guint32 network; /* data link type */ } pcap_hdr_t;
それぞれについての説明を見ていくと、
magic_number
ファイルの種類を識別する際に用いる。4バイト。
version_major
ファイルフォーマットのメジャーバージョン(ver:x.yのxの方)。2バイト。
version_minor
ファイルフォーマットのマイナーバージョン(ver:x.yのyの方)。2バイト。
sigfigs
キャプチャしたパケットのタイムゾーンの精度?らしい。基本的に値は0になるとのこと。4バイト。
snaplen
"snapshot length"の略で、パケットのキャプチャサイズを制限するために用いるもの?らしい。通常は65535もしくはそれ以上とのこと。4バイト。
network
リンク層の種類。
www.tcpdump.org
上記のサイトに書かれている数値が入るらしい。Ethernetの場合、値は1になる。4バイト。
パケットのヘッダの構造
同じページを参照した。下記のような構造になっているとのこと。
typedef struct pcaprec_hdr_s { guint32 ts_sec; / *タイムスタンプ秒* / guint32 ts_usec; / *タイムスタンプマイクロ秒* / guint32 incl_len; / *ファイルに保存されたパケットのオクテット数* / guint32 orig_len; / *パケットの実際の長さ* / } pcaprec_hdr_t;
ts_usec
パケットがキャプチャされた時間のマイクロ秒にあたる部分。4バイト。
incl_len
キャプチャした際に、実際に「保存された」パケットデータのバイト数
orig_len
キャプチャした際に、実際に「観測された」パケットデータのバイト数
パケットのデータの構造
incl_lenの長さで実際のパケットがそのまま現れる。
構造を確認してみる
SampleCaptures - The Wireshark Wiki
上記Wiresharkのwikiから"http.pcap"をダウンロードし、Wiresharkとバイナリエディタで開いて確認してみた。
pcap_hdr_s
magic_number
値は、
0xA1B2C3D4
D4 C3 B2 A1でググると、
File Signature Database:: D4C3B2A1 File Signatures
からwinpcapのキャプチャファイルだとわかります。
version_major,version_minor
それぞれ、
0x0002
0x0004
となっているので、バージョンは2.4だとわかる。
上記に挙げたWiresharkのページでも
"the commonly used format in its current version 2.4. This format version hasn't changed for quite a while (at least since libpcap 0.4 in 1998),"
と書いてあり、1998年からずっとバージョンは2.4の模様。
thiszone
0x0
sigfigs
0x0
snaplen
0xFFFF
10進数に直すと65535なので、通常の値だとわかる。
network
0x0001
Ethernetを示している模様
pcaprec_hdr_t
ts_sec
0x40A34B23
10進数に直すと1084443427である。下記のサイトでUnix時間からJSTに変換したところ、西暦2004年 3月 13日 19時 17分 7秒だとわかる。UNIXタイムスタンプ変換ツール
Wiresharkで表示されている時刻と一致していることがわかる。
ts_usec
0x0004BFB8
10進数に直すと311224である。マイクロ秒と一致していることがわかる。
incl_len,orig_len
両方とも0x3Eで、10進数に直すと62
以降の62バイトとWiresharkで表示されているパケット本体が一致していることが確認できた。