Packet editor: support for saving changed frames.

svn path=/trunk/; revision=37099
This commit is contained in:
Jakub Zawadzki 2011-05-12 19:47:49 +00:00
parent c64c481e06
commit 63981c8b35
4 changed files with 81 additions and 2 deletions

View File

@ -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);

View File

@ -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.

22
file.c
View File

@ -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) {

View File

@ -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