はじめに
この記事はMermaidで出力したパケットダイアグラムを使って、PCAPとPCAPNGの違いをまとめた記事です。
(※PCAPやPCAPNGでググってきた人は「Mermaidとは何ぞや」って話だと思うので、末尾の章でMermaidとそのパケットダイアグラムについても少し紹介しています)
PCAP/PCAPNGの違い
細かいパケット構造の話をする前に、超ざっくりPCAP/PCAPNGの違いを見ていきましょう。
PCAPとは
- パケット保存で昔からよく使われている形式だよ
- シンプルなデータ構造でパケット毎のオーバーヘッドが小さいよ
- .pcapや.capの拡張子で保存されてることが多いよ
- 2025年でも現役の現場はあるし、PCAP形式で困ることはそんなにないよ
PCAPデータ構造
- ファイル先頭にグローバルヘッダーがつくよ
- その後ろに「パケットヘッダー+パケット本体」の構造が続いていくよ
PCAPNGとは
- PCAP Next Generationの略で、次世代のパケット保存形式だよ
- ブロック単位のデータ構造でPCAP形式よりも多くの情報を格納できるよ
- タイムスタンプ精度
- パケット毎のNIC
- などなど...
- .pcapngの拡張子で保存されることが多いよ
- 2012年以降のWiresharkでデフォルト出力形式になってるよ
PCAPNGのデータ構造
- ブロック単位でデータを管理するよ
- よく使われるブロックは以下の三種類だよ
-
SHB (Section Header Block)
- セクション先頭のブロック。PCAPNGファイル先頭に必ず含まれる1
-
IDB (Interface Describe Block)
- インターフェイス(NIC等)のメタデータが記述されるブロック
-
EPB (Enhanced Packet Block)
- パケット本体とそのメタデータが格納されるブロック
-
SHB (Section Header Block)
- 「SHB⇒IDB⇒EPB」という順番のことが多いが、自由度の高い仕様のため、SHBがファイル先頭に来る以外は必ずしもこの順番とは限らないよ(これ以外の順番見たことないですが...)
これでざっくりとしたPCAP/PCAPNGの違いは見えてきたのではないでしょうか。
それでは本題のMermaidで生成したパケットダイアグラムで実際のパケット構造を見ていきましょう。
PCAP形式
おさらいですが、PCAP形式は、ファイル先頭にグローバルヘッダー、その後ろに「パケットヘッダー+パケット本体」の構造が続いていく形式です。

では、それぞれのパケットダイアグラムを見ていきましょう。
グローバルヘッダー
| フィールド名 | 説明 |
|---|---|
| マジックナンバー | PCAP形式の先頭であることを示すマジックナンバー("0xa1b2c3d4"固定) "0xd4c3b2a1"になっていたら書き込み側とバイトオーダーが逆ということが分かる |
| メジャー/マイナーバージョン | PCAP形式のバージョン(2025/12/7時点では2.4 2 ) |
| thiszone | 仕様上は、標準時からのズレを秒単位で指定する(例:日本だとUTC+9:00なので-32400)でも、基本使われていなくて0固定のフィールドになっている 3 |
| sigfigs | 仕様上は、キャプチャタイムスタンプの精度。でも基本使われていなくて0固定のフィールドになっている 3 |
| スナップ長 | パケットを切り詰めることなく保存できるバイト数(これより大きいパケットは先頭からスナップ長のバイト数だけ保存され、超過した部分は切り捨てられる) |
| ネットワークタイプ | データリンク層の種別を表す番号(例えばイーサネットは1) 対応表はtcpdumpのサイトを参照 |
パケットヘッダー
| フィールド名 | 説明 |
|---|---|
| タイムスタンプ(秒精度) | UNIX時間の秒精度 |
| タイムスタンプ(マイクロ秒精度) | UNIX時間のマイクロ秒精度 |
| パケット長(キャプチャ長) | 実際にキャプチャされたパケットのバイト数 |
| パケット長(オリジナル長) | 元のパケット長(上述のスナップ長よりもオリジナル長が長い場合、パケットが切り詰められるためオリジナル長とキャプチャ長は一致しない。キャプチャ長=スナップ長になる) |
PCAPNG形式
続いて、PCAPNG形式のパケットダイアグラムを見ていきましょう。
まずはおさらいですが、PCAPNG形式はブロックで構成されていて、ファイル先頭のSHB、IF(NIC)の情報が格納されるIDB、そしてパケットが格納されるEPB、の3つのブロックがよく使われています。

PCAPNGでは、ブロックの基本構造と各ブロック種別のパケットダイアグラムを見ていきたいと思います。
ブロックの基本構造
PCAPNGブロックの基本構造は、
- 先頭にブロックの種別を表すブロックタイプ
- 次にブロック長
- その次にブロックごとの実際のデータ
- 末尾に再度ブロック長
という構造となっています。
これはこの後のブロックで共通の構造となっているので、各ブロックでは説明は省略します。
SHB (Section Header Block)
| フィールド名 | 説明 |
|---|---|
| ブロックタイプ | SHBのブロックタイプは"0x0a0d0d0a"。ファイル先頭に来るため、PCAPNG形式ファイルのマジックナンバーでもある。 |
| ブロック長 | このブロックのバイト数 |
| バイトオーダーマーク | バイトオーダーを表す固定値"0x1a2b3c4d" |
| メジャー/マイナーバージョン | PCAPNG形式のバージョン(2025/12/7時点では1.0) |
| セクション長 | 仕様上はセクション長を表すが、通常-1が指定される(=セクション長未指定) |
| オプション | 通常はPCAPNGファイルが作成されたハード/OS/ソフトに関する情報が格納される |
| ブロック長 | このブロックのバイト数 |
IDB (Interface Description Block)
| フィールド名 | 説明 |
|---|---|
| ブロックタイプ | IDBのブロックタイプは"0x00000001" |
| ブロック長 | このブロックのバイト数 |
| リンクタイプ | データリンク層の種別を表す番号(例えばイーサネットは1) 対応表はtcpdumpのサイトを参照 |
| スナップ長 | パケットを切り詰めることなく保存できるバイト数(これより大きいパケットは先頭からスナップ長のバイト数だけ保存され、超過した部分は切り捨てられる) |
| オプション | 通常はネットワークインターフェイスに関する情報が格納される。タイムスタンプ精度の指定がある場合もここに定義される(if_tsresol) |
| ブロック長 | このブロックのバイト数 |
EPB (Enhanced Packet Block)
| フィールド名 | 説明 |
|---|---|
| ブロックタイプ | IDBのブロックタイプは"0x00000001" |
| ブロック長 | このブロックのバイト数 |
| インターフェイスID | IDBのIDを指す。これにより個々のパケットがどのインターフェイスで受信されたかをタグ付けすることが可能。IDBのIDはファイル内での暗黙的なインデックスで、1番目のIDBが0x00000000、2番目のIDBが0x00000001といった採番になる。これによりPCAPNGでは複数NICのキャプチャ結果を1ファイルにまとめて保存できるようになった◎ |
| タイムスタンプ上位4byte/下位4byte | UNIX時間の64bit精度を上位32bit下位32bitに分けて格納したフィールド。バイトオーダが逆の場合、上位・下位のバイトオーダを戻してから64bit精度として読み取らないといけないため注意。タイムスタンプの精度はIDBのオプションでの指定に依存するが、未指定の場合はミリ秒単位 |
| パケット長(キャプチャ長) | 実際にキャプチャされたパケットのバイト数 |
| パケット長(オリジナル長) | 元のパケット長(上述のスナップ長よりもオリジナル長が長い場合、パケットが切り詰められるためオリジナル長とキャプチャ長は一致しない。キャプチャ長=スナップ長になる) |
| パケットデータ | 実際のパケットデータが格納される |
| オプション | パケット毎のコメントを格納するために使用することもある(らしい。使ったことないです) |
| ブロック長 | このブロックのバイト数 |
PCAP/PCAPNGの紹介としては以上となります。
Mermaidがパケットダイアグラムに対応していることを1年越しに知ったことをきっかけに作成した記事でしたが、何事も視覚的な情報があると分かりやすい気がしますね。
PCAPがまだまだ現役で使われているので変換や両フォーマットへの対応等、大変なことはあるかと思いますが、この記事がそういったプロジェクトにアサインされた人の一助になれば幸いです。
↓は今回のパケットダイアグラム作成に使用したMermaidについてです。パケットに関わる人であれば知っていて損はないと思います!
おまけ
Mermaidとは
Mermaidはテキストベースでフローチャート等の図を描くことができるJavaScriptライブラリ(OSS)で、GitHubやここQiitaなど広くWebサービスでも利用されています。
https://mermaid.js.org/intro/
Mermaidで描けるパケットダイアグラムとは
上述の通りMermaidをつかうとテキストベースで図を描くことができるのですが、昨年リリースされたv11.0.0で、描ける図形にパケットダイアグラムが追加されました。
https://mermaid.js.org/syntax/packet.html
例えば先ほど登場したPCAPのグローバルヘッダーのパケットダイアグラムだと、以下のような記述となります。
---
title: "PCAP Global Header"
---
packet
+32: "マジックナンバー(0xa1b2c3d4)"
+16: "メジャーバージョン"
+16: "マイナーバージョン"
+32: "Timezone"
+32: "Sigfigs"
+32: "スナップ長"
+32: "ネットワーク長"
私は↑の+32等の書き方が好みですが、以下のように具体的に何bit目かを指定して記載することも可能です。
---
title: "Pcap Global Header"
---
packet
0-31: "マジックナンバー(A1B2C3D4)"
32-47: "メジャーバージョン"
48-63: "マイナーバージョン"
64-95: "Timezone"
96-127: "Sigfigs"
128-159: "スナップ長"
160-191: "ネットワーク長"
また、Qiitaは対応していないようですが、以下のようにconfigを指定することで一行のbit数や行の高さなどを調整可能です。
(VS CodeのMermaid Chart拡張機能は対応していました)
---
title: "Pcap Packet Header"
config:
packet:
bitsPerRow: 64 # 一行当たりのbit数
bitWidth: 32 # 1bit当たりの横幅
rowHeight: 64 # 行の高さ
showBits: false # bit数を表示するかどうか
---
packet
+32: "タイムスタンプ(秒精度)"
+32: "タイムスタンプ(マイクロ秒精度)"
+32: "パケット長(キャプチャ長)"
+32: "パケット長(元のパケット長)"
+32: "↓ここからパケット本体↓"
参考文献
- https://qiita.com/KenFujita/items/96474f61d9b617d9e990
- https://slankdev.hatenablog.com/entry/2015/12/22/000000
- https://pcapng.com/
- https://wiki.wireshark.org/Development/LibpcapFileFormat