From fc3f061829aa4ba20589bd4caa802aee1756f083 Mon Sep 17 00:00:00 2001 From: David Perry Date: Fri, 11 Feb 2022 01:54:53 +0000 Subject: [PATCH] Differentiate `-c` from `-a packets:` --- capture/capture_sync.c | 7 ++++ capture_opts.c | 7 ++-- capture_opts.h | 3 ++ doc/dumpcap.adoc | 4 +-- doc/tshark.adoc | 8 +++-- doc/wireshark.adoc | 4 +-- dumpcap.c | 8 ++++- tshark.c | 82 +++++++++++++++++++++++++++--------------- 8 files changed, 86 insertions(+), 37 deletions(-) diff --git a/capture/capture_sync.c b/capture/capture_sync.c index 720c4eaf93..d017215f5a 100644 --- a/capture/capture_sync.c +++ b/capture/capture_sync.c @@ -343,6 +343,13 @@ sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments, argv = sync_pipe_add_arg(argv, &argc, sautostop_duration); } + if (capture_opts->has_autostop_written_packets) { + char scount[ARGV_NUMBER_LEN]; + argv = sync_pipe_add_arg(argv, &argc, "-a"); + snprintf(scount, ARGV_NUMBER_LEN, "packets:%d",capture_opts->autostop_written_packets); + argv = sync_pipe_add_arg(argv, &argc, scount); + } + if (capture_opts->group_read_access) { argv = sync_pipe_add_arg(argv, &argc, "-g"); } diff --git a/capture_opts.c b/capture_opts.c index 525e42edef..a3809d8ab7 100644 --- a/capture_opts.c +++ b/capture_opts.c @@ -116,6 +116,8 @@ capture_opts_init(capture_options *capture_opts) capture_opts->autostop_files = 1; capture_opts->has_autostop_packets = FALSE; capture_opts->autostop_packets = 0; + capture_opts->has_autostop_written_packets = FALSE; + capture_opts->autostop_written_packets = 0; capture_opts->has_autostop_filesize = FALSE; capture_opts->autostop_filesize = 1000; /* 1 MB */ capture_opts->has_autostop_duration = FALSE; @@ -265,6 +267,7 @@ capture_opts_log(const char *log_domain, enum ws_log_level log_level, capture_op ws_log(log_domain, log_level, "AutostopFiles (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files); ws_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets); + ws_log(log_domain, log_level, "AutostopWrittenPackets (%u) : %u", capture_opts->has_autostop_written_packets, capture_opts->autostop_written_packets); ws_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize); ws_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration); ws_log(log_domain, log_level, "Temporary Directory : %s", capture_opts->temp_dir && capture_opts->temp_dir[0] ? capture_opts->temp_dir : g_get_tmp_dir()); @@ -315,8 +318,8 @@ set_autostop_criterion(capture_options *capture_opts, const char *autostoparg) capture_opts->has_autostop_files = TRUE; capture_opts->autostop_files = get_positive_int(p,"autostop files"); } else if (strcmp(autostoparg,"packets") == 0) { - capture_opts->has_autostop_packets = TRUE; - capture_opts->autostop_packets = get_positive_int(p,"packet count"); + capture_opts->has_autostop_written_packets = TRUE; + capture_opts->autostop_written_packets = get_positive_int(p,"packet write count"); } else { return FALSE; } diff --git a/capture_opts.h b/capture_opts.h index ab30e497bf..e1d3ff7960 100644 --- a/capture_opts.h +++ b/capture_opts.h @@ -307,6 +307,9 @@ typedef struct capture_options_tag { gboolean has_autostop_packets; /**< TRUE if maximum packet count is specified */ int autostop_packets; /**< Maximum packet count */ + gboolean has_autostop_written_packets; /**< TRUE if maximum packet count is + specified */ + int autostop_written_packets; /**< Maximum packet count */ gboolean has_autostop_filesize; /**< TRUE if maximum capture file size is specified */ guint32 autostop_filesize; /**< Maximum capture file size in kB */ diff --git a/doc/dumpcap.adoc b/doc/dumpcap.adoc index dd64413875..68298de584 100644 --- a/doc/dumpcap.adoc +++ b/doc/dumpcap.adoc @@ -88,7 +88,7 @@ stop writing to the current capture file and switch to the next one if filesize is reached. Note that the filesize is limited to a maximum value of 2 GiB. *packets*:__value__ Stop writing to a capture file after __value__ packets -have been written. Same as *-c* . +have been written. Acts the same as *-c* . -- -b|--ring-buffer :: @@ -170,7 +170,7 @@ the default capture buffer size is used instead. + -- Set the maximum number of packets to read when capturing live -data. Same as *-a packets:*. +data. Acts the same as *-a packets:*. -- -C :: diff --git a/doc/tshark.adoc b/doc/tshark.adoc index 63bcaa383d..10c75b5c1d 100644 --- a/doc/tshark.adoc +++ b/doc/tshark.adoc @@ -184,7 +184,9 @@ packet will be read, so more bytes than this number may be read). Note that the filesize is limited to a maximum value of 2 GiB. *packets*:__value__ switch to the next file after it contains __value__ -packets. Same as *-c*. +packets. +This does not include any packets that do not pass the display filter, so it +may differ from *-c*. -- -A ::: @@ -279,8 +281,10 @@ the default capture buffer size is used instead. + -- Set the maximum number of packets to read when capturing live -data. Same as *-a packets:*. +data. If reading a capture file, set the maximum number of packets to read. +This includes any packets that do not pass the display filter, so it +may differ from *-a packets:*. -- -C :: diff --git a/doc/wireshark.adoc b/doc/wireshark.adoc index bfc1501daa..0a9861ab7f 100644 --- a/doc/wireshark.adoc +++ b/doc/wireshark.adoc @@ -189,7 +189,7 @@ filesize is reached. Note that the filesize is limited to a maximum value of 2 GiB. *packets*:__value__ Stop writing to a capture file after it contains __value__ -packets. Same as *-c*. +packets. Acts the same as *-c*. -- -b|--ring-buffer :: @@ -266,7 +266,7 @@ the default capture buffer size is used instead. + -- Set the maximum number of packets to read when capturing live -data. Same as *-a packets:*. +data. Acts the same as *-a packets:*. -- -C :: diff --git a/dumpcap.c b/dumpcap.c index 1b585a8fca..fbd91944e8 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -4488,12 +4488,18 @@ capture_loop_wrote_one_packet(capture_src *pcap_src) { pcap_src->received++; } - /* check -c NUM / -a packets:NUM */ + /* check -c NUM */ if (global_capture_opts.has_autostop_packets && global_ld.packets_captured >= global_capture_opts.autostop_packets) { fflush(global_ld.pdh); global_ld.go = FALSE; return; } + /* check -a packets:NUM (treat like -c NUM) */ + if (global_capture_opts.has_autostop_written_packets && global_ld.packets_captured >= global_capture_opts.autostop_written_packets) { + fflush(global_ld.pdh); + global_ld.go = FALSE; + return; + } /* check -b packets:NUM */ if (global_capture_opts.has_file_packets && global_ld.packets_written >= global_capture_opts.file_packets) { do_file_switch_or_stop(&global_capture_opts); diff --git a/tshark.c b/tshark.c index c892ef7a16..1e66941ae6 100644 --- a/tshark.c +++ b/tshark.c @@ -244,7 +244,7 @@ typedef enum { PROCESS_FILE_ERROR, PROCESS_FILE_INTERRUPTED } process_file_status_t; -static process_file_status_t process_cap_file(capture_file *, char *, int, gboolean, int, gint64); +static process_file_status_t process_cap_file(capture_file *, char *, int, gboolean, int, gint64, int); static gboolean process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf, @@ -2173,9 +2173,11 @@ main(int argc, char *argv[]) status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res, #ifdef HAVE_LIBPCAP global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0, - global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0); + global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0, + global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0); #else max_packet_count, + 0, 0); #endif } @@ -3194,6 +3196,7 @@ process_cap_file_first_pass(capture_file *cf, int max_packet_count, epan_dissect_t *edt = NULL; gint64 data_offset; pass_status_t status = PASS_SUCCEEDED; + int framenum = 0; wtap_rec_init(&rec); ws_buffer_init(&buf, 1514); @@ -3232,15 +3235,18 @@ process_cap_file_first_pass(capture_file *cf, int max_packet_count, status = PASS_INTERRUPTED; break; } + framenum++; + if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) { - /* Stop reading if we have the maximum number of packets; - * When the -c option has not been used, max_packet_count - * starts at 0, which practically means, never stop reading. - * (unless we roll over max_packet_count ?) - */ - if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) { - ws_debug("tshark: max_packet_count (%d) or max_byte_count (%" PRId64 "/%" PRId64 ") reached", - max_packet_count, data_offset, max_byte_count); + /* Stop reading if we hit a stop condition */ + if (max_packet_count > 0 && framenum >= max_packet_count) { + ws_debug("tshark: max_packet_count (%d) reached", max_packet_count); + *err = 0; /* This is not an error */ + break; + } + if (max_byte_count != 0 && data_offset >= max_byte_count) { + ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached", + data_offset, max_byte_count); *err = 0; /* This is not an error */ break; } @@ -3382,11 +3388,13 @@ process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, gchar **err_info) static pass_status_t process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh, int *err, gchar **err_info, - volatile guint32 *err_framenum) + volatile guint32 *err_framenum, + int max_write_packet_count) { wtap_rec rec; Buffer buf; - guint32 framenum; + int framenum = 0; + int write_framenum = 0; frame_data *fdata; gboolean filtering_tap_listeners; guint tap_flags; @@ -3447,7 +3455,7 @@ process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh, */ set_resolution_synchrony(TRUE); - for (framenum = 1; framenum <= cf->count; framenum++) { + for (framenum = 1; framenum <= (int)cf->count; framenum++) { if (read_interrupted) { status = PASS_INTERRUPTED; break; @@ -3464,8 +3472,9 @@ process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh, /* Either there's no read filtering or this packet passed the filter, so, if we're writing to a capture file, write this packet out. */ + write_framenum++; if (pdh != NULL) { - ws_debug("tshark: writing packet #%d to outfile", framenum); + ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum); if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) { /* Error writing to the output file. */ ws_debug("tshark: error writing to a capture file (%d)", *err); @@ -3473,6 +3482,12 @@ process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh, status = PASS_WRITE_ERROR; break; } + /* Stop reading if we hit a stop condition */ + if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) { + ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count); + *err = 0; /* This is not an error */ + break; + } } } wtap_rec_reset(&rec); @@ -3490,6 +3505,7 @@ process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh, static pass_status_t process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, int max_packet_count, gint64 max_byte_count, + int max_write_packet_count, int *err, gchar **err_info, volatile guint32 *err_framenum) { @@ -3498,7 +3514,8 @@ process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, gboolean create_proto_tree = FALSE; gboolean filtering_tap_listeners; guint tap_flags; - guint32 framenum; + int framenum = 0; + int write_framenum = 0; epan_dissect_t *edt = NULL; gint64 data_offset; pass_status_t status = PASS_SUCCEEDED; @@ -3506,8 +3523,6 @@ process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, wtap_rec_init(&rec); ws_buffer_init(&buf, 1514); - framenum = 0; - /* Do we have any tap listeners with filters? */ filtering_tap_listeners = have_filtering_tap_listeners(); @@ -3581,8 +3596,10 @@ process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, /* Either there's no read filtering or this packet passed the filter, so, if we're writing to a capture file, write this packet out. */ + write_framenum++; if (pdh != NULL) { - ws_debug("tshark: writing packet #%d to outfile", framenum); + ws_debug("tshark: writing packet #%d to outfile as #%d", + framenum, write_framenum); if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) { /* Error writing to the output file. */ ws_debug("tshark: error writing to a capture file (%d)", *err); @@ -3592,14 +3609,20 @@ process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, } } } - /* Stop reading if we have the maximum number of packets; - * When the -c option has not been used, max_packet_count - * starts at 0, which practically means, never stop reading. - * (unless we roll over max_packet_count ?) - */ - if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) { - ws_debug("tshark: max_packet_count (%d) or max_byte_count (%" PRId64 "/%" PRId64 ") reached", - max_packet_count, data_offset, max_byte_count); + /* Stop reading if we hit a stop condition */ + if (max_packet_count > 0 && framenum >= max_packet_count) { + ws_debug("tshark: max_packet_count (%d) reached", max_packet_count); + *err = 0; /* This is not an error */ + break; + } + if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) { + ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count); + *err = 0; /* This is not an error */ + break; + } + if (max_byte_count != 0 && data_offset >= max_byte_count) { + ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached", + data_offset, max_byte_count); *err = 0; /* This is not an error */ break; } @@ -3621,7 +3644,8 @@ process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh, static process_file_status_t process_cap_file(capture_file *cf, char *save_file, int out_file_type, - gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count) + gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count, + int max_write_packet_count) { process_file_status_t status = PROCESS_FILE_SUCCEEDED; wtap_dumper *pdh; @@ -3749,7 +3773,8 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, * at the end. */ second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info, - &err_framenum); + &err_framenum, + max_write_packet_count); ws_debug("tshark: done with second pass"); } @@ -3762,6 +3787,7 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type, second_pass_status = process_cap_file_single_pass(cf, pdh, max_packet_count, max_byte_count, + max_write_packet_count, &err, &err_info, &err_framenum); }