aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1999-07-13 04:38:15 +0000
committerGuy Harris <guy@alum.mit.edu>1999-07-13 04:38:15 +0000
commitf57403fe466cf5dacbc7bff1dc9b0c77514c1f2c (patch)
treea63f258f6d1ff5bcdd3fbea3fcf9f78b72f156a0
parent8369394c079da21a2c8196f376f0e82a0bf045ba (diff)
When printing a packet, do it from the protocol tree, not from the GTK+
tree constructed from the protocol tree: 1) The value of "level" field of GTK+ tree items appears to depend on various random things - see a change I made to "packet-dns.c" a while ago, to change the order in which items were put in the tree, so that DNS trees printed with correct indentation - and, right now, we appear to be doing *something* wrong, as some packets I printed from one file here had randomly bogus indentation; I could probably track the problem down and fix it, but that might just hold us until we accidentally do something *else* wrong by GTK+'s lights. The new code provides its own tree level as it goes. 2) The new code is independent of GTK+, so it could be used with other toolkits, or with non-GUI variants of Ethereal. 3) This may make it easier to add a "Print..." menu item to let the user print packets other than the currently selected packet. Make the internal routines used to print the packet static. For the "Print Packet" menu item, put up a message box if they haven't yet selected a packet. svn path=/trunk/; revision=362
-rw-r--r--ethereal.c9
-rw-r--r--print.c234
-rw-r--r--print.h6
3 files changed, 132 insertions, 117 deletions
diff --git a/ethereal.c b/ethereal.c
index 8348c72fdd..d8abb4b416 100644
--- a/ethereal.c
+++ b/ethereal.c
@@ -1,6 +1,6 @@
/* ethereal.c
*
- * $Id: ethereal.c,v 1.54 1999/07/13 03:08:04 gram Exp $
+ * $Id: ethereal.c,v 1.55 1999/07/13 04:38:14 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -542,7 +542,12 @@ filter_activate_cb(GtkWidget *w, gpointer data) {
/* Print a packet */
void
file_print_cmd_cb(GtkWidget *widget, gpointer data) {
- print_tree(cf.pd, fd, GTK_TREE(tree_view));
+ if (protocol_tree == NULL) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "No packet is selected, so there's no packet to print.");
+ return;
+ }
+ proto_tree_print((GNode*) protocol_tree, cf.pd, fd);
}
/* What to do when a list item is selected/unselected */
diff --git a/print.c b/print.c
index 53bba697e8..924d2dfe73 100644
--- a/print.c
+++ b/print.c
@@ -1,7 +1,7 @@
/* print.c
* Routines for printing packet analysis trees.
*
- * $Id: print.c,v 1.11 1999/07/07 22:51:58 gram Exp $
+ * $Id: print.c,v 1.12 1999/07/13 04:38:13 guy Exp $
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
@@ -49,10 +49,12 @@ static void printer_opts_fs_cancel_cb(GtkWidget *w, gpointer data);
static void printer_opts_fs_ok_cb(GtkWidget *w, gpointer data);
static void printer_opts_toggle_format(GtkWidget *widget, gpointer data);
static void printer_opts_toggle_dest(GtkWidget *widget, gpointer data);
+static void proto_tree_print_node_text(GNode *node, gpointer data);
static void dumpit (FILE *fh, register const u_char *cp, register u_int length);
-static void dumpit_ps (FILE *fh, register const u_char *cp, register u_int length);
+static void proto_tree_print_node_ps(GNode *node, gpointer data);
static void ps_clean_string(unsigned char *out, const unsigned char *in,
int outbuf_size);
+static void dumpit_ps (FILE *fh, register const u_char *cp, register u_int length);
extern e_prefs prefs;
@@ -252,10 +254,18 @@ printer_opts_toggle_dest(GtkWidget *widget, gpointer data)
}
/* ========================================================== */
-void print_tree(const u_char *pd, frame_data *fd, GtkTree *tree)
+
+typedef struct {
+ int level;
+ FILE *fh;
+ const guint8 *pd;
+} print_data;
+
+void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd)
{
FILE *fh;
char *out;
+ print_data data;
/* Open the file or command for output */
if (prefs.pr_dest == PR_DEST_CMD) {
@@ -273,12 +283,16 @@ void print_tree(const u_char *pd, frame_data *fd, GtkTree *tree)
}
/* Create the output */
+ data.level = 0;
+ data.fh = fh;
+ data.pd = pd;
if (prefs.pr_format == PR_FMT_TEXT) {
- print_tree_text(fh, pd, fd, tree);
- }
- else {
+ g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
+ proto_tree_print_node_text, &data);
+ } else {
print_ps_preamble(fh);
- print_tree_ps(fh, pd, fd, tree);
+ g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
+ proto_tree_print_node_ps, &data);
print_ps_finale(fh);
}
@@ -291,19 +305,32 @@ void print_tree(const u_char *pd, frame_data *fd, GtkTree *tree)
}
}
-/* Print a tree's data in plain text */
-void print_tree_text(FILE *fh, const u_char *pd, frame_data *fd, GtkTree *tree)
+/* Print a tree's data, and any child nodes, in plain text */
+static
+void proto_tree_print_node_text(GNode *node, gpointer data)
{
- GList *children, *child, *widgets, *label;
- GtkWidget *subtree;
- int num_children, i;
- char *text;
+ field_info *fi = (field_info*) (node->data);
+ print_data *pdata = (print_data*) data;
+ int i;
int num_spaces;
char space[41];
- gint data_start, data_len;
+ gchar label_str[ITEM_LABEL_LENGTH];
+ gchar *label_ptr;
+
+ if (!fi->visible)
+ return;
+ /* was a free format label produced? */
+ if (fi->representation) {
+ label_ptr = fi->representation;
+ }
+ else { /* no, make a generic label */
+ label_ptr = label_str;
+ proto_item_fill_label(fi, label_str);
+ }
+
/* Prepare the tabs for printing, depending on tree level */
- num_spaces = tree->level * 4;
+ num_spaces = pdata->level * 4;
if (num_spaces > 40) {
num_spaces = 40;
}
@@ -313,34 +340,20 @@ void print_tree_text(FILE *fh, const u_char *pd, frame_data *fd, GtkTree *tree)
/* The string is NUL-terminated */
space[num_spaces] = 0;
- /* Get the children of this tree */
- children = tree->children;
- num_children = g_list_length(children);
-
- for (i = 0; i < num_children; i++) {
- /* Each child of the tree is a widget container */
- child = g_list_nth(children, i);
- widgets = gtk_container_children(GTK_CONTAINER(child->data));
+ /* Print the text */
+ fprintf(pdata->fh, "%s%s\n", space, label_ptr);
- /* And the container holds a label object, which holds text */
- label = g_list_nth(widgets, 0);
- gtk_label_get(GTK_LABEL(label->data), &text);
+ /* If it's uninterpreted data, dump it.
+ XXX - have a better way of doing this than looking for "Data (" */
+ if (strncmp("Data (", label_ptr, 6) == 0)
+ dumpit(pdata->fh, &pdata->pd[fi->start], fi->length);
- /* Print the text */
- fprintf(fh, "%s%s\n", space, text);
-
- /* Recurse into the subtree, if it exists */
- subtree = (GTK_TREE_ITEM(child->data))->subtree;
- if (subtree) {
- print_tree_text(fh, pd, fd, GTK_TREE(subtree));
- }
- else if (strncmp("Data (", text, 6) == 0) {
- data_start = (gint) gtk_object_get_data(GTK_OBJECT(child->data),
- E_TREEINFO_START_KEY);
- data_len = (gint) gtk_object_get_data(GTK_OBJECT(child->data),
- E_TREEINFO_LEN_KEY);
- dumpit(fh, &pd[data_start], data_len);
- }
+ /* Recurse into the subtree, if it exists */
+ if (g_node_n_children(node) > 0) {
+ pdata->level++;
+ g_node_children_foreach(node, G_TRAVERSE_ALL,
+ proto_tree_print_node_text, pdata);
+ pdata->level--;
}
}
@@ -381,82 +394,45 @@ void dumpit (FILE *fh, register const u_char *cp, register u_int length)
#define MAX_LINE_LENGTH 256
+/* Print a node's data, and any child nodes, in PostScript */
static
-void dumpit_ps (FILE *fh, register const u_char *cp, register u_int length)
-{
- register int ad, i, j, k;
- u_char c;
- u_char line[60];
- static u_char binhex[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
- u_char psline[MAX_LINE_LENGTH];
-
- memset (line, ' ', sizeof line);
- line[sizeof (line)-1] = 0;
- for (ad=i=j=k=0; i<length; i++) {
- c = *cp++;
- line[j++] = binhex[c>>4];
- line[j++] = binhex[c&0xf];
- if (i&1) j++;
- line[42+k++] = c >= ' ' && c < 0x7f ? c : '.';
- if ((i & 15) == 15) {
- ps_clean_string(psline, line, MAX_LINE_LENGTH);
- fprintf (fh, "(%4x %s) hexdump\n", ad, psline);
- memset (line, ' ', sizeof line);
- line[sizeof (line)-1] = j = k = 0;
- ad += 16;
- }
- }
-
- if (line[0] != ' ') {
- ps_clean_string(psline, line, MAX_LINE_LENGTH);
- fprintf (fh, "(%4x %s) hexdump\n", ad, psline);
- }
- return;
-
-}
-
-/* Print a tree's data in PostScript */
-void print_tree_ps(FILE *fh, const u_char *pd, frame_data *fd, GtkTree *tree)
+void proto_tree_print_node_ps(GNode *node, gpointer data)
{
- GList *children, *child, *widgets, *label;
- GtkWidget *subtree;
- int num_children, i;
- char *text;
- gint data_start, data_len;
+ field_info *fi = (field_info*) (node->data);
+ print_data *pdata = (print_data*) data;
+ gchar label_str[ITEM_LABEL_LENGTH];
+ gchar *label_ptr;
char psbuffer[MAX_LINE_LENGTH]; /* static sized buffer! */
- /* Get the children of this tree */
- children = tree->children;
- num_children = g_list_length(children);
-
- for (i = 0; i < num_children; i++) {
- /* Each child of the tree is a widget container */
- child = g_list_nth(children, i);
- widgets = gtk_container_children(GTK_CONTAINER(child->data));
-
- /* And the container holds a label object, which holds text */
- label = g_list_nth(widgets, 0);
- gtk_label_get(GTK_LABEL(label->data), &text);
+ if (!fi->visible)
+ return;
- /* Print the text */
- ps_clean_string(psbuffer, text, MAX_LINE_LENGTH);
- fprintf(fh, "%d (%s) putline\n", tree->level, psbuffer);
+ /* was a free format label produced? */
+ if (fi->representation) {
+ label_ptr = fi->representation;
+ }
+ else { /* no, make a generic label */
+ label_ptr = label_str;
+ proto_item_fill_label(fi, label_str);
+ }
+
+ /* Print the text */
+ ps_clean_string(psbuffer, label_ptr, MAX_LINE_LENGTH);
+ fprintf(pdata->fh, "%d (%s) putline\n", pdata->level, psbuffer);
+
+ /* If it's uninterpreted data, dump it.
+ XXX - have a better way of doing this than looking for "Data (" */
+ if (strncmp("Data (", label_ptr, 6) == 0) {
+ print_ps_hex(pdata->fh);
+ dumpit_ps(pdata->fh, &pdata->pd[fi->start], fi->length);
+ }
- /* Recurse into the subtree, if it exists */
- subtree = (GTK_TREE_ITEM(child->data))->subtree;
- if (subtree) {
- print_tree_ps(fh, pd, fd, GTK_TREE(subtree));
- }
- else if (strncmp("Data (", text, 6) == 0) {
- data_start = (gint) gtk_object_get_data(GTK_OBJECT(child->data),
- E_TREEINFO_START_KEY);
- data_len = (gint) gtk_object_get_data(GTK_OBJECT(child->data),
- E_TREEINFO_LEN_KEY);
- print_ps_hex(fh);
- dumpit_ps(fh, &pd[data_start], data_len);
- }
+ /* Recurse into the subtree, if it exists */
+ if (g_node_n_children(node) > 0) {
+ pdata->level++;
+ g_node_children_foreach(node, G_TRAVERSE_ALL,
+ proto_tree_print_node_ps, pdata);
+ pdata->level--;
}
}
@@ -487,3 +463,39 @@ void ps_clean_string(unsigned char *out, const unsigned char *in,
}
}
}
+
+static
+void dumpit_ps (FILE *fh, register const u_char *cp, register u_int length)
+{
+ register int ad, i, j, k;
+ u_char c;
+ u_char line[60];
+ static u_char binhex[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+ u_char psline[MAX_LINE_LENGTH];
+
+ memset (line, ' ', sizeof line);
+ line[sizeof (line)-1] = 0;
+ for (ad=i=j=k=0; i<length; i++) {
+ c = *cp++;
+ line[j++] = binhex[c>>4];
+ line[j++] = binhex[c&0xf];
+ if (i&1) j++;
+ line[42+k++] = c >= ' ' && c < 0x7f ? c : '.';
+ if ((i & 15) == 15) {
+ ps_clean_string(psline, line, MAX_LINE_LENGTH);
+ fprintf (fh, "(%4x %s) hexdump\n", ad, psline);
+ memset (line, ' ', sizeof line);
+ line[sizeof (line)-1] = j = k = 0;
+ ad += 16;
+ }
+ }
+
+ if (line[0] != ' ') {
+ ps_clean_string(psline, line, MAX_LINE_LENGTH);
+ fprintf (fh, "(%4x %s) hexdump\n", ad, psline);
+ }
+ return;
+
+}
diff --git a/print.h b/print.h
index 60585b4fa0..bd3548b2a3 100644
--- a/print.h
+++ b/print.h
@@ -1,7 +1,7 @@
/* print.h
* Definitions for printing packet analysis trees.
*
- * $Id: print.h,v 1.6 1998/10/28 21:38:11 gerald Exp $
+ * $Id: print.h,v 1.7 1999/07/13 04:38:15 guy Exp $
*
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
@@ -34,8 +34,6 @@ GtkWidget *printer_prefs_show();
void printer_prefs_ok(GtkWidget *w);
void printer_prefs_save(GtkWidget *w);
void printer_prefs_cancel(GtkWidget *w);
-void print_tree(const u_char *pd, frame_data *fd, GtkTree *tree);
-void print_tree_text(FILE *fh, const u_char *pd, frame_data *fd, GtkTree *tree);
-void print_tree_ps(FILE *fh, const u_char *pd, frame_data *fd, GtkTree *tree);
+void proto_tree_print(GNode *protocol_tree, const u_char *pd, frame_data *fd);
#endif /* print.h */