*
* $Id$
*
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
#include <string.h>
#include <ctype.h>
-#include <pcap.h>
-
#include <glib.h>
#include <epan/packet.h>
#include "cmdarg_err.h"
#include "capture-pcap-util.h"
-#include "capture_ui_utils.h"
#include <wiretap/file_util.h>
-static gboolean capture_opts_output_to_pipe(const char *save_file);
+static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe);
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->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 */
+ infinite, in effect */
capture_opts->promisc_mode = TRUE; /* promiscuous mode is the default */
capture_opts->linktype = -1; /* the default linktype */
+ capture_opts->saving_to_file = FALSE;
capture_opts->save_file = NULL;
capture_opts->real_time_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->fork_child = -1; /* invalid process handle */
#ifdef _WIN32
- capture_opts->signal_pipe_fd = -1;
+ capture_opts->signal_pipe_write_fd = -1;
#endif
capture_opts->state = CAPTURE_STOPPED;
capture_opts->output_to_pipe = FALSE;
g_log(log_domain, log_level, "SnapLen (%u): %u", capture_opts->has_snaplen, capture_opts->snaplen);
g_log(log_domain, log_level, "Promisc : %u", capture_opts->promisc_mode);
g_log(log_domain, log_level, "LinkType : %d", capture_opts->linktype);
+ g_log(log_domain, log_level, "SavingToFile : %u", capture_opts->saving_to_file);
g_log(log_domain, log_level, "SaveFile : %s", (capture_opts->save_file) ? capture_opts->save_file : "");
g_log(log_domain, log_level, "RealTimeMode : %u", capture_opts->real_time_mode);
g_log(log_domain, log_level, "ShowInfo : %u", capture_opts->show_info);
g_log(log_domain, log_level, "ForkChild : %d", capture_opts->fork_child);
#ifdef _WIN32
- g_log(log_domain, log_level, "SignalPipeFd : %d", capture_opts->signal_pipe_fd);
+ g_log(log_domain, log_level, "SignalPipeWrite : %d", capture_opts->signal_pipe_write_fd);
#endif
}
colonp = strchr(arg, ':');
if (colonp == NULL)
- return TRUE;
+ return FALSE;
p = colonp;
*p++ = '\0';
capture_opts->file_duration = get_positive_int(p, "ring buffer duration");
}
- *colonp = ':'; /* put the colon back */
+ *colonp = ':'; /* put the colon back */
return TRUE;
}
-#ifdef _WIN32
-/*
- * Given a string of the form "<pipe name>:<file descriptor>", as might appear
- * as an argument to a "-Z" option, parse it and set the arguments in
- * question. Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_pipe_arguments(capture_options *capture_opts, const char *arg)
-{
- gchar *p = NULL, *colonp;
- int pipe_fd;
-
-
- colonp = strchr(arg, ':');
- if (colonp == NULL)
- return TRUE;
-
- 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(arg,"sync") == 0) {
- /* associate stdout with sync pipe */
- pipe_fd = get_natural_int(p, "sync pipe file descriptor");
- if (dup2(pipe_fd, 1) < 0) {
- cmdarg_err("Unable to dup sync pipe handle");
- return FALSE;
- }
- } else if (strcmp(arg,"signal") == 0) {
- /* associate stdin with signal pipe */
- pipe_fd = get_natural_int(p, "signal pipe file descriptor");
- if (dup2(pipe_fd, 0) < 0) {
- cmdarg_err("Unable to dup signal pipe handle");
- return FALSE;
- }
- capture_opts->signal_pipe_fd = pipe_fd;
- }
-
- *colonp = ':'; /* put the colon back */
- return TRUE;
-}
-#endif
-
-
-void
+static int
capture_opts_add_iface_opt(capture_options *capture_opts, const char *optarg)
{
long adapter_index;
GList *if_list;
if_info_t *if_info;
int err;
- gchar err_str[PCAP_ERRBUF_SIZE];
+ gchar err_str[CAPTURE_PCAP_ERRBUF_SIZE];
gchar *cant_get_if_list_errstr;
/*
* If the argument is a number, treat it as an index into the list
- * of adapters, as printed by "tethereal -D".
+ * of adapters, as printed by "tshark -D".
*
* This should be OK on UNIX systems, as interfaces shouldn't have
* names that begin with digits. It can be useful on Windows, where
if (p != NULL && *p == '\0') {
if (adapter_index < 0) {
cmdarg_err("The specified adapter index is a negative number");
- exit(1);
+ return 1;
}
if (adapter_index > INT_MAX) {
cmdarg_err("The specified adapter index is too large (greater than %d)",
INT_MAX);
- exit(1);
+ return 1;
}
if (adapter_index == 0) {
cmdarg_err("there is no interface with that adapter index");
- exit(1);
+ return 1;
}
if_list = get_interface_list(&err, err_str);
if (if_list == NULL) {
cmdarg_err("There are no interfaces on which a capture can be done");
break;
}
- exit(2);
+ return 2;
}
if_info = g_list_nth_data(if_list, adapter_index - 1);
if (if_info == NULL) {
cmdarg_err("there is no interface with that adapter index");
- exit(1);
+ return 1;
}
capture_opts->iface = g_strdup(if_info->name);
free_interface_list(if_list);
} else {
capture_opts->iface = g_strdup(optarg);
}
+
+ return 0;
}
-void
+int
capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg, gboolean *start_capture)
{
+ int status;
+
switch(opt) {
case 'a': /* autostop criteria */
if (set_autostop_criterion(capture_opts, optarg) == FALSE) {
cmdarg_err("Invalid or unknown -a flag \"%s\"", optarg);
- exit(1);
+ return 1;
}
break;
case 'b': /* Ringbuffer option */
capture_opts->multi_files_on = TRUE;
if (get_ring_arguments(capture_opts, optarg) == FALSE) {
cmdarg_err("Invalid or unknown -b arg \"%s\"", optarg);
- exit(1);
+ return 1;
}
break;
#ifdef _WIN32
capture_opts->buffer_size = get_positive_int(optarg, "buffer size");
break;
#endif
- case 'c': /* Capture xxx packets */
+ case 'c': /* Capture n packets */
capture_opts->has_autostop_packets = TRUE;
capture_opts->autostop_packets = get_positive_int(optarg, "packet count");
break;
case 'H': /* Hide capture info dialog box */
capture_opts->show_info = FALSE;
break;
- case 'i': /* Use interface xxx */
- capture_opts_add_iface_opt(capture_opts, optarg);
+ case 'i': /* Use interface x */
+ status = capture_opts_add_iface_opt(capture_opts, optarg);
+ if(status != 0) {
+ return status;
+ }
break;
case 'k': /* Start capture immediately */
*start_capture = TRUE;
case 'S': /* "Real-Time" mode: used for following file ala tail -f */
capture_opts->real_time_mode = TRUE;
break;
- case 'w': /* Write to capture file xxx */
+ case 'w': /* Write to capture file x */
+ capture_opts->saving_to_file = TRUE;
#if defined _WIN32 && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
/* since GLib 2.6, we need to convert filenames to utf8 for Win32 */
capture_opts->save_file = g_locale_to_utf8(optarg, -1, NULL, NULL, NULL);
#else
capture_opts->save_file = g_strdup(optarg);
#endif
- capture_opts->output_to_pipe = capture_opts_output_to_pipe(capture_opts->save_file);
- break;
+ status = capture_opts_output_to_pipe(capture_opts->save_file, &capture_opts->output_to_pipe);
+ return status;
+ 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);
+ capture_opts->linktype = linktype_name_to_val(optarg);
if (capture_opts->linktype == -1) {
cmdarg_err("The specified data link type \"%s\" isn't valid",
optarg);
- exit(1);
+ return 1;
}
#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
- /* XXX - just treat it as a number */
+ /* we can't get the type name, 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 */
- if (get_pipe_arguments(capture_opts, optarg) == FALSE) {
- cmdarg_err("Invalid or unknown -Z flag \"%s\"", optarg);
- exit(1);
- }
- break;
-#endif /* _WIN32 */
default:
/* the caller is responsible to send us only the right opt's */
g_assert_not_reached();
}
+
+ return 0;
}
-void capture_opts_list_link_layer_types(capture_options *capture_opts)
+int capture_opts_list_link_layer_types(capture_options *capture_opts)
{
- gchar err_str[PCAP_ERRBUF_SIZE];
+ gchar err_str[CAPTURE_PCAP_ERRBUF_SIZE];
GList *lt_list, *lt_entry;
data_link_info_t *data_link_info;
lt_list = get_pcap_linktype_list(capture_opts->iface, err_str);
if (lt_list == NULL) {
if (err_str[0] != '\0') {
- cmdarg_err("The list of data link types for the capture device could not be obtained (%s)."
- "Please check to make sure you have sufficient permissions, and that\n"
- "you have the proper interface or pipe specified.\n", err_str);
+ cmdarg_err("The list of data link types for the capture device \"%s\" could not be obtained (%s)."
+ "Please check to make sure you have sufficient permissions, and that\n"
+ "you have the proper interface or pipe specified.\n", capture_opts->iface, err_str);
} else
- cmdarg_err("The capture device has no data link types.");
- exit(2);
+ cmdarg_err("The capture device \"%s\" has no data link types.", capture_opts->iface);
+ return 2;
}
cmdarg_err_cont("Data link types (use option -y to set):");
for (lt_entry = lt_list; lt_entry != NULL;
data_link_info = lt_entry->data;
cmdarg_err_cont(" %s", data_link_info->name);
if (data_link_info->description != NULL)
- cmdarg_err_cont(" (%s)", data_link_info->description);
+ cmdarg_err_cont(" (%s)", data_link_info->description);
else
- cmdarg_err_cont(" (not supported)");
+ cmdarg_err_cont(" (not supported)");
putchar('\n');
}
free_pcap_linktype_list(lt_list);
+
+ return 0;
}
-void capture_opts_list_interfaces()
+int capture_opts_list_interfaces()
{
GList *if_list;
GList *if_entry;
if_info_t *if_info;
int err;
- gchar err_str[PCAP_ERRBUF_SIZE];
+ gchar err_str[CAPTURE_PCAP_ERRBUF_SIZE];
gchar *cant_get_if_list_errstr;
int i;
+#if 0
+ GSList *ip_addr;
+ if_addr_t *if_addr;
+ guint8 ipv4[4];
+#endif
if_list = get_interface_list(&err, err_str);
cmdarg_err("There are no interfaces on which a capture can be done");
break;
}
- exit(2);
+ return 2;
}
i = 1; /* Interface id number */
printf("%d. %s", i++, if_info->name);
if (if_info->description != NULL)
printf(" (%s)", if_info->description);
+#if 0
+ for(ip_addr = g_slist_nth(if_info->ip_addr, 0); ip_addr != NULL;
+ ip_addr = g_slist_next(ip_addr)) {
+ if_addr = ip_addr->data;
+ switch(if_addr->type) {
+ case AT_IPv4:
+ memcpy(ipv4, (void *) &if_addr->ip_addr.ip4_addr, 4);
+ printf(" %u.%u.%u.%u", ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
+ break;
+ case AT_IPv6:
+ /* XXX - display the IPv6 address without using stuff from epan */
+ printf(" XXX-IPv6");
+ break;
+ default:
+ printf(" unknown address type %u", if_addr->type);
+ }
+ }
+#endif
+
printf("\n");
}
free_interface_list(if_list);
+
+ return 0;
}
GList *if_list;
if_info_t *if_info;
int err;
- gchar err_str[PCAP_ERRBUF_SIZE];
+ gchar err_str[CAPTURE_PCAP_ERRBUF_SIZE];
gchar *cant_get_if_list_errstr;
return 0;
}
-static gboolean capture_opts_output_to_pipe(const char *save_file)
+static gboolean capture_opts_output_to_pipe(const char *save_file, gboolean *is_pipe)
{
int err;
silly to do "-w - >output_file" rather than "-w output_file",
but by not checking we might be violating the Principle Of
Least Astonishment. */
- return TRUE;
+ *is_pipe = TRUE;
} else {
/* not a capture file, test for a FIFO (aka named pipe) */
err = capture_opts_test_for_fifo(save_file);
break;
case ESPIPE: /* it is a FIFO */
- return TRUE;
+ *is_pipe = TRUE;
break;
default: /* couldn't stat it */
cmdarg_err("Error testing whether capture file is a pipe: %s",
strerror(errno));
- exit(2);
+ return 2;
}
}
}
- return FALSE;
+ *is_pipe = FALSE;
+
+ return 0;
}
#endif /* HAVE_LIBPCAP */