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):





