From dd884611ac69f1c671bf11a8c57267dd629fd803 Mon Sep 17 00:00:00 2001 From: Hessam Jalali Date: Mon, 24 Apr 2017 17:31:00 +0430 Subject: Auto reset epan session 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 Petri-Dish: Evan Huus Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- doc/tshark.pod | 12 ++++++++++++ tshark.c | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/doc/tshark.pod b/doc/tshark.pod index 100049609d..e6034f64ac 100644 --- a/doc/tshark.pod +++ b/doc/tshark.pod @@ -51,6 +51,7 @@ S<[ B<-x> ]> S<[ B<-X> EeXtension optionE]> S<[ B<-y> Ecapture link typeE ]> S<[ B<-Y> EdisplaY filterE ]> +S<[ B<-M> Eauto session resetE ]> S<[ B<-z> EstatisticsE ]> S<[ B<--capture-comment> EcommentE ]> S<[ B<--export-objects> EprotocolE,EdestdirE ]> @@ -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 Eauto session resetE + +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 EstatisticsE Get B to collect various types of statistics and display the result diff --git a/tshark.c b/tshark.c index 071e5d8776..059cff3770 100644 --- 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 perform session auto reset\n"); fprintf(output, " -R packet Read filter in Wireshark display filter syntax\n"); fprintf(output, " (requires -2)\n"); fprintf(output, " -Y 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. */ -- cgit v1.2.1