/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.124 2000/09/14 22:59:00 grahamb Exp $
+ * $Id: capture.c,v 1.125 2000/09/15 05:32:18 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#include "packet-raw.h"
#include "packet-tr.h"
+int promisc_mode = TRUE; /* capture in promiscuous mode */
int sync_mode; /* fork a child to do the capture, and sync between them */
static int sync_pipe[2]; /* used to sync father */
enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
int child_process;
#endif
+/* Add a string pointer to a NULL-terminated array of string pointers. */
+static char **
+add_arg(char **args, int *argc, char *arg)
+{
+ /* Grow the array; "*argc" currently contains the number of string
+ pointers, *not* counting the NULL pointer at the end, so we have
+ to add 2 in order to get the new size of the array, including the
+ new pointer and the terminating NULL pointer. */
+ args = g_realloc(args, (*argc + 2) * sizeof (char *));
+
+ /* Stuff the pointer into the penultimate element of the array, which
+ is the one at the index specified by "*argc". */
+ args[*argc] = arg;
+
+ /* Now bump the count. */
+ (*argc)++;
+
+ /* We overwrite the NULL pointer; put it back right after the
+ element we added. */
+ args[*argc] = NULL;
+
+ return args;
+}
+
+#ifdef _WIN32
+/* Given a string, return a pointer to a quote-encapsulated version of
+ the string, so we can pass it as an argument with "spawnvp" even
+ if it contains blanks. */
+char *
+quote_encapsulate(const char *string)
+{
+ char *encapsulated_string;
+
+ encapsulated_string = g_new(char, strlen(string) + 3);
+ sprintf(encapsulated_string, "\"%s\"", string);
+ return encapsulated_string;
+}
+#endif
+
/* Open a specified file, or create a temporary file, and start a capture
to the file in question. */
void
char save_file_fd[24];
char errmsg[1024+1];
int error;
+ int argc;
+ char **argv;
#ifdef _WIN32
char sync_pipe_fd[24];
+ char *fontstring;
char *filterstring;
#endif
- sprintf(ssnap,"%d",cfile.snap); /* in lieu of itoa */
+ /* Allocate the string pointer array with enough space for the
+ terminating NULL pointer. */
+ argc = 0;
+ argv = g_malloc(sizeof (char *));
+ *argv = NULL;
+
+ /* Now add those arguments used on all platforms. */
+ argv = add_arg(argv, &argc, CHILD_NAME);
+
+ argv = add_arg(argv, &argc, "-i");
+ argv = add_arg(argv, &argc, cfile.iface);
+
+ argv = add_arg(argv, &argc, "-w");
+ argv = add_arg(argv, &argc, cfile.save_file);
+
+ argv = add_arg(argv, &argc, "-W");
+ sprintf(save_file_fd,"%d",cfile.save_file_fd); /* in lieu of itoa */
+ argv = add_arg(argv, &argc, save_file_fd);
+
+ argv = add_arg(argv, &argc, "-c");
sprintf(scount,"%d",cfile.count);
- sprintf(save_file_fd,"%d",cfile.save_file_fd);
+ argv = add_arg(argv, &argc, scount);
+
+ argv = add_arg(argv, &argc, "-s");
+ sprintf(ssnap,"%d",cfile.snap);
+ argv = add_arg(argv, &argc, ssnap);
+
+ if (!promisc_mode)
+ argv = add_arg(argv, &argc, "-p");
#ifdef _WIN32
/* Create a pipe for the child process */
return;
}
+ /* Convert font name to a quote-encapsulated string and pass to child */
+ argv = add_arg(argv, &argc, "-m");
+ fontstring = quote_encapsulate(prefs.gui_font_name);
+ argv = add_arg(argv, &argc, fontstring);
+
/* Convert pipe write handle to a string and pass to child */
+ argv = add_arg(argv, &argc, "-Z");
itoa(sync_pipe[WRITE], sync_pipe_fd, 10);
- /* Convert filter string to a quote delimited string */
- filterstring = g_new(char, strlen(cfile.cfilter) + 3);
- sprintf(filterstring, "\"%s\"", cfile.cfilter);
- filterstring[strlen(cfile.cfilter) + 2] = 0;
+ argv = add_arg(argv, &argc, sync_pipe_fd);
+
+ /* Convert filter string to a quote delimited string and pass to child */
+ if (cfile.cfilter != NULL && strlen(cfile.cfilter) != 0) {
+ argv = add_arg(argv, &argc, "-f");
+ filterstring = quote_encapsulate(cfile.cfilter);
+ argv = add_arg(argv, &argc, filterstring);
+ }
+
/* Spawn process */
- fork_child = spawnlp(_P_NOWAIT, ethereal_path, CHILD_NAME, "-i", cfile.iface,
- "-w", cfile.save_file, "-W", save_file_fd,
- "-c", scount, "-s", ssnap,
- "-Z", sync_pipe_fd,
- strlen(cfile.cfilter) == 0 ? (const char *)NULL : "-f",
- strlen(cfile.cfilter) == 0 ? (const char *)NULL : filterstring,
- (const char *)NULL);
+ fork_child = spawnvp(_P_NOWAIT, ethereal_path, argv);
+ g_free(fontstring);
g_free(filterstring);
/* Keep a copy for later evaluation by _cwait() */
child_process = fork_child;
strerror(error));
return;
}
+
+ argv = add_arg(argv, &argc, "-m");
+ argv = add_arg(argv, &argc, prefs.gui_font_name);
+
+ if (cfile.cfilter != NULL && strlen(cfile.cfilter) != 0) {
+ argv = add_arg(argv, &argc, "-f");
+ argv = add_arg(argv, &argc, cfile.cfilter);
+ }
+
if ((fork_child = fork()) == 0) {
/*
* Child process - run Ethereal with the right arguments to make
close(1);
dup(sync_pipe[WRITE]);
close(sync_pipe[READ]);
- execlp(ethereal_path, CHILD_NAME, "-i", cfile.iface,
- "-w", cfile.save_file, "-W", save_file_fd,
- "-c", scount, "-s", ssnap,
- "-m", prefs.gui_font_name,
- (cfile.cfilter == NULL)? 0 : "-f",
- (cfile.cfilter == NULL)? 0 : cfile.cfilter,
- (const char *)NULL);
+ execvp(ethereal_path, argv);
snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
ethereal_path, strerror(errno));
send_errmsg_to_parent(errmsg);
/* Parent process - read messages from the child process over the
sync pipe. */
+ g_free(argv); /* free up arg array */
/* Close the write side of the pipe, so that only the child has it
open, and thus it completely closes, and thus returns to us
ld.pdh = NULL;
/* Open the network interface to capture from it. */
- pch = pcap_open_live(cfile.iface, cfile.snap, 1, CAP_READ_TIMEOUT, err_str);
+ pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode,
+ CAP_READ_TIMEOUT, err_str);
if (pch == NULL) {
#ifdef _WIN32
/* capture.h
* Definitions for packet capture windows
*
- * $Id: capture.h,v 1.22 2000/01/05 22:31:37 gerald Exp $
+ * $Id: capture.h,v 1.23 2000/09/15 05:32:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
/* Name we give to the child process when doing a "-S" capture. */
#define CHILD_NAME "ethereal-capture"
+extern int promisc_mode; /* capture in promiscuous mode */
extern int sync_mode; /* fork a child to do the capture, and sync between them */
extern int sync_pipe[2]; /* used to sync father */
extern int quit_after_cap; /* Makes a "capture only mode". Implies -k */
S<[ B<-m> font ]>
S<[ B<-n> ]>
S<[ B<-o> preference setting ] ...>
+S<[ B<-p> ]>
S<[ B<-P> packet list height ]>
S<[ B<-Q> ]>
S<[ B<-r> infile ]>
preference (which is the same name that would appear in the preference
file), and I<value> is the value to which it should be set.
+=item -p
+
+I<Don't> put the interface into promiscuous mode. Note that the
+interface might be in promiscuous mode for some other reason; hence,
+B<-p> cannot be used to ensure that the only traffic that is captured is
+traffic sent to or from the machine on which B<Ethereal> is running,
+broadcast traffic, and multicast traffic to addresses received by that
+machine.
+
=item -P
Sets the initial height of the packet list (top) pane.
capturing live packet data.
The I<Interface:> combo box lets you specify the interface from which to
-capture packet data, or the name of a FIFO from which to get the packet data.
-The I<Count:> entry specifies the number of packets to capture. Entering 0
-will capture packets indefinitely. The I<Filter:> entry lets you specify the
-capture filter using a tcpdump-style filter string as described above. The
-I<File:> entry specifies the file to save to, as in the I<Printer Options>
-dialog above. You can specify the maximum number of bytes to capture per
-packet with the I<Capture length> entry, can specify that the display should be
-updated as packets are captured with the I<Update list of packets in real time>
-check box, can specify whether in such a capture the packet list pane should
-scroll to show the most recently captured packets with the I<Automatic
-scrolling in live capture> check box, and can specify whether addresses should
-be translated to names in the display with the I<Enable name resolution> check
-box.
+capture packet data, or the name of a FIFO from which to get the packet
+data. The I<Count:> entry specifies the number of packets to capture.
+Entering 0 will capture packets indefinitely. The I<Filter:> entry lets
+you specify the capture filter using a tcpdump-style filter string as
+described above. The I<File:> entry specifies the file to save to, as
+in the I<Printer Options> dialog above. You can specify the maximum
+number of bytes to capture per packet with the I<Capture length> entry,
+can specify whether the interface is to be put in promiscuous mode or
+not with the I<Capture packets in promiscuous mode> check box, can
+specify that the display should be updated as packets are captured with
+the I<Update list of packets in real time> check box, can specify
+whether in such a capture the packet list pane should scroll to show the
+most recently captured packets with the I<Automatic scrolling in live
+capture> check box, and can specify whether addresses should be
+translated to names in the display with the I<Enable name resolution>
+check box.
=item Display Options
S<[ B<-i> interface ]>
S<[ B<-n> ]>
S<[ B<-o> preference setting ] ...>
+S<[ B<-p> ]>
S<[ B<-r> infile ]>
S<[ B<-R> filter expression ]>
S<[ B<-s> snaplen ]>
preference (which is the same name that would appear in the preference
file), and I<value> is the value to which it should be set.
+=item -p
+
+I<Don't> put the interface into promiscuous mode. Note that the
+interface might be in promiscuous mode for some other reason; hence,
+B<-p> cannot be used to ensure that the only traffic that is captured is
+traffic sent to or from the machine on which B<Tethereal> is running,
+broadcast traffic, and multicast traffic to addresses received by that
+machine.
+
=item -r
Reads packet data from I<file>.
/* capture_dlg.c
* Routines for packet capture windows
*
- * $Id: capture_dlg.c,v 1.32 2000/08/23 20:55:44 deniel Exp $
+ * $Id: capture_dlg.c,v 1.33 2000/09/15 05:32:48 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
#define E_CAP_FILE_TE_KEY "cap_file_te"
#define E_CAP_COUNT_KEY "cap_count"
#define E_CAP_SNAP_KEY "cap_snap"
+#define E_CAP_PROMISC_KEY "cap_promisc"
#define E_CAP_SYNC_KEY "cap_sync"
#define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
#define E_CAP_RESOLVE_KEY "cap_resolve"
*file_bt, *file_te,
*caplen_hb, *table,
*bbox, *ok_bt, *cancel_bt, *snap_lb,
- *snap_sb, *sync_cb, *auto_scroll_cb, *resolv_cb;
+ *snap_sb, *promisc_cb, *sync_cb, *auto_scroll_cb, *resolv_cb;
GtkAccelGroup *accel_group;
GtkAdjustment *adj;
GList *if_list, *count_list = NULL;
gtk_box_pack_start (GTK_BOX(caplen_hb), snap_sb, FALSE, FALSE, 3);
gtk_widget_show(snap_sb);
+ promisc_cb = dlg_check_button_new_with_label_with_mnemonic(
+ "Capture packets in _promiscuous mode", accel_group);
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb), promisc_mode);
+ gtk_container_add(GTK_CONTAINER(main_vb), promisc_cb);
+ gtk_widget_show(promisc_cb);
+
sync_cb = dlg_check_button_new_with_label_with_mnemonic(
"_Update list of packets in real time", accel_group);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb), sync_mode);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY, file_te);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_KEY, count_cb);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_KEY, snap_sb);
+ gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_PROMISC_KEY, promisc_cb);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SYNC_KEY, sync_cb);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RESOLVE_KEY, resolv_cb);
static void
capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
- GtkWidget *if_cb, *filter_te, *file_te, *count_cb, *snap_sb, *sync_cb,
- *auto_scroll_cb, *resolv_cb;
+ GtkWidget *if_cb, *filter_te, *file_te, *count_cb, *snap_sb, *promisc_cb,
+ *sync_cb, *auto_scroll_cb, *resolv_cb;
gchar *if_text;
gchar *if_name;
gchar *filter_text;
file_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILE_TE_KEY);
count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_KEY);
snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_KEY);
+ promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_PROMISC_KEY);
sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RESOLVE_KEY);
else if (cfile.snap < MIN_PACKET_SIZE)
cfile.snap = MIN_PACKET_SIZE;
+ promisc_mode = GTK_TOGGLE_BUTTON (promisc_cb)->active;
+
sync_mode = GTK_TOGGLE_BUTTON (sync_cb)->active;
auto_scroll_live = GTK_TOGGLE_BUTTON (auto_scroll_cb)->active;
/* main.c
*
- * $Id: main.c,v 1.157 2000/09/14 22:59:08 grahamb Exp $
+ * $Id: main.c,v 1.158 2000/09/15 05:32:49 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled with %s\n",
comp_info_str);
#ifdef HAVE_LIBPCAP
- fprintf(stderr, "%s [ -vh ] [ -kQS ] [ -B <byte view height> ] [ -c count ]\n",
+ fprintf(stderr, "%s [ -vh ] [ -kpQS ] [ -B <byte view height> ] [ -c count ]\n",
PACKAGE);
fprintf(stderr, "\t[ -f <capture filter> ] [ -i interface ] [ -m <medium font> ] \n");
fprintf(stderr, "\t[ -n ] [ -o <preference setting> ] ... [ -P <packet list height> ]\n");
);
/* Now get our args */
- while ((opt = getopt(argc, argv, "B:c:Df:hi:km:no:P:Qr:R:Ss:t:T:w:W:vZ:")) != EOF) {
+ while ((opt = getopt(argc, argv, "B:c:Df:hi:km:no:pP:Qr:R:Ss:t:T:w:W:vZ:")) != EOF) {
switch (opt) {
case 'B': /* Byte view pane height */
bv_size = atoi(optarg);
break;
}
break;
+ case 'p': /* Don't capture in promiscuous mode */
+#ifdef HAVE_LIBPCAP
+ promisc_mode = 0;
+#else
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
+#endif
+ break;
case 'P': /* Packet list pane height */
pl_size = atoi(optarg);
break;
/* tethereal.c
*
- * $Id: tethereal.c,v 1.45 2000/09/10 06:44:37 guy Exp $
+ * $Id: tethereal.c,v 1.46 2000/09/15 05:32:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
FILE *data_out_file = NULL;
guint main_ctx, file_ctx;
ts_type timestamp_type = RELATIVE;
+static int promisc_mode = TRUE;
static void
print_usage(void)
fprintf(stderr, "This is GNU t%s %s, compiled with %s\n", PACKAGE,
VERSION, comp_info_str);
#ifdef HAVE_LIBPCAP
- fprintf(stderr, "t%s [ -vVh ] [ -c count ] [ -f <capture filter> ]\n", PACKAGE);
+ fprintf(stderr, "t%s [ -vVhp ] [ -c count ] [ -f <capture filter> ]\n", PACKAGE);
fprintf(stderr, "\t[ -F <capture file type> ] [ -i interface ] [ -n ]\n");
fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
);
/* Now get our args */
- while ((opt = getopt(argc, argv, "c:Df:F:hi:no:r:R:s:t:vw:Vx")) != EOF) {
+ while ((opt = getopt(argc, argv, "c:Df:F:hi:no:pr:R:s:t:vw:Vx")) != EOF) {
switch (opt) {
case 'c': /* Capture xxx packets */
#ifdef HAVE_LIBPCAP
break;
}
break;
+ case 'p': /* Don't capture in promiscuous mode */
+#ifdef HAVE_LIBPCAP
+ promisc_mode = 0;
+#else
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
+#endif
+ break;
case 'r': /* Read capture file xxx */
cf_name = g_strdup(optarg);
break;
ld.pdh = NULL;
/* Open the network interface to capture from it. */
- ld.pch = pcap_open_live(cfile.iface, cfile.snap, 1, 1000, err_str);
+ ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000, err_str);
if (ld.pch == NULL) {
/* Well, we couldn't start the capture. */