aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <gharris@sonic.net>2021-07-14 22:16:30 -0700
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-07-15 05:43:36 +0000
commit0a9ef601d201f87ff3effb8aca62c61184fd6146 (patch)
treece64e2ddc50cdf76bbc4dc785e069a50a820c7b4
parent94ac641efabc9830bc91db1c793bf0ba42f1e46c (diff)
Clean up handling of --capture-comment.
Don't store the comments in a capture_options structure, because that's available only if we're being built with capture support, and --capture-comment can be used in TShark when reading a capture file and writing another capture file, with no live capture taking place. This means we don't handle that option in capture_opts_add_opt(); handle it in the programs that support it. Support writing multiple comments in dumpcap when capturing. These changes also fix builds without pcap, and makes --capture-comment work in Wireshark when a capture is started from the command line with -k. Update the help messages to indicate that --capture-comment adds a capture comment, it doesn't change any comment (much less "the" comment, as there isn't necessarily a single comment). Update the man pages: - not to presume that only pcapng files support file comments (even if that's true now, it might not be true in the future); - to note that multiple instances of --capture-comment are supported, and that multiple comments will be written, whether capturing or reading one file and writing another; - clarify that Wireshark doesn't *discard* SHB comments other than the first one, even though it only displays the first one;
-rw-r--r--capture/capture_sync.c10
-rw-r--r--capture/capture_sync.h6
-rw-r--r--capture_opts.c11
-rw-r--r--capture_opts.h10
-rw-r--r--doc/dumpcap.pod9
-rw-r--r--doc/editcap.pod10
-rw-r--r--doc/tshark.pod10
-rw-r--r--doc/wireshark.pod7
-rw-r--r--dumpcap.c18
-rw-r--r--text2pcap.c7
-rw-r--r--tshark.c60
-rw-r--r--ui/capture.c7
-rw-r--r--ui/capture.h6
-rw-r--r--ui/commandline.c18
-rw-r--r--ui/commandline.h7
-rw-r--r--ui/qt/main.cpp4
-rw-r--r--ui/qt/main_window_slots.cpp3
-rw-r--r--writecap/pcapio.c21
-rw-r--r--writecap/pcapio.h4
19 files changed, 142 insertions, 86 deletions
diff --git a/capture/capture_sync.c b/capture/capture_sync.c
index ad7fbca89f..4352521fe3 100644
--- a/capture/capture_sync.c
+++ b/capture/capture_sync.c
@@ -204,7 +204,9 @@ init_pipe_args(int *argc) {
#define ARGV_NUMBER_LEN 24
/* a new capture run: start a new dumpcap task and hand over parameters through command line */
gboolean
-sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void (*update_cb)(void))
+sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
+ capture_session *cap_session, info_data_t* cap_data,
+ void (*update_cb)(void))
{
#ifdef _WIN32
HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
@@ -257,10 +259,10 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf
else
argv = sync_pipe_add_arg(argv, &argc, "-P");
- if (capture_opts->capture_comment) {
- for (j = 0; j < capture_opts->capture_comment->len; j++) {
+ if (capture_comments != NULL) {
+ for (j = 0; j < capture_comments->len; j++) {
argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
- argv = sync_pipe_add_arg(argv, &argc, (char*)g_ptr_array_index(capture_opts->capture_comment, j));
+ argv = sync_pipe_add_arg(argv, &argc, (char*)g_ptr_array_index(capture_comments, j));
}
}
diff --git a/capture/capture_sync.h b/capture/capture_sync.h
index b2c6751eff..2d7b8e116b 100644
--- a/capture/capture_sync.h
+++ b/capture/capture_sync.h
@@ -35,13 +35,17 @@ struct _info_data;
* Most of the parameters are passed through the global capture_opts.
*
* @param capture_opts the options
+ * @param capture_comments if not NULL, a GPtrArray * to a set of comments
+ * to put in the capture file's Section Header Block if it's a pcapng file
* @param cap_session a handle for the capture session
* @param cap_data a struct with capture info data
* @param update_cb update screen
* @return TRUE if a capture could be started, FALSE if not
*/
extern gboolean
-sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, struct _info_data* cap_data, void(*update_cb)(void));
+sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
+ capture_session *cap_session, struct _info_data* cap_data,
+ void(*update_cb)(void));
/** User wants to stop capturing, gracefully close the capture child */
extern void
diff --git a/capture_opts.c b/capture_opts.c
index e87bc9f653..504560caee 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -115,7 +115,6 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->autostop_filesize = 1000; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60.0; /* 1 min */
- capture_opts->capture_comment = NULL;
capture_opts->output_to_pipe = FALSE;
capture_opts->capture_child = FALSE;
@@ -147,10 +146,6 @@ capture_opts_cleanup(capture_options *capture_opts)
capture_opts->all_ifaces = NULL;
}
g_free(capture_opts->save_file);
- if (capture_opts->capture_comment != NULL) {
- g_ptr_array_free(capture_opts->capture_comment, TRUE);
- capture_opts->capture_comment = NULL;
- }
}
/* log content of capture_opts */
@@ -803,12 +798,6 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
int status, snaplen;
switch(opt) {
- case LONGOPT_CAPTURE_COMMENT: /* capture comment */
- if (!capture_opts->capture_comment) {
- capture_opts->capture_comment = g_ptr_array_new_with_free_func(g_free);
- }
- g_ptr_array_add(capture_opts->capture_comment, g_strdup(optarg_str_p));
- break;
case 'a': /* autostop criteria */
if (set_autostop_criterion(capture_opts, optarg_str_p) == FALSE) {
cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg_str_p);
diff --git a/capture_opts.h b/capture_opts.h
index 1452f30484..660a9746bd 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -44,10 +44,9 @@ extern "C" {
* In short: we must not use 1 here, which is another reason to use
* values outside the range of ASCII graphic characters.
*/
-#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_CAPTURE+1
-#define LONGOPT_LIST_TSTAMP_TYPES LONGOPT_BASE_CAPTURE+2
-#define LONGOPT_SET_TSTAMP_TYPE LONGOPT_BASE_CAPTURE+3
-#define LONGOPT_COMPRESS_TYPE LONGOPT_BASE_CAPTURE+4
+#define LONGOPT_LIST_TSTAMP_TYPES LONGOPT_BASE_CAPTURE+1
+#define LONGOPT_SET_TSTAMP_TYPE LONGOPT_BASE_CAPTURE+2
+#define LONGOPT_COMPRESS_TYPE LONGOPT_BASE_CAPTURE+3
/*
* Options for capturing common to all capturing programs.
@@ -76,7 +75,6 @@ extern "C" {
#endif
#define LONGOPT_CAPTURE_COMMON \
- {"capture-comment", required_argument, NULL, LONGOPT_CAPTURE_COMMENT}, \
{"autostop", required_argument, NULL, 'a'}, \
{"ring-buffer", required_argument, NULL, 'b'}, \
LONGOPT_BUFFER_SIZE \
@@ -313,8 +311,6 @@ typedef struct capture_options_tag {
is specified */
gdouble autostop_duration; /**< Maximum capture duration */
- GPtrArray *capture_comment; /** capture comment to write to the
- output file */
gboolean print_file_names; /**< TRUE if printing names of completed
files as we close them */
gchar *print_name_to; /**< output file name */
diff --git a/doc/dumpcap.pod b/doc/dumpcap.pod
index 19d16c5dfd..c5f043f44c 100644
--- a/doc/dumpcap.pod
+++ b/doc/dumpcap.pod
@@ -419,11 +419,14 @@ the default capture link type is used if provided.
=item --capture-comment E<lt>commentE<gt>
-Add a capture comment to the output file.
+Add a capture comment to the output file, if supported by the output
+file format.
This option is only available if we output the captured packets to a
-single file in pcapng format. Only one capture comment may be set per
-output file.
+single file.
+
+This option may be specified multiple times. Note that Wireshark
+currently only displays the first comment of a capture file.
=item --list-time-stamp-types
diff --git a/doc/editcap.pod b/doc/editcap.pod
index 1d7f520e1e..cf8bcb5f16 100644
--- a/doc/editcap.pod
+++ b/doc/editcap.pod
@@ -375,12 +375,12 @@ the same command line.
=item --capture-comment E<lt>commentE<gt>
-Adds the given comment to the Section Header Block (SHB) of the pcapng
-output file. New comments will be added I<after> any comments present in the
-input file unless B<--discard-capture-comment> is also specified.
+Adds the given comment to the output file, if supported by the output
+file format. New comments will be added I<after> any comments present
+in the input file unless B<--discard-capture-comment> is also specified.
-This option may be specified multiple times. Note that Wireshark currently only
-recognizes the first comment of a capture file.
+This option may be specified multiple times. Note that Wireshark
+currently only displays the first comment of a capture file.
=item --discard-capture-comment
diff --git a/doc/tshark.pod b/doc/tshark.pod
index 5548b1a971..e0059d43cf 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -1728,13 +1728,11 @@ SMB packets exchanged by the host at IP address 1.2.3.4 .
=item --capture-comment E<lt>commentE<gt>
-Add a capture comment to the output file.
+Add a capture comment to the output file, if supported by the output
+file format.
-This option is only available if a new output file in pcapng format is
-created.
-
-This option may be specified multiple times. Note that Wireshark currently only
-recognizes the first comment of a capture file.
+This option may be specified multiple times. Note that Wireshark
+currently only displays the first comment of a capture file.
=item --list-time-stamp-types
diff --git a/doc/wireshark.pod b/doc/wireshark.pod
index c94814901a..f9b91b19b3 100644
--- a/doc/wireshark.pod
+++ b/doc/wireshark.pod
@@ -319,7 +319,12 @@ Start with the given configuration profile.
=item --capture-comment E<lt>commentE<gt>
-Set the capture file comment, if supported by the capture format.
+When performing a capture file from the command line, with the B<-k>
+flag, add a capture comment to the output file, if supported by the
+capture format.
+
+This option may be specified multiple times. Note that Wireshark
+currently only displays the first comment of a capture file.
=item -d E<lt>layer typeE<gt>==E<lt>selectorE<gt>,E<lt>decode-as protocolE<gt>
diff --git a/dumpcap.c b/dumpcap.c
index e54725520a..e8e8323429 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -336,6 +336,7 @@ dumpcap_log_writer(const char *domain, enum ws_log_level level,
/* capture related options */
static capture_options global_capture_opts;
+static GPtrArray *capture_comments = NULL;
static gboolean quiet = FALSE;
static gboolean use_threads = FALSE;
static guint64 start_time;
@@ -3099,7 +3100,7 @@ capture_loop_init_pcapng_output(capture_options *capture_opts, loop_data *ld,
get_cpu_info(cpu_info_str);
successful = pcapng_write_section_header_block(ld->pdh,
- (const char *)capture_opts->capture_comment, /* Comment */
+ capture_comments, /* Comments */
cpu_info_str->str, /* HW */
os_info_str->str, /* OS */
get_appname_and_version(),
@@ -4815,6 +4816,7 @@ get_dumpcap_runtime_info(GString *str)
#define LONGOPT_IFNAME LONGOPT_BASE_APPLICATION+1
#define LONGOPT_IFDESCR LONGOPT_BASE_APPLICATION+2
+#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+3
/* And now our feature presentation... [ fade to music ] */
int
@@ -4828,6 +4830,7 @@ main(int argc, char *argv[])
LONGOPT_CAPTURE_COMMON
{"ifname", required_argument, NULL, LONGOPT_IFNAME},
{"ifdescr", required_argument, NULL, LONGOPT_IFDESCR},
+ {"capture-comment", required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
{0, 0, 0, 0 }
};
@@ -5139,7 +5142,6 @@ main(int argc, char *argv[])
case 's': /* Set the snapshot (capture) length */
case 'w': /* Write to capture file x */
case 'y': /* Set the pcap data link type */
- case LONGOPT_CAPTURE_COMMENT: /* add a capture comment */
#ifdef HAVE_PCAP_REMOTE
case 'u': /* Use UDP for data transfer */
case 'r': /* Capture own RPCAP traffic too */
@@ -5183,6 +5185,12 @@ main(int argc, char *argv[])
exit_main(1);
}
break;
+ case LONGOPT_CAPTURE_COMMENT: /* capture comment */
+ if (capture_comments == NULL) {
+ capture_comments = g_ptr_array_new_with_free_func(g_free);
+ }
+ g_ptr_array_add(capture_comments, g_strdup(optarg));
+ break;
case 'Z':
capture_child = TRUE;
#ifdef _WIN32
@@ -5319,10 +5327,10 @@ main(int argc, char *argv[])
global_capture_opts.use_pcapng = TRUE;
}
- if (global_capture_opts.capture_comment &&
+ if (capture_comments &&
(!global_capture_opts.use_pcapng || global_capture_opts.multi_files_on)) {
- /* XXX - for ringbuffer, should we apply the comment to each file? */
- cmdarg_err("A capture comment can only be set if we capture into a single pcapng file.");
+ /* XXX - for ringbuffer, should we apply the comments to each file? */
+ cmdarg_err("Capture comments can only be set if we capture into a single pcapng file.");
exit_main(1);
}
diff --git a/text2pcap.c b/text2pcap.c
index a706027a86..2b2471f079 100644
--- a/text2pcap.c
+++ b/text2pcap.c
@@ -883,17 +883,20 @@ write_file_header (void)
if (use_pcapng) {
char *comment;
+ GPtrArray *comments;
comment = g_strdup_printf("Generated from input file %s.", input_filename);
+ comments = g_ptr_array_new_with_free_func(g_free);
+ g_ptr_array_add(comments, comment);
success = pcapng_write_section_header_block(output_file,
- comment,
+ comments,
NULL, /* HW */
NULL, /* OS */
get_appname_and_version(),
-1, /* section_length */
&bytes_written,
&err);
- g_free(comment);
+ g_ptr_array_free(comments, TRUE);
if (success) {
success = pcapng_write_interface_description_block(output_file,
NULL,
diff --git a/tshark.c b/tshark.c
index 7da895d502..7b8071d54c 100644
--- a/tshark.c
+++ b/tshark.c
@@ -144,6 +144,7 @@
#define LONGOPT_NO_DUPLICATE_KEYS LONGOPT_BASE_APPLICATION+3
#define LONGOPT_ELASTIC_MAPPING_FILTER LONGOPT_BASE_APPLICATION+4
#define LONGOPT_EXPORT_TLS_SESSION_KEYS LONGOPT_BASE_APPLICATION+5
+#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_APPLICATION+6
capture_file cfile;
@@ -199,6 +200,9 @@ static json_dumper jdumper;
/* The line separator used between packets, changeable via the -S option */
static const char *separator = "";
+/* Per-file comments to be added to the output file. */
+static GPtrArray *capture_comments = NULL;
+
static gboolean prefs_loaded = FALSE;
#ifdef HAVE_LIBPCAP
@@ -248,7 +252,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, capture_options);
+static process_file_status_t 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, wtap_rec *rec, Buffer *buf,
@@ -425,7 +429,7 @@ print_usage(FILE *output)
fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
fprintf(output, " (or '-' for stdout)\n");
fprintf(output, " --capture-comment <comment>\n");
- fprintf(output, " set the capture file comment, if supported\n");
+ fprintf(output, " add a capture file comment, if supported\n");
fprintf(output, " -C <config profile> start with specified configuration profile\n");
fprintf(output, " -F <output file type> set the output file type, default is pcapng\n");
fprintf(output, " an empty \"-F\" option will list the file types\n");
@@ -706,6 +710,7 @@ main(int argc, char *argv[])
{"color", no_argument, NULL, LONGOPT_COLOR},
{"no-duplicate-keys", no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
{"elastic-mapping-filter", required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
+ {"capture-comment", required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
{0, 0, 0, 0 }
};
gboolean arg_error = FALSE;
@@ -1100,7 +1105,6 @@ main(int argc, char *argv[])
#endif
case 's': /* Set the snapshot (capture) length */
case 'y': /* Set the pcap data link type */
- case LONGOPT_CAPTURE_COMMENT: /* add a capture comment */
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
case 'B': /* Buffer size */
#endif
@@ -1476,6 +1480,12 @@ main(int argc, char *argv[])
no_duplicate_keys = TRUE;
node_children_grouper = proto_node_group_children_by_json_key;
break;
+ case LONGOPT_CAPTURE_COMMENT: /* capture comment */
+ if (capture_comments == NULL) {
+ capture_comments = g_ptr_array_new_with_free_func(g_free);
+ }
+ g_ptr_array_add(capture_comments, g_strdup(optarg));
+ break;
default:
case '?': /* Bad flag - print usage message */
switch(optopt) {
@@ -1710,7 +1720,7 @@ main(int argc, char *argv[])
exit_status = INVALID_OPTION;
goto clean_exit;
}
- if (global_capture_opts.capture_comment) {
+ if (capture_comments != NULL) {
if (global_capture_opts.saving_to_file) {
/* They specified a "-w" flag, so we'll be saving to a capture file.
* This is fine if they're using pcapng.
@@ -1767,8 +1777,8 @@ main(int argc, char *argv[])
exit_status = INVALID_OPTION;
goto clean_exit;
}
- if (global_capture_opts.capture_comment && !use_pcapng) {
- cmdarg_err("A capture comment can only be written to a pcapng file.");
+ if (capture_comments != NULL && !use_pcapng) {
+ cmdarg_err("Capture comments can only be written to a pcapng file.");
exit_status = INVALID_OPTION;
goto clean_exit;
}
@@ -1828,8 +1838,8 @@ main(int argc, char *argv[])
exit_status = INVALID_OPTION;
goto clean_exit;
}
- if (global_capture_opts.capture_comment) {
- cmdarg_err("A capture comment was specified, but "
+ if (capture_comments != NULL) {
+ cmdarg_err("Capture comments were specified, but "
"the capture isn't being saved to a file.");
exit_status = INVALID_OPTION;
goto clean_exit;
@@ -2090,13 +2100,14 @@ main(int argc, char *argv[])
/* Process the packets in the file */
ws_debug("tshark: invoking process_cap_file() to process the packets");
TRY {
-#ifndef HAVE_LIBPCAP
- global_capture_opts.has_autostop_packets = max_packet_count > 0;
- global_capture_opts.autostop_packets = max_packet_count;
- global_capture_opts.has_autostop_filesize = FALSE;
- global_capture_opts.autostop_filesize = 0;
+ 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);
+#else
+ max_packet_count,
+ 0);
#endif
- status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res, global_capture_opts);
}
CATCH(OutOfMemoryError) {
fprintf(stderr,
@@ -2541,7 +2552,8 @@ capture(void)
fflush(stderr);
g_string_free(str, TRUE);
- ret = sync_pipe_start(&global_capture_opts, &global_capture_session, &global_info_data, NULL);
+ ret = sync_pipe_start(&global_capture_opts, capture_comments,
+ &global_capture_session, &global_info_data, NULL);
if (!ret)
return FALSE;
@@ -3535,7 +3547,7 @@ 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, capture_options capture_opts)
+ gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count)
{
process_file_status_t status = PROCESS_FILE_SUCCEEDED;
wtap_dumper *pdh;
@@ -3548,13 +3560,6 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
char *shb_user_appl;
pass_status_t first_pass_status, second_pass_status;
- int max_packet_count = 0;
- int max_byte_count = 0;
-
- if (capture_opts.has_autostop_packets)
- max_packet_count = capture_opts.autostop_packets;
- if (capture_opts.has_autostop_filesize)
- max_byte_count = capture_opts.autostop_filesize;
if (save_file != NULL) {
/* Set up to write to the capture file. */
@@ -3565,10 +3570,11 @@ process_cap_file(capture_file *cf, char *save_file, int out_file_type,
/* this is free'd by wtap_block_unref() later */
wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
}
- if (capture_opts.capture_comment != NULL) {
- guint i;
- for (i = 0; i < capture_opts.capture_comment->len; i++) {
- wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_COMMENT, "%s", (char*)g_ptr_array_index(capture_opts.capture_comment, i));
+ if (capture_comments != NULL) {
+ for (guint i = 0; i < capture_comments->len; i++) {
+ wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
+ OPT_COMMENT, "%s",
+ (char *)g_ptr_array_index(capture_comments, i));
}
}
diff --git a/ui/capture.c b/ui/capture.c
index b88c86efdd..cff9d4ae6f 100644
--- a/ui/capture.c
+++ b/ui/capture.c
@@ -117,7 +117,9 @@ capture_callback_remove(capture_callback_t func, gpointer user_data)
* @return TRUE if the capture starts successfully, FALSE otherwise.
*/
gboolean
-capture_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void(*update_cb)(void))
+capture_start(capture_options *capture_opts, GPtrArray *capture_comments,
+ capture_session *cap_session, info_data_t* cap_data,
+ void(*update_cb)(void))
{
GString *source;
@@ -128,7 +130,8 @@ capture_start(capture_options *capture_opts, capture_session *cap_session, info_
cf_set_tempfile_source((capture_file *)cap_session->cf, source->str);
g_string_free(source, TRUE);
/* try to start the capture child process */
- if (!sync_pipe_start(capture_opts, cap_session, cap_data, update_cb)) {
+ if (!sync_pipe_start(capture_opts, capture_comments, cap_session,
+ cap_data, update_cb)) {
/* We failed to start the capture child. */
if(capture_opts->save_file != NULL) {
g_free(capture_opts->save_file);
diff --git a/ui/capture.h b/ui/capture.h
index 6589dfc8e7..f02e18ed92 100644
--- a/ui/capture.h
+++ b/ui/capture.h
@@ -60,13 +60,17 @@ capture_input_init(capture_session *cap_session, capture_file *cf);
* Start a capture session.
*
* @param capture_opts the numerous capture options
+ * @param capture_comments if not NULL, a GPtrArray * to a set of comments
+ * to put in the capture file's Section Header Block if it's a pcapng file
* @param cap_session the handle for the capture session
* @param cap_data a struct with capture info data
* @param update_cb update screen
* @return TRUE if the capture starts successfully, FALSE otherwise.
*/
extern gboolean
-capture_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void(*update_cb)(void));
+capture_start(capture_options *capture_opts, GPtrArray *capture_comments,
+ capture_session *cap_session, info_data_t* cap_data,
+ void(*update_cb)(void));
/** Stop a capture session (usually from a menu item). */
extern void
diff --git a/ui/commandline.c b/ui/commandline.c
index 66a82493ab..66f7ebe111 100644
--- a/ui/commandline.c
+++ b/ui/commandline.c
@@ -173,8 +173,10 @@ commandline_print_usage(gboolean for_help_option) {
fprintf(output, "\n");
fprintf(output, "Output:\n");
fprintf(output, " -w <outfile|-> set the output filename (or '-' for stdout)\n");
+#ifdef HAVE_LIBPCAP
fprintf(output, " --capture-comment <comment>\n");
- fprintf(output, " set the capture file comment, if supported\n");
+ fprintf(output, " add a capture file comment, if supported\n");
+#endif
ws_log_print_usage(output);
@@ -197,6 +199,7 @@ commandline_print_usage(gboolean for_help_option) {
}
#define LONGOPT_FULL_SCREEN LONGOPT_BASE_GUI+1
+#define LONGOPT_CAPTURE_COMMENT LONGOPT_BASE_GUI+2
#define OPTSTRING OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:g:HhjJ:klm:o:P:r:R:Svw:X:Y:z:"
static const struct option long_options[] = {
@@ -206,6 +209,7 @@ static const struct option long_options[] = {
{"display-filter", required_argument, NULL, 'Y' },
{"version", no_argument, NULL, 'v'},
{"fullscreen", no_argument, NULL, LONGOPT_FULL_SCREEN },
+ {"capture-comment", required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
LONGOPT_CAPTURE_COMMON
LONGOPT_DISSECT_COMMON
{0, 0, 0, 0 }
@@ -407,6 +411,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
global_commandline_info.list_link_layer_types = FALSE;
global_commandline_info.list_timestamp_types = FALSE;
global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE;
+ global_commandline_info.capture_comments = NULL;
#endif
global_commandline_info.full_screen = FALSE;
@@ -587,6 +592,17 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
case LONGOPT_FULL_SCREEN:
global_commandline_info.full_screen = TRUE;
break;
+#ifdef HAVE_LIBPCAP
+ case LONGOPT_CAPTURE_COMMENT: /* capture comment */
+ if (global_commandline_info.capture_comments == NULL) {
+ global_commandline_info.capture_comments = g_ptr_array_new_with_free_func(g_free);
+ }
+ g_ptr_array_add(global_commandline_info.capture_comments, g_strdup(optarg));
+#else
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
+#endif
+ break;
default:
case '?': /* Bad flag - print usage message */
arg_error = TRUE;
diff --git a/ui/commandline.h b/ui/commandline.h
index de1ba65528..72eeefc4d7 100644
--- a/ui/commandline.h
+++ b/ui/commandline.h
@@ -27,6 +27,13 @@ typedef struct commandline_param_info
gboolean list_timestamp_types;
gboolean start_capture;
gboolean quit_after_cap;
+
+ /*
+ * We currently don't support this as a way to add file comments
+ * to an existing capture file in Wireshark; we only support it
+ * for adding comments to live captures.
+ */
+ GPtrArray *capture_comments;
#endif
e_prefs *prefs_p;
search_direction jump_backwards;
diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp
index 975c0e21b5..efb55caad6 100644
--- a/ui/qt/main.cpp
+++ b/ui/qt/main.cpp
@@ -1034,7 +1034,9 @@ int main(int argc, char *qt_argv[])
if (global_capture_opts.ifaces->len == 0)
collect_ifaces(&global_capture_opts);
CaptureFile::globalCapFile()->window = main_w;
- if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
+ if (capture_start(&global_capture_opts, global_commandline_info.capture_comments,
+ main_w->captureSession(), main_w->captureInfoData(),
+ main_window_update)) {
/* The capture started. Open stat windows; we do so after creating
the main window, to avoid GTK warnings, and after successfully
opening the capture file, so we know we have something to compute
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index eed66d9ad9..0c18aece0d 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -868,7 +868,8 @@ void MainWindow::startCapture() {
CaptureFile::globalCapFile()->window = this;
info_data_.ui.ui = this;
- if (capture_start(&global_capture_opts, &cap_session_, &info_data_, main_window_update)) {
+ if (capture_start(&global_capture_opts, NULL, &cap_session_, &info_data_,
+ main_window_update)) {
capture_options *capture_opts = cap_session_.capture_opts;
GString *interface_names;
diff --git a/writecap/pcapio.c b/writecap/pcapio.c
index 14e4d7f31b..124531de9c 100644
--- a/writecap/pcapio.c
+++ b/writecap/pcapio.c
@@ -307,7 +307,7 @@ pcapng_write_block(FILE* pfile,
gboolean
pcapng_write_section_header_block(FILE* pfile,
- const char *comment,
+ GPtrArray *comments,
const char *hw,
const char *os,
const char *appname,
@@ -324,13 +324,17 @@ pcapng_write_section_header_block(FILE* pfile,
block_total_length = sizeof(struct shb) +
sizeof(guint32);
options_length = 0;
- options_length += pcapng_count_string_option(comment);
+ if (comments != NULL) {
+ for (guint i = 0; i < comments->len; i++) {
+ options_length += pcapng_count_string_option((char *)g_ptr_array_index(comments, i));
+ }
+ }
options_length += pcapng_count_string_option(hw);
options_length += pcapng_count_string_option(os);
options_length += pcapng_count_string_option(appname);
/* If we have options add size of end-of-options */
if (options_length != 0) {
- options_length += (guint32)sizeof(struct option);
+ options_length += (guint32)sizeof(struct option);
}
block_total_length += options_length;
@@ -345,9 +349,14 @@ pcapng_write_section_header_block(FILE* pfile,
if (!write_to_file(pfile, (const guint8*)&shb, sizeof(struct shb), bytes_written, err))
return FALSE;
- if (!pcapng_write_string_option(pfile, OPT_COMMENT, comment,
- bytes_written, err))
- return FALSE;
+ if (comments != NULL) {
+ for (guint i = 0; i < comments->len; i++) {
+ if (!pcapng_write_string_option(pfile, OPT_COMMENT,
+ (char *)g_ptr_array_index(comments, i),
+ bytes_written, err))
+ return FALSE;
+ }
+ }
if (!pcapng_write_string_option(pfile, SHB_HARDWARE, hw,
bytes_written, err))
return FALSE;
diff --git a/writecap/pcapio.h b/writecap/pcapio.h
index 065e04877b..72df645a76 100644
--- a/writecap/pcapio.h
+++ b/writecap/pcapio.h
@@ -44,8 +44,8 @@ pcapng_write_block(FILE* pfile,
*/
extern gboolean
pcapng_write_section_header_block(FILE* pfile, /**< Write information */
- const char *comment, /**< Comment on the section, Optinon 1 opt_comment
- * A UTF-8 string containing a comment that is associated to the current block.
+ GPtrArray *comments, /**< Comments on the section, Optinon 1 opt_comment
+ * UTF-8 strings containing comments that areassociated to the current block.
*/
const char *hw, /**< HW, Optinon 2 shb_hardware
* An UTF-8 string containing the description of the hardware used to create this section.