Ethereal-dev: Re: [Ethereal-dev] new add-on: Hethereal

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Guy Harris <gharris@xxxxxxxxxxxx>
Date: Tue, 17 Apr 2001 00:11:33 -0700
On Tue, Mar 06, 2001 at 10:46:43PM +0100, Carsten Buchenau wrote:
> htmlcgi:
> We are using version 1.61 from  Eugene Eric Kim, eekim@xxxxxxxxx. It can be 
> downloaded from http://www.eekim.com/software/cgihtml/index.html. This might 
> be the point where Hethereal gets incompatible to Windows...

...and means that, in order to build Hethereal, you have to have that
installed.

It also means that the configure script should check whether it's
present and, if it isn't, not set up the Makefiles to build Hethereal.

(It also means I don't have time to check whether it builds right now.)

I've attached a patch to the current CVS version of Ethereal that

	1) patches "print.c" (the patch you supplied doesn't work with
	   the current version of Ethereal, or even with 0.8.17);

	2) patches "print.h" (the patch you supplied didn't do so);

	3) patches "Makefile.am" and "configure.in" to include Hethereal
	   as a target (but doesn't include the check for htmlcgi).

Note also that having "hethereal.c" include "dfilter-grammar.c" is
probably not a good idea; you should just link in the libethereal
library and get the parser from there.

There are also a bunch of changes to the list of files "hethereal.c"
includes, and perhaps other changes, that are necessary to get it to
work with the current version of Ethereal; I haven't looked into doing
those.
Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ethereal/Makefile.am,v
retrieving revision 1.306
diff -c -r1.306 Makefile.am
*** Makefile.am	2001/04/17 06:29:12	1.306
--- Makefile.am	2001/04/17 07:03:22
***************
*** 61,71 ****
  # automake will arrange that the Makefile define it as the union of all
  # the "man{section}_MANS" variables.
  #
! bin_PROGRAMS = @ethereal_bin@ @editcap_bin@ @tethereal_bin@ @dftest_bin@ @randpkt_bin@
  man1_MANS = @ethereal_man@ @editcap_man@ @tethereal_man@
  man_MANS = 
  
! EXTRA_PROGRAMS = ethereal ethereal_static tethereal tethereal_static editcap dftest
  
  sysconf_DATA = manuf
  
--- 61,71 ----
  # automake will arrange that the Makefile define it as the union of all
  # the "man{section}_MANS" variables.
  #
! bin_PROGRAMS = @ethereal_bin@ @editcap_bin@ @tethereal_bin@ @hethereal_bin@ @dftest_bin@ @randpkt_bin@
  man1_MANS = @ethereal_man@ @editcap_man@ @tethereal_man@
  man_MANS = 
  
! EXTRA_PROGRAMS = ethereal ethereal_static tethereal tethereal_static hethereal hethereal_static editcap dftest
  
  sysconf_DATA = manuf
  
***************
*** 503,508 ****
--- 503,555 ----
  
  tethereal_LDFLAGS = -export-dynamic
  tethereal_static_LDFLAGS = -Wl,-static
+ 
+ hethereal_SOURCES = \
+ 	$(DISSECTOR_SOURCES) \
+ 	$(ETHEREAL_COMMON_SOURCES) \
+ 	hethereal.c
+ 
+ hethereal_static_SOURCES = \
+ 	$(hethereal_SOURCES)
+ 
+ # Additional libs that I know how to build. These will be
+ # linked into the hethereal executable.
+ hethereal_additional_libs =		\
+ 	wiretap/libwiretap.a		\
+ 	epan/libethereal.a		\
+ 	epan/ftypes/libftypes.a		\
+ 	epan/dfilter/libdfilter.a
+ 
+ # This is the automake dependency variable for the executable
+ hethereal_DEPENDENCIES = \
+ 	$(ethereal_optional_objects)	\
+ 	$(hethereal_additional_libs)	\
+ 	plugins/gryphon/gryphon.la	\
+ 	plugins/mgcp/mgcp.la
+ 
+ hethereal_static_DEPENDENCIES = \
+ 	$(ethereal_optional_objects)	\
+ 	$(hethereal_additional_libs)	
+ 
+ # This automake variable adds to the link-line for the executable
+ hethereal_LDADD = wiretap/libwiretap.a	\
+ 	$(ethereal_optional_objects)	\
+ 	$(hethereal_additional_libs)	\
+ 	@SNMP_LIBS@ @SSL_LIBS@		\
+ 	"-dlopen" self	\
+ 	"-dlopen" plugins/gryphon/gryphon.la @GLIB_LIBS@ -lm \
+ 	"-dlopen" plugins/mgcp/mgcp.la @GLIB_LIBS@ -lm \
+ 	@PCAP_LIBS@ @SOCKET_LIBS@ @NSL_LIBS@
+ 
+ hethereal_static_LDADD = wiretap/libwiretap.a	\
+ 	$(ethereal_optional_objects)	\
+ 	$(hethereal_additional_libs)	\
+ 	@SNMP_LIBS@ @SSL_LIBS@		\
+ 	@GLIB_LIBS@ -lm \
+ 	@PCAP_LIBS@ @SOCKET_LIBS@ @NSL_LIBS@
+ 
+ hethereal_LDFLAGS = -export-dynamic
+ hethereal_static_LDFLAGS = -Wl,-static
  
  editcap_SOURCES = editcap.c
  
Index: configure.in
===================================================================
RCS file: /usr/local/cvsroot/ethereal/configure.in,v
retrieving revision 1.119
diff -c -r1.119 configure.in
*** configure.in	2001/04/11 23:52:50	1.119
--- configure.in	2001/04/17 07:03:23
***************
*** 221,226 ****
--- 221,240 ----
  
  
  
+ # Enable/disable hethereal
+ 
+ AC_ARG_ENABLE(hethereal,
+ [  --enable-hethereal      build hethereal.  [default=yes]],,enable_hethereal=yes)
+ 
+ if test "x$enable_hethereal" = "xyes" ; then
+ 	hethereal_bin="hethereal"
+ else
+ 	hethereal_bin=""
+ fi
+ AC_SUBST(hethereal_bin)
+ 
+ 
+ 
  # Enable/disable editcap
  
  AC_ARG_ENABLE(editcap,
Index: print.c
===================================================================
RCS file: /usr/local/cvsroot/ethereal/print.c,v
retrieving revision 1.32
diff -c -r1.32 print.c
*** print.c	2001/03/24 23:49:14	1.32
--- print.c	2001/04/17 07:03:25
***************
*** 9,14 ****
--- 9,31 ----
   * By Gerald Combs <gerald@xxxxxxxx>
   * Copyright 1998 Gerald Combs
   *
+  * HTML/JavaScript extensions by
+  *      Carsten Buchenau <carsten@xxxxxxxxxxxx>
+  *      Tim Abenath <tim@xxxxxxxxxxxx>
+  *      University of Applied Science, Dortmund, Germany
+  *
+  *	New functions:
+  *		proto_tree_print_node_html
+  *		print_hex_data_html
+  *	Modified functions:
+  *		proto_tree_print
+  *		print_hex_data
+  *	Modified structs:
+  *		print_data, additional values:
+  *			int	js_level;
+  *			int	js_parent_idx;
+  *			int	js_self_idx;
+  *		
   * 
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
***************
*** 42,52 ****
--- 59,72 ----
  #include "util.h"
  
  static void proto_tree_print_node_text(GNode *node, gpointer data);
+ static void proto_tree_print_node_html(GNode *node, gpointer data);
  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 print_hex_data_text(FILE *fh, register const u_char *cp,
  		register u_int length, char_enc encoding);
+ static void print_hex_data_html(FILE *fh, register const u_char *cp,
+ 		register u_int length, char_enc encoding);
  static void print_hex_data_ps(FILE *fh, register const u_char *cp,
  		register u_int length, char_enc encoding);
  
***************
*** 60,67 ****
--- 80,92 ----
  	gboolean	print_all_levels;
  	gboolean	print_hex_for_data;
  	char_enc	encoding;
+ 	/* HTML/JavaScript extension (hethereal): add 3 new values */
+ 	int		js_level;
+ 	int		js_parent_idx;
+ 	int		js_self_idx;
  } print_data;
  
+ 
  FILE *open_print_dest(int to_file, const char *dest)
  {
  	FILE	*fh;
***************
*** 110,119 ****
--- 135,151 ----
  	data.print_hex_for_data = !print_args->print_hex;
  	    /* If we're printing the entire packet in hex, don't
  	       print uninterpreted data fields in hex as well. */
+ 	data.js_level = 0;
+ 	data.js_self_idx = 0;
+ 	data.js_parent_idx = 0;
  
+ 	/* HTML/JavaScript: PR_FMT_HTML must be defined in hethereal.c */
  	if (print_args->format == PR_FMT_TEXT) {
  		g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
  			proto_tree_print_node_text, &data);
+ 	} else if (print_args->format == PR_FMT_HTML) {
+ 		g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
+ 			proto_tree_print_node_html, &data);
  	} else {
  		g_node_children_foreach((GNode*) protocol_tree, G_TRAVERSE_ALL,
  			proto_tree_print_node_ps, &data);
***************
*** 177,182 ****
--- 209,280 ----
  	}
  }
  
+ /* HTML/JavaScript extension (hethereal): */
+ /* Print a tree's data, and any child nodes, in HTML */
+ static
+ void proto_tree_print_node_html(GNode *node, gpointer data)
+ {
+ 	field_info	*fi = (field_info*) (node->data);
+ 	print_data	*pdata = (print_data*) data;
+ 	gchar		label_str[ITEM_LABEL_LENGTH];
+ 	gchar		*label_ptr;
+ 	/* for JavaScript Menu-traversal */
+ 	int		saved_js_parent_idx=0;
+ 
+ 	/* Don't print invisible entries. */
+ 	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);
+ 	}
+ 
+ 	
+ 	switch (g_node_n_children(node)) {
+ 	  case 0:
+ 	    fprintf(pdata->fh,
+ 	      "mD.neu(new LE(\"%d\",\"%s\",\"javascript:parent.print_hex_data(%d,%d)\",\"\",\"leer.gif\",\"%s\"))\n",
+ 	      pdata->js_parent_idx, label_ptr, fi->start, fi->length, label_ptr);
+ 	    break;
+ 	  default:
+ 	    pdata->js_self_idx++;
+ 	    fprintf(pdata->fh,
+ 	      "mD.neu(new VE(\"%d\",\"%d\",\"%s\",\"javascript:parent.print_hex_data(%d,%d)\",\"\",\"\",\"%s\"))\n",
+ 	      pdata->js_self_idx, pdata->js_parent_idx, label_ptr, fi->start, fi->length, label_ptr);
+ 	}
+ 
+ 
+ 	/* If it's uninterpreted data, dump it (unless our caller will
+ 	   be printing the entire packet in hex). */
+ 	if (fi->hfinfo->id == proto_data && pdata->print_hex_for_data)
+ 		print_hex_data_html(pdata->fh, &pdata->pd[fi->start],
+ 				fi->length, pdata->encoding);
+ 
+ 	/* If we're printing all levels, or if this level is expanded,
+ 	   recurse into the subtree, if it exists. */
+ 	if (pdata->print_all_levels || tree_is_expanded[fi->tree_type]) {
+ 		if (g_node_n_children(node) > 0) {
+ 			/* - Increment pdata->level each time we finde a new node */
+ 			/* - Save present pdata->js_parent_idx, enter recursion
+ 			     with new value from pdata->level and restore old value
+ 			     afterwards. */
+ 			pdata->level++;
+ 			pdata->js_level++;
+ 			saved_js_parent_idx = pdata->js_parent_idx;
+ 			pdata->js_parent_idx = pdata->js_level;
+ 			g_node_children_foreach(node, G_TRAVERSE_ALL,
+ 				proto_tree_print_node_html, pdata);
+ 			pdata->js_parent_idx = saved_js_parent_idx;
+ 			pdata->level--;
+ 		}
+ 	}
+ }
+ 
  void print_hex_data(FILE *fh, gint format, frame_data *fd)
  {
  	gboolean multiple_sources;
***************
*** 208,217 ****
  		}
  		length = tvb_length(tvb);
  		cp = tvb_get_ptr(tvb, 0, length);
! 		if (format == PR_FMT_PS)
! 			print_hex_data_ps(fh, cp, length, fd->flags.encoding);
! 		else
  			print_hex_data_text(fh, cp, length, fd->flags.encoding);
  	}
  }
  
--- 306,328 ----
  		}
  		length = tvb_length(tvb);
  		cp = tvb_get_ptr(tvb, 0, length);
! 		switch (format) {
! 
! 		case PR_FMT_TEXT:
  			print_hex_data_text(fh, cp, length, fd->flags.encoding);
+ 			break;
+ 
+ 		case PR_FMT_PS:
+ 			print_hex_data_ps(fh, cp, length, fd->flags.encoding);
+ 			break;
+ 
+ 		case PR_FMT_HTML:
+ 			print_hex_data_html(fh, cp, length, fd->flags.encoding);
+ 			break;
+ 
+ 		default:
+ 			g_assert_not_reached();
+ 		}
  	}
  }
  
***************
*** 252,257 ****
--- 363,430 ----
          fprintf(fh, "\n");
          return;
  
+ }
+ 
+ /*
+  * HTML/JavaScript extension (hethereal):
+  * This routine was created by Dan Lasley <DLASLEY@xxxxxxxxxx>, only
+  * slightly modified for ethereal by Gilbert Ramirez, and then duplicated
+  * and modified for hethereal by carsten@xxxxxxxxxxxx and tim@xxxxxxxxxxxx.
+  */
+ static
+ void print_hex_data_html(FILE *fh, register const u_char *cp,
+ 		register u_int length, char_enc encoding)
+ {
+         register int i;
+         u_char c;
+ 	u_char c_ascii_str[3];
+ 	u_char *cp_ascii = (u_char *)cp;
+ 	
+ 	void convert_to_ascii(u_char c_ascii_str[3], const u_char c)
+ 	{
+ 	  u_char c_ascii;
+ 	  
+ 	  c_ascii = c >= 0x20 && c < 0x7f ? c : '.';
+ 	  switch (c_ascii) {
+ 	    case 0x22:
+ 	    case 0x5c:
+ 	      sprintf(c_ascii_str, "\\%c", c_ascii);
+ 	      break;
+ 	    default:
+ 	      sprintf(c_ascii_str, "%c", c_ascii);
+ 	  }
+ 	}
+ 
+ 	/* close open JavaScript function first */
+ 	fprintf(fh, "}\n\n");
+ 	
+ 
+ 	/* Now build JavaScript array for hex-data */
+ 	fprintf(fh, "var hexdaten = new Array(");
+         for (i=0; i<length-1; i++) {
+                 c = *cp++;
+ 		if (encoding == CHAR_EBCDIC) c = EBCDIC_to_ASCII1(c);
+ 	        fprintf(fh, "\"%02X\",", c);
+         }
+ 	/* print last byte and close hex-array */
+ 	c = *cp++;
+ 	fprintf(fh, "\"%02X\")\n", c);
+ 
+ 
+ 	/* Now build JavaScript array for ASCII-data */
+ 	fprintf(fh, "var asciidaten = new Array(");
+ 	for (i=0; i<length-1; i++) {
+                 c = *cp_ascii++;
+ 		if (encoding == CHAR_EBCDIC) c = EBCDIC_to_ASCII1(c);
+ 		convert_to_ascii(c_ascii_str, c);
+ 		fprintf(fh, "\"%s\",", c_ascii_str);
+ 	}
+ 	/* print last byte and close ascii-array */
+ 	c = *cp_ascii++;
+ 	convert_to_ascii(c_ascii_str, c);
+ 	fprintf(fh, "\"%s\")\n", c_ascii_str);
+ 	
+         return;
  }
  
  #define MAX_LINE_LENGTH 256
Index: print.h
===================================================================
RCS file: /usr/local/cvsroot/ethereal/print.h,v
retrieving revision 1.21
diff -c -r1.21 print.h
*** print.h	2001/03/23 18:44:20	1.21
--- print.h	2001/04/17 07:03:25
***************
*** 32,37 ****
--- 32,38 ----
  
  #define PR_FMT_TEXT 0
  #define PR_FMT_PS   1
+ #define PR_FMT_HTML 2
  
  typedef struct {
    gboolean	to_file;	/* TRUE if we're printing to a file */