diff -ur ethereal-0.10.0a/file.c ethereal-0.10.0a-jc/file.c
--- ethereal-0.10.0a/file.c	2003-12-10 11:00:00.000000000 -0500
+++ ethereal-0.10.0a-jc/file.c	2003-12-29 13:01:38.000000000 -0500
@@ -2211,6 +2211,8 @@
 {
   frame->flags.marked = TRUE;
   cf->marked_count++;
+  if(cf->marked_count == 1)
+  	set_menus_for_compare_packets(TRUE);
 }
 
 /*
@@ -2221,6 +2223,8 @@
 {
   frame->flags.marked = FALSE;
   cf->marked_count--;
+  if(cf->marked_count == 0)
+  	set_menus_for_compare_packets(FALSE);
 }
 
 /*
diff -ur ethereal-0.10.0a/gtk/menu.c ethereal-0.10.0a-jc/gtk/menu.c
--- ethereal-0.10.0a/gtk/menu.c	2003-12-10 11:00:05.000000000 -0500
+++ ethereal-0.10.0a-jc/gtk/menu.c	2003-12-28 21:51:23.000000000 -0500
@@ -196,6 +196,8 @@
     ITEM_FACTORY_ENTRY("/View/<separator>", NULL, NULL, 0, "<Separator>", NULL),
     ITEM_FACTORY_ENTRY("/View/_Show Packet In New Window", NULL,
                        new_window_cb, 0, NULL, NULL),
+    ITEM_FACTORY_ENTRY("/View/Show Compare Packets In New Window", NULL,
+                       new_cmp_window_cb, 0, NULL, NULL),
     ITEM_FACTORY_STOCK_ENTRY("/View/_Reload", "<control>R", file_reload_cmd_cb,
                              0, GTK_STOCK_REFRESH),
 #ifdef HAVE_LIBPCAP
@@ -327,6 +329,8 @@
     ITEM_FACTORY_ENTRY("/Print...", NULL, file_print_cmd_cb, 0, NULL, NULL),
     ITEM_FACTORY_ENTRY("/Show Packet In New Window", NULL, new_window_cb,
                        0, NULL, NULL),
+    ITEM_FACTORY_ENTRY("/Show Compare Packets In New Window", NULL, new_cmp_window_cb,
+                       0, NULL, NULL),
 };
 
 static GtkItemFactoryEntry tree_view_menu_items[] =
@@ -453,6 +457,7 @@
     set_menus_for_captured_packets(FALSE);
     set_menus_for_selected_packet(&cfile);
     set_menus_for_selected_tree_row(&cfile);
+    set_menus_for_compare_packets(FALSE);
   }
 }
 
@@ -723,6 +728,13 @@
     return FALSE;
 }
 
+void
+set_menus_for_compare_packets(gboolean have_compare_packets)
+{
+  set_menu_sensitivity(main_menu_factory, "/View/Show Compare Packets In New Window", have_compare_packets);
+  set_menu_sensitivity(packet_list_menu_factory, "/Show Compare Packets In New Window", have_compare_packets);
+}
+
 /* Enable or disable menu items based on whether you have a capture file
    you've finished reading. */
 void
diff -ur ethereal-0.10.0a/gtk/packet_win.c ethereal-0.10.0a-jc/gtk/packet_win.c
--- ethereal-0.10.0a/gtk/packet_win.c	2002-11-12 20:57:45.000000000 -0500
+++ ethereal-0.10.0a-jc/gtk/packet_win.c	2003-12-28 21:54:06.000000000 -0500
@@ -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_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) {
+                        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 -ur ethereal-0.10.0a/gtk/packet_win.h ethereal-0.10.0a-jc/gtk/packet_win.h
--- ethereal-0.10.0a/gtk/packet_win.h	2002-09-21 22:55:45.000000000 -0400
+++ ethereal-0.10.0a-jc/gtk/packet_win.h	2003-12-28 21:22:59.000000000 -0500
@@ -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);
Only in ethereal-0.10.0a/help: capture_filters.h
Only in ethereal-0.10.0a/help: display_filters.h
Only in ethereal-0.10.0a/help: faq.h
Only in ethereal-0.10.0a/help: overview.h
Only in ethereal-0.10.0a/help: well_known.h
diff -ur ethereal-0.10.0a/menu.h ethereal-0.10.0a-jc/menu.h
--- ethereal-0.10.0a/menu.h	2003-09-27 20:36:12.000000000 -0400
+++ ethereal-0.10.0a-jc/menu.h	2003-12-28 21:22:59.000000000 -0500
@@ -55,6 +55,8 @@
    and and on whether a "Match Selected" can be done. */
 void set_menus_for_selected_tree_row(capture_file *cf);
 
+void set_menus_for_compare_packets(gboolean);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
Only in ethereal-0.10.0a/plugins: Xass-list
Only in ethereal-0.10.0a/plugins: Xplugin_api.c
Only in ethereal-0.10.0a/plugins: Xplugin_api.h
Only in ethereal-0.10.0a/plugins: Xplugin_api_decls.h
Only in ethereal-0.10.0a/plugins: Xplugin_table.h
Only in ethereal-0.10.0a: ps.c
