Wireshark OpenFlow Dissector and TremaShark

[追記 2013-10-27] See Also : Trema/Wireshark/OpenFlow Dissector関連情報

はじめに

OpenFlow とか、単純にサンプルで動かすレベルなら特に考えなくても割と動いてしまう。が、ある程度複雑なものを作ってみようとか、ソフトウェア・シミュレーションから実機ベースに移してみると、とたんに、今どこで何が起きていて、予想通りに動いているのか、あるいは何が問題で動いていないのか、という状況に直面する。やる前にある程度、観測手段/検証方法を準備しておかないと、やってみたダメだった、というだけで、そこから先のステップに手が出せず、行き詰まってしまう。*1

Trema はその辺すごく考えてあって、テストフレームワークデバッグツールなんかを用意して、開発プロセス全体をフォローしようという思想があったりする。今回は、低レベルでバッグツールである Tremashark のインストール方法と、付随して、Wireshark 用の OpenFlow プロトコルプラグイン (OpenFlow dissector) のインストールについての話を。

使うもの

Cygwin/X

Ubuntu11 は desktop package なしで入れているので、X Server をリモート側でたてておく。

ssh してサーバにログインするときは X Forwarding を有効にしておくのを忘れずに。

Trema and Tremashark

Building Trema

Trema のダウンロードとビルドについては下記参照。

この連載の最終回(Software Design 2012/05)で Tremashark の話が出てきますがまだ Web 公開はされていないですね。今回は SD 2012/05 を参照してます。

Building Tremashark

Wireshark Source の取得とビルド

ofcsv:~$ apt-get source wireshark
(略)
ofcsv:~$ sudo apt-get build-dep wireshark
(略)

Tremashark のビルド

ofcsv:~/trema/src/tremashark/plugin$ ls
packet-trema  user_dlts
ofcsv:~/trema/src/tremashark/plugin$ ln -s ~/wireshark-1.6.2 wireshark
ofcsv:~/trema/src/tremashark/plugin$ ls -l
total 8
drwxrwxr-x 2 stereocat stereocat 4096 Apr 27 00:47 packet-trema
-rw-rw-r-- 1 stereocat stereocat   96 Nov  6 13:58 user_dlts
lrwxrwxrwx 1 stereocat stereocat   31 May  1 21:39 wireshark -> /home/stereocat/wireshark-1.6.2
ofcsv:~/trema/src/tremashark/plugin$ cd wireshark
ofcsv:~/trema/src/tremashark/plugin/wireshark$ ./configure | tee configure.log 2>&1
(略)
config.status: executing depfiles commands
config.status: executing libtool commands

The Wireshark package has been configured with the following options.
                    Build wireshark : yes
                       Build tshark : yes
                     Build capinfos : yes
                      Build editcap : yes
                      Build dumpcap : yes
                     Build mergecap : yes
                    Build text2pcap : yes
                      Build idl2wrs : yes
                      Build randpkt : yes
                       Build dftest : yes
                     Build rawshark : yes

  Install dumpcap with capabilities : no
             Install dumpcap setuid : no
                  Use dumpcap group : (none)
                        Use plugins : yes
                    Use lua library : yes
                 Use python binding : no
                   Build rtp_player : yes
                        Use threads : no
             Build profile binaries : no
                   Use pcap library : yes
                   Use zlib library : yes
                   Use pcre library : no (using GRegex instead)
               Use kerberos library : yes (MIT)
                 Use c-ares library : yes
               Use GNU ADNS library : no (using c-ares instead)
                Use SMI MIB library : yes
             Use GNU crypto library : yes
             Use SSL crypto library : no
           Use IPv6 name resolution : yes
                 Use gnutls library : yes
     Use POSIX capabilities library : yes
                  Use GeoIP library : yes
ofcsv:~/trema/src/tremashark/plugin/wireshark$ cd ~/trema/src/tremashark/plugin/packet-trema/
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ ls
Makefile  Makefile.am  Makefile.common  moduleinfo.h  packet-trema.c  plugin.c
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ make | tee make.log 2>&1
(略)
In file included from /usr/include/glib-2.0/glib/galloca.h:34:0,
                 from /usr/include/glib-2.0/glib.h:32,
                 from packet-trema.c:27:
/usr/include/glib-2.0/glib/gtypes.h:34:24: fatal error: glibconfig.h: No such file or directory
compilation terminated.
make: *** [packet-trema.o] Error 1
ofcsv:~/trema/src/tremashark/plugin/packet-trema$

…と、ここで、ヘッダファイルがないと言われてしまった。ただし、libglib2.0-dev package はインストールしてあるし、検索するとファイル自体はある。

ofcsv:~/trema/src/tremashark/plugin/packet-trema$ aptitude search libglib2.0-dev
i A libglib2.0-dev                  - Development files for the GLib library
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ sudo find / -name glibconfig.h
/home/stereocat/wireshark-1.6.2/packaging/macosx/native-gtk/glibconfig.h
/usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h
ofcsv:~/trema/src/tremashark/plugin/packet-trema$

Makefile を書き換えておく。(-I/usr/lib/x86_64-linux-gnu/glib-2.0/include を追加)

--- Makefile.orig       2012-05-01 21:47:14.244111296 +0900
+++ Makefile    2012-05-01 21:48:38.359086961 +0900
@@ -45,7 +45,7 @@
INC_TREMA = -I../../../lib

INC_DIRS = -I. $(INC_GLIB) $(INC_OPENFLOW) $(INC_TREMA)
-CFLAGS = -std=gnu99 -D_GNU_SOURCE $(INC_DIRS) -DHAVE_CONFIG_H -I$(WIRESHARK_SRC_DIR) -I/usr/local/include -I/usr/local/include -DINET6 -D_U_=__attribute__\(\(unused\)\) -Wall -Wpointer-arith -g -I/usr/local/include -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -fPIC -DPIC $(ENDIAN) $(DISSECT_PORT)
+CFLAGS = -std=gnu99 -D_GNU_SOURCE $(INC_DIRS) -DHAVE_CONFIG_H -I$(WIRESHARK_SRC_DIR) -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/local/include -I/usr/local/include -DINET6 -D_U_=__attribute__\(\(unused\)\) -Wall -Wpointer-arith -g -I/usr/local/include -DXTHREADS -D_REENTRANT -DXUSE_MTSAFE_API -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/X11R6/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/include/freetype2 -I/usr/include/freetype2/config -fPIC -DPIC $(ENDIAN) $(DISSECT_PORT)

LDFLAGS = -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib -L$(WIRESHARK_SRC_DIR)/epan -L. -lgmodule-2.0 -ldl -lglib-2.0 -pthread -Wl,--export-dynamic -Wl,-soname -Wl,$(PLUGIN_NAME).so

もう一度 make したら通ったので、~/.wireshark/plugin に必要なファイルをコピーして終わり。

ofcsv:~/trema/src/tremashark/plugin/packet-trema$ make
(略)
gcc -shared  packet-trema.o  plugin.o -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib -L../wireshark/epan -L. -lgmodule-2.0 -ldl -lglib-2.0 -pthread -Wl,--export-dynamic -Wl,-soname -Wl,packet-trema.so -o packet-trema.so
ofcsv:~/trema/src/tremashark/plugin/packet-trema$
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ ls
Makefile         Makefile.orig  packet-trema.c   plugin.c
Makefile.am      make.log       packet-trema.o   plugin.o
Makefile.common  moduleinfo.h   packet-trema.so
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ mkdir -p ~/.wireshark/plugins/
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ cp packet-trema.so ~/.wireshark/plugins/
ofcsv:~/trema/src/tremashark/plugin/packet-trema$ cp ../user_dlts ~/.wireshark/

Wireshark OpenFlow Dissector

Tremashark の OpenFlow 解析器としても使うし、あるいは実機ベースでやるならスイッチ〜コントローラ間のやりとりを解析するのにも必要。

まずは、OpenFlow プロトコルを解析するためのプラグインをビルドする。

ソースコードのダウンロード。上のURLに tar.gz のソースおいてあるけど、これだとビルド上手くいかなかったので、必ず git から最新版を取得すること。

ofcsv:~$ git clone git://gitosis.stanford.edu/openflow.git
Cloning into openflow...
remote: Counting objects: 14960, done.
remote: Compressing objects: 100% (4611/4611), done.
remote: Total 14960 (delta 10171), reused 13376 (delta 9015)
Receiving objects: 100% (14960/14960), 10.87 MiB | 2.14 MiB/s, done.
Resolving deltas: 100% (10171/10171), done.
ofcsv:~$
ofcsv:~$ cd openflow/utilities/wireshark_dissectors/
ofcsv:~/openflow/utilities/wireshark_dissectors$ ls
Makefile  README  openflow  wireshark-1.0.0-includes
ofcsv:~/openflow/utilities/wireshark_dissectors$ cd openflow/
ofcsv:~/openflow/utilities/wireshark_dissectors/openflow$ ls
Makefile  Makefile.am  Makefile.common  build_distribution_tarball.sh  moduleinfo.h  packet-openflow.c  plugin.c
ofcsv:~/openflow/utilities/wireshark_dissectors/openflow$

Wireshark 1.6.x を使う場合はパッチを当てる必要がある。

dissector_add を dissector_add_uint に変更するだけなので手で変えてしまっても良いけど、Trema package の中にこのためのパッチも含まれているのでそれを使用する。

ofcsv:~/openflow/utilities/wireshark_dissectors/openflow$ patch < ~/trema/vendor/packet-openflow.diff
patching file packet-openflow.c
ofcsv:~/openflow/utilities/wireshark_dissectors/openflow$ cd ..
ofcsv:~/openflow/utilities/wireshark_dissectors$ make
(略)
ofcsv:~/openflow/utilities/wireshark_dissectors$ make install


*** Installed plugin for user stereocat (/home/stereocat/.wireshark/plugins/packet-openflow.so)


ofcsv:~/openflow/utilities/wireshark_dissectors$

make install で ~/.wireshark/plugin に packet-openflow.so がインストールされる。

Wireshark dumpcap capability

Wireshark を起動する場合、通常 root 権限じゃないとインタフェースをプロミスキャスモードに変更できないが、root として実行すると "Lua: Error during loading: [string "/usr/share/wireshark/init.lua"]:45: dofile has been disabled" みたいな警告ダイアログが出る。警告は一旦 ok してしまえば使えるのだけど、一般ユーザ権限で wireshark 動かせるように設定しておく。

stereocat@lambda02:~$ which setcap
/sbin/setcap
stereocat@lambda02:~$ ls /usr/bin/dumpcap
/usr/bin/dumpcap
stereocat@lambda02:~$ sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' /usr/bin/dumpcap
[sudo] password for stereocat:
stereocat@lambda02:~$ 

wireshark の configure したときに "Install dumpcap with capabilities : no" ってなってるので、この辺を有効化した上でビルドすることもできるのかもしれないけど。

実行

とりあえず単純に wireshark 起動してみて、プラグインが読み込まれていることを確認する。

確認できたら実際に Trema 動かしてみて確認。

ofcsv:~/trema$ ./trema run ./src/examples/learning_switch/learning-switch.rb -c ./src/examples/learning_switch/learning_switch.conf -s -d
ofcsv:~/trema$ ls tmp/pid/
LearningSwitch.pid    phost.trema0-1.pid  switch.0xabc.pid    tremashark.pid
open_vswitch.lsw.pid  phost.trema1-1.pid  switch_manager.pid
ofcsv:~/trema$ kill -USR2 `cat tmp/pid/LearningSwitch.pid`
ofcsv:~/trema$ kill -USR2 `cat tmp/pid/switch.0xabc.pid`
ofcsv:~/trema$ ./trema send_packets --source host2 --dest host1
ofcsv:~/trema$ ./trema send_packets --source host1 --dest host2


こんな感じでイベントが見えていたらOK

*1:チェック方法がないのにやっても仕方がないというのは、開発プロセス全般に当てはまる話だけど。