☆ Ethereal外置解码器(插件)简介 所谓外置解码器,就是以插件方式提供的解码函数,不会被编译到libethereal.dll 中。源代码位于plugins\xxx\目录,名为packet-xxx.c的便是。与内置解码器相比, 外置的packet-xxx.c固定增加了几处内容: -------------------------------------------------------------------------- /************************************************************************ * * * Head File * * * ************************************************************************/ #include "moduleinfo.h" /* * 外置解码器(插件)必须包含这个头文件 */ #include /************************************************************************ * * * Static Global Var * * * ************************************************************************/ /* * Define version if we are not building ethereal statically */ #ifndef ENABLE_STATIC G_MODULE_EXPORT const gchar version[] = VERSION; #endif /************************************************************************/ /* * Start the functions we need for the plugin stuff */ #ifndef ENABLE_STATIC G_MODULE_EXPORT void plugin_register ( void ) { /* * execute protocol initialization only once */ if ( -1 == proto_xxx ) { proto_register_xxx(); } } /* end of plugin_register */ G_MODULE_EXPORT void plugin_reg_handoff ( void ) { proto_reg_handoff_xxx(); } /* end of plugin_reg_handoff */ #endif /* * End the functions we need for plugin stuff */ /************************************************************************/ -------------------------------------------------------------------------- 内置、外置解码器之间没有本质区别。即使以插件方式编写packet-xxx.c,也可以在 编译时指定ENABLE_STATIC宏,使得packet-xxx.c被内置: nmake -f Makefile.nmake ENABLE_STATIC=1 libethereal.dll引出了abs_time_to_str(),却没有引出abs_time_secs_to_str()。 假设内置的packet-xxx.c用到了abs_time_secs_to_str(),在外置化时只好从epan\ to_str.c抠代码出来用。这点很奇怪啊。注意用#ifndef ENABLE_STATIC/#endif包裹 一下。 编译、测试解码插件的整个步骤如下(以packet-time.c为例): -------------------------------------------------------------------------- 1) 创建plugins\time\目录并进入该目录 2) 按外置方式编写packet-time.c 3) 从plugins\asn1\复制moduleinfo.h、Makefile.am、Makefile.nmake到plugins\time\, 将其中的asn1字符串替换成time,VERSION宏可以是任意字符串,比如时间串,将来 会显示在Help->About Ethereal->Plugins->Version处。 4) 编辑plugins\Makefile.am,在如下位置添加time相关设置: SUBDIRS = 编辑plugins\Makefile.nmake,在如下位置添加time相关设置: all: time:: clean: distclean: maintainer-clean: install-plugins: 为避免不必要的麻烦(比如TAB相关的),最好是copy/paste类似行,然后修改。 5) 编辑顶层Makefile.am,在如下位置添加time相关设置: plugin_libs = plugin_ldadd = 编辑顶层configure.in,在如下位置添加time相关设置: AC_OUTPUT 6) 回退到源代码树的根目录,执行如下命令: nmake -f Makefile.nmake nmake -f Makefile.nmake install-deps 7) 事实上可以直接进入plugins\time\目录,执行nmake -f Makefile.nmake,而不必做 4至6步的操作,这样编译要快得多。手工将生成的time.dll复制到plugins\0.10.13\ 目录,执行ethereal-gtk2.exe即可测试插件。 8) 从plugins\0.10.13\目录中删除time.dll,这个插件就不再生效了。可以考虑先开发 外置的插件,测试无误后再内置化。 -------------------------------------------------------------------------- 内置packet-time.c未对37/TCP解码,我以插件方式实现了一个新的packet-time.c, 对37/TCP、37/UDP同时解码: dissector_add ( "tcp.port", TIME_PORT, time_handle ); dissector_add ( "udp.port", TIME_PORT, time_handle ); 后一个dissector_add()操作会覆盖epan\dissectors\packet-time.c提供的解码函数, 实测出来的结论。如果删除plugins\0.10.13\time.dll,内置解码函数重新生效。这 正是我所期望的效果。 假设你想简单测试。先将内置packet-time.c复制出来,按前文所说固定增加几处内 容改写成外置packet-time.c。 修改proto_register_time(): proto_time = proto_register_protocol( "Time Protocol New", "TIMENEW", "timenew" ); 修改proto_reg_handoff_time(),增加: dissector_add( "tcp.port", UDP_PORT_TIME, time_handle ); 从epan\to_str.c抠abs_time_secs_to_str()函数及相关全局变量mon_names[]出来。 注意用#ifndef ENABLE_STATIC/#endif包裹。 编译成time.dll即可测试。当然,这样简单测试有点问题,原packet-time.c未仔细 检查数据区长度,TCP通信是字节流,不能保证解码时协议数据区是完整的。