move capture_opts related things (init, command line, ...) from capture.c to a new file capture_opts.c and let both ethereal and tethereal use it.

svn path=/trunk/; revision=13474
This commit is contained in:
Ulf Lamping 2005-02-23 01:01:19 +00:00
parent a25fd8d7ca
commit d643a55488
5 changed files with 361 additions and 508 deletions

View File

@ -152,6 +152,7 @@ ethereal_SOURCES = \
$(ETHEREAL_COMMON_SRC) \ $(ETHEREAL_COMMON_SRC) \
alert_box.c \ alert_box.c \
capture.c \ capture.c \
capture_opts.c \
capture_sync.c \ capture_sync.c \
capture_loop.c \ capture_loop.c \
color_filters.c \ color_filters.c \
@ -186,6 +187,7 @@ ethereal_INCLUDES = \
tethereal_SOURCES = \ tethereal_SOURCES = \
$(ETHEREAL_COMMON_SRC) \ $(ETHEREAL_COMMON_SRC) \
$(TETHEREAL_TAP_SRC) \ $(TETHEREAL_TAP_SRC) \
capture_opts.c \
tethereal-tap-register.c \ tethereal-tap-register.c \
tethereal.c tethereal.c

272
capture.c
View File

@ -76,278 +76,6 @@ static gboolean normal_do_capture(capture_options *capture_opts, gboolean is_tem
static void stop_capture_signal_handler(int signo); static void stop_capture_signal_handler(int signo);
void
capture_opts_init(capture_options *capture_opts, void *cfile)
{
capture_opts->cf = cfile;
capture_opts->cfilter = g_strdup("");
capture_opts->iface = NULL;
#ifdef _WIN32
capture_opts->buffer_size = 1; /* 1 MB */
#endif
capture_opts->has_snaplen = FALSE;
capture_opts->snaplen = MIN_PACKET_SIZE;
capture_opts->promisc_mode = TRUE;
capture_opts->linktype = -1; /* the default linktype */
capture_opts->capture_child = FALSE;
capture_opts->save_file = NULL;
capture_opts->save_file_fd = -1;
capture_opts->sync_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->quit_after_cap = FALSE;
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60; /* 1 min */
capture_opts->has_ring_num_files = TRUE;
capture_opts->ring_num_files = 2;
capture_opts->has_autostop_files = FALSE;
capture_opts->autostop_files = 1;
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 1;
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1024 * 1024; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
}
static int
get_natural_int(const char *string, const char *name)
{
long number;
char *p;
number = strtol(string, &p, 10);
if (p == string || *p != '\0') {
fprintf(stderr, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
name, string);
exit(1);
}
if (number < 0) {
fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
name, string);
exit(1);
}
if (number > INT_MAX) {
fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
name, string, INT_MAX);
exit(1);
}
return number;
}
static int
get_positive_int(const char *string, const char *name)
{
long number;
number = get_natural_int(string, name);
if (number == 0) {
fprintf(stderr, "ethereal: The specified %s is zero\n",
name);
exit(1);
}
return number;
}
/*
* Given a string of the form "<autostop criterion>:<value>", as might appear
* as an argument to a "-a" option, parse it and set the criterion in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
{
gchar *p, *colonp;
colonp = strchr(autostoparg, ':');
if (colonp == NULL)
return FALSE;
p = colonp;
*p++ = '\0';
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace((guchar)*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
if (strcmp(autostoparg,"duration") == 0) {
capture_opts->has_autostop_duration = TRUE;
capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
} else if (strcmp(autostoparg,"filesize") == 0) {
capture_opts->has_autostop_filesize = TRUE;
capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
} else if (strcmp(autostoparg,"files") == 0) {
capture_opts->multi_files_on = TRUE;
capture_opts->has_autostop_files = TRUE;
capture_opts->autostop_files = get_positive_int(p,"autostop files");
} else {
return FALSE;
}
*colonp = ':'; /* put the colon back */
return TRUE;
}
/*
* Given a string of the form "<ring buffer file>:<duration>", as might appear
* as an argument to a "-b" option, parse it and set the arguments in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
get_ring_arguments(capture_options *capture_opts, const char *arg)
{
gchar *p = NULL, *colonp;
colonp = strchr(arg, ':');
if (colonp != NULL) {
p = colonp;
*p++ = '\0';
}
capture_opts->ring_num_files =
get_natural_int(arg, "number of ring buffer files");
if (colonp == NULL)
return TRUE;
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace((guchar)*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
capture_opts->has_file_duration = TRUE;
capture_opts->file_duration = get_positive_int(p,
"ring buffer duration");
*colonp = ':'; /* put the colon back */
return TRUE;
}
void
capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
{
#ifdef _WIN32
int i;
#endif
switch(opt) {
case 'a': /* autostop criteria */
if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
exit(1);
}
break;
case 'b': /* Ringbuffer option */
capture_opts->multi_files_on = TRUE;
capture_opts->has_ring_num_files = TRUE;
if (get_ring_arguments(capture_opts, optarg) == FALSE) {
fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
exit(1);
}
break;
case 'c': /* Capture xxx packets */
capture_opts->has_autostop_packets = TRUE;
capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
break;
case 'f': /* capture filter */
if (capture_opts->cfilter)
g_free(capture_opts->cfilter);
capture_opts->cfilter = g_strdup(optarg);
break;
case 'H': /* Hide capture info dialog box */
capture_opts->show_info = FALSE;
break;
case 'i': /* Use interface xxx */
capture_opts->iface = g_strdup(optarg);
break;
case 'k': /* Start capture immediately */
*start_capture = TRUE;
break;
/*case 'l':*/ /* Automatic scrolling in live capture mode */
case 'p': /* Don't capture in promiscuous mode */
capture_opts->promisc_mode = FALSE;
break;
case 'Q': /* Quit after capture (just capture to file) */
capture_opts->quit_after_cap = TRUE;
*start_capture = TRUE; /*** -Q implies -k !! ***/
break;
case 's': /* Set the snapshot (capture) length */
capture_opts->has_snaplen = TRUE;
capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
break;
case 'S': /* "Sync" mode: used for following file ala tail -f */
capture_opts->sync_mode = TRUE;
break;
case 'w': /* Write to capture file xxx */
capture_opts->save_file = g_strdup(optarg);
break;
case 'W': /* Write to capture file FD xxx */
capture_opts->save_file_fd = atoi(optarg);
break;
case 'y': /* Set the pcap data link type */
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
capture_opts->linktype = pcap_datalink_name_to_val(optarg);
if (capture_opts->linktype == -1) {
fprintf(stderr, "ethereal: The specified data link type \"%s\" isn't valid\n",
optarg);
exit(1);
}
#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
/* XXX - just treat it as a number */
capture_opts->linktype = get_natural_int(optarg, "data link type");
#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
break;
#ifdef _WIN32
/* Hidden option supporting Sync mode */
case 'Z': /* Write to pipe FD XXX */
/* associate stdout with pipe */
i = atoi(optarg);
if (dup2(i, 1) < 0) {
fprintf(stderr, "Unable to dup pipe handle\n");
exit(1);
}
break;
#endif /* _WIN32 */
default:
/* the caller is responsible to send us only the right opt's */
g_assert_not_reached();
}
}
/* open the output file (temporary/specified name/ringbuffer) and close the old one */ /* open the output file (temporary/specified name/ringbuffer) and close the old one */
/* Returns TRUE if the file opened successfully, FALSE otherwise. */ /* Returns TRUE if the file opened successfully, FALSE otherwise. */
static gboolean static gboolean

318
capture_opts.c Normal file
View File

@ -0,0 +1,318 @@
/* capture_opts.c
* Routines for capture options setting
*
* $Id$
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_LIBPCAP
#ifdef HAVE_IO_H
# include <io.h>
#endif
#include <pcap.h>
#include <glib.h>
#include <epan/packet.h>
#include "capture.h"
#include "ringbuffer.h"
void
capture_opts_init(capture_options *capture_opts, void *cfile)
{
capture_opts->cf = cfile;
capture_opts->cfilter = g_strdup(""); /* No capture filter string specified */
capture_opts->iface = NULL; /* Default is "pick the first interface" */
#ifdef _WIN32
capture_opts->buffer_size = 1; /* 1 MB */
#endif
capture_opts->has_snaplen = FALSE;
capture_opts->snaplen = WTAP_MAX_PACKET_SIZE; /* snapshot length - default is
infinite, in effect */
capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
capture_opts->linktype = -1; /* the default linktype */
capture_opts->capture_child = FALSE;
capture_opts->save_file = NULL;
capture_opts->save_file_fd = -1;
capture_opts->sync_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->quit_after_cap = FALSE;
capture_opts->multi_files_on = FALSE;
capture_opts->has_file_duration = FALSE;
capture_opts->file_duration = 60; /* 1 min */
capture_opts->has_ring_num_files = FALSE;
capture_opts->ring_num_files = RINGBUFFER_MIN_NUM_FILES;
capture_opts->has_autostop_files = FALSE;
capture_opts->autostop_files = 1;
capture_opts->has_autostop_packets = FALSE;
capture_opts->autostop_packets = 1;
capture_opts->has_autostop_filesize = FALSE;
capture_opts->autostop_filesize = 1024 * 1024; /* 1 MB */
capture_opts->has_autostop_duration = FALSE;
capture_opts->autostop_duration = 60; /* 1 min */
}
static int
get_natural_int(const char *string, const char *name)
{
long number;
char *p;
number = strtol(string, &p, 10);
if (p == string || *p != '\0') {
fprintf(stderr, "ethereal: The specified %s \"%s\" isn't a decimal number\n",
name, string);
exit(1);
}
if (number < 0) {
fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
name, string);
exit(1);
}
if (number > INT_MAX) {
fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
name, string, INT_MAX);
exit(1);
}
return number;
}
static int
get_positive_int(const char *string, const char *name)
{
long number;
number = get_natural_int(string, name);
if (number == 0) {
fprintf(stderr, "ethereal: The specified %s is zero\n",
name);
exit(1);
}
return number;
}
/*
* Given a string of the form "<autostop criterion>:<value>", as might appear
* as an argument to a "-a" option, parse it and set the criterion in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
set_autostop_criterion(capture_options *capture_opts, const char *autostoparg)
{
gchar *p, *colonp;
colonp = strchr(autostoparg, ':');
if (colonp == NULL)
return FALSE;
p = colonp;
*p++ = '\0';
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace((guchar)*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
if (strcmp(autostoparg,"duration") == 0) {
capture_opts->has_autostop_duration = TRUE;
capture_opts->autostop_duration = get_positive_int(p,"autostop duration");
} else if (strcmp(autostoparg,"filesize") == 0) {
capture_opts->has_autostop_filesize = TRUE;
capture_opts->autostop_filesize = get_positive_int(p,"autostop filesize");
} else if (strcmp(autostoparg,"files") == 0) {
capture_opts->multi_files_on = TRUE;
capture_opts->has_autostop_files = TRUE;
capture_opts->autostop_files = get_positive_int(p,"autostop files");
} else {
return FALSE;
}
*colonp = ':'; /* put the colon back */
return TRUE;
}
/*
* Given a string of the form "<ring buffer file>:<duration>", as might appear
* as an argument to a "-b" option, parse it and set the arguments in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
get_ring_arguments(capture_options *capture_opts, const char *arg)
{
gchar *p = NULL, *colonp;
colonp = strchr(arg, ':');
if (colonp != NULL) {
p = colonp;
*p++ = '\0';
}
capture_opts->ring_num_files =
get_natural_int(arg, "number of ring buffer files");
if (colonp == NULL)
return TRUE;
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace((guchar)*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
capture_opts->has_file_duration = TRUE;
capture_opts->file_duration = get_positive_int(p,
"ring buffer duration");
*colonp = ':'; /* put the colon back */
return TRUE;
}
void
capture_opt_add(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
{
#ifdef _WIN32
int i;
#endif
switch(opt) {
case 'a': /* autostop criteria */
if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
exit(1);
}
break;
case 'b': /* Ringbuffer option */
capture_opts->multi_files_on = TRUE;
capture_opts->has_ring_num_files = TRUE;
if (get_ring_arguments(capture_opts, optarg) == FALSE) {
fprintf(stderr, "ethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
exit(1);
}
break;
case 'c': /* Capture xxx packets */
capture_opts->has_autostop_packets = TRUE;
capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
break;
case 'f': /* capture filter */
if (capture_opts->cfilter)
g_free(capture_opts->cfilter);
capture_opts->cfilter = g_strdup(optarg);
break;
case 'H': /* Hide capture info dialog box */
capture_opts->show_info = FALSE;
break;
case 'i': /* Use interface xxx */
capture_opts->iface = g_strdup(optarg);
break;
case 'k': /* Start capture immediately */
*start_capture = TRUE;
break;
/*case 'l':*/ /* Automatic scrolling in live capture mode */
case 'p': /* Don't capture in promiscuous mode */
capture_opts->promisc_mode = FALSE;
break;
case 'Q': /* Quit after capture (just capture to file) */
capture_opts->quit_after_cap = TRUE;
*start_capture = TRUE; /*** -Q implies -k !! ***/
break;
case 's': /* Set the snapshot (capture) length */
capture_opts->has_snaplen = TRUE;
capture_opts->snaplen = get_positive_int(optarg, "snapshot length");
break;
case 'S': /* "Sync" mode: used for following file ala tail -f */
capture_opts->sync_mode = TRUE;
break;
case 'w': /* Write to capture file xxx */
capture_opts->save_file = g_strdup(optarg);
break;
case 'W': /* Write to capture file FD xxx */
capture_opts->save_file_fd = atoi(optarg);
break;
case 'y': /* Set the pcap data link type */
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
capture_opts->linktype = pcap_datalink_name_to_val(optarg);
if (capture_opts->linktype == -1) {
fprintf(stderr, "ethereal: The specified data link type \"%s\" isn't valid\n",
optarg);
exit(1);
}
#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
/* XXX - just treat it as a number */
capture_opts->linktype = get_natural_int(optarg, "data link type");
#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
break;
#ifdef _WIN32
/* Hidden option supporting Sync mode */
case 'Z': /* Write to pipe FD XXX */
/* associate stdout with pipe */
i = atoi(optarg);
if (dup2(i, 1) < 0) {
fprintf(stderr, "Unable to dup pipe handle\n");
exit(1);
}
break;
#endif /* _WIN32 */
default:
/* the caller is responsible to send us only the right opt's */
g_assert_not_reached();
}
}
#endif /* HAVE_LIBPCAP */

View File

@ -1620,6 +1620,9 @@ main(int argc, char *argv[])
by preference settings and then again by the command line parameters. */ by preference settings and then again by the command line parameters. */
capture_opts_init(capture_opts, &cfile); capture_opts_init(capture_opts, &cfile);
capture_opts->snaplen = MIN_PACKET_SIZE;
capture_opts->has_ring_num_files = TRUE;
command_name = get_basename(ethereal_path); command_name = get_basename(ethereal_path);
/* Set "capture_child" to indicate whether this is going to be a child /* Set "capture_child" to indicate whether this is going to be a child
process for a "-S" capture. */ process for a "-S" capture. */

View File

@ -103,11 +103,12 @@
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
#include <wiretap/wtap-capture.h> #include <wiretap/wtap-capture.h>
#include <wiretap/libpcap.h> #include <wiretap/libpcap.h>
#endif
#ifdef _WIN32 #ifdef _WIN32
#include "capture-wpcap.h" #include "capture-wpcap.h"
#endif #endif
#include "capture.h"
#endif
/* /*
* This is the template for the decode as option; it is shared between the * This is the template for the decode as option; it is shared between the
@ -168,22 +169,23 @@ typedef struct _loop_data {
static loop_data ld; static loop_data ld;
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
#if 0
typedef struct { typedef struct {
gchar *cfilter; /* Capture filter string */ gchar *cfilter; /* Capture filter string */
gchar *iface; /* the network interface to capture from */ gchar *iface; /* the network interface to capture from */
int snaplen; /* Maximum captured packet length */ int snaplen; /* Maximum captured packet length */
int promisc_mode; /* Capture in promiscuous mode */ int promisc_mode; /* Capture in promiscuous mode */
int autostop_count; /* Maximum packet count */ int autostop_packets; /* Maximum packet count */
gboolean has_autostop_duration; /* TRUE if maximum capture duration gboolean has_autostop_duration; /* TRUE if maximum capture duration
is specified */ is specified */
gint32 autostop_duration; /* Maximum capture duration */ gint32 autostop_duration; /* Maximum capture duration */
gboolean has_autostop_filesize; /* TRUE if maximum capture file size gboolean has_autostop_filesize; /* TRUE if maximum capture file size
is specified */ is specified */
gint32 autostop_filesize; /* Maximum capture file size */ gint32 autostop_filesize; /* Maximum capture file size */
gboolean ringbuffer_on; /* TRUE if ring buffer in use */ gboolean multi_files_on; /* TRUE if ring buffer in use */
guint32 ringbuffer_num_files; /* Number of ring buffer files */ guint32 ring_num_files; /* Number of ring buffer files */
gboolean has_ring_duration; /* TRUE if ring duration specified */ gboolean has_file_duration; /* TRUE if ring duration specified */
gint32 ringbuffer_duration; /* Switch file after n seconds */ gint32 file_duration; /* Switch file after n seconds */
int linktype; /* Data link type to use, or -1 for int linktype; /* Data link type to use, or -1 for
"use default" */ "use default" */
} capture_options; } capture_options;
@ -208,6 +210,8 @@ static capture_options capture_opts = {
0, /* specified time is off by default */ 0, /* specified time is off by default */
-1 /* Default to not change link type */ -1 /* Default to not change link type */
}; };
#endif /* 0 */
static capture_options capture_opts;
static gboolean list_link_layer_types; static gboolean list_link_layer_types;
@ -306,145 +310,6 @@ print_usage(gboolean print_ver)
fprintf(output, "\tdefault is libpcap\n"); fprintf(output, "\tdefault is libpcap\n");
} }
#ifdef HAVE_LIBPCAP
static int
get_natural_int(const char *string, const char *name)
{
long number;
char *p;
number = strtol(string, &p, 10);
if (p == string || *p != '\0') {
fprintf(stderr, "tethereal: The specified %s \"%s\" isn't a decimal number\n",
name, string);
exit(1);
}
if (number < 0) {
fprintf(stderr, "tethereal: The specified %s is a negative number\n",
name);
exit(1);
}
if (number > INT_MAX) {
fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
name, INT_MAX);
exit(1);
}
return number;
}
static int
get_positive_int(const char *string, const char *name)
{
long number;
number = get_natural_int(string, name);
if (number == 0) {
fprintf(stderr, "tethereal: The specified %s is zero\n",
name);
exit(1);
}
return number;
}
/*
* Given a string of the form "<autostop criterion>:<value>", as might appear
* as an argument to a "-a" option, parse it and set the criterion in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
set_autostop_criterion(const char *autostoparg)
{
guchar *p, *colonp;
colonp = strchr(autostoparg, ':');
if (colonp == NULL)
return FALSE;
p = colonp;
*p++ = '\0';
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace(*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
if (strcmp(autostoparg,"duration") == 0) {
capture_opts.has_autostop_duration = TRUE;
capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
} else if (strcmp(autostoparg,"filesize") == 0) {
capture_opts.has_autostop_filesize = TRUE;
capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
} else {
return FALSE;
}
*colonp = ':'; /* put the colon back */
return TRUE;
}
/*
* Given a string of the form "<ring buffer file>:<duration>", as might appear
* as an argument to a "-b" option, parse it and set the arguments in
* question. Return an indication of whether it succeeded or failed
* in some fashion.
*/
static gboolean
get_ring_arguments(const char *arg)
{
guchar *p = NULL, *colonp;
colonp = strchr(arg, ':');
if (colonp != NULL) {
p = colonp;
*p++ = '\0';
}
capture_opts.ringbuffer_num_files =
get_natural_int(arg, "number of ring buffer files");
if (colonp == NULL)
return TRUE;
/*
* Skip over any white space (there probably won't be any, but
* as we allow it in the preferences file, we might as well
* allow it here).
*/
while (isspace(*p))
p++;
if (*p == '\0') {
/*
* Put the colon back, so if our caller uses, in an
* error message, the string they passed us, the message
* looks correct.
*/
*colonp = ':';
return FALSE;
}
capture_opts.has_ring_duration = TRUE;
capture_opts.ringbuffer_duration = get_positive_int(p,
"ring buffer duration");
*colonp = ':'; /* put the colon back */
return TRUE;
}
#endif
/* structure to keep track of what tap listeners have been registered. /* structure to keep track of what tap listeners have been registered.
*/ */
typedef struct _ethereal_tap_list { typedef struct _ethereal_tap_list {
@ -847,6 +712,7 @@ main(int argc, char *argv[])
int out_file_type = WTAP_FILE_PCAP; int out_file_type = WTAP_FILE_PCAP;
gchar *cf_name = NULL, *rfilter = NULL; gchar *cf_name = NULL, *rfilter = NULL;
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
gboolean start_capture = FALSE;
gchar *if_text; gchar *if_text;
GList *lt_list, *lt_entry; GList *lt_list, *lt_entry;
data_link_info_t *data_link_info; data_link_info_t *data_link_info;
@ -861,8 +727,7 @@ main(int argc, char *argv[])
gboolean got_tap = FALSE; gboolean got_tap = FALSE;
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
/* XXX - better use capture_opts_init instead */ capture_opts_init(&capture_opts, NULL /* cfile */);
capture_opts.cfilter = g_strdup("");
#endif #endif
set_timestamp_setting(TS_RELATIVE); set_timestamp_setting(TS_RELATIVE);
@ -974,32 +839,14 @@ main(int argc, char *argv[])
while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) { while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) {
switch (opt) { switch (opt) {
case 'a': /* autostop criteria */ case 'a': /* autostop criteria */
#ifdef HAVE_LIBPCAP
if (set_autostop_criterion(optarg) == FALSE) {
fprintf(stderr, "tethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
exit(1);
}
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
case 'b': /* Ringbuffer option */ case 'b': /* Ringbuffer option */
#ifdef HAVE_LIBPCAP
capture_opts.ringbuffer_on = TRUE;
if (get_ring_arguments(optarg) == FALSE) {
fprintf(stderr, "tethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
exit(1);
}
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
case 'c': /* Capture xxx packets */ case 'c': /* Capture xxx packets */
case 'f': /* capture filter */
case 'p': /* Don't capture in promiscuous mode */
case 's': /* Set the snapshot (capture) length */
case 'y': /* Set the pcap data link type */
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
capture_opts.autostop_count = capture_opt_add(&capture_opts, opt, optarg, &start_capture);
get_positive_int(optarg, "packet count");
#else #else
capture_option_specified = TRUE; capture_option_specified = TRUE;
arg_error = TRUE; arg_error = TRUE;
@ -1042,17 +889,6 @@ main(int argc, char *argv[])
#else #else
capture_option_specified = TRUE; capture_option_specified = TRUE;
arg_error = TRUE; arg_error = TRUE;
#endif
break;
case 'f':
#ifdef HAVE_LIBPCAP
capture_filter_specified = TRUE;
if (capture_opts.cfilter)
g_free(capture_opts.cfilter);
capture_opts.cfilter = g_strdup(optarg);
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif #endif
break; break;
case 'F': case 'F':
@ -1178,14 +1014,6 @@ main(int argc, char *argv[])
break; break;
} }
break; break;
case 'p': /* Don't capture in promiscuous mode */
#ifdef HAVE_LIBPCAP
capture_opts.promisc_mode = FALSE;
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
case 'q': /* Quiet */ case 'q': /* Quiet */
quiet = TRUE; quiet = TRUE;
break; break;
@ -1195,14 +1023,6 @@ main(int argc, char *argv[])
case 'R': /* Read file filter */ case 'R': /* Read file filter */
rfilter = optarg; rfilter = optarg;
break; break;
case 's': /* Set the snapshot (capture) length */
#ifdef HAVE_LIBPCAP
capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
case 'S': /* show packets in real time */ case 'S': /* show packets in real time */
print_packet_info = TRUE; print_packet_info = TRUE;
break; break;
@ -1260,24 +1080,6 @@ main(int argc, char *argv[])
case 'x': /* Print packet data in hex (and ASCII) */ case 'x': /* Print packet data in hex (and ASCII) */
print_hex = TRUE; print_hex = TRUE;
break; break;
case 'y': /* Set the pcap data link type */
#ifdef HAVE_LIBPCAP
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
capture_opts.linktype = pcap_datalink_name_to_val(optarg);
if (capture_opts.linktype == -1) {
fprintf(stderr, "tethereal: The specified data link type \"%s\" isn't valid\n",
optarg);
exit(1);
}
#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
/* XXX - just treat it as a number */
capture_opts.linktype = get_natural_int(optarg, "data link type");
#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
#else
capture_option_specified = TRUE;
arg_error = TRUE;
#endif
break;
case 'z': case 'z':
for(tli=tap_list;tli;tli=tli->next){ for(tli=tap_list;tli;tli=tli->next){
if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){ if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){
@ -1417,7 +1219,7 @@ main(int argc, char *argv[])
exit(1); exit(1);
} }
/* No - did they specify a ring buffer option? */ /* No - did they specify a ring buffer option? */
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
fprintf(stderr, "tethereal: Ring buffer requested, but a capture isn't being done.\n"); fprintf(stderr, "tethereal: Ring buffer requested, but a capture isn't being done.\n");
exit(1); exit(1);
} }
@ -1430,7 +1232,7 @@ main(int argc, char *argv[])
exit(1); exit(1);
} }
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
/* Ring buffer works only under certain conditions: /* Ring buffer works only under certain conditions:
a) ring buffer does not work if you're not saving the capture to a) ring buffer does not work if you're not saving the capture to
a file; a file;
@ -1520,12 +1322,12 @@ main(int argc, char *argv[])
else if (capture_opts.snaplen < MIN_PACKET_SIZE) else if (capture_opts.snaplen < MIN_PACKET_SIZE)
capture_opts.snaplen = MIN_PACKET_SIZE; capture_opts.snaplen = MIN_PACKET_SIZE;
/* Check the value range of the ringbuffer_num_files parameter */ /* Check the value range of the ring_num_files parameter */
if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES) if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES; capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
#if RINGBUFFER_MIN_NUM_FILES > 0 #if RINGBUFFER_MIN_NUM_FILES > 0
else if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES) else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES; capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
#endif #endif
#endif #endif
@ -1694,7 +1496,7 @@ main(int argc, char *argv[])
capture(save_file, out_file_type); capture(save_file, out_file_type);
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
ringbuf_free(); ringbuf_free();
} }
#else #else
@ -1909,9 +1711,9 @@ capture(char *save_file, int out_file_type)
goto error; goto error;
} }
ld.save_file = save_file; ld.save_file = save_file;
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
save_file_fd = ringbuf_init(save_file, save_file_fd = ringbuf_init(save_file,
capture_opts.ringbuffer_num_files); capture_opts.ring_num_files);
if (save_file_fd != -1) { if (save_file_fd != -1) {
ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype, ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
file_snaplen, &err); file_snaplen, &err);
@ -1972,9 +1774,9 @@ capture(char *save_file, int out_file_type)
cnd_stop_timeout = cnd_new((const char*)CND_CLASS_TIMEOUT, cnd_stop_timeout = cnd_new((const char*)CND_CLASS_TIMEOUT,
(gint32)capture_opts.autostop_duration); (gint32)capture_opts.autostop_duration);
if (capture_opts.ringbuffer_on && capture_opts.has_ring_duration) if (capture_opts.multi_files_on && capture_opts.has_file_duration)
cnd_ring_timeout = cnd_new(CND_CLASS_TIMEOUT, cnd_ring_timeout = cnd_new(CND_CLASS_TIMEOUT,
capture_opts.ringbuffer_duration); capture_opts.file_duration);
if (!setjmp(ld.stopenv)) { if (!setjmp(ld.stopenv)) {
ld.go = TRUE; ld.go = TRUE;
@ -2025,15 +1827,15 @@ capture(char *save_file, int out_file_type)
reading the FIFO sees the packets immediately and doesn't get reading the FIFO sees the packets immediately and doesn't get
any partial packet, forcing it to block in the middle of reading any partial packet, forcing it to block in the middle of reading
that packet. */ that packet. */
if (capture_opts.autostop_count == 0) if (capture_opts.autostop_packets == 0)
pcap_cnt = -1; pcap_cnt = -1;
else { else {
if (ld.packet_count >= capture_opts.autostop_count) { if (ld.packet_count >= capture_opts.autostop_packets) {
/* XXX do we need this test here? */ /* XXX do we need this test here? */
/* It appears there's nothing more to capture. */ /* It appears there's nothing more to capture. */
break; break;
} }
pcap_cnt = capture_opts.autostop_count - ld.packet_count; pcap_cnt = capture_opts.autostop_packets - ld.packet_count;
} }
} else { } else {
/* We need to check the capture file size or the timeout after /* We need to check the capture file size or the timeout after
@ -2055,8 +1857,8 @@ capture(char *save_file, int out_file_type)
/* The specified capture time has elapsed; stop the capture. */ /* The specified capture time has elapsed; stop the capture. */
ld.go = FALSE; ld.go = FALSE;
} else if (inpkts > 0) { } else if (inpkts > 0) {
if (capture_opts.autostop_count != 0 && if (capture_opts.autostop_packets != 0 &&
ld.packet_count >= capture_opts.autostop_count) { ld.packet_count >= capture_opts.autostop_packets) {
/* The specified number of packets have been captured and have /* The specified number of packets have been captured and have
passed both any capture filter in effect and any read filter passed both any capture filter in effect and any read filter
in effect. */ in effect. */
@ -2066,7 +1868,7 @@ capture(char *save_file, int out_file_type)
(guint32)wtap_get_bytes_dumped(ld.pdh))) { (guint32)wtap_get_bytes_dumped(ld.pdh))) {
/* We're saving the capture to a file, and the capture file reached /* We're saving the capture to a file, and the capture file reached
its maximum size. */ its maximum size. */
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
/* Switch to the next ringbuffer file */ /* Switch to the next ringbuffer file */
if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) { if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) {
/* File switch succeeded: reset the condition */ /* File switch succeeded: reset the condition */
@ -2135,7 +1937,7 @@ capture(char *save_file, int out_file_type)
if (save_file != NULL) { if (save_file != NULL) {
/* We're saving to a file or files; close all files. */ /* We're saving to a file or files; close all files. */
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
dump_ok = ringbuf_wtap_dump_close(&save_file, &err); dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
} else { } else {
dump_ok = wtap_dump_close(ld.pdh, &err); dump_ok = wtap_dump_close(ld.pdh, &err);
@ -2172,7 +1974,7 @@ capture(char *save_file, int out_file_type)
return TRUE; return TRUE;
error: error:
if (capture_opts.ringbuffer_on) { if (capture_opts.multi_files_on) {
ringbuf_error_cleanup(); ringbuf_error_cleanup();
} }
g_free(save_file); g_free(save_file);