9.6 如何产生协议统计
如果你的协议已经有了一个窃听器接口,你可以使用它从协议追踪中产生一些有趣的统计信息(假设是有趣的吧!)
这个可以在一个分离的插件中完成,也可以在进行协议解析的同一个插件中完成。第二种模式更好一些,因为窃听器和统计模块通常依靠共享协议指定数据,这些数据在不同插件中可能需要的步骤更加繁琐。
下面是一个在TAP接口之上产生统计的机制。
例子 9.21 初始化状态接口
/* register all http trees */
static void register_foo_stat_trees(void) {
stats_tree_register("foo", "foo", "Foo/Packet Types",
foo_stats_tree_packet, foo_stats_tree_init, NULL);
}
G_MODULE_EXPORT const gchar version[] = "0.0";
G_MODULE_EXPORT void plugin_register_tap_listener(void)
{
register_foo_stat_trees();
}
#endif
自下往上工作,首先定义插件接口入口点,plugin_register_tap_listener()。这通常调用初始化函数register_foo_stat_trees()。
这个函数内部调用stats_tree_register()函数,该函数带有3个字符串和3个函数。
1.之前注册的窃听器名称
2.窃听器名称的简称
3.统计模块的名称,'/'字符被使用来建立子目录
4.这个函数被调用来产生统计信息
5.这个函数被调用来初始化统计数据
6.这个函数被调用来清理统计数据
在我们的示例中仅仅时候用前两个函数,没有任何具体东西需要被清理。
例子 9.22 初始化一个统计会话
static const guint8* st_str_packets = "Total Packets";
static const guint8* st_str_packet_types = "FOO Packet Types";
static int st_node_packets = -1;
static int st_node_packet_types = -1;
static void foo_stats_tree_init(stats_tree* st)
{
st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
st_node_packet_types = stats_tree_create_pivot(st, st_str_packet_types, st_node_packets);
}
在这个例子中,我们创建一个新的树结点,用于处理所有报文,作为这个树结点的孩子,我们创建一个中轴表用户处理不同报文类型的统计。
例子9.23 产生统计
static int foo_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt,
const void* p)
{
struct FooTap *pi = (struct FooTap *)p;
tick_stat_node(st, st_str_packets, 0, FALSE);
stats_tree_tick_pivot(st, st_node_packet_types,
val_to_str(pi->packet_type, msgtypevalues, "Unknown packet type (%d)"));
return 1;
}
在这个例子中,处理统计信息非常简单。首先我们为st_str_packets报文结点调用tick_stat_node,从而计算报文数,然后在st_node_packet_types子树上调用stats_tree_tick_pivot使得我们记录每种报文类型的统计信息。
版权所有:Jason Tu,转载请注明