プログラミング

パケットキャプチャツールのつくり方 〜UDPヘッダー解析〜

このページはこんな方におすすめです
  • 自分でパケットキャプチャツールを作ってみたい
  • パケットの構造に興味がある

前回はパケットキャプチャでIPヘッダーの表示を行いました。

今回はUDPヘッダーの解析と表示をおこないます。

UDPヘッダーは単純な構造のため、UDPヘッダーの解析ができればTCPやICMPでも同様に対応できるはずです。

UDPヘッダーの構造については次の記事を参照してください。

≫TCP/IPヘッダ構造

パケットキャプチャツールのつくり方

ヘッダーファイル取り扱いについての注意

macOS、BSDとLinuxで共通のコードを記述する場合は対策をしないとUDPヘッダーの構造体定義が異なるためコンパイルエラーになります

幸いにもLinuxにはBSD形式の構造体が用意されていて「__FAVOR_BSD」を定義することで使用することができるようになります。

具体的にどうするのかというと、以下のようにnetinet/udp.hをincludeする前に__FAVOR_BSDを定義します。

UDPヘッダーのマッピング方法

この方法はTCPやICMPでも同様の方法です。

パケットの中でUDPヘッダーの先頭へアクセスするためには、IPヘッダーのサイズを知る必要があります。

IPヘッダーは可変長ですから、IPヘッダーの長さを知るために ip_hl を使用します。ip_hl IPヘッダーのサイズを4オクテット単位で表しているため、ip_hlの値を4倍することによってIPヘッダーのサイズを知ることができます

今回のサンプルコードでは、以下のようにしてUDPヘッダーが格納されているメモリアドレスを計算しています。

このようにip_hlを左へ2ビットシフトした値をポインタipに加算しています。

上位プロトコルの判定

IPヘッダーの上位プロトコルについては、IPヘッダーの ip_p を調べることによって知ることができます。

どのような値が定義されているのかについてはヘッダーファイルのnetinet/in.hを見てください。

サンプルコードでは、以下のようにしてプロトコルによる処理の振り分けをおこなっています(まだUDPしか処理していません)。

UDPヘッダー値を表示する

UDPヘッダーの表示はIPヘッダーでのやり方と変わりません。

バイトオーダーに注意して各フィールドの値を表示するだけです。

サンプルコードでは、以下のようにしています。

サンプルコードと実行例

サンプルコード

サンプルコードはGitHubからも落とせます。

≫サンプルコード

コンパイルは以下のようにします。libpcapとリンクするために”-l pcap”が必要であることに注意してください。

今回のサンプルコードはパケットフィルターを引数で指定できるようにしているので、実行時に「udp and port 53」を引数として渡すことで、DNSパケットのみ受信しています。

まとめ

UDPヘッダーはとても単純なため、UDPヘッダーを表示させられるようになれば、TCPやICMPも簡単に対応できますから、興味のある方は是非UDPヘッダーを自在に表示できるようになってください。

ネットワークプログラミングのオススメ本は、やはり「UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI・ソケットとXTI」で決まりです。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)