Wireshark-users: [Wireshark-users] editcap question
Date: Tue, 21 Jan 2014 18:07:34 +0000
Hi,

When I have a huge pcap file ("huge.pcap")
and I do this:

  editcap -r -F libpcap huge.pcap tiny.pcap 1

Then I get a correct pcap-file (tiny.pcap)
although what is surprising is that editcap goes through the whole input pcap-file
instead of terminating right after the first (and definitely the last) packet was produced.

I wonder, why is this?

That is, cannot editcap compute the maximum packet number (wrt. given selections) and then,
when it reaches that packet-number, regardless of how many other packets there are in the origin input pcap-file,
it would terminate?

-------------------------------------------------------------------------------------

The attached patch file (against wireshark-1.10.5)
is my attempt to modify editcap so that it avoids excess parsing.
When applied, then things like:

  editcap -r -F libpcap huge.pcap tiny.pcap 1
  editcap -r -F libpcap huge.pcap tiny.pcap 1-10
  editcap -r -F libpcap huge.pcap tiny.pcap 1-10 200-300

take the same time to complete regardless of the size of the input (huge.pcap) file.
(immeditelly after producing the 1-st, the 10-th, or 300-th packet respectively).
diff -crN wireshark-1.10.5/editcap.c wireshark-1.10.5.changed/editcap.c
*** wireshark-1.10.5/editcap.c	2013-04-22 19:05:29.000000000 +0100
--- wireshark-1.10.5.changed/editcap.c	2014-01-21 17:50:42.902953003 +0000
***************
*** 873,878 ****
--- 873,879 ----
    gchar *fprefix = NULL;
    gchar *fsuffix = NULL;
    char appname[100];
+   int max_packet_index = 0;
  
  #ifdef HAVE_PLUGINS
    char* init_progfile_dir_error;
***************
*** 1159,1165 ****
--- 1160,1186 ----
        }
      }
  
+     if (keep_em) {
+        for (i=0; i <= max_selected; i++) {
+          if (selectfrm[i].inclusive) {
+            if (selectfrm[i].second == 0) {
+              max_packet_index = INT_MAX;
+              break;
+            } else {
+              max_packet_index = max_packet_index < selectfrm[i].second ? selectfrm[i].second : max_packet_index;
+            }
+          } else {
+              max_packet_index = max_packet_index < selectfrm[i].first ? selectfrm[i].first : max_packet_index;
+          }
+        }
+     } else {
+        max_packet_index = INT_MAX;
+     }
+ 
      while (wtap_read(wth, &err, &err_info, &data_offset)) {
+       if (max_packet_index <= read_count)
+         break;
+ 
        read_count++;
  
        phdr = wtap_phdr(wth);