aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cfile.h3
-rw-r--r--epan/frame_data.h8
-rw-r--r--file.c22
-rw-r--r--gtk/packet_win.c50
4 files changed, 81 insertions, 2 deletions
diff --git a/cfile.h b/cfile.h
index 83d2309267..163f4ca426 100644
--- a/cfile.h
+++ b/cfile.h
@@ -108,6 +108,9 @@ typedef struct _capture_file {
gint current_row; /* Row number for current frame */
epan_dissect_t *edt; /* Protocol dissection for currently selected packet */
field_info *finfo_selected; /* Field info for currently selected field */
+#ifdef WANT_PACKET_EDITOR
+ GTree *edited_frames; /* BST with modified frames */
+#endif
} capture_file;
extern void cap_file_init(capture_file *cf);
diff --git a/epan/frame_data.h b/epan/frame_data.h
index f472fd7d0f..2947d09bf7 100644
--- a/epan/frame_data.h
+++ b/epan/frame_data.h
@@ -65,6 +65,14 @@ typedef struct _frame_data {
nstime_t del_cap_ts; /**< Delta timestamp to previous captured frame (yes, it can be negative) */
} frame_data;
+#ifdef WANT_PACKET_EDITOR
+/* XXX, where this struct should go? */
+typedef struct {
+ union wtap_pseudo_header ph; /**< Modified pseudo header */
+ char *pd; /**< Modified packet data */
+} modified_frame_data;
+#endif
+
/**
* A data source.
* Has a tvbuff and a name.
diff --git a/file.c b/file.c
index e9d9b23be8..b114844a6c 100644
--- a/file.c
+++ b/file.c
@@ -396,6 +396,12 @@ cf_reset_state(capture_file *cf)
free_frame_data_sequence(cf->frames);
cf->frames = NULL;
}
+#ifdef WANT_PACKET_EDITOR
+ if (cf->edited_frames) {
+ g_tree_destroy(cf->edited_frames);
+ cf->edited_frames = NULL;
+ }
+#endif
cf_unselect_packet(cf); /* nothing to select */
cf->first_displayed = 0;
cf->last_displayed = 0;
@@ -1517,6 +1523,22 @@ cf_read_frame_r(capture_file *cf, frame_data *fdata,
gchar *err_info;
char errmsg_errno[1024+1];
+#ifdef WANT_PACKET_EDITOR
+ /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
+ if (G_UNLIKELY(fdata->file_off == -1)) {
+ const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
+
+ if (!frame) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "fdata->file_off == -1, but can't find modified frame!");
+ return FALSE;
+ }
+
+ *pseudo_header = frame->ph;
+ memcpy(pd, frame->pd, fdata->cap_len);
+ return TRUE;
+ }
+#endif
+
if (!wtap_seek_read(cf->wth, fdata->file_off, pseudo_header, pd,
fdata->cap_len, &err, &err_info)) {
switch (err) {
diff --git a/gtk/packet_win.c b/gtk/packet_win.c
index d78f1aa8ef..6355e1fa58 100644
--- a/gtk/packet_win.c
+++ b/gtk/packet_win.c
@@ -824,6 +824,36 @@ edit_pkt_win_key_pressed_cb(GtkWidget *win _U_, GdkEventKey *event, gpointer use
}
return TRUE;
}
+
+static void
+edit_pkt_destroy_new_window(GtkObject *object _U_, gpointer user_data)
+{
+ /* like destroy_new_window, but without freeding DataPtr->pd */
+ struct PacketWinData *DataPtr = user_data;
+
+ detail_windows = g_list_remove(detail_windows, DataPtr);
+ epan_dissect_cleanup(&(DataPtr->edt));
+ g_free(DataPtr);
+
+ /* XXX, notify main packet list that packet should be redisplayed */
+}
+
+static gint g_direct_compare_func(gconstpointer a, gconstpointer b, gpointer user_data _U_) {
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+ else
+ return 0;
+}
+
+static void modifed_frame_data_free(gpointer data) {
+ modified_frame_data *mfd = (modified_frame_data *) data;
+
+ g_free(mfd->pd);
+ g_free(mfd);
+}
+
#endif /* WANT_PACKET_EDITOR */
void new_packet_window(GtkWidget *w _U_, gboolean editable _U_)
@@ -915,9 +945,10 @@ void new_packet_window(GtkWidget *w _U_, gboolean editable _U_)
g_signal_connect(main_w, "key-press-event", G_CALLBACK(edit_pkt_win_key_pressed_cb), DataPtr);
/* XXX, popup-menu instead of row-activated? */
g_signal_connect(tree_view, "row-activated", G_CALLBACK(edit_pkt_tree_row_activated_cb), DataPtr);
- }
+ g_signal_connect(main_w, "destroy", G_CALLBACK(edit_pkt_destroy_new_window), DataPtr);
+ } else
#endif
- g_signal_connect(main_w, "destroy", G_CALLBACK(destroy_new_window), DataPtr);
+ g_signal_connect(main_w, "destroy", G_CALLBACK(destroy_new_window), DataPtr);
/* draw the protocol tree & print hex data */
add_byte_views(&(DataPtr->edt), tree_view, DataPtr->bv_nb_ptr);
@@ -927,6 +958,21 @@ void new_packet_window(GtkWidget *w _U_, gboolean editable _U_)
DataPtr->pd_offset = 0;
DataPtr->pd_bitoffset = 0;
gtk_widget_show(main_w);
+
+#ifdef WANT_PACKET_EDITOR
+ if (editable && DataPtr->frame->cap_len != 0) {
+ /* XXX, there's no Save button here, so lets assume packet is always edited */
+ modified_frame_data *mfd = g_malloc(sizeof(modified_frame_data));
+
+ mfd->pd = DataPtr->pd;
+ mfd->ph = DataPtr->pseudo_header;
+
+ if (cfile.edited_frames == NULL)
+ cfile.edited_frames = g_tree_new_full(g_direct_compare_func, NULL, NULL, modifed_frame_data_free);
+ g_tree_insert(cfile.edited_frames, GINT_TO_POINTER(DataPtr->frame->num), mfd);
+ DataPtr->frame->file_off = -1;
+ }
+#endif
}
static void