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 <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>
This commit is contained in:
Hessam Jalali 2017-04-24 17:31:00 +04:30 committed by Michael Mann
parent 8e52cfb891
commit dd884611ac
2 changed files with 48 additions and 4 deletions

View 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

View File

@ -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.
*/