Move condition logic to dumpcap.c

Move the condition logic from capture_stop_conditions.c to dumpcap.c.
Remove capture_stop_conditions.[ch] and conditions.[ch].

Switch duration values to doubles.

Change-Id: Ifa74fb13ec8fc923b0721597a6cf071d72069ea0
Reviewed-on: https://code.wireshark.org/review/30440
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Gerald Combs 2018-10-31 11:34:35 +01:00 committed by Anders Broman
parent 01784a5946
commit 8b977a43d6
16 changed files with 92 additions and 777 deletions

View File

@ -2539,8 +2539,6 @@ if(BUILD_dumpcap AND PCAP_FOUND)
)
set(dumpcap_FILES
capture_opts.c
capture_stop_conditions.c
conditions.c
dumpcap.c
ringbuffer.c
sync_pipe_write.c

View File

@ -279,7 +279,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf
if (capture_opts->has_file_duration) {
argv = sync_pipe_add_arg(argv, &argc, "-b");
g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->file_duration);
argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
}
@ -316,7 +316,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, inf
if (capture_opts->has_autostop_duration) {
argv = sync_pipe_add_arg(argv, &argc, "-a");
g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->autostop_duration);
argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
}

View File

@ -98,7 +98,7 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60; /* 1 min */
capture_opts->file_duration = 60.0; /* 1 min */
capture_opts->has_file_interval = FALSE;
capture_opts->file_interval = 60; /* 1 min */
capture_opts->has_ring_num_files = FALSE;
@ -111,7 +111,7 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1000; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
capture_opts->autostop_duration = 60.0; /* 1 min */
capture_opts->capture_comment = NULL;
capture_opts->output_to_pipe = FALSE;
@ -241,14 +241,14 @@ capture_opts_log(const char *log_domain, GLogLevelFlags log_level, capture_optio
g_log(log_domain, log_level, "ShowInfo : %u", capture_opts->show_info);
g_log(log_domain, log_level, "MultiFilesOn : %u", capture_opts->multi_files_on);
g_log(log_domain, log_level, "FileDuration (%u) : %u", capture_opts->has_file_duration, capture_opts->file_duration);
g_log(log_domain, log_level, "FileDuration (%u) : %.3f", capture_opts->has_file_duration, capture_opts->file_duration);
g_log(log_domain, log_level, "FileInterval (%u) : %u", capture_opts->has_file_interval, capture_opts->file_interval);
g_log(log_domain, log_level, "RingNumFiles (%u) : %u", capture_opts->has_ring_num_files, capture_opts->ring_num_files);
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, "AutostopDuration(%u) : %u", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
g_log(log_domain, log_level, "AutostopDuration(%u) : %.3f", capture_opts->has_autostop_duration, capture_opts->autostop_duration);
}
/*
@ -287,7 +287,7 @@ set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
}
if (strcmp(autostoparg,"duration") == 0) {
capture_opts->has_autostop_duration = TRUE;
capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
capture_opts->autostop_duration = get_positive_double(p,"autostop duration");
} else if (strcmp(autostoparg,"filesize") == 0) {
capture_opts->has_autostop_filesize = TRUE;
capture_opts->autostop_filesize = get_nonzero_guint32(p,"autostop filesize");
@ -397,7 +397,7 @@ get_ring_arguments(capture_options *capture_opts, const char *arg)
capture_opts->autostop_filesize = get_nonzero_guint32(p, "ring buffer filesize");
} else if (strcmp(arg,"duration") == 0) {
capture_opts->has_file_duration = TRUE;
capture_opts->file_duration = get_positive_int(p, "ring buffer duration");
capture_opts->file_duration = get_positive_double(p, "ring buffer duration");
} else if (strcmp(arg,"interval") == 0) {
capture_opts->has_file_interval = TRUE;
capture_opts->file_interval = get_positive_int(p, "ring buffer interval");

View File

@ -290,7 +290,7 @@ typedef struct capture_options_tag {
gboolean multi_files_on; /**< TRUE if ring buffer in use */
gboolean has_file_duration; /**< TRUE if ring duration specified */
gint32 file_duration; /**< Switch file after n seconds */
gdouble file_duration; /**< Switch file after n seconds */
gboolean has_file_interval; /**< TRUE if ring interval specified */
gint32 file_interval; /**< Create time intervals of n seconds */
gboolean has_ring_num_files; /**< TRUE if ring num_files specified */
@ -306,10 +306,10 @@ typedef struct capture_options_tag {
int autostop_packets; /**< Maximum packet count */
gboolean has_autostop_filesize; /**< TRUE if maximum capture file size
is specified */
guint32 autostop_filesize; /**< Maximum capture file size */
guint32 autostop_filesize; /**< Maximum capture file size in kB */
gboolean has_autostop_duration; /**< TRUE if maximum capture duration
is specified */
gint32 autostop_duration; /**< Maximum capture duration */
gdouble autostop_duration; /**< Maximum capture duration */
gchar *capture_comment; /** capture comment to write to the
output file */

View File

@ -1,303 +0,0 @@
/* capture_stop_conditions.c
* Implementation for 'stop condition handler'.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "conditions.h"
#include "capture_stop_conditions.h"
#include "ws_attributes.h"
/* predefined classes function prototypes */
static condition* _cnd_constr_timeout(condition*, va_list);
static void _cnd_destr_timeout(condition*);
static gboolean _cnd_eval_timeout(condition*, va_list);
static void _cnd_reset_timeout(condition*);
static condition* _cnd_constr_capturesize(condition*, va_list);
static void _cnd_destr_capturesize(condition*);
static gboolean _cnd_eval_capturesize(condition*, va_list);
static void _cnd_reset_capturesize(condition*);
static condition* _cnd_constr_interval(condition*, va_list);
static void _cnd_destr_interval(condition*);
static gboolean _cnd_eval_interval(condition*, va_list);
static void _cnd_reset_interval(condition*);
void init_capture_stop_conditions(void){
cnd_register_class(CND_CLASS_TIMEOUT,
_cnd_constr_timeout,
_cnd_destr_timeout,
_cnd_eval_timeout,
_cnd_reset_timeout);
cnd_register_class(CND_CLASS_CAPTURESIZE,
_cnd_constr_capturesize,
_cnd_destr_capturesize,
_cnd_eval_capturesize,
_cnd_reset_capturesize);
cnd_register_class(CND_CLASS_INTERVAL,
_cnd_constr_interval,
_cnd_destr_interval,
_cnd_eval_interval,
_cnd_reset_interval);
} /* END init_capture_stop_conditions() */
void cleanup_capture_stop_conditions(void){
cnd_unregister_class(CND_CLASS_TIMEOUT);
cnd_unregister_class(CND_CLASS_CAPTURESIZE);
cnd_unregister_class(CND_CLASS_INTERVAL);
} /* END cleanup_capture_stop_conditions() */
/*****************************************************************************/
/* Predefined condition 'timeout'. */
/* class id */
const char* CND_CLASS_TIMEOUT = "cnd_class_timeout";
/* structure that contains user supplied data for this condition */
typedef struct _cnd_timeout_dat{
time_t start_time;
gint32 timeout_s;
}cnd_timeout_dat;
/*
* Constructs new condition for timeout check. This function is invoked by
* 'cnd_new()' in order to perform class specific initialization.
*
* parameter: cnd - Pointer to condition passed by 'cnd_new()'.
* ap - Pointer to user supplied arguments list for this
* constructor.
* returns: Pointer to condition - Construction was successful.
* NULL - Construction failed.
*/
static condition* _cnd_constr_timeout(condition* cnd, va_list ap){
cnd_timeout_dat *data = NULL;
/* allocate memory */
if((data = (cnd_timeout_dat*)g_malloc(sizeof(cnd_timeout_dat))) == NULL)
return NULL;
/* initialize user data */
data->start_time = time(NULL);
data->timeout_s = va_arg(ap, gint32);
cnd_set_user_data(cnd, (void*)data);
return cnd;
} /* END _cnd_constr_timeout() */
/*
* Destroys condition for timeout check. This function is invoked by
* 'cnd_delete()' in order to perform class specific clean up.
*
* parameter: cnd - Pointer to condition passed by 'cnd_delete()'.
*/
static void _cnd_destr_timeout(condition* cnd){
/* free memory */
g_free(cnd_get_user_data(cnd));
} /* END _cnd_destr_timeout() */
/*
* Condition handler for timeout condition. This function is invoked by
* 'cnd_eval()' in order to perform class specific condition checks.
*
* parameter: cnd - The inititalized timeout condition.
* ap - Pointer to user supplied arguments list for this
* handler.
* returns: TRUE - Condition is true.
* FALSE - Condition is false.
*/
static gboolean _cnd_eval_timeout(condition* cnd, va_list ap _U_){
cnd_timeout_dat* data = (cnd_timeout_dat*)cnd_get_user_data(cnd);
gint32 elapsed_time;
/* check timeout here */
if(data->timeout_s == 0) return FALSE; /* 0 == infinite */
elapsed_time = (gint32) (time(NULL) - data->start_time);
if(elapsed_time >= data->timeout_s) return TRUE;
return FALSE;
} /* END _cnd_eval_timeout()*/
/*
* Call this function to reset this condition to its initial state, i.e. the
* state it was in right after creation.
*
* parameter: cnd - Pointer to an initialized condition.
*/
static void _cnd_reset_timeout(condition *cnd){
((cnd_timeout_dat*)cnd_get_user_data(cnd))->start_time = time(NULL);
} /* END _cnd_reset_timeout() */
/*****************************************************************************/
/* Predefined condition 'max. capturesize'. */
/* class id */
const char* CND_CLASS_CAPTURESIZE = "cnd_class_capturesize";
/* structure that contains user supplied data for this condition */
typedef struct _cnd_capturesize_dat{
guint64 max_capture_size;
}cnd_capturesize_dat;
/*
* Constructs new condition for capturesize check. This function is invoked by
* 'cnd_new()' in order to perform class specific initialization.
*
* parameter: cnd - Pointer to condition passed by 'cnd_new()'.
* ap - Pointer to user supplied arguments list for this
* constructor.
* returns: Pointer to condition - Construction was successful.
* NULL - Construction failed.
*/
static condition* _cnd_constr_capturesize(condition* cnd, va_list ap){
cnd_capturesize_dat *data = NULL;
/* allocate memory */
if((data = (cnd_capturesize_dat*)g_malloc(sizeof(cnd_capturesize_dat))) == NULL)
return NULL;
/* initialize user data */
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() */
/*
* Destroys condition for capturesize check. This function is invoked by
* 'cnd_delete()' in order to perform class specific clean up.
*
* parameter: cnd - Pointer to condition passed by 'cnd_delete()'.
*/
static void _cnd_destr_capturesize(condition* cnd){
/* free memory */
g_free(cnd_get_user_data(cnd));
} /* END _cnd_destr_capturesize() */
/*
* Condition handler for capturesize condition. This function is invoked by
* 'cnd_eval()' in order to perform class specific condition checks.
*
* parameter: cnd - The inititalized capturesize condition.
* ap - Pointer to user supplied arguments list for this
* handler.
* returns: TRUE - Condition is true.
* FALSE - Condition is false.
*/
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, guint64) >= data->max_capture_size){
return TRUE;
}
return FALSE;
} /* END _cnd_eval_capturesize() */
/*
* Call this function to reset this condition to its initial state, i.e. the
* state it was in right after creation.
*
* parameter: cnd - Pointer to an initialized condition.
*/
static void _cnd_reset_capturesize(condition *cnd _U_){
} /* END _cnd_reset_capturesize() */
/*****************************************************************************/
/* Predefined condition 'interval'. */
/* class id */
const char* CND_CLASS_INTERVAL = "cnd_class_interval";
/* structure that contains user supplied data for this condition */
typedef struct _cnd_interval_dat{
time_t start_time;
gint32 interval_s;
}cnd_interval_dat;
/*
* Constructs new condition for interval check. This function is invoked by
* 'cnd_new()' in order to perform class specific initialization.
*
* parameter: cnd - Pointer to condition passed by 'cnd_new()'.
* ap - Pointer to user supplied arguments list for this
* constructor.
* returns: Pointer to condition - Construction was successful.
* NULL - Construction failed.
*/
static condition* _cnd_constr_interval(condition* cnd, va_list ap){
cnd_interval_dat *data = NULL;
/* allocate memory */
if((data = (cnd_interval_dat*)g_malloc(sizeof(cnd_interval_dat))) == NULL)
return NULL;
/* initialize user data */
data->start_time = time(NULL);
data->interval_s = va_arg(ap, gint32);
data->start_time -= data->start_time % data->interval_s;
cnd_set_user_data(cnd, (void*)data);
return cnd;
} /* END _cnd_constr_interval() */
/*
* Destroys condition for interval check. This function is invoked by
* 'cnd_delete()' in order to perform class specific clean up.
*
* parameter: cnd - Pointer to condition passed by 'cnd_delete()'.
*/
static void _cnd_destr_interval(condition* cnd){
/* free memory */
g_free(cnd_get_user_data(cnd));
} /* END _cnd_destr_interval() */
/*
* Condition handler for interval condition. This function is invoked by
* 'cnd_eval()' in order to perform class specific condition checks.
*
* parameter: cnd - The inititalized interval condition.
* ap - Pointer to user supplied arguments list for this
* handler.
* returns: TRUE - Condition is true.
* FALSE - Condition is false.
*/
static gboolean _cnd_eval_interval(condition* cnd, va_list ap _U_){
cnd_interval_dat* data = (cnd_interval_dat*)cnd_get_user_data(cnd);
gint32 elapsed_time;
/* check interval here */
if(data->interval_s == 0) return FALSE; /* 0 == infinite */
elapsed_time = (gint32) (time(NULL) - data->start_time);
if(elapsed_time >= data->interval_s) return TRUE;
return FALSE;
} /* END _cnd_eval_interval()*/
/*
* Call this function to reset this condition to its initial state, i.e. the
* state it was in right after creation.
*
* parameter: cnd - Pointer to an initialized condition.
*/
static void _cnd_reset_interval(condition *cnd){
((cnd_interval_dat*)cnd_get_user_data(cnd))->start_time = time(NULL);
((cnd_interval_dat*)cnd_get_user_data(cnd))->start_time -=
((cnd_interval_dat*)cnd_get_user_data(cnd))->start_time % ((cnd_interval_dat*)cnd_get_user_data(cnd))->interval_s;
} /* END _cnd_reset_interval() */
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

View File

@ -1,29 +0,0 @@
/* capture_stop_conditions.h
* Implementation for 'stop condition handler'.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
void init_capture_stop_conditions(void);
void cleanup_capture_stop_conditions(void);
extern const char *CND_CLASS_TIMEOUT;
extern const char *CND_CLASS_CAPTURESIZE;
extern const char *CND_CLASS_INTERVAL;
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

View File

@ -1,220 +0,0 @@
/* conditions.c
* Implementation for condition handler.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "conditions.h"
#include "ws_attributes.h"
/* container for condition classes */
static GHashTable *classes = NULL;
/* condition data structure declaration */
struct condition{
char *class_id;
void *user_data;
_cnd_eval eval_func;
_cnd_reset reset_func;
};
/* structure used to store class functions in GHashTable */
typedef struct _cnd_class{
_cnd_constr constr_func;
_cnd_destr destr_func;
_cnd_eval eval_func;
_cnd_reset reset_func;
} _cnd_class;
/* helper function prototypes */
static void _cnd_init(void);
static void _cnd_find_hash_key_for_class_id(gpointer, gpointer, gpointer);
condition *cnd_new(const char *class_id, ...) {
va_list ap;
condition *cnd = NULL;
condition *cnd_ref = NULL;
_cnd_class *cls = NULL;
char *id = NULL;
/* check if hash table is already initialized */
_cnd_init();
/* get class structure for this id */
if ((cls = (_cnd_class *)g_hash_table_lookup(classes, class_id)) == NULL) {
g_warning("cnd_new: Couldn't find class ID \"%s\"", class_id);
return NULL;
}
/* initialize the basic structure */
if ((cnd_ref = (condition *)g_malloc(sizeof(condition))) == NULL)
return NULL;
cnd_ref->user_data = NULL;
cnd_ref->eval_func = cls->eval_func;
cnd_ref->reset_func = cls->reset_func;
cnd_ref->class_id = g_strdup(class_id);
/* perform class specific initialization */
va_start(ap, class_id);
cnd = (cls->constr_func)(cnd_ref, ap);
va_end(ap);
/* check for successful construction */
if (cnd == NULL) {
g_free(cnd_ref);
g_free(id);
}
return cnd;
} /* END cnd_new() */
void cnd_delete(condition *cnd) {
_cnd_class *cls = NULL;
const char* class_id;
/* check for valid pointer */
if (cnd == NULL)
return;
class_id = cnd->class_id;
/* check if hash table is already initialized */
_cnd_init();
/* get the condition class */
cls = (_cnd_class *)g_hash_table_lookup(classes, class_id);
/* call class specific destructor */
if (cls != NULL)
(cls->destr_func)(cnd);
/* free memory */
g_free(cnd->class_id);
/* free basic structure */
g_free(cnd);
} /* END cnd_delete() */
gboolean cnd_eval(condition *cnd, ...) {
va_list ap;
gboolean ret_val = FALSE;
/* validate cnd */
if (cnd == NULL)
return FALSE;
/* call specific handler */
va_start(ap, cnd);
ret_val = (cnd->eval_func)(cnd, ap);
va_end(ap);
return ret_val;
} /* END cnd_eval() */
void cnd_reset(condition *cnd) {
if (cnd != NULL)
(cnd->reset_func)(cnd);
} /* END cnd_reset() */
void* cnd_get_user_data(condition *cnd) {
return cnd->user_data;
} /* END cnd_get_user_data() */
void cnd_set_user_data(condition *cnd, void *user_data) {
cnd->user_data = user_data;
} /* END cnd_set_user_data() */
gboolean cnd_register_class(const char *class_id,
_cnd_constr constr_func,
_cnd_destr destr_func,
_cnd_eval eval_func,
_cnd_reset reset_func) {
char *key = NULL;
_cnd_class *cls = NULL;
/* check for valid parameters */
if ((constr_func == NULL) || (destr_func == NULL) ||
(eval_func == NULL) || (reset_func == NULL) || (class_id == NULL))
return FALSE;
/* check if hash table is already initialized */
_cnd_init();
/* check for unique class id */
if (g_hash_table_lookup(classes, class_id) != NULL) {
g_warning("cnd_register_class: Duplicate class ID \"%s\"", class_id);
return FALSE;
}
/* GHashTable keys need to be persistent for the lifetime of the hash
table. Allocate memory and copy the class id which we use as key. */
key = g_strdup(class_id);
/* initialize class structure */
if ((cls = (_cnd_class*)g_malloc(sizeof(_cnd_class))) == NULL) {
g_free(key);
return FALSE;
}
cls->constr_func = constr_func;
cls->destr_func = destr_func;
cls->eval_func = eval_func;
cls->reset_func = reset_func;
/* insert new class */
g_hash_table_insert(classes, key, cls);
return TRUE;
} /* END cnd_register_class() */
static char *pkey = NULL;
void cnd_unregister_class(const char* class_id) {
const char *key = (const char*)class_id;
_cnd_class *cls = NULL;
/* check if hash table is already initialized */
_cnd_init();
/* find the key for this class id and store it in 'pkey' */
g_hash_table_foreach(classes,
_cnd_find_hash_key_for_class_id,
(gpointer)key);
/* find the class structure for this class id */
cls = (_cnd_class*)g_hash_table_lookup(classes, class_id);
/* remove constructor from hash table */
g_hash_table_remove(classes, class_id);
/* free the key */
g_free(pkey);
pkey = NULL;
/* free the value */
g_free(cls);
} /* END cnd_unregister_class() */
/*
* Initialize hash table.
*/
static void _cnd_init(void) {
if (classes != NULL)
return;
/* create hash table, we use strings as keys */
classes = g_hash_table_new(g_str_hash, g_str_equal);
} /* END _cnd_init() */
/*
* Callback for function 'g_hash_table_foreach()'.
* We don't keep references to hash table keys. Keys have memory allocated
* which must be freed when they are not used anymore. This function finds
* the reference to a key corresponding to a particular class id. The reference
* to the key is stored in a global variable.
*/
void _cnd_find_hash_key_for_class_id(gpointer key,
gpointer value _U_,
gpointer user_data) {
char *class_id = (char *)user_data;
char *key_value = (char *)key;
if (strcmp(class_id, key_value) == 0)
pkey = key_value;
} /* END _cnd_find_hash_key_for_class_id() */
/*
* Editor modelines
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

View File

@ -1,133 +0,0 @@
/* conditions.h
* Header for condition handler.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef CONDITIONS_H
#define CONDITIONS_H
#include <stdarg.h>
#include <glib.h>
/* forward declaration for type 'condition' */
typedef struct condition condition;
/* condition evaluation handler type */
typedef gboolean (*_cnd_eval)(condition *, va_list);
/* condition reset handler type */
typedef void (*_cnd_reset)(condition *);
/* condition class constructor type */
typedef condition *(*_cnd_constr)(condition *, va_list);
/* condition class destructor type */
typedef void (*_cnd_destr)(condition *);
/*
* Conditions must be created with this function. They can be created for
* registered classes only.
*
* parameter: const char * - Identification of a registered condition class.
* ... - Any number of class specific initial values.
* returns: Pointer to a initialized condition of the particular class on
* success or NULL on failure.
*/
condition *cnd_new(const char *, ...);
/*
* Conditions must be deleted with this function when not used anymore.
*
* parameter: condition * - Pointer to a condition created with 'cnd_new()'.
* returns: -
*/
void cnd_delete(condition *);
/*
* Call this function to check whether or not a particular condition is true.
*
* parameter: condition * - Pointer to an initialized condition.
* ... - Any number of condition specific arguments.
* returns: TRUE - Condition is true.
* FALSE - Condition is false.
*/
gboolean cnd_eval(condition *, ...);
/*
* Call this function to reset this condition to its initial state, i.e. the
* state it was in right after creation.
*
* parameter: condition * - Pointer to an initialized condition.
* returns: -
*/
void cnd_reset(condition *);
/*
* Register a new conditon class.
* New conditions of this class can be created by calling 'cnd_new()' and
* supplying the appropriate class id.
*
* parameter: const char * - The class id.
* _cnd_constr - User supplied constructor function for this
* class.
* _cnd_destr - User supplied destructor function for this
* class.
* _cnd_eval - User supplied evaluation handler function for this
class.
* _cnd_reset - User supplied reset handler for this class.
* returns: TRUE - Success.
* FALSE - Failure.
*/
gboolean cnd_register_class(const char *,
_cnd_constr,
_cnd_destr,
_cnd_eval,
_cnd_reset);
/*
* Unregister a previously registered conditon class. After unregistration
* of a class it is no longer possible to create conditions of this kind by
* calling 'cnd_new()'.
*
* parameter: const char * - An identification for this condition class.
* returns: -
*/
void cnd_unregister_class(const char *);
/*
* This function returns the user data of the condition.
*
* parameter: condition * - Pointer to an initialized condition.
* returns: void * - Pointer to user data of this condition.
*/
void* cnd_get_user_data(condition*);
/*
* This function sets the user data of the condition.
*
* parameter: condition * - Pointer to an initialized condition.
* void * - Pointer to user specified data structure.
* returns: -
*/
void cnd_set_user_data(condition *, void *);
#endif /* CONDITIONS_H */
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -25,13 +25,9 @@ capture.h
capture_loop.c
capture_loop.h
capture_opts.c
capture-stop-conditions.c
capture-stop-conditions.h
capture_sync.c
capture_ui_utils.c
capture_ui_utils.h
conditions.c (XXX: is conditions generic or capture specific?)
conditions.h
Capture driver

View File

@ -72,7 +72,7 @@ to a capture file. The criterion is of the form I<test>B<:>I<value>,
where I<test> is one of:
B<duration>:I<value> Stop writing to a capture file after I<value> seconds have
elapsed.
elapsed. Floating point values (e.g. 0.5) are allowed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
I<value> kB. If this option is used together with the -b option, dumpcap will
@ -103,7 +103,8 @@ The criterion is of the form I<key>B<:>I<value>,
where I<key> is one of:
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.
elapsed, even if the current file is not completely filled up. Floating
point values (e.g. 0.5) are allowed.
B<interval>:I<value> switch to the next file when the time is an exact
multiple of I<value> seconds

View File

@ -216,7 +216,7 @@ to a capture file. The criterion is of the form I<test>B<:>I<value>,
where I<test> is one of:
B<duration>:I<value> Stop writing to a capture file after I<value> seconds
have elapsed.
have elapsed. Floating point values (e.g. 0.5) are allowed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
I<value> kB. If this option is used together with the -b option, B<TShark>
@ -250,7 +250,8 @@ The criterion is of the form I<key>B<:>I<value>,
where I<key> is one of:
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.
elapsed, even if the current file is not completely filled up. Floating
point values (e.g. 0.5) are allowed.
B<interval>:I<value> switch to the next file when the time is an exact
multiple of I<value> seconds

View File

@ -240,7 +240,7 @@ to a capture file. The criterion is of the form I<test>B<:>I<value>,
where I<test> is one of:
B<duration>:I<value> Stop writing to a capture file after I<value> seconds have
elapsed.
elapsed. Floating point values (e.g. 0.5) are allowed.
B<filesize>:I<value> Stop writing to a capture file after it reaches a size of
I<value> kB. If this option is used together with the -b option, Wireshark
@ -272,7 +272,8 @@ The criterion is of the form I<key>B<:>I<value>,
where I<key> is one of:
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.
elapsed, even if the current file is not completely filled up. Floating
point values (e.g. 0.5) are allowed.
B<interval>:I<value> switch to the next file when the time is an exact
multiple of I<value> seconds

119
dumpcap.c
View File

@ -82,9 +82,6 @@
#include <capchild/capture_session.h>
#include <capchild/capture_sync.h>
#include "conditions.h"
#include "capture_stop_conditions.h"
#include "wsutil/tempfile.h"
#include "log.h"
#include "wsutil/file_util.h"
@ -317,6 +314,14 @@ typedef struct _pcap_queue_element {
u_char *pd;
} pcap_queue_element;
/* Conditions required by do_file_switch_or_stop */
typedef struct _condition_data {
GTimer *file_duration_timer;
time_t next_interval_time;
int interval_s;
unsigned autostop_files;
} condition_data;
/*
* Standard secondary message for unexpected errors.
*/
@ -448,7 +453,7 @@ print_usage(FILE *output)
fprintf(output, "Stop conditions:\n");
fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
fprintf(output, " -a <autostop cond.> ... duration:NUM - stop after NUM seconds\n");
fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
fprintf(output, " filesize:NUM - stop this file after NUM kB\n");
fprintf(output, " files:NUM - stop after NUM files\n");
/*fprintf(output, "\n");*/
fprintf(output, "Output (files):\n");
@ -456,7 +461,7 @@ print_usage(FILE *output)
fprintf(output, " -g enable group read access on the output file(s)\n");
fprintf(output, " -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
fprintf(output, " interval:NUM - create time intervals of NUM secs\n");
fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
fprintf(output, " filesize:NUM - switch to next file after NUM kB\n");
fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
fprintf(output, " -n use pcapng format instead of pcap (default)\n");
fprintf(output, " -P use libpcap format instead of pcapng\n");
@ -3447,15 +3452,18 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
return TRUE;
}
static time_t get_next_time_interval(int interval_s) {
time_t next_time = time(NULL);
next_time -= next_time % interval_s;
next_time += interval_s;
return next_time;
}
/* Do the work of handling either the file size or file duration capture
conditions being reached, and switching files or stopping. */
static gboolean
do_file_switch_or_stop(capture_options *capture_opts,
condition *cnd_autostop_files,
condition *cnd_autostop_size,
condition *cnd_file_duration,
condition *cnd_file_interval)
condition_data *conditions)
{
guint i;
capture_src *pcap_src;
@ -3463,8 +3471,8 @@ do_file_switch_or_stop(capture_options *capture_opts,
gboolean successful;
if (capture_opts->multi_files_on) {
if (cnd_autostop_files != NULL &&
cnd_eval(cnd_autostop_files, (guint64)++global_ld.autostop_files)) {
if (conditions->autostop_files &&
++global_ld.autostop_files >= conditions->autostop_files) {
/* no files left: stop here */
global_ld.go = FALSE;
return FALSE;
@ -3546,12 +3554,12 @@ do_file_switch_or_stop(capture_options *capture_opts,
global_ld.go = FALSE;
return FALSE;
}
if (cnd_autostop_size)
cnd_reset(cnd_autostop_size);
if (cnd_file_duration)
cnd_reset(cnd_file_duration);
if (cnd_file_interval)
cnd_reset(cnd_file_interval);
if (conditions->file_duration_timer) {
g_timer_reset(conditions->file_duration_timer);
}
if (conditions->next_interval_time) {
conditions->next_interval_time = get_next_time_interval(conditions->interval_s);
}
fflush(global_ld.pdh);
if (!quiet)
report_packet_count(global_ld.inpkts_to_sync_pipe);
@ -3603,11 +3611,8 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
#endif
int err_close;
int inpkts;
condition *cnd_file_duration = NULL;
condition *cnd_file_interval = NULL;
condition *cnd_autostop_files = NULL;
condition *cnd_autostop_size = NULL;
condition *cnd_autostop_duration = NULL;
condition_data conditions;
GTimer *autostop_duration_timer = NULL;
gboolean write_ok;
gboolean close_ok;
gboolean cfilter_error = FALSE;
@ -3709,31 +3714,28 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* initialize capture stop (and alike) conditions */
init_capture_stop_conditions();
memset(&conditions, 0, sizeof(conditions));
if (capture_opts->has_file_interval) {
conditions.interval_s = capture_opts->file_interval;
conditions.next_interval_time = get_next_time_interval(conditions.interval_s);
}
/* create stop conditions */
if (capture_opts->has_autostop_filesize) {
if (capture_opts->autostop_filesize > (((guint32)INT_MAX + 1) / 1000)) {
capture_opts->autostop_filesize = ((guint32)INT_MAX + 1) / 1000;
}
cnd_autostop_size =
cnd_new(CND_CLASS_CAPTURESIZE, (guint64)capture_opts->autostop_filesize * 1000);
}
if (capture_opts->has_autostop_duration)
cnd_autostop_duration =
cnd_new(CND_CLASS_TIMEOUT,(gint32)capture_opts->autostop_duration);
if (capture_opts->has_autostop_duration) {
autostop_duration_timer = g_timer_new();
}
if (capture_opts->multi_files_on) {
if (capture_opts->has_file_duration)
cnd_file_duration =
cnd_new(CND_CLASS_TIMEOUT, capture_opts->file_duration);
if (capture_opts->has_file_duration) {
conditions.file_duration_timer = g_timer_new();
}
if (capture_opts->has_autostop_files)
cnd_autostop_files =
cnd_new(CND_CLASS_CAPTURESIZE, (guint64)capture_opts->autostop_files);
if (capture_opts->has_file_interval)
cnd_file_interval =
cnd_new(CND_CLASS_INTERVAL, capture_opts->file_interval);
conditions.autostop_files = capture_opts->autostop_files;
}
/* init the time values */
@ -3824,14 +3826,11 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
global_ld.inpkts_to_sync_pipe += inpkts;
/* check capture size condition */
if (cnd_autostop_size != NULL &&
cnd_eval(cnd_autostop_size, global_ld.bytes_written)) {
if (capture_opts->has_autostop_filesize &&
capture_opts->autostop_filesize > 0 &&
global_ld.bytes_written / 1000 >= capture_opts->autostop_filesize) {
/* 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,
cnd_file_interval))
if (!do_file_switch_or_stop(capture_opts, &conditions))
continue;
} /* cnd_autostop_size */
if (capture_opts->output_to_pipe) {
@ -3876,31 +3875,23 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
/* check capture duration condition */
if (cnd_autostop_duration != NULL && cnd_eval(cnd_autostop_duration)) {
if (autostop_duration_timer != NULL && g_timer_elapsed(autostop_duration_timer, NULL) >= capture_opts->autostop_duration) {
/* The maximum capture time has elapsed; stop the capture. */
global_ld.go = FALSE;
continue;
}
/* check capture file duration condition */
if (cnd_file_duration != NULL && cnd_eval(cnd_file_duration)) {
if (conditions.file_duration_timer != NULL && g_timer_elapsed(conditions.file_duration_timer, NULL) >= capture_opts->file_duration) {
/* duration limit reached, do we have another file? */
if (!do_file_switch_or_stop(capture_opts,
cnd_autostop_files,
cnd_autostop_size,
cnd_file_duration,
cnd_file_interval))
if (!do_file_switch_or_stop(capture_opts, &conditions))
continue;
} /* cnd_file_duration */
/* check capture file interval condition */
if (cnd_file_interval != NULL && cnd_eval(cnd_file_interval)) {
if (conditions.interval_s && time(NULL) >= conditions.next_interval_time) {
/* end of interval reached, do we have another file? */
if (!do_file_switch_or_stop(capture_opts,
cnd_autostop_files,
cnd_autostop_size,
cnd_file_duration,
cnd_file_interval))
if (!do_file_switch_or_stop(capture_opts, &conditions))
continue;
} /* cnd_file_interval */
}
@ -3946,16 +3937,10 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
/* delete stop conditions */
if (cnd_file_duration != NULL)
cnd_delete(cnd_file_duration);
if (cnd_file_interval != NULL)
cnd_delete(cnd_file_interval);
if (cnd_autostop_files != NULL)
cnd_delete(cnd_autostop_files);
if (cnd_autostop_size != NULL)
cnd_delete(cnd_autostop_size);
if (cnd_autostop_duration != NULL)
cnd_delete(cnd_autostop_duration);
if (conditions.file_duration_timer != NULL)
g_timer_destroy(conditions.file_duration_timer);
if (autostop_duration_timer != NULL)
g_timer_destroy(autostop_duration_timer);
/* did we have a pcap (input) error? */
for (i = 0; i < capture_opts->ifaces->len; i++) {

View File

@ -70,8 +70,6 @@
#include "ui/util.h"
#include "ui/dissect_opts.h"
#include "ui/failure_message.h"
#include "conditions.h"
#include "capture_stop_conditions.h"
#include <epan/epan_dissect.h>
#include <epan/stat_tap_ui.h>
#include <epan/timestamp.h>

View File

@ -90,6 +90,23 @@ get_nonzero_guint32(const char *string, const char *name)
return number;
}
double
get_positive_double(const char *string, const char *name)
{
double number = g_ascii_strtod(string, NULL);
if (errno == EINVAL) {
cmdarg_err("The specified %s \"%s\" isn't a floating point number", name, string);
exit(1);
}
if (number < 0.0) {
cmdarg_err("The specified %s \"%s\" is a negative number", name, string);
exit(1);
}
return number;
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*

View File

@ -29,6 +29,9 @@ get_guint32(const char *string, const char *name);
WS_DLL_PUBLIC guint32
get_nonzero_guint32(const char *string, const char *name);
WS_DLL_PUBLIC double
get_positive_double(const char *string, const char *name);
#ifdef __cplusplus
}
#endif /* __cplusplus */