Ethereal-dev: [Ethereal-dev] Wish list item 22 - compare packets
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Jason Copenhaver <jcopenha@xxxxxxxxxxx>
Date: Thu, 28 Aug 2003 21:43:53 -0400 (EDT)
Attached is a patch at a begining implementation of a compare packets window. It can also be found a http://www.typedef.org/jcopenha/patches/ethereal/compare-packets.diff . This is only the begining, right now it allows you to mark a couple of packets for compare and show them in a window side by side. The next step, actually indicating differences in the packet, will be a bit tougher. It addes a new flag to the frame_data structure (marked_cmp) along with the functions to mark a frame for comparison. I used the packet_win.c as a basis so most of the changes are there. I've made it so the same code is used for the compare window and for the show packet window. I welcome any comments, corrections, and or additions. Jason Copenhaver
diff -urN ethereal-0.9.14/cfile.h ethereal-0.9.14-jc/cfile.h --- ethereal-0.9.14/cfile.h 2003-07-22 22:05:35.000000000 -0400 +++ ethereal-0.9.14-jc/cfile.h 2003-08-09 18:29:49.000000000 -0400 @@ -45,6 +45,7 @@ guint32 vers; /* Version. For tcpdump minor is appended to major */ int count; /* Total number of frames */ int marked_count; /* Number of marked frames */ + int marked_cmp_count; /* Number of frames marked for compare */ gboolean drops_known; /* TRUE if we know how many packets were dropped */ guint32 drops; /* Dropped packets */ guint32 esec; /* Elapsed seconds */ diff -urN ethereal-0.9.14/epan/frame_data.h ethereal-0.9.14-jc/epan/frame_data.h --- ethereal-0.9.14/epan/frame_data.h 2003-07-09 21:20:13.000000000 -0400 +++ ethereal-0.9.14-jc/epan/frame_data.h 2003-08-09 18:29:18.000000000 -0400 @@ -51,6 +51,7 @@ unsigned int encoding : 2; /* Character encoding (ASCII, EBCDIC...) */ unsigned int visited : 1; /* Has this packet been visited yet? 1=Yes,0=No*/ unsigned int marked : 1; /* 1 = marked by user, 0 = normal */ + unsigned int marked_cmp : 1; /* 1 = marked by user for compare, 0 = normal */ } flags; } frame_data; diff -urN ethereal-0.9.14/file.c ethereal-0.9.14-jc/file.c --- ethereal-0.9.14/file.c 2003-07-22 22:05:35.000000000 -0400 +++ ethereal-0.9.14-jc/file.c 2003-08-09 18:35:00.000000000 -0400 @@ -1945,6 +1945,23 @@ cf->marked_count--; } +/* + * this should take into account some MAX_CMP_FRAME + */ +void +mark_cmp_frame(capture_file *cf, frame_data *frame) +{ + frame->flags.marked_cmp = TRUE; + cf->marked_cmp_count++; +} + +void +unmark_cmp_frame(capture_file *cf, frame_data *frame) +{ + frame->flags.marked_cmp = FALSE; + cf->marked_cmp_count--; +} + static void freeze_plist(capture_file *cf) { diff -urN ethereal-0.9.14/file.h ethereal-0.9.14-jc/file.h --- ethereal-0.9.14/file.h 2003-07-22 22:05:35.000000000 -0400 +++ ethereal-0.9.14-jc/file.h 2003-08-09 18:31:47.000000000 -0400 @@ -76,6 +76,9 @@ */ void unmark_frame(capture_file *, frame_data *); +void mark_cmp_frame(capture_file *, frame_data *); +void unmark_cmp_frame(capture_file *, frame_data *); + /* Moves or copies a file. Returns 0 on failure, 1 on success */ int file_mv(char *from, char *to); diff -urN ethereal-0.9.14/gtk/main.c ethereal-0.9.14-jc/gtk/main.c --- ethereal-0.9.14/gtk/main.c 2003-07-19 10:48:59.000000000 -0400 +++ ethereal-0.9.14-jc/gtk/main.c 2003-08-12 00:12:03.000000000 -0400 @@ -686,6 +686,28 @@ file_set_save_marked_sensitive(); } +static void +set_cmp_frame_mark(gboolean set, frame_data *frame, gint row) { + GdkColor fg, bg; + + if (row == -1) + return; + if (set) { + mark_cmp_frame(&cfile, frame); + /* need a different color for compare frames */ + color_t_to_gdkcolor(&fg, &prefs.gui_marked_fg); + color_t_to_gdkcolor(&bg, &prefs.gui_marked_bg); + gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg); + gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg); + } else { + unmark_cmp_frame(&cfile, frame); + gtk_clist_set_background(GTK_CLIST(packet_list), row, NULL); + gtk_clist_set_foreground(GTK_CLIST(packet_list), row, NULL); + } + /* do we want an option like this for compare frames? */ + /*file_set_save_marked_sensitive();*/ +} + #if GTK_MAJOR_VERSION < 2 static void packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_) @@ -744,6 +766,16 @@ } } +void mark_cmp_frame_cb(GtkWidget *w _U_, gpointer data _U_) { + if (cfile.current_frame) { + /* XXX hum, should better have a "cfile->current_row" here ... */ + set_cmp_frame_mark(!cfile.current_frame->flags.marked_cmp, + cfile.current_frame, + gtk_clist_find_row_from_data(GTK_CLIST(packet_list), + cfile.current_frame)); + } +} + static void mark_all_frames(gboolean set) { frame_data *fdata; for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) { diff -urN ethereal-0.9.14/gtk/main.h ethereal-0.9.14-jc/gtk/main.h --- ethereal-0.9.14/gtk/main.h 2002-12-21 11:24:52.000000000 -0500 +++ ethereal-0.9.14-jc/gtk/main.h 2003-08-12 00:10:06.000000000 -0400 @@ -96,6 +96,7 @@ void collapse_all_cb(GtkWidget *, gpointer); void resolve_name_cb(GtkWidget *, gpointer); void mark_frame_cb(GtkWidget *, gpointer); +void mark_cmp_frame_cb(GtkWidget *, gpointer); void mark_all_frames_cb(GtkWidget *w, gpointer); void unmark_all_frames_cb(GtkWidget *w, gpointer); void update_marked_frames(void); diff -urN ethereal-0.9.14/gtk/menu.c ethereal-0.9.14-jc/gtk/menu.c --- ethereal-0.9.14/gtk/menu.c 2003-05-03 22:24:55.000000000 -0400 +++ ethereal-0.9.14-jc/gtk/menu.c 2003-08-12 00:12:53.000000000 -0400 @@ -140,6 +140,8 @@ ITEM_FACTORY_ENTRY("/Edit/<separator>", NULL, NULL, 0, "<Separator>", NULL), ITEM_FACTORY_ENTRY("/Edit/_Mark Frame", "<control>M", mark_frame_cb, 0, NULL, NULL), + ITEM_FACTORY_ENTRY("/Edit/_Mark Compare Frame", "<control>M", mark_cmp_frame_cb, + 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Edit/Mark _All Frames", NULL, mark_all_frames_cb, 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Edit/_Unmark All Frames", NULL, unmark_all_frames_cb, @@ -203,6 +205,8 @@ 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Display/_Show Packet In New Window", NULL, new_window_cb, 0, NULL, NULL), + ITEM_FACTORY_ENTRY("/Display/Show Compare Packet In New Window", NULL, + new_cmp_window_cb, 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Display/User Specified Decodes...", NULL, decode_show_cb, 0, NULL, NULL), ITEM_FACTORY_ENTRY("/_Tools", NULL, NULL, 0, "<Branch>", NULL), @@ -252,6 +256,7 @@ 0, NULL, NULL), ITEM_FACTORY_ENTRY("/<separator>", NULL, NULL, 0, "<Separator>", NULL), ITEM_FACTORY_ENTRY("/Mark Frame", NULL, mark_frame_cb, 0, NULL, NULL), + ITEM_FACTORY_ENTRY("/Mark Compare Frame", NULL, mark_cmp_frame_cb, 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Match", NULL, NULL, 0, "<Branch>", NULL), ITEM_FACTORY_ENTRY("/Match/_Selected", NULL, match_selected_cb_replace_plist, 0, NULL, NULL), @@ -286,6 +291,8 @@ 0, NULL, NULL), ITEM_FACTORY_ENTRY("/Show Packet In New Window", NULL, new_window_cb, 0, NULL, NULL), + ITEM_FACTORY_ENTRY("/Show Compare Packet In New Window", NULL, new_cmp_window_cb, + 0, NULL, NULL), }; static GtkItemFactoryEntry tree_view_menu_items[] = diff -urN ethereal-0.9.14/gtk/packet_win.c ethereal-0.9.14-jc/gtk/packet_win.c --- ethereal-0.9.14/gtk/packet_win.c 2002-11-12 20:57:45.000000000 -0500 +++ ethereal-0.9.14-jc/gtk/packet_win.c 2003-08-28 20:45:47.000000000 -0400 @@ -73,6 +73,11 @@ epan_dissect_t *edt; }; +struct PacketWinDataPtrs { + int numPackets; + struct PacketWinData **Ptr; +}; + /* List of all the packet-detail windows popped up. */ static GList *detail_windows; @@ -90,103 +95,172 @@ static void destroy_new_window(GtkObject *object, gpointer user_data); +static void new_multi_window(gint numPackets); + void new_window_cb(GtkWidget *w _U_) { -#define NewWinTitleLen 1000 - char Title[NewWinTitleLen] = ""; - char *TextPtr; - gint tv_size = 95, bv_size = 75; - GtkWidget *main_w, *main_vbox, *pane, - *tree_view, *tv_scrollw, - *bv_nb_ptr; - struct PacketWinData *DataPtr; - int i; - - /* Allocate data structure to represent this window. */ - DataPtr = (struct PacketWinData *) g_malloc(sizeof(struct PacketWinData)); - - DataPtr->frame = cfile.current_frame; - memcpy(&DataPtr->pseudo_header, &cfile.pseudo_header, sizeof DataPtr->pseudo_header); - DataPtr->pd = g_malloc(DataPtr->frame->cap_len); - memcpy(DataPtr->pd, cfile.pd, DataPtr->frame->cap_len); - DataPtr->edt = epan_dissect_new(TRUE, TRUE); - epan_dissect_run(DataPtr->edt, &DataPtr->pseudo_header, DataPtr->pd, - DataPtr->frame, &cfile.cinfo); - epan_dissect_fill_in_columns(DataPtr->edt); - - main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - /* - * Build title of window by getting column data constructed when the - * frame was dissected. - */ - for (i = 0; i < cfile.cinfo.num_cols; ++i) { - TextPtr = cfile.cinfo.col_data[i]; - if ((strlen(Title) + strlen(TextPtr)) < NewWinTitleLen - 1) { - strcat(Title, TextPtr); - strcat(Title, " "); - } - } + new_multi_window(0); +} - gtk_window_set_title(GTK_WINDOW(main_w), Title); - gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1); +void new_cmp_window_cb(GtkWidget *w _U_) +{ + new_multi_window(cfile.marked_cmp_count); +} - /* Container for paned windows */ - main_vbox = gtk_vbox_new(FALSE, 1); - gtk_container_border_width(GTK_CONTAINER(main_vbox), 1); - gtk_container_add(GTK_CONTAINER(main_w), main_vbox); - gtk_widget_show(main_vbox); - - /* Panes for the tree and byte view */ - pane = gtk_vpaned_new(); - gtk_paned_gutter_size(GTK_PANED(pane), (GTK_PANED(pane))->handle_size); - gtk_container_add(GTK_CONTAINER(main_vbox), pane); - gtk_widget_show(pane); - - /* Tree view */ - create_tree_view(tv_size, &prefs, pane, &tv_scrollw, &tree_view); - gtk_widget_show(tree_view); - - /* Byte view */ - bv_nb_ptr = create_byte_view(bv_size, pane); - - DataPtr->main = main_w; - DataPtr->tv_scrollw = tv_scrollw; - DataPtr->tree_view = tree_view; - DataPtr->bv_nb_ptr = bv_nb_ptr; - detail_windows = g_list_append(detail_windows, DataPtr); +static +void new_multi_window(gint numPackets) +{ +#define NewWinTitleLen 1000 + char Title[NewWinTitleLen] = ""; + char *TextPtr; + gint tv_size = 95, bv_size = 75; + GtkWidget *main_w, *main_hbox; + GtkWidget **vpane, **tree_view, **tv_scrollw, **bv_nb_ptr; + struct PacketWinData **DataPtr; + struct PacketWinDataPtrs *DataPtrs; + int i, err; + frame_data *curframe = NULL; + frame_data *startframe = NULL; + + + if(numPackets == 0) + numPackets = 1; + + + /* hmm, no failure path if numPackets is large and we fail to allocate enought widgets */ + vpane = (GtkWidget**)g_malloc(sizeof(GtkWidget*) * numPackets); + tree_view = (GtkWidget**)g_malloc(sizeof(GtkWidget*) * numPackets); + tv_scrollw = (GtkWidget**)g_malloc(sizeof(GtkWidget*) * numPackets); + bv_nb_ptr = (GtkWidget**)g_malloc(sizeof(GtkWidget*) * numPackets); + DataPtr = (struct PacketWinData**)g_malloc(sizeof(struct PacketWinData*) * numPackets); + DataPtrs = (struct PacketWinDataPtrs*)g_malloc(sizeof(struct PacketWinDataPtrs*)); + + startframe = cfile.plist; + for(i = 0; i < numPackets; i++) { + /*curframe = find_next_marked(cfile,curframe); */ + for(startframe; startframe != NULL; startframe = startframe->next) { + if (startframe->flags.marked_cmp) { + curframe = startframe; + startframe = startframe->next; + break; + } + } + if(curframe == NULL) { + /* now what */ + printf("argghh..!!\n"); + } + + DataPtr[i] = (struct PacketWinData *)g_malloc(sizeof(struct PacketWinData)); + DataPtr[i]->frame = curframe; + DataPtr[i]->pd = g_malloc(DataPtr[i]->frame->cap_len); + + /* should I care about err? no one else does */ + wtap_seek_read(cfile.wth, curframe->file_off, &DataPtr[i]->pseudo_header, DataPtr[i]->pd, curframe->cap_len, &err); + + DataPtr[i]->edt = epan_dissect_new(TRUE, TRUE); + epan_dissect_run(DataPtr[i]->edt, &DataPtr[i]->pseudo_header, DataPtr[i]->pd, + DataPtr[i]->frame, NULL); /* umm.. &cfile.cinfo what happens if NULL?*/ + /* what is this.. why do we need it ? */ + /*epan_dissect_fill_in_columns(DataPtr[i]->edt);(*/ + } + + main_w = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + /* + * Build title of window by getting column data constructed when the + * frame was dissected. + */ + /* + for (i = 0; i < cfile.cinfo.num_cols; ++i) { + TextPtr = cfile.cinfo.col_data[i]; + if ((strlen(Title) + strlen(TextPtr)) < NewWinTitleLen - 1) { + strcat(Title, TextPtr); + strcat(Title, " "); + } + } + */ + + /* hmm.. what's a good title? */ + gtk_window_set_title(GTK_WINDOW(main_w), "Compare Packets"); + gtk_window_set_default_size(GTK_WINDOW(main_w), DEF_WIDTH, -1); + + /* Container for paned windows */ + main_hbox = gtk_hbox_new(FALSE, 1); + gtk_container_border_width(GTK_CONTAINER(main_hbox), 1); + gtk_container_add(GTK_CONTAINER(main_w), main_hbox); + gtk_widget_show(main_hbox); + + /* Panes for the tree and byte view */ + for(i = 0; i < numPackets; i++) { + vpane[i] = gtk_vpaned_new(); + gtk_paned_gutter_size(GTK_PANED(vpane[i]), (GTK_PANED(vpane[i]))->handle_size); + gtk_container_add(GTK_CONTAINER(main_hbox), vpane[i]); + gtk_widget_show(vpane[i]); + + create_tree_view(tv_size, &prefs, vpane[i], &tv_scrollw[i], &tree_view[i]); + gtk_widget_show(tree_view[i]); + + bv_nb_ptr[i] = create_byte_view(bv_size, vpane[i]); + + DataPtr[i]->main = main_w; + DataPtr[i]->tv_scrollw = tv_scrollw[i]; + DataPtr[i]->tree_view = tree_view[i]; + DataPtr[i]->bv_nb_ptr = bv_nb_ptr[i]; + detail_windows = g_list_append(detail_windows, DataPtr[i]); + + } + + DataPtrs->numPackets = numPackets; + DataPtrs->Ptr = (struct PacketWinData**)g_malloc(sizeof(struct PacketWinData*) * numPackets); + for(i = 0; i < numPackets; i++) { + DataPtrs->Ptr[i] = DataPtr[i]; + } - /* load callback handlers */ + + /* load callback handlers */ + for(i = 0; i < numPackets; i++) { #if GTK_MAJOR_VERSION < 2 - SIGNAL_CONNECT(tree_view, "tree-select-row", new_tree_view_select_row_cb, - DataPtr); + SIGNAL_CONNECT(tree_view[i], "tree-select-row", new_tree_view_select_row_cb, + DataPtr[i]); - SIGNAL_CONNECT(tree_view, "tree-unselect-row", new_tree_view_unselect_row_cb, - DataPtr); + SIGNAL_CONNECT(tree_view[i], "tree-unselect-row", new_tree_view_unselect_row_cb, + DataPtr[i]); #else - SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)), - "changed", new_tree_view_selection_changed_cb, DataPtr); + SIGNAL_CONNECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view[i])), + "changed", new_tree_view_selection_changed_cb, DataPtr[i]); #endif + } - SIGNAL_CONNECT(main_w, "destroy", destroy_new_window, DataPtr); + /* this might need to be changed to pass pointers to both the left and right dataptr */ + SIGNAL_CONNECT(main_w, "destroy", destroy_new_window, DataPtrs); - /* draw the protocol tree & print hex data */ - add_byte_views(DataPtr->edt, tree_view, DataPtr->bv_nb_ptr); - proto_tree_draw(DataPtr->edt->tree, tree_view); + /* draw the protocol tree & print hex data */ + for(i = 0; i < numPackets; i++) { + add_byte_views(DataPtr[i]->edt, tree_view[i], DataPtr[i]->bv_nb_ptr); + proto_tree_draw(DataPtr[i]->edt->tree, tree_view[i]); - DataPtr->finfo_selected = NULL; - gtk_widget_show(main_w); -} + DataPtr[i]->finfo_selected = NULL; + + } + + gtk_widget_show(main_w); +} static void destroy_new_window(GtkObject *object _U_, gpointer user_data) { - struct PacketWinData *DataPtr = user_data; + struct PacketWinDataPtrs *DataPtrs = user_data; + int i; + + for(i = 0; i < DataPtrs->numPackets; i++) { + detail_windows = g_list_remove(detail_windows, DataPtrs->Ptr[i]); + epan_dissect_free(DataPtrs->Ptr[i]->edt); + g_free(DataPtrs->Ptr[i]->pd); + g_free(DataPtrs->Ptr[i]); + } - detail_windows = g_list_remove(detail_windows, DataPtr); - epan_dissect_free(DataPtr->edt); - g_free(DataPtr->pd); - g_free(DataPtr); + g_free(DataPtrs->Ptr); + g_free(DataPtrs); } #if GTK_MAJOR_VERSION < 2 diff -urN ethereal-0.9.14/gtk/packet_win.h ethereal-0.9.14-jc/gtk/packet_win.h --- ethereal-0.9.14/gtk/packet_win.h 2002-09-21 22:55:45.000000000 -0400 +++ ethereal-0.9.14-jc/gtk/packet_win.h 2003-08-08 17:55:38.000000000 -0400 @@ -29,6 +29,7 @@ /* Create a new packet window. */ extern void new_window_cb(GtkWidget *w); +extern void new_cmp_window_cb(GtkWidget *w); /* Redraw the hex dump panes of all packet windows. */ void redraw_hex_dump_packet_wins(void);
- Prev by Date: Re: [Ethereal-dev] Updates to find dialog
- Next by Date: Re: [Ethereal-dev] Updated find capabilities.
- Previous by thread: Re: [Ethereal-dev] Updates to find dialog
- Next by thread: [Ethereal-dev] Re: [Ethereal-users] Query - Bug reports go where?
- Index(es):