Wireshark-dev: Re: [Wireshark-dev] On Copy as Filter
From: didier <dgautheron@xxxxxxxx>
Date: Sat, 06 Jun 2009 01:29:35 +0200
Le samedi 06 juin 2009 à 00:26 +0200, Sake Blok a écrit :
> On Fri, Jun 05, 2009 at 11:55:02PM +0200, didier wrote:
> > Le dimanche 31 mai 2009 à 11:56 +0200, Sake Blok a écrit :
> > > Hi Jaap (& list),
> > > 
> > > As the "father" of the "copy as filter" functionality, I would vote for it 
> > > to be present all the time in the packet details pane (where I use it most). 
> > > Keeping track of all possible filters for the packet list pane seems like an 
> > > overkill to me and could be made optional to save memory. Or it should be 
> > > implemented in a way where it will dynamically be generated. For 1.2.0 I 
> > > would suggest to just revert the implemented memory-consuming patch and 
> > > disable the functionality in the packet-list. Then we can decide later to 
> > > make it either optional of write code that dynamically generate the filter 
> > > string on use (if that is at all possible).
> > 
> > Anyone remember why it was changed from dynamically generate?
> > The SVN log msg doesn't make sense to me.
> 
> IIRC, the filter strings were not generated dynamically, they were
> generated while building the packet-list, resulting in having the
> filters for the last row to be the filters for all rows. But my memory
> might not be totally accurate ;-)
It was generated, cf svn  24511 but:
1- didn't work with col_custom 
2- use ep_alloc, a bit dangerous? 

attached a modified version which work for me.

Didier

=== modified file 'gtk/main.c'
--- gtk/main.c	2009-06-02 20:15:46 +0000
+++ gtk/main.c	2009-06-05 21:57:09 +0000
@@ -496,14 +496,40 @@
     gint	row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
     gint	column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY));
     frame_data *fdata = (frame_data *)packet_list_get_row_data(row);
+    epan_dissect_t *edt;
+    gchar      *buf=NULL;
+    int         len;
+    int         err;
+    gchar       *err_info;
 
-    if(strlen(fdata->col_expr.col_expr[column]) != 0 &&
-       strlen(fdata->col_expr.col_expr_val[column]) != 0)
-	    return ep_strdup_printf("%s == %s",
-				    fdata->col_expr.col_expr[column],
-				    fdata->col_expr.col_expr_val[column]);
-    else
+    if (fdata != NULL) {
+	if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
+		       cfile.pd, fdata->cap_len, &err, &err_info)) {
+	    simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+		          cf_read_error_message(err, err_info), cfile.filename);
 	    return NULL;
+	}
+	/* proto tree, visible. We need a proto tree if there's custom columns */
+	edt = epan_dissect_new(have_custom_cols(&cfile.cinfo), FALSE);
+        col_custom_prime_edt(edt, &cfile.cinfo);
+	    
+	epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
+			 &cfile.cinfo);
+	epan_dissect_fill_in_columns(edt);
+
+	if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
+	    strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
+	    len = strlen(cfile.cinfo.col_expr.col_expr[column]) +
+		  strlen(cfile.cinfo.col_expr.col_expr_val[column]) + 5;
+	    buf = se_alloc0(len); /* leak a little but safer than ep_ here*/
+	    g_snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr.col_expr[column],
+		     cfile.cinfo.col_expr.col_expr_val[column]);
+    	}
+
+	epan_dissect_free(edt);
+    }
+
+    return buf;
 }
 
 void