Wireshark は、世界で最も広く使われているネットワークプロトコルアナライザの一つです。その強力な機能の核心部分を支えるライブラリ群があり、その中でもファイルI/Oを担当するのが libwiretap
です。そして、この libwiretap
を利用した開発を行うために必要となるのが libwiretap-dev
パッケージです。
このブログ記事では、libwiretap-dev
パッケージの概要から、それを使ってC言語で簡単なプログラムを作成する手順までを、初心者にも分かりやすく解説します。ネットワークパケット解析ツールの自作や、特定のキャプチャファイル形式を扱うプログラムの開発に興味がある方は、ぜひ読み進めてください。
libwiretap とは? 🤔
libwiretap
は、Wireshark プロジェクトの一部として開発されているライブラリです。その主な役割は、様々な形式のパケットキャプチャファイルの読み書きです。Wireshark が非常に多くのファイル形式に対応できるのは、この libwiretap
のおかげと言っても過言ではありません。
具体的には、以下のような機能を提供します:
- 多種多様なキャプチャファイル形式の自動判別とオープン
- ファイルからのパケットデータの逐次読み込み
- 指定された形式でのキャプチャファイルへのパケットデータの書き込み
- ファイルに関するメタ情報(インターフェース情報、タイムスタンプ精度など)の取得
libwiretap
がサポートするファイル形式は多岐にわたります。代表的なものとしては以下が挙げられます:
- Libpcap (pcap): 最も広く使われている形式。tcpdump など多くのツールがこの形式を使用します。
- Pcap Next Generation (pcapng): pcap の後継フォーマットで、複数のインターフェースからのキャプチャ情報、コメント、名前解決情報などを同一ファイル内に格納できます。
- Network Monitor: Microsoft Network Monitor が使用する形式。
- Sniffer: Network Associates (旧 Network General) の Sniffer 製品が使用する形式。
- その他、snoop, iptrace, HP-UX nettl, Cisco Secure IDS iplogging など、多数の形式に対応しています。
ただし、libwiretap
自体には、ライブキャプチャ(ネットワークインターフェースから直接パケットを取得する機能)や、パケットフィルタリング(特定の条件に合うパケットだけを選別する機能)は含まれていません。これらの機能は、主に libpcap
や Wireshark のコアエンジン (libwireshark
) が担当します。libwiretap
はあくまでファイル I/O に特化したライブラリです。
libwiretap-dev パッケージの役割とインストール 📦
libwiretap-dev
は、libwiretap
ライブラリを利用した開発を行うために必要なファイルを集めたパッケージです。具体的には、以下のものが含まれます:
- ヘッダーファイル (.h): C/C++ のソースコードから
libwiretap
の関数やデータ構造を利用するためにインクルードする必要があるファイル群です (例:wiretap/wtap.h
)。 - スタティックライブラリ (.a): プログラムをコンパイル(リンク)する際に、
libwiretap
の機能をプログラム本体に静的に組み込むためのファイルです。(共有ライブラリ (.so) は通常、libwiretapX
のような実行時ライブラリパッケージに含まれますが、開発時にはヘッダーとリンク情報が必要になります。)
このパッケージがないと、libwiretap
を使うプログラムのソースコードを書いても、コンパイルすることができません。
Kali Linux でのインストール
Kali Linux を使用している場合、libwiretap-dev
は APT パッケージマネージャを使って簡単にインストールできます。ターミナルを開き、以下のコマンドを実行してください。
# パッケージリストを更新
sudo apt update
# libwiretap-dev パッケージをインストール
sudo apt install libwiretap-dev
依存関係のある他のパッケージ (libwiretap
の本体である共有ライブラリパッケージや、libwsutil-dev
など) も自動的にインストールされます。
他の Debian/Ubuntu ベースのディストリビューションでも、同様のコマンドでインストール可能です。
基本的な使い方: C言語による開発入門 💻
それでは、実際に libwiretap-dev
を使って、pcap ファイルを読み込み、各パケットの基本情報(タイムスタンプ、長さ)を表示する簡単な C プログラムを作成してみましょう。
1. ヘッダーファイルのインクルード
まず、libwiretap
の機能を使うために必要なヘッダーファイルをインクルードします。中心となるのは wiretap/wtap.h
です。
#include <stdio.h>
#include <stdlib.h>
#include <glib.h> // libwiretap は GLib に依存しているため必要
#include <wiretap/wtap.h>
libwiretap
は内部で GLib ライブラリを使用しているため、glib.h
もインクルードする必要があります。
2. ファイルを開く
wtap_open_offline()
関数を使ってキャプチャファイルを開きます。この関数はファイルパスを引数に取り、成功すればファイルハンドル (wtap*
) を、失敗すれば NULL
を返します。エラー処理も重要です。
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <capture_file>\n", argv[0]);
return 1;
}
const char *filename = argv[1];
wtap *wth;
int err = 0;
gchar *err_info = NULL;
gboolean exists;
// ファイルが存在するか確認 (オプション)
exists = g_file_test(filename, G_FILE_TEST_EXISTS);
if (!exists) {
fprintf(stderr, "Error: File not found: %s\n", filename);
return 1;
}
// ファイルを開く
// 第3引数 (use_stdin) は FALSE
// 第4引数 (verified) は読み込み専用なので FALSE で OK
wth = wtap_open_offline(filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if (wth == NULL) {
fprintf(stderr, "Error opening file '%s': %s\n", filename, wtap_strerror(err));
if (err_info != NULL) {
fprintf(stderr, "Additional info: %s\n", err_info);
g_free(err_info);
}
return 1;
}
printf("Successfully opened file: %s\n", filename);
printf("File type: %s\n", wtap_file_type_subtype_string(wtap_file_type_subtype(wth)));
printf("Snapshot length: %d bytes\n", wtap_snapshot_length(wth)); // 0 if unknown
// ... (パケット読み込み処理) ...
// ファイルを閉じる
wtap_close(wth);
printf("File closed.\n");
return 0;
}
wtap_open_offline
の第2引数にはファイルタイプを指定しますが、WTAP_TYPE_AUTO
を指定すると自動で判別してくれます。エラーが発生した場合、err
にエラーコードが、err_info
に詳細なエラーメッセージ(不要になったら g_free()
で解放が必要)が格納されます。wtap_strerror()
でエラーコードに対応する文字列を取得できます。
ファイルを開いた後、wtap_file_type_subtype()
でファイル形式を、wtap_snapshot_length()
でスナップショット長(パケットの最大キャプチャ長)を取得できます。
3. パケットを読み込む
wtap_read()
関数を使って、ファイルからパケットを1つずつ読み込みます。この関数はループ内で呼び出すのが一般的です。
// ... (ファイルオープン処理の後) ...
struct wtap_pkthdr *phdr; // パケットヘッダ情報
Buffer *buf; // パケットデータバッファ (wiretap/buffer.h)
long packet_count = 0;
int read_err = 0;
gchar *read_err_info = NULL;
// wtap_read() は成功すれば TRUE を返す
while (wtap_read(wth, &read_err, &read_err_info, &buf)) {
packet_count++;
phdr = wtap_phdr(wth); // 現在のパケットのヘッダ情報を取得
// パケット情報を表示
printf("Packet %ld: Timestamp=%lld.%09d, Captured Len=%u, Original Len=%u\n",
packet_count,
(long long)phdr->ts.secs, // 秒
phdr->ts.nsecs, // ナノ秒
phdr->caplen, // キャプチャされた長さ
phdr->len); // オリジナルの長さ
// パケットデータ自体は buf に格納されている (今回は使わない)
// buffer_free(buf); // wtap_read が内部で再利用・解放するので不要
}
// ループ終了後のエラーチェック
if (read_err != 0 && read_err != WTAP_ERR_SHORT_READ) {
// WTAP_ERR_SHORT_READ は正常なファイル終端を示すことが多い
fprintf(stderr, "Error reading packet %ld: %s\n", packet_count + 1, wtap_strerror(read_err));
if (read_err_info != NULL) {
fprintf(stderr, "Additional info: %s\n", read_err_info);
g_free(read_err_info);
}
wtap_close(wth);
return 1;
}
printf("Finished reading %ld packets.\n", packet_count);
// ... (ファイルクローズ処理) ...
wtap_read()
は成功すると TRUE
を返します。ループ内でこの関数を呼び出し続けることで、ファイルの終端までパケットを読み進めることができます。読み込んだパケットのヘッダ情報(タイムスタンプ、キャプチャ長、オリジナル長など)は、wtap_phdr()
で取得できる struct wtap_pkthdr
構造体ポインタを通じてアクセスします。パケットの生データは Buffer *buf
に格納されますが、このサンプルでは使用していません。
wtap_read()
が FALSE
を返してループが終了した場合、エラーが発生したか、ファイルの終端に達したかのどちらかです。read_err
の値を確認し、WTAP_ERR_SHORT_READ
(正常な終端を示すことが多い) 以外のエラーであれば、エラーメッセージを表示します。
4. ファイルを閉じる
処理が終わったら、wtap_close()
関数でファイルハンドルを解放します。
// main 関数の最後
wtap_close(wth);
printf("File closed.\n");
5. コンパイルとリンク
作成した C のソースコード (例: `readpcap.c`) をコンパイルするには、`gcc` などの C コンパイラを使用します。その際、`libwiretap` と `libglib-2.0` ライブラリをリンクする必要があります。
gcc readpcap.c -o readpcap $(pkg-config --cflags --libs glib-2.0) -lwiretap
pkg-config
を使うと、GLib に必要なコンパイラフラグ (--cflags
) とリンカフラグ (--libs
) を簡単に取得できます。-lwiretap
で libwiretap
ライブラリをリンクしています。
コンパイルが成功すれば、実行ファイル readpcap
が生成されます。
6. 実行
適当な pcap ファイル (例: `test.pcap`) を用意して、作成したプログラムを実行します。
./readpcap test.pcap
実行すると、pcap ファイル内の各パケットのタイムスタンプと長さがコンソールに出力されるはずです。
応用例と発展 🚀
基本的なファイル読み込みができるようになったところで、libwiretap
の応用例やさらに発展的な使い方について見ていきましょう。
ファイル書き込み
libwiretap
はファイルの書き込みもサポートしています。wtap_dump_open()
や wtap_dump()
といった関数を使用します。
wtap_dump_open()
: 書き込み用のファイルを開きます。ファイル形式やスナップショット長などを指定します。wtap_dump()
: パケットデータをファイルに書き込みます。struct wtap_pkthdr
でパケット情報を提供し、パケットデータをバッファで渡します。wtap_dump_close()
: 書き込みファイルを閉じます。
これを利用すれば、以下のようなツールを作成できます。
- ファイル形式変換ツール: ある形式のキャプチャファイルを読み込み、別の形式 (例: pcapng) で書き出す。
- パケットフィルタリング/加工ツール: 特定の条件に合うパケットだけを読み込んで新しいファイルに書き出したり、パケットデータを一部変更して書き出したりする (ただし、パケット内容の深い解析や変更は
libwireshark
の領域になることが多いです)。
Wireshark プラグイン開発 (Dissector) との連携
Wireshark の Dissector (特定のプロトコルを解析するプラグイン) を開発する際、その Dissector が扱うプロトコルが独自のファイル形式で保存されている場合があります。そのような場合に、libwiretap
を使ってそのカスタムファイル形式を読み込むための File Format Dissector を作成することができます。
これにより、Wireshark 本体が直接サポートしていないファイル形式でも、あたかも標準でサポートされているかのように Wireshark 上で開いて解析できるようになります。
他のライブラリとの組み合わせ
- libpcap との連携:
libpcap
でライブキャプチャしたパケットを、libwiretap
を使ってファイルに保存する。 - libwireshark との連携:
libwiretap
で読み込んだパケットデータを、libwireshark
を使って詳細に解析し、特定の情報を抽出する。
高度な機能
libwiretap
は pcapng 形式の高度な機能(複数のインターフェース情報、名前解決ブロック、カスタムブロックなど)の読み書きにも対応しようとしています (開発中のバージョンによる)。これらの機能を使うことで、よりリッチな情報をキャプチャファイルに含めたり、読み取ったりすることが可能になります。
開発時の注意点 ⚠️
libwiretap
を使った開発を進める上で、いくつか注意すべき点があります。
-
API の安定性:
libwiretap
は Wireshark 本体の一部として開発が進められています。Wireshark のバージョンアップに伴い、API (関数、データ構造など) が変更される可能性があります。特定の Wireshark バージョンに同梱されているlibwiretap
をターゲットにして開発した場合、新しいバージョンの Wireshark 環境では互換性がなくなる可能性があります。安定した API を求める場合は、LTS (長期サポート) バージョンの Wireshark をベースにすることを検討すると良いでしょう。 -
エラーハンドリング: ファイル I/O 操作は失敗する可能性があります (ファイルが存在しない、権限がない、ファイルが破損しているなど)。
wtap_open_offline
,wtap_read
,wtap_dump
などの関数はエラーコードと詳細情報を返す仕組みを持っています。これらを適切にチェックし、エラー発生時にプログラムが安全に終了するか、問題をユーザーに通知するように実装することが非常に重要です。 -
メモリ管理:
libwiretap
は内部で GLib を利用しており、一部の関数は GLib によって割り当てられたメモリへのポインタを返すことがあります (例:err_info
)。これらのメモリは、不要になった際に適切に解放 (例:g_free()
) する必要があります。ドキュメントやヘッダーファイルで、どの関数がメモリの所有権を呼び出し元に渡すのかを確認しましょう。 -
ドキュメントの参照:
libwiretap
に関する独立した詳細なチュートリアルやドキュメントは限られています。最も信頼できる情報は、Wireshark のソースコード (特にwiretap/
ディレクトリ以下のコードとヘッダーファイルのコメント) や、Wireshark Developer’s Guide になります。開発に行き詰まった場合は、これらを参照することをお勧めします。 -
依存ライブラリ (GLib):
libwiretap
は GLib に依存しています。GLib の基本的な使い方 (データ型、メモリ管理、エラー処理など) を理解していると、libwiretap
の利用がよりスムーズになります。
まとめ ✨
libwiretap-dev
パッケージは、Wireshark の強力なファイル I/O ライブラリである libwiretap
を使った開発を可能にするための重要なコンポーネントです。これを利用することで、様々な形式のキャプチャファイルを読み書きするカスタムツールや、Wireshark の機能を拡張するプラグインなどを開発できます。
この記事では、libwiretap
の基本的な概念から、libwiretap-dev
のインストール、そして簡単な C 言語プログラムによるファイル読み込みのサンプルまでを紹介しました。基本的な使い方をマスターすれば、ファイル形式の変換、特定パケットの抽出、他のツールとの連携など、様々な応用が考えられます。
開発には C 言語と GLib の知識が必要となり、API の変更やエラーハンドリングといった注意点もありますが、Wireshark のソースコードや Developer’s Guide を参照しながら進めることで、ネットワーク解析の可能性をさらに広げることができるでしょう。ぜひ libwiretap
を活用した開発に挑戦してみてください! 💪
参考情報 📚
-
Wireshark 公式サイト: Wireshark に関する最新情報、ダウンロード、ドキュメントなど。
https://www.wireshark.org/ -
Wireshark Developer’s Guide: Wireshark の内部構造、ライブラリの使い方、プラグイン開発など、開発者向けの詳細情報。
libwiretap
についても触れられています。
https://www.wireshark.org/docs/wsdg_html_chunked/ (このドキュメントはwireshark-doc
パッケージにも含まれている場合があります。) -
Kali Linux Tools – wireshark: Kali Linux における Wireshark 関連パッケージ (libwiretap-dev を含む) の情報。
https://www.kali.org/tools/wireshark/
コメント