2 * dcerpc_stat 2002 Ronnie Sahlberg
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 /* This module provides rpc call/reply SRT statistics to Wireshark,
24 * and displays them graphically.
25 * It is only used by Wireshark and not tshark
27 * It serves as an example on how to use the tap api.
37 #include <epan/packet_info.h>
38 #include <epan/stat_tap_ui.h>
40 #include <epan/dissectors/packet-dcerpc.h>
43 #include "ui/simple_dialog.h"
45 #include "ui/gtk/dlg_utils.h"
46 #include "ui/gtk/gui_utils.h"
47 #include "ui/gtk/filter_dlg.h"
48 #include "ui/gtk/stock_icons.h"
49 #include "ui/gtk/service_response_time_table.h"
50 #include "ui/gtk/gtkglobals.h"
51 #include "ui/gtk/main.h"
52 #include "ui/gtk/filter_autocomplete.h"
55 void register_tap_listener_gtkdcerpcstat(void);
57 /* used to keep track of the statistics for an entire program interface */
58 typedef struct _dcerpcstat_t {
60 srt_stat_table srt_table;
69 uuid_equal(e_uuid_t *uuid1, e_uuid_t *uuid2)
71 if( (uuid1->Data1 != uuid2->Data1)
72 ||(uuid1->Data2 != uuid2->Data2)
73 ||(uuid1->Data3 != uuid2->Data3)
74 ||(uuid1->Data4[0] != uuid2->Data4[0])
75 ||(uuid1->Data4[1] != uuid2->Data4[1])
76 ||(uuid1->Data4[2] != uuid2->Data4[2])
77 ||(uuid1->Data4[3] != uuid2->Data4[3])
78 ||(uuid1->Data4[4] != uuid2->Data4[4])
79 ||(uuid1->Data4[5] != uuid2->Data4[5])
80 ||(uuid1->Data4[6] != uuid2->Data4[6])
81 ||(uuid1->Data4[7] != uuid2->Data4[7]) ){
88 dcerpcstat_gen_title(dcerpcstat_t *rs)
93 display_name = cf_get_display_name(&cfile);
94 title = g_strdup_printf("DCE-RPC Service Response Time statistics for %s major version %u: %s", rs->prog, rs->ver, display_name);
100 dcerpcstat_set_title(dcerpcstat_t *rs)
104 title = dcerpcstat_gen_title(rs);
105 gtk_window_set_title(GTK_WINDOW(rs->win), title);
110 dcerpcstat_reset(void *rs_arg)
112 dcerpcstat_t *rs = (dcerpcstat_t *)rs_arg;
114 reset_srt_table_data(&rs->srt_table);
115 dcerpcstat_set_title(rs);
120 dcerpcstat_packet(void *rs_arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *ri_arg)
122 dcerpcstat_t *rs = (dcerpcstat_t *)rs_arg;
123 const dcerpc_info *ri = (dcerpc_info *)ri_arg;
128 if(!ri->call_data->req_frame){
129 /* we have not seen the request so we don't know the delta*/
132 if(ri->call_data->opnum >= rs->num_procedures){
133 /* don't handle this since it's outside of known table */
137 /* we are only interested in reply packets */
138 if(ri->ptype != PDU_RESP){
142 /* we are only interested in certain program/versions */
143 if( (!uuid_equal( (&ri->call_data->uuid), (&rs->uuid)))
144 ||(ri->call_data->ver != rs->ver)){
149 add_srt_table_data(&rs->srt_table, ri->call_data->opnum, &ri->call_data->req_time, pinfo);
156 dcerpcstat_draw(void *rs_arg)
158 dcerpcstat_t *rs = (dcerpcstat_t *)rs_arg;
160 draw_srt_table_data(&rs->srt_table);
164 win_destroy_cb(GtkWindow *win _U_, gpointer data)
166 dcerpcstat_t *rs = (dcerpcstat_t *)data;
168 remove_tap_listener(rs);
170 free_srt_table_data(&rs->srt_table);
174 /* When called, this function will create a new instance of gtk-dcerpcstat.
177 gtk_dcerpcstat_init(const char *opt_arg, void* userdata _U_)
180 guint32 i, max_procs;
184 GtkWidget *stat_label;
185 GtkWidget *filter_label;
188 dcerpc_sub_dissector *procs;
190 guint d1,d2,d3,d40,d41,d42,d43,d44,d45,d46,d47;
194 const char *filter = NULL;
195 GString *error_string;
199 * XXX - DCE RPC statistics are maintained only by major version,
200 * not by major and minor version, so the minor version number is
203 * Should we just stop supporting minor version numbers here?
204 * Or should we allow it to be omitted? Or should we keep
205 * separate statistics for different minor version numbers,
206 * and allow the minor version number to be omitted, and
207 * report aggregate statistics for all minor version numbers
212 "dcerpc,srt,%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x,%d.%d,%n",
213 &d1,&d2,&d3,&d40,&d41,&d42,&d43,&d44,&d45,&d46,&d47,&major,&minor,&pos)
227 filter = opt_arg+pos;
232 fprintf(stderr, "wireshark: invalid \"-z dcerpc,srt,<uuid>,<major version>.<minor version>[,<filter>]\" argument\n");
235 if ((major < 0) || (major > 65535)) {
236 fprintf(stderr,"wireshark: dcerpcstat_init() Major version number %d is invalid - must be positive and <= 65535\n", major);
239 if ((minor < 0) || (minor > 65535)) {
240 fprintf(stderr,"wireshark: dcerpcstat_init() Minor version number %d is invalid - must be positive and <= 65535\n", minor);
245 rs = (dcerpcstat_t *)g_malloc(sizeof(dcerpcstat_t));
246 rs->prog = dcerpc_get_proto_name(&uuid, ver);
250 "wireshark: dcerpcstat_init() Protocol with uuid:%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x v%u not supported\n",
251 uuid.Data1,uuid.Data2,uuid.Data3,uuid.Data4[0],uuid.Data4[1],uuid.Data4[2],uuid.Data4[3],uuid.Data4[4],uuid.Data4[5],uuid.Data4[6],uuid.Data4[7],ver);
254 hf_opnum = dcerpc_get_proto_hf_opnum(&uuid, ver);
255 procs = dcerpc_get_proto_sub_dissector(&uuid, ver);
259 rs->win = dlg_window_new("dcerpc-stat"); /* transient_for top_level */
260 gtk_window_set_destroy_with_parent(GTK_WINDOW(rs->win), TRUE);
262 dcerpcstat_set_title(rs);
263 gtk_window_set_default_size(GTK_WINDOW(rs->win), 550, 400);
265 vbox =ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
266 gtk_container_add(GTK_CONTAINER(rs->win), vbox);
267 gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
269 title_string = dcerpcstat_gen_title(rs);
270 stat_label = gtk_label_new(title_string);
271 g_free(title_string);
272 gtk_box_pack_start(GTK_BOX(vbox), stat_label, FALSE, FALSE, 0);
274 filter_string = g_strdup_printf("Filter: %s",filter ? filter : "");
275 filter_label = gtk_label_new(filter_string);
276 g_free(filter_string);
277 gtk_label_set_line_wrap(GTK_LABEL(filter_label), TRUE);
278 gtk_box_pack_start(GTK_BOX(vbox), filter_label, FALSE, FALSE, 0);
280 for(i=0,max_procs=0;procs[i].name;i++){
281 if(procs[i].num>max_procs){
282 max_procs = procs[i].num;
285 rs->num_procedures = max_procs+1;
287 /* We must display TOP LEVEL Widget before calling init_srt_table() */
288 gtk_widget_show_all(rs->win);
291 init_srt_table(&rs->srt_table, max_procs+1, vbox, proto_registrar_get_nth(hf_opnum)->abbrev);
293 init_srt_table(&rs->srt_table, max_procs+1, vbox, NULL);
296 for(i=0;i<(max_procs+1);i++){
298 const char *proc_name;
300 proc_name = "unknown";
301 for(j=0;procs[j].name;j++){
302 if (procs[j].num == i){
303 proc_name = procs[j].name;
307 init_srt_table_row(&rs->srt_table, i, proc_name);
311 error_string = register_tap_listener("dcerpc", rs, filter, 0, dcerpcstat_reset, dcerpcstat_packet, dcerpcstat_draw);
313 /* error, we failed to attach to the tap. clean up */
314 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
315 g_string_free(error_string, TRUE);
316 free_srt_table_data(&rs->srt_table);
322 bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
323 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
325 close_bt = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
326 window_set_cancel_button(rs->win, close_bt, window_cancel_button_cb);
328 g_signal_connect(rs->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
329 g_signal_connect(rs->win, "destroy", G_CALLBACK(win_destroy_cb), rs);
331 gtk_widget_show_all(rs->win);
332 window_present(rs->win);
334 cf_retap_packets(&cfile);
335 gdk_window_raise(gtk_widget_get_window(rs->win));
340 static e_uuid_t *dcerpc_uuid_program;
341 static guint16 dcerpc_version;
342 static GtkWidget *dlg = NULL;
343 static GtkWidget *filter_entry;
344 static dcerpc_uuid_key *current_uuid_key;
345 static dcerpc_uuid_value *current_uuid_value;
346 static dcerpc_uuid_key *new_uuid_key;
347 static dcerpc_uuid_value *new_uuid_value;
350 dcerpcstat_start_button_clicked(GtkWidget *item _U_, gpointer data _U_)
355 if (dcerpc_uuid_program == NULL) {
356 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Please select a program");
359 str = g_string_new("dcerpc,srt");
360 g_string_append_printf(str,
361 ",%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x,%u.%u",
362 dcerpc_uuid_program->Data1, dcerpc_uuid_program->Data2,
363 dcerpc_uuid_program->Data3,
364 dcerpc_uuid_program->Data4[0], dcerpc_uuid_program->Data4[1],
365 dcerpc_uuid_program->Data4[2], dcerpc_uuid_program->Data4[3],
366 dcerpc_uuid_program->Data4[4], dcerpc_uuid_program->Data4[5],
367 dcerpc_uuid_program->Data4[6], dcerpc_uuid_program->Data4[7],
369 filter = gtk_entry_get_text(GTK_ENTRY(filter_entry));
371 g_string_append_printf(str, ",%s", filter);
374 gtk_dcerpcstat_init(str->str,NULL);
375 g_string_free(str, TRUE);
380 dcerpcstat_version_select(GtkWidget *vers_combo_box, gpointer user_data _U_)
384 if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(vers_combo_box), (gpointer *)&k)) {
385 g_assert_not_reached(); /* Programming error: somehow no active item */
388 dcerpc_version = k->ver;
392 dcerpcstat_find_vers(gpointer *key, gpointer *value _U_, gpointer user_data)
394 dcerpc_uuid_key *k = (dcerpc_uuid_key *)key;
395 GtkWidget *vers_combo_box = (GtkWidget *)user_data;
398 if(!uuid_equal(&(k->uuid), dcerpc_uuid_program)){
401 g_snprintf(vs, sizeof(vs), "%u", k->ver);
402 ws_combo_box_append_text_and_pointer(GTK_COMBO_BOX(vers_combo_box), vs, k);
406 dcerpcstat_program_select(GtkWidget *prog_combo_box, gpointer user_data)
409 GtkWidget *vers_combo_box;
411 vers_combo_box = (GtkWidget *)user_data;
413 if (! ws_combo_box_get_active_pointer(GTK_COMBO_BOX(prog_combo_box), (gpointer *)&k)) {
414 g_assert_not_reached(); /* Programming error: somehow no active item */
417 g_signal_handlers_disconnect_by_func(vers_combo_box, G_CALLBACK(dcerpcstat_version_select), NULL );
418 ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(vers_combo_box));
420 /* dcerpc_stat: invalid selection... somehow selected top level ?? */
422 dcerpc_uuid_program = &(k->uuid);
424 /* re-create version menu */
425 g_signal_handlers_disconnect_by_func(vers_combo_box, G_CALLBACK(dcerpcstat_version_select), NULL );
426 ws_combo_box_clear_text_and_pointer(GTK_COMBO_BOX(vers_combo_box));
428 g_hash_table_foreach(dcerpc_uuids, (GHFunc)dcerpcstat_find_vers, vers_combo_box);
430 g_signal_connect(vers_combo_box, "changed", G_CALLBACK(dcerpcstat_version_select), NULL);
431 ws_combo_box_set_active(GTK_COMBO_BOX(vers_combo_box), 0); /* default: triggers dcerpcstat_version_select callback */
436 dcerpcstat_add_program_to_menu(dcerpc_uuid_key *k, dcerpc_uuid_value *v, GtkWidget *prog_combo_box, int program_item_index)
438 static GtkTreeIter iter;
441 switch(program_item_index%15){
443 g_snprintf(str,sizeof(str),"%s ...",v->name);
444 iter = ws_combo_box_append_text_and_pointer_full(
445 GTK_COMBO_BOX(prog_combo_box), NULL, str, NULL, FALSE); /* top-level entries are insensitive */
452 return ws_combo_box_append_text_and_pointer_full(
453 GTK_COMBO_BOX(prog_combo_box), &iter, v->name, k, TRUE);
457 dcerpcstat_find_next_program(gpointer *key, gpointer *value, gpointer *user_data _U_)
459 dcerpc_uuid_key *k = (dcerpc_uuid_key *)key;
460 dcerpc_uuid_value *v = (dcerpc_uuid_value *)value;
462 /* first time called, just set new_uuid to this one */
463 if((current_uuid_key==NULL) && (new_uuid_key==NULL)){
469 /* if we haven't got a current one yet, just check the new
470 and scan for the first one alphabetically */
471 if(current_uuid_key==NULL){
472 if(strcmp(new_uuid_value->name, v->name)>0){
480 /* searching for the next one we are only interested in those
481 that sorts alphabetically after the current one */
482 if(strcmp(current_uuid_value->name, v->name) >= 0){
483 /* this one doesn't so just skip it */
487 /* is it the first potential new entry? */
488 if(new_uuid_key==NULL){
494 /* does it sort before the current new one? */
495 if(strcmp(new_uuid_value->name, v->name) > 0){
506 dlg_destroy_cb(GtkWidget *w _U_, gpointer user_data _U_)
512 void gtk_dcerpcstat_cb(GtkAction *action _U_, gpointer user_data _U_)
515 GtkWidget *prog_box, *prog_label, *prog_combo_box;
516 GtkWidget *vers_label, *vers_combo_box;
517 GtkWidget *filter_box, *filter_bt;
518 GtkWidget *bbox, *start_button, *cancel_button;
519 GtkCellRenderer *cell_renderer;
521 GtkTreeIter program_first_item_iter;
524 int program_item_index = 0;
526 static construct_args_t args = {
527 "Service Response Time Statistics Filter",
533 /* if the window is already open, bring it to front and
534 un-minimize it, as necessary */
536 reactivate_window(dlg);
540 dlg = dlg_window_new("Wireshark: Compute DCE-RPC SRT statistics");
541 gtk_window_set_default_size(GTK_WINDOW(dlg), 400, -1);
543 dlg_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 10, FALSE);
544 gtk_container_set_border_width(GTK_CONTAINER(dlg_box), 10);
545 gtk_container_add(GTK_CONTAINER(dlg), dlg_box);
546 gtk_widget_show(dlg_box);
549 prog_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
552 gtk_container_set_border_width(GTK_CONTAINER(prog_box), 10);
553 prog_label = gtk_label_new("Program:");
554 gtk_box_pack_start(GTK_BOX(prog_box), prog_label, FALSE, FALSE, 0);
555 gtk_widget_show(prog_label);
558 dcerpc_uuid_program = NULL; /* default: no program selected */
560 /* The "program combo box" is implemented with a two-level tree.
561 Each top-level of the tree has (up to) 15 selectable "program name"
562 children and shows the name of the first child of that entry
563 as "child_name ...". Each of the top-level entries can be expanded
564 (to show the children) but is "insensitive": ie: cannot be selected.
565 (dcerpcstat_add_program_to_menu() does the actual work to add entries
567 XXX: A simpler alternative might be to just do away with all the two-level
568 complexity and just use a standard ws_combo_box... even though the
569 list of "program names" is quite large.
570 XXX: The gtkrc file distributed with Windows Wireshark has the
571 "appears-as-list" GtkComboBox style property set to 1 and thus
572 on Windows the entries for this combo box will appear as a tree-view.
573 The default is 0(FALSE). In this case the the combo box entries will
574 display as a menu with sub-menus.
575 A possibility would be to set "appears-as-list" to 0 just for this
576 particular combo box on Windows so that the entries will appear as a
577 menu even on Windows).
579 prog_combo_box = ws_combo_box_new_text_and_pointer_full(&cell_renderer);
581 /* XXX: Hack So that the top-level insensitive entries don't show
582 as "grayed out"; The "foreground normal" color is used instead.
583 This may not really be necessary but seems better to me.
585 #if GTK_CHECK_VERSION(3,0,0)
586 GtkStyleContext *context;
587 GdkRGBA *new_rgba_fg_color;
588 context = gtk_widget_get_style_context (prog_combo_box);
589 gtk_style_context_get (context, GTK_STATE_FLAG_NORMAL,
590 "color", &new_rgba_fg_color,
593 g_object_set(cell_renderer,
594 "foreground-rgba", &new_rgba_fg_color,
595 "foreground-set", TRUE,
600 s = gtk_widget_get_style(prog_combo_box);
601 g_object_set(cell_renderer,
602 "foreground-gdk", &(s->fg[GTK_STATE_NORMAL]),
603 "foreground-set", TRUE,
608 current_uuid_key = NULL;
609 current_uuid_value = NULL;
612 new_uuid_value = NULL;
613 g_hash_table_foreach(dcerpc_uuids, (GHFunc)dcerpcstat_find_next_program, NULL);
616 GtkTreeIter tmp_iter;
617 tmp_iter = dcerpcstat_add_program_to_menu(new_uuid_key, new_uuid_value,
618 prog_combo_box, program_item_index);
619 if (program_item_index == 0)
620 program_first_item_iter = tmp_iter;
622 dcerpcstat_add_program_to_menu(new_uuid_key, new_uuid_value,
623 prog_combo_box, program_item_index);
625 program_item_index += 1;
627 current_uuid_key = new_uuid_key;
628 current_uuid_value = new_uuid_value;
629 } while(new_uuid_key != NULL);
630 gtk_box_pack_start(GTK_BOX(prog_box), prog_combo_box, TRUE, TRUE, 0);
631 gtk_widget_show(prog_combo_box);
634 gtk_container_set_border_width(GTK_CONTAINER(prog_box), 10);
635 vers_label = gtk_label_new("Version:");
636 gtk_box_pack_start(GTK_BOX(prog_box), vers_label, FALSE, FALSE, 0);
637 gtk_widget_show(vers_label);
639 /* Version combo-box */
640 /* Note: version combo box rows set when dcerpcstat_program_select() callback invoked */
641 vers_combo_box = ws_combo_box_new_text_and_pointer();
642 gtk_box_pack_start(GTK_BOX(prog_box), vers_combo_box, TRUE, TRUE, 0);
643 gtk_widget_show(vers_combo_box);
645 g_signal_connect(prog_combo_box, "changed", G_CALLBACK(dcerpcstat_program_select), vers_combo_box);
646 #if 0 /* Don't select an active entry given the way the drop down treeview appears if a default (active) entry is set */
647 ws_combo_box_set_active_iter(GTK_COMBO_BOX(prog_combo_box), &program_first_item_iter); /* triggers callback */
649 gtk_box_pack_start(GTK_BOX(dlg_box), prog_box, TRUE, TRUE, 0);
650 gtk_widget_show(prog_box);
653 filter_box = ws_gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3, FALSE);
656 filter_bt = ws_gtk_button_new_from_stock(WIRESHARK_STOCK_DISPLAY_FILTER_ENTRY);
657 g_signal_connect(filter_bt, "clicked", G_CALLBACK(display_filter_construct_cb), &args);
658 gtk_box_pack_start(GTK_BOX(filter_box), filter_bt, FALSE, FALSE, 0);
659 gtk_widget_show(filter_bt);
662 filter_entry = gtk_entry_new();
663 g_signal_connect(filter_entry, "changed", G_CALLBACK(filter_te_syntax_check_cb), NULL);
664 g_object_set_data(G_OBJECT(filter_box), E_FILT_AUTOCOMP_PTR_KEY, NULL);
665 g_signal_connect(filter_entry, "key-press-event", G_CALLBACK (filter_string_te_key_pressed_cb), NULL);
666 g_signal_connect(dlg, "key-press-event", G_CALLBACK (filter_parent_dlg_key_pressed_cb), NULL);
667 gtk_box_pack_start(GTK_BOX(filter_box), filter_entry, TRUE, TRUE, 0);
668 filter = gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
670 gtk_entry_set_text(GTK_ENTRY(filter_entry), filter);
672 colorize_filter_te_as_empty(filter_entry);
674 gtk_widget_show(filter_entry);
676 gtk_box_pack_start(GTK_BOX(dlg_box), filter_box, TRUE, TRUE, 0);
677 gtk_widget_show(filter_box);
679 g_object_set_data(G_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_entry);
682 bbox = dlg_button_row_new(WIRESHARK_STOCK_CREATE_STAT, GTK_STOCK_CANCEL, NULL);
683 gtk_box_pack_start(GTK_BOX(dlg_box), bbox, FALSE, FALSE, 0);
684 gtk_widget_show(bbox);
686 start_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), WIRESHARK_STOCK_CREATE_STAT);
687 g_signal_connect_swapped(start_button, "clicked",
688 G_CALLBACK(dcerpcstat_start_button_clicked), NULL);
690 cancel_button = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CANCEL);
691 window_set_cancel_button(dlg, cancel_button, window_cancel_button_cb);
693 g_signal_connect(dlg, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
694 g_signal_connect(dlg, "destroy", G_CALLBACK(dlg_destroy_cb), NULL);
696 /* Catch the "activate" signal on the filter text entry, so that
697 if the user types Return there, we act as if the "Create Stat"
698 button had been selected, as happens if Return is typed if some
699 widget that *doesn't* handle the Return key has the input
701 dlg_set_activate(filter_entry, start_button);
703 gtk_widget_grab_default(start_button );
705 /* Give the initial focus to the "Filter" entry box. */
706 gtk_widget_grab_focus(filter_entry);
708 gtk_widget_show_all(dlg);
712 static stat_tap_ui dcerpcstat_ui = {
713 REGISTER_STAT_GROUP_GENERIC,
723 register_tap_listener_gtkdcerpcstat(void)
725 register_stat_tap_ui(&dcerpcstat_ui, NULL);