Ethereal-dev: [Ethereal-dev] Dumping PDUs of reassembled protocols

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

From: Loïc Minier <lool+ethereal@xxxxxxxxxx>
Date: Mon, 4 Aug 2003 16:46:42 +0200
     Hello list,


 As I hoped to find a PDU dumper in ethereal but did not find one, I met
 other people interested in the same functionality in ethereal-users.
   Here's a draft of a patch slightly modifying packet-wtp.c,
 packet-ip.c, and Makefile.am. It shows the use of two new files,
 dump-pdu.c and .h.

 I currently can save all WSP packets (or ICMP packet) of a pcap file
 with a single command line:
    ./tethereal -o 'ip.defragment:true wap_wsp_wtp.dump_wsp:true
 wap_wsp_wtp.dump_wsp_pathname:wsp-packet' -r ../traces/trace.o -x -V >
 /dev/null

 And this can also work in real time.

 However, I understand some things might not match the usual syntax in
 ethereal's code.
   Additionnally, a lot of features are missing:
    - user format strings to specify output file (for example
 '%f-%p-%t-%i.pdu' could be a format string expressing the frame
 number, protocol short name, type of packet, and index, ie
 '12-wsp-connect-0.pdu').
    - support of never fragmented protocols
    - on-demand dump via ethereal's gui
    - ...

   I hope you'll be interested in this dumper as I am, and I am
 awaiting your comments,


   Best regards,

-- 
Lo�c Minier <lool@xxxxxxxx>
Index: Makefile.am
===================================================================
RCS file: /cvsroot/ethereal/Makefile.am,v
retrieving revision 1.605
diff -u -b -r1.605 Makefile.am
--- Makefile.am	4 Aug 2003 00:17:55 -0000	1.605
+++ Makefile.am	4 Aug 2003 14:32:50 -0000
@@ -709,6 +709,8 @@
 	crypt-md5.h    \
 	crypt-rc4.c    \
 	crypt-rc4.h    \
+	dump-pdu.c     \
+	dump-pdu.h     \
 	packet-dcerpc-nt.c \
 	etypes.h       \
 	file.h         \
Index: packet-ip.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ip.c,v
retrieving revision 1.194
diff -u -b -r1.194 packet-ip.c
--- packet-ip.c	11 Jul 2003 09:30:48 -0000	1.194
+++ packet-ip.c	4 Aug 2003 14:32:51 -0000
@@ -40,6 +40,7 @@
 #include "ip_opts.h"
 #include "prefs.h"
 #include "reassemble.h"
+#include "dump-pdu.h"
 #include "etypes.h"
 #include "greproto.h"
 #include "ppptypes.h"
@@ -62,6 +63,11 @@
 /* Defragment fragmented IP datagrams */
 static gboolean ip_defragment = FALSE;
 
+/* Dump ICMP PDUs to files */
+static gboolean ip_dump_icmp = FALSE;
+/* name of these files */
+static gchar *ip_dump_icmp_pathname = "icmp-dump";
+
 /* Place IP summary in proto tree */
 static gboolean ip_summary_in_tree = TRUE;
 
@@ -1502,6 +1508,11 @@
 	   original datagram. */
 	next_tvb = tvb_new_subset(tvb, 8, -1, -1);
 	call_dissector(ip_handle, next_tvb, pinfo, icmp_tree);
+	if (ip_dump_icmp) {
+		dump( tvb_new_subset(tvb, 8, -1, -1),
+			ip_dump_icmp_pathname,
+			FALSE );
+	}
 
 	/* Restore the "we're inside an error packet" flag. */
 	pinfo->in_error_pkt = save_in_error_pkt;
@@ -1511,6 +1522,11 @@
       case ICMP_ECHO:
 	call_dissector(data_handle, tvb_new_subset(tvb, 8, -1, -1), pinfo,
 	               icmp_tree);
+	if (ip_dump_icmp) {
+		dump( tvb_new_subset(tvb, 8, -1, -1),
+			ip_dump_icmp_pathname,
+			FALSE );
+	}
 	break;
 
       case ICMP_RTRADVERT:
@@ -1727,6 +1743,14 @@
 		"Reassemble fragmented IP datagrams",
 		"Whether fragmented IP datagrams should be reassembled",
 		&ip_defragment);
+	prefs_register_bool_preference(ip_module, "dump_icmp",
+		"dump ICMP packets to a file",
+		"Whether ICMP PDUs should be dumped to a file",
+		&ip_dump_icmp);
+	prefs_register_string_preference(ip_module, "dump_icmp_pathname",
+					 "ICMP PDUs dumps pathname",
+					 "Sets the name of dumped ICMP PDUs",
+					 &ip_dump_icmp_pathname);
 	prefs_register_bool_preference(ip_module, "summary_in_tree",
 	    "Show IP summary in protocol tree",
 	    "Whether the IP summary line should be shown in the protocol tree",
Index: packet-wsp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-wtp.c,v
retrieving revision 1.51
diff -u -b -r1.51 packet-wtp.c
--- packet-wtp.c	29 Jul 2003 22:10:18 -0000	1.51
+++ packet-wtp.c	4 Aug 2003 14:32:55 -0000
@@ -42,6 +42,8 @@
 #include <glib.h>
 #include <epan/packet.h>
 #include "reassemble.h"
+#include "prefs.h"
+#include "dump-pdu.h"
 #include "packet-wap.h"
 #include "packet-wtp.h"
 #include "packet-wsp.h"
@@ -225,6 +227,12 @@
  */
 static GHashTable	*wtp_fragment_table = NULL;
 
+/* Dump WSP PDUs to files */
+static gboolean wtp_dump_wsp = FALSE;
+/* name of these files */
+static gchar *wtp_dump_wsp_pathname = "wsp-dump";
+
+
 static void
 wtp_defragment_init(void)
 {
@@ -628,6 +636,9 @@
 					wtp_tree, pinfo, wsp_tvb);
 
 		call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
+		if (wtp_dump_wsp) {
+			dump( wsp_tvb, wtp_dump_wsp_pathname, FALSE );
+		}
 	    }
 	    else
 	    {
@@ -664,6 +675,9 @@
 	    } else {
 		wsp_tvb = tvb_new_subset(tvb, dataOffset, -1, -1);
 		call_dissector(wsp_handle, wsp_tvb, pinfo, tree);
+		if (wtp_dump_wsp) {
+			dump( wsp_tvb, wtp_dump_wsp_pathname, FALSE );
+		}
 	    }
 	}
     }
@@ -948,12 +962,13 @@
 	&ett_wsp_fragments,
 	&ett_wtp_fragment,
     };
+    module_t *wtp_module;
 
     /* Register the protocol name and description */
     proto_wtp = proto_register_protocol(
 	"Wireless Transaction Protocol",   /* protocol name for use by ethereal */
 	"WTP",                             /* short version of name */
-	"wap-wsp-wtp"                      /* Abbreviated protocol name, should Match IANA
+	"wap_wsp_wtp"                      /* Abbreviated protocol name, should Match IANA
 					    < URL:http://www.isi.edu/in-notes/iana/assignments/port-numbers/ >
 					    */
     );
@@ -965,6 +980,17 @@
     register_dissector("wtp", dissect_wtp_fromwap, proto_wtp);
     register_dissector("wtp-udp", dissect_wtp_fromudp, proto_wtp);
     register_init_routine(wtp_defragment_init);
+
+    /* Register configuration options */
+    wtp_module = prefs_register_protocol(proto_wtp, NULL);
+    prefs_register_bool_preference(wtp_module, "dump_wsp",
+		"dump WSP packets to a file",
+		"Whether WSP PDUs should be dumped to a file",
+		&wtp_dump_wsp);
+    prefs_register_string_preference(wtp_module, "dump_wsp_pathname",
+					 "WSP PDUs dumps pathname",
+					 "Sets the name of dumped WSP PDUs",
+					 &wtp_dump_wsp_pathname);
 };
 
 void
/* dump-pdu.c
 * Routines to dump reassembled PDU
 *
 * $Id:$
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * Copyright 1998 Gerald Combs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <glib.h>

#include <epan/packet.h>

#include "dump-pdu.h"

/* local functions */
static int
open_file(const char *pathname, gboolean append);

static int
search_filename_open(const char *base_pathname, gboolean append);


static int
open_file(const char *pathname, gboolean append) {
    int flags = O_WRONLY | O_CREAT | O_EXCL;
    if (append == TRUE) {
        flags |= O_APPEND;
    } else {
        flags |= O_EXCL;
    }
    return open(pathname, flags);
}

static int
search_filename_open(const char *base_pathname, gboolean append) {
    int file;           /* file descriptor */
    size_t size;        /* size of the filename */
    int i;
    char *pathname;

    if (base_pathname == NULL) {        /* use default name if none is given */
        base_pathname = DEFAULT_DUMP_PDU_PATHNAME;
    }

    if ((file = open_file(base_pathname, append)) >= 0) { /* try to open */
        return file;
    }

    /* search sequentially a name of the form "base_name.xxx" */
    size = strlen(base_pathname) + 4 + 1;       /* name.".999"."\0" */
    pathname = malloc(size);
    if (pathname == NULL) {
        return -1;
    }
    for (i = 0; i < 1000; i++ ) {
        snprintf(pathname, size, "%s.%i", base_pathname, i);
        if ((file = open_file(pathname, append)) >= 0) {
            return file;
        }
    }
    return -1;
}

int
dump(tvbuff_t *tvb, const char *base_pathname, gboolean append) {
    int file;
    guint length;

    file = search_filename_open(base_pathname, append);
    if (file < 0) {
        return file;
    }

    length = tvb_length(tvb);

    write(file, tvb_get_ptr(tvb, 0, length), length);
    return close(file);
}
/* dump-pdu.h
 * Declaration of routines to dump reassembled PDU
 *
 * $Id:$
 *
 * Ethereal - Network traffic analyzer
 * By Gerald Combs <gerald@xxxxxxxxxxxx>
 * Copyright 1998 Gerald Combs
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

extern int dump(tvbuff_t* tvb, const char *base_pathname, gboolean append);

#define DEFAULT_DUMP_PDU_PATHNAME "dumped-pdu"