Andrew Hood: don't rely on last modified date + use numeric compare
[metze/wireshark/wip.git] / gtk / endpoint_talkers_table.c
1 /* mem leak   should free the column_arrows when the table is destroyed */
2
3 /* endpoint_talkers_table.c
4  * endpoint_talkers_table   2003 Ronnie Sahlberg
5  * Helper routines common to all endpoint talkers tap.
6  *
7  * $Id: endpoint_talkers_table.c,v 1.32 2004/02/23 22:48:51 guy Exp $
8  *
9  * Ethereal - Network traffic analyzer
10  * By Gerald Combs <gerald@ethereal.com>
11  * Copyright 1998 Gerald Combs
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <math.h>
36
37 #include <gtk/gtk.h>
38
39 #include "compat_macros.h"
40 #include "epan/packet_info.h"
41 #include "epan/to_str.h"
42 #include "endpoint_talkers_table.h"
43 #include "image/clist_ascend.xpm"
44 #include "image/clist_descend.xpm"
45 #include "simple_dialog.h"
46 #include "globals.h"
47 #include "tap.h"
48 #include "gtk/find_dlg.h"
49 #include "color.h"
50 #include "gtk/color_dlg.h"
51 #include "gtkglobals.h"
52 #include "main.h"
53 #include "ui_util.h"
54
55 extern GtkWidget   *main_display_filter_widget;
56
57
58 #define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
59
60 #define NUM_COLS 10
61
62
63 /* convert a port number into a string */
64 static char *
65 ett_port_to_str(int port_type, guint32 port)
66 {
67         static int i=0;
68         static gchar *strp, str[4][12];
69
70         i++;
71         if(i>=4){
72                 i=0;
73         }
74         strp=str[i];
75
76         switch(port_type){
77         case PT_TCP:
78         case PT_UDP:
79                 snprintf(strp, 11, "%d", port);
80                 return strp;
81         }
82         return NULL;
83 }
84
85
86 #define FN_SRC_ADDRESS          0
87 #define FN_DST_ADDRESS          1
88 #define FN_ANY_ADDRESS          2
89 #define FN_SRC_PORT             3
90 #define FN_DST_PORT             4
91 #define FN_ANY_PORT             5
92 /* given an address (to distinguis between ipv4 and ipv6 for tcp/udp
93    a port_type and a name_type (FN_...)
94    return a string for the filter name
95
96    some addresses, like AT_ETHER may actually be any of multiple types
97    of protocols,   either ethernet, tokenring, fddi etc so we must be more 
98    specific there  thats why we need specific_addr_type
99 */
100 static char *
101 ett_get_filter_name(address *addr, int specific_addr_type, int port_type, int name_type)
102 {
103         switch(name_type){
104         case FN_SRC_ADDRESS:
105                 switch(addr->type){
106                 case AT_ETHER:
107                         switch(specific_addr_type){
108                         case SAT_ETHER:
109                                 return "eth.src";
110                         case SAT_FDDI:
111                                 return "fddi.src";
112                         case SAT_TOKENRING:
113                                 return "tr.src";
114                         }
115                 case AT_IPv4:
116                         return "ip.src";
117                 case AT_IPv6:
118                         return "ipv6.src";
119                 case AT_IPX:
120                         return "ipx.src";
121                 case AT_FC:
122                         return "fc.s_id";
123                 default:
124                         ;
125                 }
126         case FN_DST_ADDRESS:
127                 switch(addr->type){
128                 case AT_ETHER:
129                         switch(specific_addr_type){
130                         case SAT_ETHER:
131                                 return "eth.dst";
132                         case SAT_FDDI:
133                                 return "fddi.dst";
134                         case SAT_TOKENRING:
135                                 return "tr.dst";
136                         }
137                 case AT_IPv4:
138                         return "ip.dst";
139                 case AT_IPv6:
140                         return "ipv6.dst";
141                 case AT_IPX:
142                         return "ipx.dst";
143                 case AT_FC:
144                         return "fc.d_id";
145                 default:
146                         ;
147                 }
148         case FN_ANY_ADDRESS:
149                 switch(addr->type){
150                 case AT_ETHER:
151                         switch(specific_addr_type){
152                         case SAT_ETHER:
153                                 return "eth.addr";
154                         case SAT_FDDI:
155                                 return "fddi.addr";
156                         case SAT_TOKENRING:
157                                 return "tr.addr";
158                         }
159                 case AT_IPv4:
160                         return "ip.addr";
161                 case AT_IPv6:
162                         return "ipv6.addr";
163                 case AT_IPX:
164                         return "ipx.addr";
165                 case AT_FC:
166                         return "fc.id";
167                 default:
168                         ;
169                 }
170         case FN_SRC_PORT:
171                 switch(port_type){
172                 case PT_TCP:
173                         return "tcp.srcport";
174                 case PT_UDP:
175                         return "udp.srcport";
176                 }
177                 break;
178         case FN_DST_PORT:
179                 switch(port_type){
180                 case PT_TCP:
181                         return "tcp.dstport";
182                 case PT_UDP:
183                         return "udp.dstport";
184                 }
185                 break;
186         case FN_ANY_PORT:
187                 switch(port_type){
188                 case PT_TCP:
189                         return "tcp.port";
190                 case PT_UDP:
191                         return "udp.port";
192                 }
193                 break;
194         }
195
196         g_assert_not_reached();
197         return NULL;
198 }
199
200
201 typedef struct column_arrows {
202         GtkWidget *table;
203         GtkWidget *ascend_pm;
204         GtkWidget *descend_pm;
205 } column_arrows;
206
207
208
209 static void
210 reset_ett_table_data(endpoints_table *et)
211 {
212         guint32 i;
213         char title[256];
214
215         snprintf(title, 255, "%s Conversations: %s", et->name, cf_get_display_name(&cfile));
216         gtk_window_set_title(GTK_WINDOW(et->win), title);
217
218         /* remove all entries from the clist */
219         for(i=0;i<et->num_endpoints;i++){
220                 gtk_clist_remove(et->table, et->num_endpoints-i);
221         }
222
223         /* delete all endpoints */
224         for(i=0;i<et->num_endpoints;i++){
225                 g_free((gpointer)et->endpoints[i].src_address.data);
226                 g_free((gpointer)et->endpoints[i].dst_address.data);
227         }
228         g_free(et->endpoints);
229         et->endpoints=NULL;
230         et->num_endpoints=0;
231 }
232
233
234 void protect_thread_critical_region(void);
235 void unprotect_thread_critical_region(void);
236 static void
237 ett_win_destroy_cb(GtkWindow *win _U_, gpointer data)
238 {
239         endpoints_table *talkers=(endpoints_table *)data;
240
241         protect_thread_critical_region();
242         remove_tap_listener(talkers);
243         unprotect_thread_critical_region();
244
245         reset_ett_table_data(talkers);
246         g_free(talkers);
247 }
248
249
250
251 static gint
252 ett_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2)
253 {
254         char *text1 = NULL;
255         char *text2 = NULL;
256         int i1, i2;
257
258         GtkCListRow *row1 = (GtkCListRow *) ptr1;
259         GtkCListRow *row2 = (GtkCListRow *) ptr2;
260
261         text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
262         text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
263
264         switch(clist->sort_column){
265         case 0:
266         case 2:
267                 return strcmp (text1, text2);
268         case 1:
269         case 3:
270         case 4:
271         case 5:
272         case 6:
273         case 7:
274         case 8:
275         case 9:
276                 i1=atoi(text1);
277                 i2=atoi(text2);
278                 return i1-i2;
279         }
280         g_assert_not_reached();
281         return 0;
282 }
283
284
285 static void
286 ett_click_column_cb(GtkCList *clist, gint column, gpointer data)
287 {
288         column_arrows *col_arrows = (column_arrows *) data;
289         int i;
290
291         gtk_clist_freeze(clist);
292
293         for (i = 0; i < NUM_COLS; i++) {
294                 gtk_widget_hide(col_arrows[i].ascend_pm);
295                 gtk_widget_hide(col_arrows[i].descend_pm);
296         }
297
298         if (column == clist->sort_column) {
299                 if (clist->sort_type == GTK_SORT_ASCENDING) {
300                         clist->sort_type = GTK_SORT_DESCENDING;
301                         gtk_widget_show(col_arrows[column].descend_pm);
302                 } else {
303                         clist->sort_type = GTK_SORT_ASCENDING;
304                         gtk_widget_show(col_arrows[column].ascend_pm);
305                 }
306         } else {
307                 clist->sort_type = GTK_SORT_DESCENDING;
308                 gtk_widget_show(col_arrows[column].descend_pm);
309                 gtk_clist_set_sort_column(clist, column);
310         }
311         gtk_clist_thaw(clist);
312
313         gtk_clist_sort(clist);
314 }
315
316
317 /* action is encoded as 
318    filter_action*65536+filter_type*256+filter_direction
319
320    filter_action:
321         0: Match
322         1: Prepare
323         2: Find Frame
324         3:   Find Next
325         4:   Find Previous
326         5: Colorize Conversation
327    filter_type:
328         0: Selected
329         1: Not Selected
330         2: And Selected
331         3: Or Selected
332         4: And Not Selected
333         5: Or Not Selected
334    filter_direction:
335         0: EP1 To/From EP2
336         1: EP1 To EP2
337         2: EP1 From EP2
338         3: EP1 To/From ANY
339         4: EP1 To ANY
340         5: EP1 From ANY
341         6: EP1 To/From ANY
342         7: EP2 To ANY
343         8: EP2 From ANY
344 */
345 static void
346 ett_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint callback_action)
347 {
348         int action, type, direction;
349         int selection;
350         endpoints_table *et = (endpoints_table *)callback_data;
351         char dirstr[128];
352         char str[256];
353         const char *current_filter;
354         char *sport, *dport;
355
356         action=(callback_action>>16)&0xff;
357         type=(callback_action>>8)&0xff;
358         direction=callback_action&0xff;
359
360
361         selection=GPOINTER_TO_INT(g_list_nth_data(GTK_CLIST(et->table)->selection, 0));
362         if(selection>=(int)et->num_endpoints){
363                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "No conversation selected");
364                 return;
365         }
366         /* translate it back from row index to index in enndpoint array */
367         selection=GPOINTER_TO_INT(gtk_clist_get_row_data(et->table, selection));
368
369         sport=ett_port_to_str(et->endpoints[selection].port_type, et->endpoints[selection].src_port);
370         dport=ett_port_to_str(et->endpoints[selection].port_type, et->endpoints[selection].dst_port);
371
372         switch(direction){
373         case 0:
374                 /* EP1 <-> EP2 */
375                 snprintf(dirstr, 127, "%s==%s %s%s%s%s && %s==%s %s%s%s%s",
376                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_ADDRESS),
377                         address_to_str(&et->endpoints[selection].src_address),
378                         sport?" && ":"",
379                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_PORT):"",
380                         sport?"==":"",
381                         sport?sport:"",
382                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_ADDRESS),
383                         address_to_str(&et->endpoints[selection].dst_address),
384                         dport?" && ":"",
385                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_PORT):"",
386                         dport?"==":"",
387                         dport?dport:""
388                 );
389                 break;
390         case 1:
391                 /* EP1 --> EP2 */
392                 snprintf(dirstr, 127, "%s==%s %s%s%s%s && %s==%s %s%s%s%s",
393                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_ADDRESS),
394                         address_to_str(&et->endpoints[selection].src_address),
395                         sport?" && ":"",
396                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_PORT):"",
397                         sport?"==":"",
398                         sport?sport:"",
399                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_ADDRESS),
400                         address_to_str(&et->endpoints[selection].dst_address),
401                         dport?" && ":"",
402                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_PORT):"",
403                         dport?"==":"",
404                         dport?dport:""
405                 );
406                 break;
407         case 2:
408                 /* EP1 <-- EP2 */
409                 snprintf(dirstr, 127, "%s==%s %s%s%s%s && %s==%s %s%s%s%s",
410                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_ADDRESS),
411                         address_to_str(&et->endpoints[selection].src_address),
412                         sport?" && ":"",
413                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_PORT):"",
414                         sport?"==":"",
415                         sport?sport:"",
416                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_ADDRESS),
417                         address_to_str(&et->endpoints[selection].dst_address),
418                         dport?" && ":"",
419                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_PORT):"",
420                         dport?"==":"",
421                         dport?dport:""
422                 );
423                 break;
424         case 3:
425                 /* EP1 <-> ANY */
426                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
427                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_ADDRESS),
428                         address_to_str(&et->endpoints[selection].src_address),
429                         sport?" && ":"",
430                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_PORT):"",
431                         sport?"==":"",
432                         sport?sport:""
433                 );
434                 break;
435         case 4:
436                 /* EP1 --> ANY */
437                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
438                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_ADDRESS),
439                         address_to_str(&et->endpoints[selection].src_address),
440                         sport?" && ":"",
441                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_PORT):"",
442                         sport?"==":"",
443                         sport?sport:""
444                 );
445                 break;
446         case 5:
447                 /* EP1 <-- ANY */
448                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
449                         ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_ADDRESS),
450                         address_to_str(&et->endpoints[selection].src_address),
451                         sport?" && ":"",
452                         sport?ett_get_filter_name(&et->endpoints[selection].src_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_PORT):"",
453                         sport?"==":"",
454                         sport?sport:""
455                 );
456                 break;
457         case 6:
458                 /* EP2 <-> ANY */
459                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
460                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_ADDRESS),
461                         address_to_str(&et->endpoints[selection].dst_address),
462                         dport?" && ":"",
463                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_ANY_PORT):"",
464                         dport?"==":"",
465                         dport?dport:""
466                 );
467                 break;
468         case 7:
469                 /* EP2 --> ANY */
470                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
471                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_ADDRESS),
472                         address_to_str(&et->endpoints[selection].dst_address),
473                         dport?" && ":"",
474                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_SRC_PORT):"",
475                         dport?"==":"",
476                         dport?dport:""
477                 );
478                 break;
479         case 8:
480                 /* EP2 <-- ANY */
481                 snprintf(dirstr, 127, "%s==%s %s%s%s%s",
482                         ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_ADDRESS),
483                         address_to_str(&et->endpoints[selection].dst_address),
484                         dport?" && ":"",
485                         dport?ett_get_filter_name(&et->endpoints[selection].dst_address, et->endpoints[selection].sat, et->endpoints[selection].port_type,  FN_DST_PORT):"",
486                         dport?"==":"",
487                         dport?dport:""
488                 );
489                 break;
490         }
491
492         current_filter=gtk_entry_get_text(GTK_ENTRY(main_display_filter_widget));
493         switch(type){
494         case 0:
495                 /* selected */
496                 snprintf(str, 255, "%s", dirstr);
497                 break;
498         case 1:
499                 /* not selected */
500                 snprintf(str, 255, "!(%s)", dirstr);
501                 break;
502         case 2:
503                 /* and selected */
504                 snprintf(str, 255, "(%s) && (%s)", current_filter, dirstr);
505                 break;
506         case 3:
507                 /* or selected */
508                 snprintf(str, 255, "(%s) || (%s)", current_filter, dirstr);
509                 break;
510         case 4:
511                 /* and not selected */
512                 snprintf(str, 255, "(%s) && !(%s)", current_filter, dirstr);
513                 break;
514         case 5:
515                 /* or not selected */
516                 snprintf(str, 255, "(%s) || !(%s)", current_filter, dirstr);
517                 break;
518         }
519
520         switch(action){
521         case 0:
522                 /* match */
523                 gtk_entry_set_text(GTK_ENTRY(main_display_filter_widget), str);
524                 main_filter_packets(&cfile, str, FALSE);
525                 gdk_window_raise(top_level->window);
526                 break;
527         case 1:
528                 /* prepare */
529                 gtk_entry_set_text(GTK_ENTRY(main_display_filter_widget), str);
530                 break;
531         case 2:
532                 /* find frame */
533                 find_frame_with_filter(str);
534                 break;
535         case 3:
536                 /* find next */
537                 find_previous_next_frame_with_filter(str, FALSE);
538                 break;
539         case 4:
540                 /* find previous */
541                 find_previous_next_frame_with_filter(str, TRUE);
542                 break;
543         case 5:
544                 /* colorize conversation */
545                 color_display_with_filter(str);
546                 break;
547         }
548
549 }
550
551 static gint
552 ett_show_popup_menu_cb(void *widg _U_, GdkEvent *event, endpoints_table *et)
553 {
554         GdkEventButton *bevent = (GdkEventButton *)event;
555
556         if(event->type==GDK_BUTTON_PRESS && bevent->button==3){
557                 gtk_menu_popup(GTK_MENU(et->menu), NULL, NULL, NULL, NULL, 
558                         bevent->button, bevent->time);
559         }
560
561         return FALSE;
562 }
563
564 static GtkItemFactoryEntry ett_list_menu_items[] =
565 {
566         /* Match */
567         ITEM_FACTORY_ENTRY("/Match Display Filter", NULL, NULL, 0, "<Branch>", NULL),
568         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected", NULL, NULL, 0, "<Branch>", NULL),
569         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 <-> EP2", NULL,
570                 ett_select_filter_cb, 0*65536+0*256+0, NULL, NULL),
571         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 --> EP2", NULL,
572                 ett_select_filter_cb, 0*65536+0*256+1, NULL, NULL),
573         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 <-- EP2", NULL,
574                 ett_select_filter_cb, 0*65536+0*256+2, NULL, NULL),
575         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 <-> ANY", NULL,
576                 ett_select_filter_cb, 0*65536+0*256+3, NULL, NULL),
577         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 --> ANY", NULL,
578                 ett_select_filter_cb, 0*65536+0*256+4, NULL, NULL),
579         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/EP1 <-- ANY", NULL,
580                 ett_select_filter_cb, 0*65536+0*256+5, NULL, NULL),
581         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/ANY <-> EP2", NULL,
582                 ett_select_filter_cb, 0*65536+0*256+6, NULL, NULL),
583         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/ANY <-- EP2", NULL,
584                 ett_select_filter_cb, 0*65536+0*256+7, NULL, NULL),
585         ITEM_FACTORY_ENTRY("/Match Display Filter/Selected/ANY --> EP2", NULL,
586                 ett_select_filter_cb, 0*65536+0*256+8, NULL, NULL),
587
588         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected", NULL, NULL, 0, "<Branch>", NULL),
589         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 <-> EP2", NULL,
590                 ett_select_filter_cb, 0*65536+1*256+0, NULL, NULL),
591         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 --> EP2", NULL,
592                 ett_select_filter_cb, 0*65536+1*256+1, NULL, NULL),
593         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 <-- EP2", NULL,
594                 ett_select_filter_cb, 0*65536+1*256+2, NULL, NULL),
595         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 --> ANY", NULL,
596                 ett_select_filter_cb, 0*65536+1*256+3, NULL, NULL),
597         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 <-> ANY", NULL,
598                 ett_select_filter_cb, 0*65536+1*256+4, NULL, NULL),
599         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/EP1 <-- ANY", NULL,
600                 ett_select_filter_cb, 0*65536+1*256+5, NULL, NULL),
601         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/ANY <-> EP2", NULL,
602                 ett_select_filter_cb, 0*65536+1*256+6, NULL, NULL),
603         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/ANY <-- EP2", NULL,
604                 ett_select_filter_cb, 0*65536+1*256+7, NULL, NULL),
605         ITEM_FACTORY_ENTRY("/Match Display Filter/Not Selected/ANY --> EP2", NULL,
606                 ett_select_filter_cb, 0*65536+1*256+8, NULL, NULL),
607
608
609         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected", NULL, NULL, 0, "<Branch>", NULL),
610         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 <-> EP2", NULL,
611                 ett_select_filter_cb, 0*65536+2*256+0, NULL, NULL),
612         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 --> EP2", NULL,
613                 ett_select_filter_cb, 0*65536+2*256+1, NULL, NULL),
614         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 <-- EP2", NULL,
615                 ett_select_filter_cb, 0*65536+2*256+2, NULL, NULL),
616         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 <-> ANY", NULL,
617                 ett_select_filter_cb, 0*65536+2*256+3, NULL, NULL),
618         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 --> ANY", NULL,
619                 ett_select_filter_cb, 0*65536+2*256+4, NULL, NULL),
620         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/EP1 <-- ANY", NULL,
621                 ett_select_filter_cb, 0*65536+2*256+5, NULL, NULL),
622         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/ANY <-> EP2", NULL,
623                 ett_select_filter_cb, 0*65536+2*256+6, NULL, NULL),
624         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/ANY <-- EP2", NULL,
625                 ett_select_filter_cb, 0*65536+2*256+7, NULL, NULL),
626         ITEM_FACTORY_ENTRY("/Match Display Filter/And Selected/ANY --> EP2", NULL,
627                 ett_select_filter_cb, 0*65536+2*256+8, NULL, NULL),
628
629         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected", NULL, NULL, 0, "<Branch>", NULL),
630         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 <-> EP2", NULL,
631                 ett_select_filter_cb, 0*65536+3*256+0, NULL, NULL),
632         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 --> EP2", NULL,
633                 ett_select_filter_cb, 0*65536+3*256+1, NULL, NULL),
634         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 <-- EP2", NULL,
635                 ett_select_filter_cb, 0*65536+3*256+2, NULL, NULL),
636         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 <-> ANY", NULL,
637                 ett_select_filter_cb, 0*65536+3*256+3, NULL, NULL),
638         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 --> ANY", NULL,
639                 ett_select_filter_cb, 0*65536+3*256+4, NULL, NULL),
640         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/EP1 <-- ANY", NULL,
641                 ett_select_filter_cb, 0*65536+3*256+5, NULL, NULL),
642         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/ANY <-> EP2", NULL,
643                 ett_select_filter_cb, 0*65536+3*256+6, NULL, NULL),
644         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/ANY <-- EP2", NULL,
645                 ett_select_filter_cb, 0*65536+3*256+7, NULL, NULL),
646         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Selected/ANY --> EP2", NULL,
647                 ett_select_filter_cb, 0*65536+3*256+8, NULL, NULL),
648
649         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected", NULL, NULL, 0, "<Branch>", NULL),
650         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 <-> EP2", NULL,
651                 ett_select_filter_cb, 0*65536+4*256+0, NULL, NULL),
652         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 --> EP2", NULL,
653                 ett_select_filter_cb, 0*65536+4*256+1, NULL, NULL),
654         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 <-- EP2", NULL,
655                 ett_select_filter_cb, 0*65536+4*256+2, NULL, NULL),
656         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 <-> ANY", NULL,
657                 ett_select_filter_cb, 0*65536+4*256+3, NULL, NULL),
658         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 --> ANY", NULL,
659                 ett_select_filter_cb, 0*65536+4*256+4, NULL, NULL),
660         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/EP1 <-- ANY", NULL,
661                 ett_select_filter_cb, 0*65536+4*256+5, NULL, NULL),
662         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/ANY <-> EP2", NULL,
663                 ett_select_filter_cb, 0*65536+4*256+6, NULL, NULL),
664         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/ANY <-- EP2", NULL,
665                 ett_select_filter_cb, 0*65536+4*256+7, NULL, NULL),
666         ITEM_FACTORY_ENTRY("/Match Display Filter/And Not Selected/ANY --> EP2", NULL,
667                 ett_select_filter_cb, 0*65536+4*256+8, NULL, NULL),
668
669         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected", NULL, NULL, 0, "<Branch>", NULL),
670         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 <-> EP2", NULL,
671                 ett_select_filter_cb, 0*65536+5*256+0, NULL, NULL),
672         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 --> EP2", NULL,
673                 ett_select_filter_cb, 0*65536+5*256+1, NULL, NULL),
674         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 <-- EP2", NULL,
675                 ett_select_filter_cb, 0*65536+5*256+2, NULL, NULL),
676         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 <-> ANY", NULL,
677                 ett_select_filter_cb, 0*65536+5*256+3, NULL, NULL),
678         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 --> ANY", NULL,
679                 ett_select_filter_cb, 0*65536+5*256+4, NULL, NULL),
680         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/EP1 <-- ANY", NULL,
681                 ett_select_filter_cb, 0*65536+5*256+5, NULL, NULL),
682         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/ANY <-> EP2", NULL,
683                 ett_select_filter_cb, 0*65536+5*256+6, NULL, NULL),
684         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/ANY <-- EP2", NULL,
685                 ett_select_filter_cb, 0*65536+5*256+7, NULL, NULL),
686         ITEM_FACTORY_ENTRY("/Match Display Filter/Or Not Selected/ANY --> EP2", NULL,
687                 ett_select_filter_cb, 0*65536+5*256+8, NULL, NULL),
688
689         /* Prepare */
690         ITEM_FACTORY_ENTRY("/Prepare Display Filter", NULL, NULL, 0, "<Branch>", NULL),
691         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected", NULL, NULL, 0, "<Branch>", NULL),
692         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 <-> EP2", NULL,
693                 ett_select_filter_cb, 1*65536+0*256+0, NULL, NULL),
694         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 --> EP2", NULL,
695                 ett_select_filter_cb, 1*65536+0*256+1, NULL, NULL),
696         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 <-- EP2", NULL,
697                 ett_select_filter_cb, 1*65536+0*256+2, NULL, NULL),
698         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 <-> ANY", NULL,
699                 ett_select_filter_cb, 1*65536+0*256+3, NULL, NULL),
700         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 --> ANY", NULL,
701                 ett_select_filter_cb, 1*65536+0*256+4, NULL, NULL),
702         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/EP1 <-- ANY", NULL,
703                 ett_select_filter_cb, 1*65536+0*256+5, NULL, NULL),
704         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/ANY <-> EP2", NULL,
705                 ett_select_filter_cb, 1*65536+0*256+6, NULL, NULL),
706         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/ANY <-- EP2", NULL,
707                 ett_select_filter_cb, 1*65536+0*256+7, NULL, NULL),
708         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Selected/ANY --> EP2", NULL,
709                 ett_select_filter_cb, 1*65536+0*256+8, NULL, NULL),
710
711         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected", NULL, NULL, 0, "<Branch>", NULL),
712         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 <-> EP2", NULL,
713                 ett_select_filter_cb, 1*65536+1*256+0, NULL, NULL),
714         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 --> EP2", NULL,
715                 ett_select_filter_cb, 1*65536+1*256+1, NULL, NULL),
716         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 <-- EP2", NULL,
717                 ett_select_filter_cb, 1*65536+1*256+2, NULL, NULL),
718         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 <-> ANY", NULL,
719                 ett_select_filter_cb, 1*65536+1*256+3, NULL, NULL),
720         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 --> ANY", NULL,
721                 ett_select_filter_cb, 1*65536+1*256+4, NULL, NULL),
722         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/EP1 <-- ANY", NULL,
723                 ett_select_filter_cb, 1*65536+1*256+5, NULL, NULL),
724         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/ANY <-> EP2", NULL,
725                 ett_select_filter_cb, 1*65536+1*256+6, NULL, NULL),
726         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/ANY <-- EP2", NULL,
727                 ett_select_filter_cb, 1*65536+1*256+7, NULL, NULL),
728         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Not Selected/ANY --> EP2", NULL,
729                 ett_select_filter_cb, 1*65536+1*256+8, NULL, NULL),
730
731         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected", NULL, NULL, 0, "<Branch>", NULL),
732         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 <-> EP2", NULL,
733                 ett_select_filter_cb, 1*65536+2*256+0, NULL, NULL),
734         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 --> EP2", NULL,
735                 ett_select_filter_cb, 1*65536+2*256+1, NULL, NULL),
736         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 <-- EP2", NULL,
737                 ett_select_filter_cb, 1*65536+2*256+2, NULL, NULL),
738         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 <-> ANY", NULL,
739                 ett_select_filter_cb, 1*65536+2*256+3, NULL, NULL),
740         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 --> ANY", NULL,
741                 ett_select_filter_cb, 1*65536+2*256+4, NULL, NULL),
742         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/EP1 <-- ANY", NULL,
743                 ett_select_filter_cb, 1*65536+2*256+5, NULL, NULL),
744         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/ANY <-> EP2", NULL,
745                 ett_select_filter_cb, 1*65536+2*256+6, NULL, NULL),
746         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/ANY <-- EP2", NULL,
747                 ett_select_filter_cb, 1*65536+2*256+7, NULL, NULL),
748         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Selected/ANY --> EP2", NULL,
749                 ett_select_filter_cb, 1*65536+2*256+8, NULL, NULL),
750
751         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected", NULL, NULL, 0, "<Branch>", NULL),
752         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 <-> EP2", NULL,
753                 ett_select_filter_cb, 1*65536+3*256+0, NULL, NULL),
754         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 --> EP2", NULL,
755                 ett_select_filter_cb, 1*65536+3*256+1, NULL, NULL),
756         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 <-- EP2", NULL,
757                 ett_select_filter_cb, 1*65536+3*256+2, NULL, NULL),
758         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 <-> ANY", NULL,
759                 ett_select_filter_cb, 1*65536+3*256+3, NULL, NULL),
760         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 --> ANY", NULL,
761                 ett_select_filter_cb, 1*65536+3*256+4, NULL, NULL),
762         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/EP1 <-- ANY", NULL,
763                 ett_select_filter_cb, 1*65536+3*256+5, NULL, NULL),
764         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/ANY <-> EP2", NULL,
765                 ett_select_filter_cb, 1*65536+3*256+6, NULL, NULL),
766         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/ANY <-- EP2", NULL,
767                 ett_select_filter_cb, 1*65536+3*256+7, NULL, NULL),
768         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Selected/ANY --> EP2", NULL,
769                 ett_select_filter_cb, 1*65536+3*256+8, NULL, NULL),
770
771         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected", NULL, NULL, 0, "<Branch>", NULL),
772         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 <-> EP2", NULL,
773                 ett_select_filter_cb, 1*65536+4*256+0, NULL, NULL),
774         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 --> EP2", NULL,
775                 ett_select_filter_cb, 1*65536+4*256+1, NULL, NULL),
776         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 <-- EP2", NULL,
777                 ett_select_filter_cb, 1*65536+4*256+2, NULL, NULL),
778         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 <-> ANY", NULL,
779                 ett_select_filter_cb, 1*65536+4*256+3, NULL, NULL),
780         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 --> ANY", NULL,
781                 ett_select_filter_cb, 1*65536+4*256+4, NULL, NULL),
782         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/EP1 <-- ANY", NULL,
783                 ett_select_filter_cb, 1*65536+4*256+5, NULL, NULL),
784         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/ANY <-> EP2", NULL,
785                 ett_select_filter_cb, 1*65536+4*256+6, NULL, NULL),
786         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/ANY <-- EP2", NULL,
787                 ett_select_filter_cb, 1*65536+4*256+7, NULL, NULL),
788         ITEM_FACTORY_ENTRY("/Prepare Display Filter/And Not Selected/ANY --> EP2", NULL,
789                 ett_select_filter_cb, 1*65536+4*256+8, NULL, NULL),
790
791         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected", NULL, NULL, 0, "<Branch>", NULL),
792         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 <-> EP2", NULL,
793                 ett_select_filter_cb, 1*65536+5*256+0, NULL, NULL),
794         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 --> EP2", NULL,
795                 ett_select_filter_cb, 1*65536+5*256+1, NULL, NULL),
796         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 <-- EP2", NULL,
797                 ett_select_filter_cb, 1*65536+5*256+2, NULL, NULL),
798         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 <-> ANY", NULL,
799                 ett_select_filter_cb, 1*65536+5*256+3, NULL, NULL),
800         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 --> ANY", NULL,
801                 ett_select_filter_cb, 1*65536+5*256+4, NULL, NULL),
802         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/EP1 <-- ANY", NULL,
803                 ett_select_filter_cb, 1*65536+5*256+5, NULL, NULL),
804         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/ANY <-> EP2", NULL,
805                 ett_select_filter_cb, 1*65536+5*256+6, NULL, NULL),
806         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/ANY <-- EP2", NULL,
807                 ett_select_filter_cb, 1*65536+5*256+7, NULL, NULL),
808         ITEM_FACTORY_ENTRY("/Prepare Display Filter/Or Not Selected/ANY --> EP2", NULL,
809                 ett_select_filter_cb, 1*65536+5*256+8, NULL, NULL),
810
811         /* Find Frame */
812         ITEM_FACTORY_ENTRY("/Find Frame", NULL, NULL, 0, "<Branch>", NULL),
813         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame", NULL, NULL, 0, "<Branch>", NULL),
814         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 <-> EP2", NULL,
815                 ett_select_filter_cb, 2*65536+0*256+0, NULL, NULL),
816         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 --> EP2", NULL,
817                 ett_select_filter_cb, 2*65536+0*256+1, NULL, NULL),
818         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 <-- EP2", NULL,
819                 ett_select_filter_cb, 2*65536+0*256+2, NULL, NULL),
820         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 <-> ANY", NULL,
821                 ett_select_filter_cb, 2*65536+0*256+3, NULL, NULL),
822         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 --> ANY", NULL,
823                 ett_select_filter_cb, 2*65536+0*256+4, NULL, NULL),
824         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/EP1 <-- ANY", NULL,
825                 ett_select_filter_cb, 2*65536+0*256+5, NULL, NULL),
826         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/ANY <-> EP2", NULL,
827                 ett_select_filter_cb, 2*65536+0*256+6, NULL, NULL),
828         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/ANY <-- EP2", NULL,
829                 ett_select_filter_cb, 2*65536+0*256+7, NULL, NULL),
830         ITEM_FACTORY_ENTRY("/Find Frame/Find Frame/ANY --> EP2", NULL,
831                 ett_select_filter_cb, 2*65536+0*256+8, NULL, NULL),
832         /* Find Next */
833         ITEM_FACTORY_ENTRY("/Find Frame/Find Next", NULL, NULL, 0, "<Branch>", NULL),
834         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 <-> EP2", NULL,
835                 ett_select_filter_cb, 3*65536+0*256+0, NULL, NULL),
836         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 --> EP2", NULL,
837                 ett_select_filter_cb, 3*65536+0*256+1, NULL, NULL),
838         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 <-- EP2", NULL,
839                 ett_select_filter_cb, 3*65536+0*256+2, NULL, NULL),
840         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 <-> ANY", NULL,
841                 ett_select_filter_cb, 3*65536+0*256+3, NULL, NULL),
842         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 --> ANY", NULL,
843                 ett_select_filter_cb, 3*65536+0*256+4, NULL, NULL),
844         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/EP1 <-- ANY", NULL,
845                 ett_select_filter_cb, 3*65536+0*256+5, NULL, NULL),
846         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/ANY <-> EP2", NULL,
847                 ett_select_filter_cb, 3*65536+0*256+6, NULL, NULL),
848         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/ANY <-- EP2", NULL,
849                 ett_select_filter_cb, 3*65536+0*256+7, NULL, NULL),
850         ITEM_FACTORY_ENTRY("/Find Frame/Find Next/ANY --> EP2", NULL,
851                 ett_select_filter_cb, 3*65536+0*256+8, NULL, NULL),
852         /* Find Previous */
853         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous", NULL, NULL, 0, "<Branch>", NULL),
854         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 <-> EP2", NULL,
855                 ett_select_filter_cb, 4*65536+0*256+0, NULL, NULL),
856         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 --> EP2", NULL,
857                 ett_select_filter_cb, 4*65536+0*256+1, NULL, NULL),
858         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 <-- EP2", NULL,
859                 ett_select_filter_cb, 4*65536+0*256+2, NULL, NULL),
860         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 <-> ANY", NULL,
861                 ett_select_filter_cb, 4*65536+0*256+3, NULL, NULL),
862         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 --> ANY", NULL,
863                 ett_select_filter_cb, 4*65536+0*256+4, NULL, NULL),
864         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/EP1 <-- ANY", NULL,
865                 ett_select_filter_cb, 4*65536+0*256+5, NULL, NULL),
866         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/ANY <-> EP2", NULL,
867                 ett_select_filter_cb, 4*65536+0*256+6, NULL, NULL),
868         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/ANY <-- EP2", NULL,
869                 ett_select_filter_cb, 4*65536+0*256+7, NULL, NULL),
870         ITEM_FACTORY_ENTRY("/Find Frame/Find Previous/ANY --> EP2", NULL,
871                 ett_select_filter_cb, 4*65536+0*256+8, NULL, NULL),
872         /* Colorize Conversation */
873         ITEM_FACTORY_ENTRY("/Colorize Conversation", NULL, NULL, 0, "<Branch>", NULL),
874         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 <-> EP2", NULL,
875                 ett_select_filter_cb, 5*65536+0*256+0, NULL, NULL),
876         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 --> EP2", NULL,
877                 ett_select_filter_cb, 5*65536+0*256+1, NULL, NULL),
878         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 <-- EP2", NULL,
879                 ett_select_filter_cb, 5*65536+0*256+2, NULL, NULL),
880         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 <-> ANY", NULL,
881                 ett_select_filter_cb, 5*65536+0*256+3, NULL, NULL),
882         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 --> ANY", NULL,
883                 ett_select_filter_cb, 5*65536+0*256+4, NULL, NULL),
884         ITEM_FACTORY_ENTRY("/Colorize Conversation/EP1 <-- ANY", NULL,
885                 ett_select_filter_cb, 5*65536+0*256+5, NULL, NULL),
886         ITEM_FACTORY_ENTRY("/Colorize Conversation/ANY <-> EP2", NULL,
887                 ett_select_filter_cb, 5*65536+0*256+6, NULL, NULL),
888         ITEM_FACTORY_ENTRY("/Colorize Conversation/ANY <-- EP2", NULL,
889                 ett_select_filter_cb, 5*65536+0*256+7, NULL, NULL),
890         ITEM_FACTORY_ENTRY("/Colorize Conversation/ANY --> EP2", NULL,
891                 ett_select_filter_cb, 5*65536+0*256+8, NULL, NULL),
892
893
894 };
895
896 static void
897 ett_create_popup_menu(endpoints_table *et)
898 {
899         et->item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
900
901         gtk_item_factory_create_items_ac(et->item_factory, sizeof(ett_list_menu_items)/sizeof(ett_list_menu_items[0]), ett_list_menu_items, et, 2);
902
903         et->menu = gtk_item_factory_get_widget(et->item_factory, "<main>");
904         SIGNAL_CONNECT(et->table, "button_press_event", ett_show_popup_menu_cb, et);
905 }
906
907
908
909 /* XXX should freeze/thaw table here and in the srt thingy? */
910 static void 
911 draw_ett_table_data(endpoints_table *et)
912 {
913         guint32 i;
914         int j;
915
916         for(i=0;i<et->num_endpoints;i++){
917                 char str[16];
918
919                 j=gtk_clist_find_row_from_data(et->table, (gpointer)i);
920
921                 sprintf(str, "%u", et->endpoints[i].tx_frames+et->endpoints[i].rx_frames);
922                 gtk_clist_set_text(et->table, j, 4, str);               
923                 sprintf(str, "%u", et->endpoints[i].tx_bytes+et->endpoints[i].rx_bytes);
924                 gtk_clist_set_text(et->table, j, 5, str);               
925
926
927                 sprintf(str, "%u", et->endpoints[i].tx_frames);
928                 gtk_clist_set_text(et->table, j, 6, str);       
929                 sprintf(str, "%u", et->endpoints[i].tx_bytes);
930                 gtk_clist_set_text(et->table, j, 7, str);               
931
932
933                 sprintf(str, "%u", et->endpoints[i].rx_frames);
934                 gtk_clist_set_text(et->table, j, 8, str);               
935                 sprintf(str, "%u", et->endpoints[i].rx_bytes);
936                 gtk_clist_set_text(et->table, j, 9, str);               
937
938         }
939         gtk_clist_sort(et->table);
940 }
941
942
943 void
944 init_ett_table(gboolean hide_ports, char *table_name, char *tap_name, char *filter, void *packet_func)
945 {
946         int i;
947         column_arrows *col_arrows;
948         GdkBitmap *ascend_bm, *descend_bm;
949         GdkPixmap *ascend_pm, *descend_pm;
950         GtkStyle *win_style;
951         GtkWidget *column_lb;
952         GString *error_string;
953         endpoints_table *talkers;
954         GtkWidget *vbox;
955         GtkWidget *label;
956         char title[256];
957         char *default_titles[] = { "EP1 Address", "Port", "EP2 Address", "Port", "Frames", "Bytes", "-> Frames", "-> Bytes", "<- Frames", "<- Bytes" };
958
959
960         talkers=g_malloc(sizeof(endpoints_table));
961
962         talkers->name=table_name;
963         snprintf(title, 255, "%s Conversations: %s", table_name, cf_get_display_name(&cfile));
964         talkers->win=window_new(GTK_WINDOW_TOPLEVEL, title);
965         gtk_window_set_default_size(GTK_WINDOW(talkers->win), 750, 400);
966
967         SIGNAL_CONNECT(talkers->win, "destroy", ett_win_destroy_cb, talkers);
968
969         vbox=gtk_vbox_new(FALSE, 0);
970         gtk_container_add(GTK_CONTAINER(talkers->win), vbox);
971         gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
972         gtk_widget_show(vbox);
973
974         snprintf(title, 255, "%s Conversations", table_name);
975         label=gtk_label_new(title);
976         gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
977         gtk_widget_show(label);
978
979         /* We must display TOP LEVEL Widget before calling init_ett_table() */
980         gtk_widget_show(talkers->win);
981
982
983         talkers->scrolled_window=scrolled_window_new(NULL, NULL);
984         gtk_box_pack_start(GTK_BOX(vbox), talkers->scrolled_window, TRUE, TRUE, 0);
985
986         talkers->table=(GtkCList *)gtk_clist_new(NUM_COLS);
987
988         gtk_widget_show(GTK_WIDGET(talkers->table));
989         gtk_widget_show(talkers->scrolled_window);
990
991         col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * NUM_COLS);
992         win_style = gtk_widget_get_style(talkers->scrolled_window);
993         ascend_pm = gdk_pixmap_create_from_xpm_d(talkers->scrolled_window->window,
994                         &ascend_bm,
995                         &win_style->bg[GTK_STATE_NORMAL],
996                         (gchar **)clist_ascend_xpm);
997         descend_pm = gdk_pixmap_create_from_xpm_d(talkers->scrolled_window->window,
998                         &descend_bm,
999                         &win_style->bg[GTK_STATE_NORMAL],
1000                         (gchar **)clist_descend_xpm);
1001         for (i = 0; i < NUM_COLS; i++) {
1002                 col_arrows[i].table = gtk_table_new(2, 2, FALSE);
1003                 gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
1004                 column_lb = gtk_label_new(default_titles[i]);
1005                 gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
1006                 gtk_widget_show(column_lb);
1007
1008                 col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
1009                 gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
1010                 col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm);
1011                 gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
1012                 /* make total frames be the default sort order */
1013                 if (i == 4) {
1014                         gtk_widget_show(col_arrows[i].descend_pm);
1015                 }
1016                 gtk_clist_set_column_widget(GTK_CLIST(talkers->table), i, col_arrows[i].table);
1017                 gtk_widget_show(col_arrows[i].table);
1018         }
1019         gtk_clist_column_titles_show(GTK_CLIST(talkers->table));
1020
1021         gtk_clist_set_compare_func(talkers->table, ett_sort_column);
1022         gtk_clist_set_sort_column(talkers->table, 4);
1023         gtk_clist_set_sort_type(talkers->table, GTK_SORT_DESCENDING);
1024
1025
1026         /*XXX instead of this we should probably have some code to
1027                 dynamically adjust the width of the columns */
1028         gtk_clist_set_column_width(talkers->table, 0, 100);
1029         gtk_clist_set_column_width(talkers->table, 1, 40);
1030         gtk_clist_set_column_width(talkers->table, 2, 100);
1031         gtk_clist_set_column_width(talkers->table, 3, 40);
1032         gtk_clist_set_column_width(talkers->table, 4, 70);
1033         gtk_clist_set_column_width(talkers->table, 5, 60);
1034         gtk_clist_set_column_width(talkers->table, 6, 70);
1035         gtk_clist_set_column_width(talkers->table, 7, 60);
1036         gtk_clist_set_column_width(talkers->table, 8, 70);
1037         gtk_clist_set_column_width(talkers->table, 9, 60);
1038
1039
1040         gtk_clist_set_shadow_type(talkers->table, GTK_SHADOW_IN);
1041         gtk_clist_column_titles_show(talkers->table);
1042         gtk_container_add(GTK_CONTAINER(talkers->scrolled_window), (GtkWidget *)talkers->table);
1043
1044         SIGNAL_CONNECT(talkers->table, "click-column", ett_click_column_cb, col_arrows);
1045
1046         gtk_widget_show(GTK_WIDGET(talkers->table));
1047         gtk_widget_show(talkers->scrolled_window);
1048
1049         talkers->num_endpoints=0;
1050         talkers->endpoints=NULL;
1051
1052         /* hide srcport and dstport if we don't use ports */
1053         if(hide_ports){
1054                 gtk_clist_set_column_visibility(talkers->table, 1, FALSE);
1055                 gtk_clist_set_column_visibility(talkers->table, 3, FALSE);
1056         }
1057
1058         /* create popup menu for this table */
1059         ett_create_popup_menu(talkers);
1060
1061
1062         /* register the tap and rerun the taps on the packet list */
1063         error_string=register_tap_listener(tap_name, talkers, filter, (void *)reset_ett_table_data, packet_func, (void *)draw_ett_table_data);
1064         if(error_string){
1065                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str);
1066                 g_string_free(error_string, TRUE);
1067                 g_free(talkers);
1068                 return;
1069         }
1070
1071         gtk_widget_show_all(talkers->win);
1072         retap_packets(&cfile);
1073
1074 }
1075
1076
1077 void 
1078 add_ett_table_data(endpoints_table *et, address *src, address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes, int sat, int port_type)
1079 {
1080         address *addr1, *addr2;
1081         guint32 port1, port2;
1082         endpoint_talker_t *talker=NULL;
1083         int talker_idx=0;
1084         gboolean new_talker;
1085
1086         if(src_port>dst_port){
1087                 addr1=src;
1088                 addr2=dst;
1089                 port1=src_port;
1090                 port2=dst_port;
1091         } else if(src_port<dst_port){
1092                 addr2=src;
1093                 addr1=dst;
1094                 port2=src_port;
1095                 port1=dst_port;
1096         } else if(CMP_ADDRESS(src, dst)<0){
1097                 addr1=src;
1098                 addr2=dst;
1099                 port1=src_port;
1100                 port2=dst_port;
1101         } else {
1102                 addr2=src;
1103                 addr1=dst;
1104                 port2=src_port;
1105                 port1=dst_port;
1106         }
1107
1108
1109         new_talker=FALSE;
1110         /* XXX should be optimized to allocate n extra entries at a time
1111            instead of just one */
1112         /* if we dont have any entries at all yet */
1113         if(et->endpoints==NULL){
1114                 et->endpoints=g_malloc(sizeof(endpoint_talker_t));
1115                 et->num_endpoints=1;
1116                 talker=&et->endpoints[0];
1117                 talker_idx=0;
1118                 new_talker=TRUE;
1119         }
1120
1121         /* try to find it among the existing known talkers */
1122         if(talker==NULL){
1123                 guint32 i;
1124                 for(i=0;i<et->num_endpoints;i++){
1125                         if(  (!CMP_ADDRESS(&et->endpoints[i].src_address, addr1))&&(!CMP_ADDRESS(&et->endpoints[i].dst_address, addr2))&&(et->endpoints[i].src_port==port1)&&(et->endpoints[i].dst_port==port2) ){
1126                                 talker=&et->endpoints[i];
1127                                 talker_idx=i;
1128                                 break;
1129                         }
1130                         if( (!CMP_ADDRESS(&et->endpoints[i].src_address, addr2))&&(!CMP_ADDRESS(&et->endpoints[i].dst_address, addr1))&&(et->endpoints[i].src_port==port2)&&(et->endpoints[i].dst_port==port1) ){
1131                                 talker=&et->endpoints[i];
1132                                 talker_idx=i;
1133                                 break;
1134                         }
1135                 }
1136         }
1137
1138         /* if we still dont know what talker this is it has to be a new one
1139            and we have to allocate it and append it to the end of the list */
1140         if(talker==NULL){
1141                 new_talker=TRUE;
1142                 et->num_endpoints++;
1143                 et->endpoints=g_realloc(et->endpoints, et->num_endpoints*sizeof(endpoint_talker_t));
1144                 talker=&et->endpoints[et->num_endpoints-1];
1145                 talker_idx=et->num_endpoints-1;
1146         }
1147
1148         /* if this is a new talker we need to initialize the struct */
1149         if(new_talker){
1150                 COPY_ADDRESS(&talker->src_address, addr1);
1151                 COPY_ADDRESS(&talker->dst_address, addr2);
1152                 talker->sat=sat;
1153                 talker->port_type=port_type;
1154                 talker->src_port=port1;
1155                 talker->dst_port=port2;
1156                 talker->rx_frames=0;
1157                 talker->tx_frames=0;
1158                 talker->rx_bytes=0;
1159                 talker->tx_bytes=0;
1160         }
1161
1162         /* update the talker struct */
1163         if( (!CMP_ADDRESS(src, addr1))&&(!CMP_ADDRESS(dst, addr2))&&(src_port==port1)&&(dst_port==port2) ){
1164                 talker->tx_frames+=num_frames;
1165                 talker->tx_bytes+=num_bytes;
1166         } else {
1167                 talker->rx_frames+=num_frames;
1168                 talker->rx_bytes+=num_bytes;
1169         }
1170
1171         /* if this was a new talker we have to create a clist row for it */
1172         if(new_talker){
1173                 char *entries[NUM_COLS];
1174                 char *sport, *dport;
1175                 char frames[16],bytes[16],txframes[16],txbytes[16],rxframes[16],rxbytes[16];
1176
1177                 sport=ett_port_to_str(talker->port_type, talker->src_port);
1178                 dport=ett_port_to_str(talker->port_type, talker->dst_port);
1179
1180                 entries[0]=address_to_str(&talker->src_address);
1181                 entries[1]=sport?sport:"";
1182                 entries[2]=address_to_str(&talker->dst_address);
1183                 entries[3]=dport?dport:"";
1184
1185                 sprintf(frames,"%u", talker->tx_frames+talker->rx_frames);
1186                 entries[4]=frames;
1187                 sprintf(bytes,"%u", talker->tx_bytes+talker->rx_bytes);
1188                 entries[5]=bytes;
1189
1190                 sprintf(txframes,"%u", talker->tx_frames);
1191                 entries[6]=txframes;
1192                 sprintf(txbytes,"%u", talker->tx_bytes);
1193                 entries[7]=txbytes;
1194
1195                 sprintf(rxframes,"%u", talker->rx_frames);
1196                 entries[8]=rxframes;
1197                 sprintf(rxbytes,"%u", talker->rx_bytes);
1198                 entries[9]=rxbytes;
1199
1200                 gtk_clist_insert(et->table, talker_idx, entries);
1201                 gtk_clist_set_row_data(et->table, talker_idx, (gpointer) talker_idx);
1202         }
1203
1204 }
1205
1206