Ethereal-dev: [Ethereal-dev] mergecap patch: dissimilar frame encapsulation types

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

From: Scott Renfro <scott@xxxxxxxxxx>
Date: Fri, 13 Jul 2001 02:54:59 -0700
Merging capture files with dissimilar frame encapsulation types (e.g.,
one file came from an ethernet interface and the other from loopback)
appears to be unuseful (i.e., Ethereal can't process all packets in the
file and the frame encapsulation type is an attribute of the file and
not the frame).  (Correct me if I'm wrong or if this is only true of
pcap files).

The attached patch (relative to the latest cvs after the multiple-files
patch was checked in), causes mergecap to check the frame types of all
input files before opening the output file.  If this condition is found,
an error message is printed and mergecap exits without merging the
files.  I also added a -f option to force output, overriding the default
behavior.

There may be better long-term solutions (e.g., (1) merge all files that
have the same frame type as the specified type or type of the first file
if no type was specified, (2) merge all files with similar frame types
into multiple output files, [pre|a]ppending the frame type to the
specified output filename, (3) fixing up the frames with dummy data).

cheers,
--Scott

-- 
Scott Renfro <scott@xxxxxxxxxx>                          +1 650 862 4206
Index: mergecap.c
===================================================================
RCS file: /cvsroot/ethereal/mergecap.c,v
retrieving revision 1.2
diff -u -r1.2 mergecap.c
--- mergecap.c	2001/07/13 08:16:15	1.2
+++ mergecap.c	2001/07/13 09:42:45
@@ -39,6 +39,7 @@
  * Global variables
  */
 static int verbose = 0;                      /* Not so verbose         */
+static int force   = 0;         /* force output, even disparate frame types */
 
 /* 
  * Structures to manage our files
@@ -184,6 +185,49 @@
 
 
 /*
+ * Check the set of input files to ensure
+ * that their frame_types are consistent
+ */
+static void
+check_frame_types(int count, in_file_t files[])
+{
+  int i;
+  int initial_frame_type;
+  gboolean mismatch = FALSE;
+  
+  initial_frame_type = wtap_file_encap(files[0].wth);
+  
+  if (verbose)
+    fprintf(stderr, "mergecap: first input file has frame type %s (%s)\n",
+            wtap_encap_string(initial_frame_type),
+            wtap_encap_short_string(initial_frame_type));
+
+  for (i = 1; i < count; i++) {
+    int this_frame_type = wtap_file_encap(files[i].wth);
+    if (initial_frame_type != this_frame_type) {
+      fprintf(stderr,
+              "mergecap: file \"%s\" has frame type %s (%s)\n",
+              files[i].filename,
+              wtap_encap_string(this_frame_type),
+              wtap_encap_short_string(this_frame_type));
+      mismatch = TRUE;
+    }
+  }
+  
+  if (mismatch) {
+    fprintf(stderr, "mergecap: detected dissimilar frame types\n");
+    fprintf(stderr, "          \"%s\" had frame type %s (%s)\n",
+            files[0].filename,
+            wtap_encap_string(initial_frame_type),
+            wtap_encap_short_string(initial_frame_type));
+    if (!force)
+      exit(1);
+  }
+
+}
+    
+
+/*
  * Close the output file
  */
 static void
@@ -308,10 +352,11 @@
   int i;
   const char *string;
 
-  fprintf(stderr, "Usage: mergecap [-h] [-v] [-a] [-s <snaplen>] [-T <encap type>]\n");
+  fprintf(stderr, "Usage: mergecap [-hvaf] [-s <snaplen>] [-T <encap type>]\n");
   fprintf(stderr, "          [-F <capture type>] -w <outfile> <infile> [...]\n\n");
   fprintf(stderr, "  where\t-h produces this help listing.\n");
   fprintf(stderr, "       \t-v verbose operation, default is silent\n");
+  fprintf(stderr, "       \t-f force output, even with disparate frame types\n");
   fprintf(stderr, "       \t-a files should be concatenated, not merged\n");
   fprintf(stderr, "       \t     Default merges based on frame timestamps\n");
   fprintf(stderr, "       \t-s <snaplen>: truncate packets to <snaplen> bytes of data\n");
@@ -356,9 +401,13 @@
   out_file.count      = 1;                 /* frames output */
 
   /* Process the options first */
-  while ((opt = getopt(argc, argv, "w:aT:F:vs:h")) != EOF) {
+  while ((opt = getopt(argc, argv, "hvafs:T:F:w:")) != EOF) {
 
     switch (opt) {
+    case 'f':
+      force = !force;
+      break;
+
     case 'w':
       out_file.filename = optarg;
       break;
@@ -429,6 +478,9 @@
     fprintf(stderr, "mergecap: No valid input files\n");
     exit(1);
   }
+
+  /* check the frame_types for inconsistency */
+  check_frame_types(in_file_count, in_files);
 
   /* set the outfile frame type */
   if (out_file.frame_type == -2)
Index: doc/mergecap.pod
===================================================================
RCS file: /cvsroot/ethereal/doc/mergecap.pod,v
retrieving revision 1.2
diff -u -r1.2 mergecap.pod
--- mergecap.pod	2001/07/13 08:16:16	1.2
+++ mergecap.pod	2001/07/13 09:42:47
@@ -6,12 +6,10 @@
 =head1 SYNOPSYS
 
 B<mergecap>
+S<[ B<-hvaf> ]>
+S<[ B<-s> I<snaplen> ]>
 S<[ B<-F> I<file format> ]>
 S<[ B<-T> I<encapsulation type> ]>
-S<[ B<-a> ]>
-S<[ B<-v> ]>
-S<[ B<-s> I<snaplen> ]>
-S<[ B<-h> ]>
 S<B<-w> I<outfile>>
 I<infile>
 I<...>
@@ -95,6 +93,15 @@
 are merged in chronological order based on each frame's timestamp.
 Note: when merging, B<mergecap> assumes that packets within a capture
 file are already in chronological order.
+
+=item -f
+
+Causes B<mergecap> to generate output, even when the output may not be
+useful.  Specifically, merging files with dissimilar frame encapsulation
+types (e.g., an ethernet capture and a loopback capture) produces a file
+that is not useful.  By default, B<mergecap> will not merge files with
+dissimilar frame encapsulation types.  The <-f> option overrides this
+behavior.
 
 =item -v