forked from osmocom/wireshark
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:
parent
a25fd8d7ca
commit
d643a55488
|
@ -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
272
capture.c
|
@ -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
|
||||||
|
|
|
@ -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 */
|
|
@ -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. */
|
||||||
|
|
274
tethereal.c
274
tethereal.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue