Ethereal-dev: Re: [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: Sat, 14 Jul 2001 00:10:35 -0700
On Fri, Jul 13, 2001 at 02:49:02PM -0700, Scott Renfro wrote:
> On Fri, Jul 13, 2001 at 11:22:14AM -0700, Guy Harris wrote:
> > 
> > As such, just changing the code so that WTAP_ENCAP_PER_PACKET is chosen
> > if not all files have the same frame encapsulation type should be
> > sufficient - if the output type can handle that, you win, otherwise
> > "wtap_dump_open()" will fail and mergecap will print the right error
> > message.
> 
> Ah, great.  Thanks for the clear feedback.  I'll implement this logic
> and resubmit the patch.

Here's the updated patch to mergecap.

One thing I noticed in testing it: for file types that have an
XXX_dump_can_write_encap(), XXX_dump_can_write_encap always appears to
return unsupported when the type is per-packet.

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/14 06:57:09
@@ -184,6 +184,52 @@
 
 
 /*
+ * Select an output frame type based on the input files
+ * From Guy: If all files have the same frame type, then use that.
+ *           Otherwise select WTAP_ENCAP_PER_PACKET.  If the selected
+ *           output file type doesn't support per packet frame types,
+ *           then the wtap_dump_open call will fail with a reasonable
+ *           error condition.
+ */
+static int
+select_frame_type(int count, in_file_t files[])
+{
+  int i;
+  int selected_frame_type;
+  
+  selected_frame_type = wtap_file_encap(files[0].wth);
+  
+  for (i = 1; i < count; i++) {
+    int this_frame_type = wtap_file_encap(files[i].wth);
+    if (selected_frame_type != this_frame_type) {
+      selected_frame_type = WTAP_ENCAP_PER_PACKET;
+      if (verbose) {
+        fprintf(stderr, "mergecap: multiple frame encapsulation types detected\n");
+        fprintf(stderr, "          defaulting to WTAP_ENCAP_PER_PACKET\n");
+        fprintf(stderr, "          %s had type %s (%s)\n",
+                files[0].filename,
+                wtap_encap_string(selected_frame_type),
+                wtap_encap_short_string(selected_frame_type));
+        fprintf(stderr, "          %s had type %s (%s)\n",
+                files[i].filename,
+                wtap_encap_string(this_frame_type),
+                wtap_encap_short_string(this_frame_type));
+      }
+      break;
+    }
+  }
+  
+  if (verbose) {
+      fprintf(stderr, "mergecap: selected frame_type %s (%s)\n",
+              wtap_encap_string(selected_frame_type),
+              wtap_encap_short_string(selected_frame_type));
+  }
+
+  return selected_frame_type;
+}
+    
+
+/*
  * Close the output file
  */
 static void
@@ -215,8 +261,8 @@
   out_file->pdh = wtap_dump_open(out_file->filename, out_file->file_type,
                                  out_file->frame_type, snapshot_len, &err);
   if (!out_file->pdh) {
-    fprintf(stderr, "mergecap: Can't open/create %s: %s\n",
-            out_file->filename, wtap_strerror(err));
+    fprintf(stderr, "mergecap: Can't open/create %s:\n", out_file->filename);
+    fprintf(stderr, "          %s\n", wtap_strerror(err));
     return FALSE;
   }
   return TRUE;
@@ -285,7 +331,7 @@
               wtap_strerror(err));
     } else {
       if (verbose) {
-        fprintf(stderr, "File %s is a %s capture file.\n", argv[i],
+        fprintf(stderr, "mergecap: %s is type %s.\n", argv[i],
                 wtap_file_type_string(wtap_file_type(files[count].wth)));
       }
       count++;
@@ -308,7 +354,7 @@
   int i;
   const char *string;
 
-  fprintf(stderr, "Usage: mergecap [-h] [-v] [-a] [-s <snaplen>] [-T <encap type>]\n");
+  fprintf(stderr, "Usage: mergecap [-hva] [-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");
@@ -356,7 +402,7 @@
   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, "hvas:T:F:w:")) != EOF) {
 
     switch (opt) {
     case 'w':
@@ -432,7 +478,7 @@
 
   /* set the outfile frame type */
   if (out_file.frame_type == -2)
-    out_file.frame_type = wtap_file_encap(in_files[0].wth);
+    out_file.frame_type = select_frame_type(in_file_count, in_files);
   
   /* open the outfile */
   if (!open_outfile(&out_file, max_snapshot_length(in_file_count, in_files))) {
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/14 06:57:10
@@ -6,12 +6,10 @@
 =head1 SYNOPSYS
 
 B<mergecap>
+S<[ B<-hva> ]>
+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<...>
@@ -59,11 +57,18 @@
 appear to reject Ethernet frames larger than the standard Ethernet MTU,
 making them incapable of handling gigabit Ethernet captures if jumbo
 frames were used).
+
+The output file frame encapsulation type is set to the type of the input
+files, if all input files have the same type.  If not all of the input
+files have the same frame encapsulation type, the output file type is
+set to WTAP_ENCAP_PER_PACKET.  Note that some capture file formats, most
+notably B<libpcap>, do not currently support WTAP_ENCAP_PER_PACKET.
+This combination will cause the output file creation to fail.
 
-If the B<-T> flag is used to specify an encapsulation type, the
+If the B<-T> flag is used to specify a frame encapsulation type, the
 encapsulation type of the output capture file will be forced to the
 specified type, rather than being the type appropriate to the
-encapsulation type of the input capture file.  Note that this merely
+encapsulation type of the input capture files.  Note that this merely
 forces the encapsulation type of the output file to be the specified
 type; the packet headers of the packets will not be translated from the
 encapsulation type of the input capture file to the specified