summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Maynard <Christopher.Maynard@GTECH.COM>2013-08-29 18:15:13 +0000
committerChris Maynard <Christopher.Maynard@GTECH.COM>2013-08-29 18:15:13 +0000
commitbc654875f03fef8248b06b4bdc8bd26df0a50211 (patch)
treefc06b8170f66f0422810abf5eae8cbcaf3119703
parent894ca4e904e86b6b9b687e9bfd0036cee70811c0 (diff)
downloadwireshark-bc654875f03fef8248b06b4bdc8bd26df0a50211.tar.gz
Handle the 2GiB boundary case of the max filesize autostop condition properly so that we avoid overflow conditions and so that we ensure we don't capture more than 2GiB. Also, document the max filesize autostop value of 2GIB as well as indicating that it's truly GiB and not GB.
This fixes the problem reported on ask: http://ask.wireshark.org/questions/23891/wireshark-wont-run-with-multiple-capture-files #BACKPORT(1.10) ... not sure about 1.8? svn path=/trunk/; revision=51576
-rw-r--r--capture_opts.c4
-rw-r--r--capture_opts.h4
-rw-r--r--capture_stop_conditions.c8
-rw-r--r--capture_sync.c32
-rw-r--r--doc/dumpcap.pod8
-rw-r--r--doc/tshark.pod14
-rw-r--r--doc/wireshark.pod.template11
-rw-r--r--dumpcap.c10
-rw-r--r--ui/gtk/capture_dlg.c30
9 files changed, 66 insertions, 55 deletions
diff --git a/capture_opts.c b/capture_opts.c
index 9ec0b993f9..2e77bc1e44 100644
--- a/capture_opts.c
+++ b/capture_opts.c
@@ -109,7 +109,7 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 0;
capture_opts->has_autostop_filesize = FALSE;
- capture_opts->autostop_filesize = 1024; /* 1 MB */
+ capture_opts->autostop_filesize = 1024; /* 1 MiB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
capture_opts->capture_comment = NULL;
@@ -216,7 +216,7 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
g_log(log_domain, log_level, "AutostopFiles (%u) : %u", capture_opts->has_autostop_files, capture_opts->autostop_files);
g_log(log_domain, log_level, "AutostopPackets (%u) : %u", capture_opts->has_autostop_packets, capture_opts->autostop_packets);
- g_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
+ g_log(log_domain, log_level, "AutostopFilesize(%u) : %u (KiB)", capture_opts->has_autostop_filesize, capture_opts->autostop_filesize);
g_log(log_domain, log_level, "AutostopDuration(%u) : %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
}
diff --git a/capture_opts.h b/capture_opts.h
index cd98b56f7b..05db1dec1b 100644
--- a/capture_opts.h
+++ b/capture_opts.h
@@ -205,14 +205,14 @@ typedef struct capture_options_tag {
int autostop_packets; /**< Maximum packet count */
gboolean has_autostop_filesize; /**< TRUE if maximum capture file size
is specified */
- gint32 autostop_filesize; /**< Maximum capture file size */
+ guint32 autostop_filesize; /**< Maximum capture file size */
gboolean has_autostop_duration; /**< TRUE if maximum capture duration
is specified */
gint32 autostop_duration; /**< Maximum capture duration */
gchar *capture_comment; /** capture comment to write to the
output file */
-
+
/* internally used (don't touch from outside) */
gboolean output_to_pipe; /**< save_file is a pipe (named or stdout) */
gboolean capture_child; /**< hidden option: Wireshark child mode */
diff --git a/capture_stop_conditions.c b/capture_stop_conditions.c
index debf9f9247..386bf809bb 100644
--- a/capture_stop_conditions.c
+++ b/capture_stop_conditions.c
@@ -145,7 +145,7 @@ const char* CND_CLASS_CAPTURESIZE = "cnd_class_capturesize";
/* structure that contains user supplied data for this condition */
typedef struct _cnd_capturesize_dat{
- long max_capture_size;
+ guint64 max_capture_size;
}cnd_capturesize_dat;
/*
@@ -164,7 +164,9 @@ static condition* _cnd_constr_capturesize(condition* cnd, va_list ap){
if((data = (cnd_capturesize_dat*)g_malloc(sizeof(cnd_capturesize_dat))) == NULL)
return NULL;
/* initialize user data */
- data->max_capture_size = va_arg(ap, long);
+ data->max_capture_size = va_arg(ap, guint64);
+ if (data->max_capture_size > ((guint64)INT_MAX + 1))
+ data->max_capture_size = (guint64)INT_MAX + 1;
cnd_set_user_data(cnd, (void*)data);
return cnd;
} /* END _cnd_constr_capturesize() */
@@ -194,7 +196,7 @@ static gboolean _cnd_eval_capturesize(condition* cnd, va_list ap){
cnd_capturesize_dat* data = (cnd_capturesize_dat*)cnd_get_user_data(cnd);
/* check capturesize here */
if(data->max_capture_size == 0) return FALSE; /* 0 == infinite */
- if(va_arg(ap, long) >= data->max_capture_size){
+ if(va_arg(ap, guint64) >= data->max_capture_size){
return TRUE;
}
return FALSE;
diff --git a/capture_sync.c b/capture_sync.c
index 71884ae1f0..12429301f4 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -245,7 +245,7 @@ win32strerror(DWORD error)
char *p;
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
+ NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
/*
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
@@ -415,7 +415,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
if (capture_opts->multi_files_on) {
if (capture_opts->has_autostop_filesize) {
argv = sync_pipe_add_arg(argv, &argc, "-b");
- g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
+ g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
argv = sync_pipe_add_arg(argv, &argc, sfilesize);
}
@@ -439,7 +439,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi
} else {
if (capture_opts->has_autostop_filesize) {
argv = sync_pipe_add_arg(argv, &argc, "-a");
- g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
+ g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
}
}
@@ -1146,7 +1146,7 @@ sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
return ret;
}
-/* centralised logging and timing for sync_pipe_run_command_actual(),
+/* centralised logging and timing for sync_pipe_run_command_actual(),
* redirects to sync_pipe_run_command_actual()
*/
static int
@@ -1158,7 +1158,7 @@ sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
GTimeVal end_time;
float elapsed;
int logging_enabled;
-
+
/* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
if(logging_enabled){
@@ -1653,10 +1653,10 @@ pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
/* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
memcpy(msg, header, sizeof(header));
newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
- if (newly < 0) { /* error */
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
- "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
- }
+ if (newly < 0) { /* error */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
+ "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
+ }
*err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
msg);
return -1;
@@ -1760,13 +1760,13 @@ sync_pipe_input_cb(gint source, gpointer user_data)
/* The child has sent us a filename which we couldn't open.
This could mean that the child is creating files faster
- than we can handle it. (XXX - why would that result in
- a failure to open the file?)
+ than we can handle it. (XXX - why would that result in
+ a failure to open the file?)
That should only be the case for very fast file switches;
We can't do much more than telling the child to stop.
(This is the "emergency brake" if the user e.g. wants to
- switch files every second).
+ switch files every second).
This can also happen if the user specified "-", meaning
"standard output", as the capture file. */
@@ -2003,13 +2003,13 @@ sync_pipe_signame(int sig)
static void create_dummy_signal_pipe() {
gchar *dummy_signal_pipe_name;
-
+
if (dummy_signal_pipe != NULL) return;
-
+
if (!dummy_control_id) {
- dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
+ dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
}
-
+
/* Create the signal pipe */
dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
diff --git a/doc/dumpcap.pod b/doc/dumpcap.pod
index de969ceaa1..dc2ef1df66 100644
--- a/doc/dumpcap.pod
+++ b/doc/dumpcap.pod
@@ -68,9 +68,9 @@ B<duration>:I<value> Stop writing to a capture file after I<value> seconds have
elapsed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes). If this option is used
-together with the -b option, dumpcap will stop writing to the current capture
-file and switch to the next one if filesize is reached.
+I<value> KiB. If this option is used together with the -b option, dumpcap will
+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.
B<files>:I<value> Stop writing to capture files after I<value> number of files
were written.
@@ -99,7 +99,7 @@ B<duration>:I<value> switch to the next file after I<value> seconds have
elapsed, even if the current file is not completely filled up.
B<filesize>:I<value> switch to the next file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes).
+I<value> KiB. Note that the filesize is limited to a maximum value of 2 GiB.
B<files>:I<value> begin again with the first file after I<value> number of
files were written (form a ring buffer). This value must be less than 100000.
diff --git a/doc/tshark.pod b/doc/tshark.pod
index 670a2bd659..a8c3059108 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -165,12 +165,12 @@ B<duration>:I<value> Stop writing to a capture file after I<value> seconds
have elapsed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes). If this option is used
-together with the -b option, B<TShark> will stop writing to the current
-capture file and switch to the next one if filesize is reached. When reading a
-capture file, B<TShark> will stop reading the file after the number of bytes
-read exceeds this number (the complete packet will be read, so more bytes than
-this number may be read).
+I<value> KiB. If this option is used together with the -b option, B<TShark>
+will stop writing to the current capture file and switch to the next one if
+filesize is reached. When reading a capture file, B<TShark> will stop reading
+the file after the number of bytes read exceeds this number (the complete
+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.
B<files>:I<value> Stop writing to capture files after I<value> number of files
were written.
@@ -199,7 +199,7 @@ B<duration>:I<value> switch to the next file after I<value> seconds have
elapsed, even if the current file is not completely filled up.
B<filesize>:I<value> switch to the next file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes).
+I<value> KiB. Note that the filesize is limited to a maximum value of 2 GiB.
B<files>:I<value> begin again with the first file after I<value> number of
files were written (form a ring buffer). This value must be less than 100000.
diff --git a/doc/wireshark.pod.template b/doc/wireshark.pod.template
index 9f2f2c5478..28e1ebfc31 100644
--- a/doc/wireshark.pod.template
+++ b/doc/wireshark.pod.template
@@ -232,9 +232,10 @@ B<duration>:I<value> Stop writing to a capture file after I<value> seconds have
elapsed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes). If this option is used
-together with the -b option, Wireshark will stop writing to the current
-capture file and switch to the next one if filesize is reached.
+I<value> KiB. If this option is used together with the -b option, Wireshark
+will 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.
B<files>:I<value> Stop writing to capture files after I<value> number of files
were written.
@@ -263,7 +264,7 @@ B<duration>:I<value> switch to the next file after I<value> seconds have
elapsed, even if the current file is not completely filled up.
B<filesize>:I<value> switch to the next file after it reaches a size of
-I<value> kilobytes (where a kilobyte is 1024 bytes).
+I<value> KiB. Note that the filesize is limited to a maximum value of 2 GiB.
B<files>:I<value> begin again with the first file after I<value> number of
files were written (form a ring buffer). This value must be less than 100000.
@@ -2361,7 +2362,7 @@ I<Update list of packets in real time> option is checked.
The I<Next file every ... megabyte(s)> check box and fields lets
you specify that a switch to a next file should be done
if the specified filesize is reached. You can also select the appropriate
-unit, but beware that the filesize has a maximum of 2 GB.
+unit, but beware that the filesize has a maximum of 2 GiB.
The check box is forced to be checked, as "multiple files" mode requires a
file size to be specified.
diff --git a/dumpcap.c b/dumpcap.c
index 99e0492cf2..ce2f4bf5d4 100644
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -3575,9 +3575,13 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* initialize capture stop (and alike) conditions */
init_capture_stop_conditions();
/* create stop conditions */
- if (capture_opts->has_autostop_filesize)
+ if (capture_opts->has_autostop_filesize) {
+ if (capture_opts->autostop_filesize > (((guint32)INT_MAX + 1) / 1024)) {
+ capture_opts->autostop_filesize = ((guint32)INT_MAX + 1) / 1024;
+ }
cnd_autostop_size =
- cnd_new(CND_CLASS_CAPTURESIZE,(long)capture_opts->autostop_filesize * 1024);
+ cnd_new(CND_CLASS_CAPTURESIZE, (guint64)capture_opts->autostop_filesize * 1024);
+ }
if (capture_opts->has_autostop_duration)
cnd_autostop_duration =
cnd_new(CND_CLASS_TIMEOUT,(gint32)capture_opts->autostop_duration);
@@ -3678,7 +3682,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* check capture size condition */
if (cnd_autostop_size != NULL &&
- cnd_eval(cnd_autostop_size, (guint32)global_ld.bytes_written)) {
+ cnd_eval(cnd_autostop_size, global_ld.bytes_written)) {
/* Capture size limit reached, do we have another file? */
if (!do_file_switch_or_stop(capture_opts, cnd_autostop_files,
cnd_autostop_size, cnd_file_duration))
diff --git a/ui/gtk/capture_dlg.c b/ui/gtk/capture_dlg.c
index c5d0974e93..b3943d75b8 100644
--- a/ui/gtk/capture_dlg.c
+++ b/ui/gtk/capture_dlg.c
@@ -952,9 +952,9 @@ guint32 value)
#define SIZE_UNIT_GIGABYTES 2
#define MAX_SIZE_UNITS 3
static const char *size_unit_name[MAX_SIZE_UNITS] = {
- "kilobyte(s)",
- "megabyte(s)",
- "gigabyte(s)",
+ "kibibyte(s)",
+ "mebibyte(s)",
+ "gibibyte(s)"
};
/* create one of the size options */
@@ -1013,15 +1013,19 @@ guint32 value)
switch(unit) {
case(SIZE_UNIT_KILOBYTES):
- return value;
+ if (value > (((guint32)G_MAXINT + 1) / 1024)) {
+ return 0;
+ } else {
+ return value;
+ }
case(SIZE_UNIT_MEGABYTES):
- if (value > G_MAXINT / 1024) {
+ if (value > (((guint32)G_MAXINT + 1) / (1024 * 1024))) {
return 0;
} else {
return value * 1024;
}
case(SIZE_UNIT_GIGABYTES):
- if (value > G_MAXINT / (1024 * 1024)) {
+ if (value > (((guint32)G_MAXINT + 1) / (1024 * 1024 * 1024))) {
return 0;
} else {
return value * 1024 * 1024;
@@ -5308,7 +5312,7 @@ fprintf(stderr, "Adding the default filter \"%s\"???\n", global_capture_opts.def
window_get_geometry(top_level, &tl_geom);
gtk_window_set_default_size(GTK_WINDOW(cap_open_w), tl_geom.width * 8 / 10, -1);
-
+
gtk_widget_show_all(cap_open_w);
window_present(cap_open_w);
@@ -5601,8 +5605,8 @@ capture_dlg_prep(gpointer parent_w) {
} else {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"%sMultiple files: Requested filesize too large!%s\n\n"
- "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GB).",
- simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
+ "The setting \"Next file every x byte(s)\" can't be greater than %u bytes (2GiB).",
+ simple_dialog_primary_start(), simple_dialog_primary_end(), (guint32)G_MAXINT + 1);
return FALSE;
}
}
@@ -5635,8 +5639,8 @@ capture_dlg_prep(gpointer parent_w) {
} else {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"%sStop Capture: Requested filesize too large!%s\n\n"
- "The setting \"after x byte(s)\" can't be greater than %u bytes (2GB).",
- simple_dialog_primary_start(), simple_dialog_primary_end(), G_MAXINT);
+ "The setting \"after x byte(s)\" can't be greater than %u bytes (2GiB).",
+ simple_dialog_primary_start(), simple_dialog_primary_end(), (guint32)G_MAXINT + 1);
return FALSE;
}
}
@@ -5704,7 +5708,7 @@ create_and_fill_model(GtkTreeView *view)
device.snaplen = WTAP_MAX_PACKET_SIZE;
device.has_snaplen = FALSE;
}
-
+
if (device.has_snaplen) {
snaplen_string = g_strdup_printf("%d", device.snaplen);
} else {
@@ -5717,7 +5721,7 @@ create_and_fill_model(GtkTreeView *view)
device.buffer = buffer;
} else {
device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
- }
+ }
#endif
global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
g_array_insert_val(global_capture_opts.all_ifaces, i, device);