MasaのITC Life

夢は起業家!全てにおいて凡人だけど頑張ることだけはいっちょ前!

やってみた系/その他

PcapとPcapNGのフォーマットの違いを詳しく調査する!

投稿日:2020年2月21日 更新日:



パケットキャプチャのフォーマットである

旧式Pacpと新式PcapNGのフォーマットを

自分の目で調査したのでまとめます。

ちなみに NG は "Next Generation" です。



パケットキャプチャをする際にツールとして、

Wiresharkやtcpdump(WinDump)などを

使う方が多いかと思います。



これらはlibpcapやWinPcap(Npcap)などの

APIから出来ており、Cで実装されています。



libpcapなどを知るにはまずは、

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

PcapとPcapNGについて理解する必要があります。




この記事の前半部分に Pcapのフォーマット

この記事の後半部分にPcapNGのフォーマット

という構成になっています。

それではまずはPcapからです。


Pcapのフォーマット


Pcapは主に3つで構成されています。

  • PCAP Header (24bytes)
  • Packet Header (16bytes)
  • Raw Packet (Any bytes)


この3つの構造はこのようになっています。




最初にPCAPヘッダーがあって、

それ以降はパケットヘッダーと

実際にのキャプチャデータがそれぞれ

1セットとなって繰り返されます。



PCAPヘッダーとパケットヘッダーは

格納されている情報が異なり、

それぞれ24バイトと16バイトの情報が入ります。

次にそれらを見てみましょう。




まずはPACPヘッダーからです。

細かい内容は次のようになっています。


PCAPヘッダー



pcap.hの中身を覗いてみると、

以下のように定義されています。


(構造体のところだけ抜粋)



tcpdump magic : 4バイト


ファイルの一番最初に来るものです。

ネットワークにおいてmagicというと、

何かの識別子を意味します。

以下の値が入ります。

ホストマシンのアーキテクチャによって違います。

"A1 B2 C3 D4" (ビッグエンディアンの場合)

"D4 C3 B2 A1" (リトルエンディアンの場合)

ファイルの先頭にこの値が来ることで

「これはPCAPファイルだ!」

ということが分かります。


余談:

magic で他に有名なものにDHCPがあります。

DHCPとBOOTPのフォーマットは、

ほとんど同じなのでmagicによって見分けます。

"63 82 53 63"がパケット中に入ります。

なおDHCPはネットワークエンディアンなので、

実際はビッグエンディアンです。




major version : 2バイト


フォーマットバージョンが入ります。

一般的に言うバージョン○.△の

○の部分がmajor versionに該当します。




minor verion : 2バイト


フォーマットバージョン○.△の

△の部分が入ります。




time zone : 4バイト


基本的には0x00000000が入ります。




sigfigs : 4バイト


タイムスタンプの精度を示します。

基本的には0x00000000が入ります。




snaplen : 4バイト


キャプチャ可能なパケット最大長です。

基本的には0x0000FFFFが入ります。




link type : 4バイト


データリンク層のタイプです。

Ethernetの場合は0x00000001です。

Wi-Fiで使われるIEEE802.11の場合は、

105つまり0x01111001が入ります。




続いてはPacketヘッダーを見てみましょう。


Packetヘッダー



pcap.hの中身を覗いてみると、

以下のように定義されています。


(構造体のところだけ抜粋)


補足ですがタイムスタンプのところは、
timeval構造体だと上手く動作しないとか。

bpf_u_int32 ts_sec;
bpf_u_int32 ts_usec;

としっかり分けた方がよいとか。



さて、話しを戻しまして・・・



time stamp : 8バイト


8バイトを4バイトづつに分けます。

前4バイトはUNIX時刻形式の値です。

1970年1月1日0時0分0秒から

経過した秒数が入ります。

後ろ4バイトはμ秒を表します。




caplen : 4バイト


ファイルに記録されているパケット長です。




len : 4バイト

実際のパケット長です。

caplenと同じ値が入ることが多いですが、

PCAPヘッダーにある最大長を示す

snaplenよりもキャプチャしたパケットが

大きいと、分割されるので、

上記の2つは違う値を示すことになります。




以上が従来のフォーマットであるPCAPでした。

続いては新しい方のPcapNGフォーマットです。



PcapNGのフォーマット



PCAPよりも機能的になったのがPcapNGです。

キャプチャしたインターフェースの情報など

キャプチャデータ以外にも埋めることが

出来るようになりました。



PCAPは、PCAP Header、Packet Header、

Raw Packet の3種類から構成されていました。



一方、PcapNGでは呼び名が変わり、

"セクション"という単位で構成されています。

.pcapngのファイルを構成するセクションは

1つだけの場合もあれば、複数の場合もあります。



セクションは "ブロック" という単位で

構成されており、各セクションの先頭には、

SHBと呼ばれるセクションヘッダーがいます。



セクションヘッダーの下には、

データに該当する各ブロックが付きます。




ブロックにはセクションヘッダー含め、

6種類あり、それぞれ名前が付いています。

  • SHB : Section Header Block
  • IDB : Interface Description Block
  • EPB : Enhanced Packet Block
  • SPB : Simple Packet Block
  • NRB : Name Resolution Block
  • ISB : Interface Statistics Block



PacpNGはこれらのブロックを

組み合わせて一つのファイルにします。



これらのブロックはそれぞれ、

フォーマットが決まっており、

どういう情報を格納する定義されています。



上から3つだけ覚えておけば、

個人的に大丈夫だと思います。



PcapNGは以下のように定義される

ブロック階層にそって構成されます。



最初の2つの SHBIDB は、

1ファイルに最低1つずつ必要で、

SHBはファイルの先頭に必ず来ます。

お察しの通りSHBはmagicを含みます。



それ以外のEPBSPBNRBISBの4つは

オプションとなっています。




それでは各ブロックについて見てみましょう。

SHB : Section Header Block


フォーマットは次のようになっています。


Block Type :

PcapNGを識別するmagicが入ります。

"0A 0D 0D 0A" によってこのファイルが

PcapNGであることが分かります。

それと同時にこのブロックは、

SHBですよ、ということも意味しています。

このBlock Typeはブロックごとに

決まった値が割り振られており、

それによってどの種のブロックか見分けれます。

ちなみにSHBの magic はシンメトリなので、

リトルもビッグエンディアンも関係なしです。



Block Total Length :


このブロックのサイズが入ります。

SHBの最後にも再び、

Block Total Lengthを詰めます。



Byte-Order Magic :


"1A 2B 3C 4D" が入ります。

リトルエンディアンかビッグエンディアンか

判断するための magic になります。



major version :

Pcapのフォーマットに同じです。



minor version :

Pcapのフォーマットに同じです。



Section Length :

SHBを含めたセクションサイズが入ります。

もしセクションサイズが、

0xFFFFFFFF だった場合は、

セクションサイズ不明記を意味します。



Option :

SHBだけではなく全てのブロックは、

オプションフィールドをもっています。


キャプチャしたパケットを読むのに、

役立つ情報を挿入するためにありますが、

あくまでオプションなので必須ではないです。


全てのブロックに共通して、

オプションフィールド専用の

フォーマットが定義されています。


しかし、もちろん格納する情報は、

ブロックごとで異なります。

記事の最後にオプションフィールドに関する

フォーマットと具体例を記載しました。






PcapNGファイルからSHBだけを抜き取ると、

こんな感じになりました。

Wiresharkでキャプチャしたパケットを

バイナリエディタで開いた画像です。



最初にPcapNGのmagicが来て、

次にブロックサイズの0x000000B4、

そしてByte-order magicを示す

4D 3C 2B 1Aが来ています。
(リトルエンディアンです。)




次は、IDBです。

IDB : Interface Description Block


キャプチャを行ったインタフェースの情報を

格納するためのブロックでPcapNGファイルを

作成するのに必須となっています。

フォーマットは次のようになっています。


Block Type :

IDBは0x00000001が入ります。



Block Total Length :

このブロック(IDB)の全体サイズを入れます。



Link Type :

Pcap同様にキャプチャしたパケットの

データリンク層を示す値が入ります。

例えば、Ethernetなら 1 が、

IEEE802.11なら 105 が入ります。



Reserved :

将来使われる予定で現在は使われていません。



snapLen :

キャプチャ可能な最大バイト数が入ります。

このサイズより大きいパケットは、

別のファイルに分けて保存します。



Option :

省略。




次はEPBです。

EPB : Enhanced Packet Block


キャプチャパケットを保存するために

一番よく使われるブロックです。

フォーマットは次のようになっています。


Block Type :

EHBと認識するために、

このフィールドには 0x00000006 が入ります。



Block Total Length :

SHBに同じです。



Interface ID :

パケットが来たインターフェースを明記します。

もし正しいパケットキャプチャファイルであるならば、

IDBのインターフェースと同じ値が入ります。



Time Stamp (Hign and Low) :

PcapのTime Stampと同じで、

Unix時刻形式に基づいて格納されます。



Captured Len :

Pcapのcaplenに同じです。



Packet Len :

Pcapのlenに同じです。



Packet Data :

パケットキャプチャした生データが入ります。


Option :


省略。




次はSPBです。


SPB : Simple Packet Block


EPBと似ていますが名前から分かる通り、

最小限の情報しか保存しないブロックです。



ここでいう最小限とは、

キャプチャしたデータのことではなく、

EPBにあるインターフェースIDなどの

余分な?情報のことを言います。



フォーマットを見ていただくと分かるのですが、

インターフェースIDがない分、

このブロックからはどのインターフェース(L2層)で

キャプチャしたか分かりません。


したがって、IDB の Link Type で

記されたインターフェースと仮定して

パケットをフォーマット化します。

タイムスタンプもない点も注意です。



感覚的なイメージで言うと、

TCPのEPBに対し、UDPのSPBでしょうか。




フォーマットは次のようになっています。


Block Type :

SPBと認識するために0x0000003が入ります。



あとのフィールドはEPBと同じ意味を持ちます。

EPBと違ってオプションフィールドは持ちません。




次はNRBです。

NRB : Name Resolution Block



NRBはホスト名とアドレスの対応関係を入れます。

基本的にパケットにはアドレスは含まれているが、

ホスト名が含まれておらずDNSによって取得します。



もしPcapNGファイルに、アドレスしか

入っていなかった場合を想定すると、

キャプチャファイルを読んだ人は

ホスト名がないために、

少し不便に思うかもしれません。



そこでをPcapNGファイルを構築する際に、

DNSによって名前を取得し、わざわざ

キャプチャファイルを読む際に、ユーザが

自らDNSしなくても済む仕組みになっています。



つまり時間節約のメリットが得られます。



フォーマットは次のようになっています。


Block Type :

NRBと認識するために、0x00000004が入ります。



その他のフィールドでDNSエントリーにある

アドレスと名前の情報を含めることが出来ます。

また名前解決をしたDNSサーバのIPアドレスも

含めることが出来ます。




最後はISBです。

ISB : Interface Statistics Block


IDBによって記されたインターフェースに関して、

インターフェースのより詳細な情報をセットします。



フォーマットは次のようになっています。


Block Type :

ISBと認識するために0x00000005が入ります。



Block Total LengthやInterface ID、

Time Stampは他のブロックで説明した通りです。



これだけではこのブロックの特徴が分からないので、

このブロックだけはオプションについて触れます。

SHBで述べた通り、オプションフィールドにも

オプションフォーマットがあります。



どのブロックも上記の

オプションフォーマットに従って、

オプションフィールドが埋められます。




ISBのオプションに関しては、

以下の情報が入ります。

Name Code Length Description
isb_starttime 2 8 キャプチャ開始時刻。
isb_endtime 3 8 キャプチャ終了時刻。
isb_ifrecv 4 8 インターフェースが受信したパケット数。
isb_ifdrop 5 8 物理資源の不足によって、インターフェースが捨てたパケット数。
isb_filteraccept 6 8 フィルターを通過したパケット数。
isb_osdrop 7 8 OSが捨てたパケット数。
isb_usrdeliv 8 8 ユーザが配送したパケット数。キャプチャ終了時点では、OSバッファにまだパケットが残っている可能性がある




以上がPcapとPcapNGのフォーマットの違いです。

最後まで読んでいただきありがとうございました。



参考:PcapNG :https://pcapng.com/


-やってみた系/その他

Copyright© MasaのITC Life , 2023 All Rights Reserved Powered by STINGER.