Auto reset epan session
authorHessam Jalali <hessam.jalali@gmail.com>
Mon, 24 Apr 2017 13:01:00 +0000 (17:31 +0430)
committerMichael Mann <mmann78@netscape.net>
Fri, 5 May 2017 00:51:58 +0000 (00:51 +0000)
Automatically resets intarnal epan session after reaching to
specified number of packets, for example
-M 1000
will reset the session every 1000 packets.

this is more like a proposal since the usage is very specific
it is useful for 24/7 live capture with dissection and sending
data directly to another application.

example:

tshark -Y "gtp" -M 100000 -T fields -e gtp.message -e gtp.teid

Change-Id: I8ee8b0380017c684120a93cb3fb43f41615a9c04
Reviewed-on: https://code.wireshark.org/review/21312
Reviewed-by: Evan Huus <eapache@gmail.com>
Petri-Dish: Evan Huus <eapache@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
doc/tshark.pod
tshark.c

index 100049609df075c57b56ec97da86787e43003fe9..e6034f64ac00a4552810dfbb6a9a0fb5e93f32b4 100644 (file)
@@ -51,6 +51,7 @@ S<[ B<-x> ]>
 S<[ B<-X> E<lt>eXtension optionE<gt>]>
 S<[ B<-y> E<lt>capture link typeE<gt> ]>
 S<[ B<-Y> E<lt>displaY filterE<gt> ]>
+S<[ B<-M> E<lt>auto session resetE<gt> ]>
 S<[ B<-z> E<lt>statisticsE<gt> ]>
 S<[ B<--capture-comment> E<lt>commentE<gt> ]>
 S<[ B<--export-objects> E<lt>protocolE<gt>,E<lt>destdirE<gt> ]>
@@ -904,6 +905,17 @@ Use this instead of -R for filtering using single-pass analysis. If doing
 two-pass analysis (see -2) then only packets matching the read filter (if there
 is one) will be checked against this filter.
 
+=item -M  E<lt>auto session resetE<gt>
+
+Automatically reset internal session when reached to specified number of packets.
+for example,
+
+    -M 100000
+
+will reset session every 100000 packets.
+
+This feature does not support -2 two-pass analysis
+
 =item -z  E<lt>statisticsE<gt>
 
 Get B<TShark> to collect various types of statistics and display the result
index 071e5d8776a26ce17df5ce496a9c0b047d5085a7..059cff3770f7910560f14c1b3b9eae48256e9bef 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -162,6 +162,8 @@ static frame_data *prev_cap;
 static frame_data prev_cap_frame;
 
 static gboolean perform_two_pass_analysis;
+static guint32 epan_auto_reset_count = 0;
+static gboolean epan_auto_reset = FALSE;
 
 /*
  * The way the packet decode is to be written.
@@ -228,6 +230,7 @@ static char *output_file_name;
 
 #endif /* HAVE_LIBPCAP */
 
+static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, gboolean tree, gboolean visual);
 static gboolean process_cap_file(capture_file *, char *, int, gboolean, int, gint64);
 static gboolean process_packet_single_pass(capture_file *cf,
     epan_dissect_t *edt, gint64 offset, struct wtap_pkthdr *whdr,
@@ -356,6 +359,7 @@ print_usage(FILE *output)
   fprintf(output, "\n");
   fprintf(output, "Processing:\n");
   fprintf(output, "  -2                       perform a two-pass analysis\n");
+  fprintf(output, "  -M <packet count>        perform session auto reset\n");
   fprintf(output, "  -R <read filter>         packet Read filter in Wireshark display filter syntax\n");
   fprintf(output, "                           (requires -2)\n");
   fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
@@ -703,7 +707,7 @@ main(int argc, char *argv[])
  * We do *not* use a leading - because the behavior of a leading - is
  * platform-dependent.
  */
-#define OPTSTRING "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:e:E:F:gG:hH:j:J:lo:O:PqQr:R:S:T:U:vVw:W:xX:Y:z:"
+#define OPTSTRING "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "M:C:e:E:F:gG:hH:j:J:lo:O:PqQr:R:S:T:U:vVw:W:xX:Y:z:"
 
   static const char    optstring[] = OPTSTRING;
 
@@ -1027,8 +1031,20 @@ main(int argc, char *argv[])
   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
     switch (opt) {
     case '2':        /* Perform two pass analysis */
+      if(epan_auto_reset){
+        cmdarg_err("-2 does not support auto session reset.");
+        arg_error=TRUE;
+      }
       perform_two_pass_analysis = TRUE;
       break;
+    case 'M':
+      if(perform_two_pass_analysis){
+        cmdarg_err("-M does not support two pass analysis.");
+        arg_error=TRUE;
+      }
+      epan_auto_reset_count = get_positive_int(optarg, "epan reset count");
+      epan_auto_reset = TRUE;
+      break;
     case 'a':        /* autostop criteria */
     case 'b':        /* Ringbuffer option */
     case 'c':        /* Capture x packets */
@@ -2594,6 +2610,7 @@ capture_input_new_packets(capture_session *cap_session, int to_read)
     while (to_read-- && cf->wth) {
       wtap_cleareof(cf->wth);
       ret = wtap_read(cf->wth, &err, &err_info, &data_offset);
+      reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
       if (ret == FALSE) {
         /* read from file failed, tell the capture child to stop */
         sync_pipe_stop(cap_session);
@@ -3202,12 +3219,10 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
   else {
     /* !perform_two_pass_analysis */
     framenum = 0;
-
+    gboolean create_proto_tree = FALSE;
     tshark_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
 
     if (do_dissection) {
-      gboolean create_proto_tree;
-
       /*
        * Determine whether we need to create a protocol tree.
        * We do if:
@@ -3247,6 +3262,8 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
 
       tshark_debug("tshark: processing packet #%d", framenum);
 
+      reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
+
       if (process_packet_single_pass(cf, edt, data_offset, wtap_phdr(cf->wth),
                                      wtap_buf_ptr(cf->wth), tap_flags)) {
         /* Either there's no read filtering or this packet passed the
@@ -4019,6 +4036,21 @@ write_failure_message(const char *filename, int err)
              filename, g_strerror(err));
 }
 
+static void reset_epan_mem(capture_file *cf,epan_dissect_t *edt, gboolean tree, gboolean visual)
+{
+  if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
+    return;
+
+  fprintf(stderr, "resetting session.\n");
+
+  epan_dissect_cleanup(edt);
+  epan_free(cf->epan);
+
+  cf->epan = tshark_epan_new(cf);
+  edt = epan_dissect_init(edt,cf->epan, tree, visual);
+  cf->count = 0;
+}
+
 /*
  * Report additional information for an error in command-line arguments.
  */