summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>1999-09-23 06:27:27 +0000
committerGuy Harris <guy@alum.mit.edu>1999-09-23 06:27:27 +0000
commit12d3278d0b23873b407621268b549f9161eee419 (patch)
tree8a390a7bbfd89ee2b55f021006fe10ffa98ff393
parent560e64cb7308d8a509bbfa05140e8213cdce9fb5 (diff)
downloadwireshark-12d3278d0b23873b407621268b549f9161eee419.tar.gz
Move the toolkit-independent code to create a temporary capture file,
and to fork off and run a separate copy of "ethereal" for "-S" and "-F" captures or just call "capture()" otherwise, out of "gtk/capture_dlg.c" and into a routine in "capture.c". If the attempt to create said temporary capture file fails, pop up a dialog box and don't do the capture. Have the child capture process send a message upstream after it either successfully starts the capture and syncs out the header of the capture file, or fails to start the capture; the message indicates whether it succeeded or failed, and, if it failed, includes a failure message. This: avoids the use of a signal, and thus means we don't have to worry about whether to capture the signal, or whether to start or stop capturing depending on whether this particular capture is in sync mode or not; lets us pop up the message box for the error in the parent process if we're in sync mode, rather than doing it in the child, which didn't work well. Add a check button to the Capture/Start dialog box, so that we can control, for each capture, whether it's to be done in sync mode or not. svn path=/trunk/; revision=708
-rw-r--r--capture.c596
-rw-r--r--capture.h3
-rw-r--r--globals.h3
-rw-r--r--gtk/capture_dlg.c113
-rw-r--r--gtk/main.c16
5 files changed, 404 insertions, 327 deletions
diff --git a/capture.c b/capture.c
index 9ad3996107..79e8282c7f 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.67 1999/09/11 06:23:22 guy Exp $
+ * $Id: capture.c,v 1.68 1999/09/23 06:27:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -41,6 +41,7 @@
#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
+#include <ctype.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
@@ -97,7 +98,141 @@ typedef struct _loop_data {
} loop_data;
void
-capture(void) {
+do_capture(void)
+{
+ char tmpname[128+1];
+ char c;
+ int i;
+ guint byte_count;
+ char *msg;
+
+ /* Choose a random name for the capture buffer */
+ if (cf.save_file && !cf.user_saved) {
+ unlink(cf.save_file); /* silently ignore error */
+ g_free(cf.save_file);
+ }
+ cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
+ if (cf.save_file_fd == -1) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "The file to which the capture would be saved (\"%s\")"
+ "could not be opened: %s.", tmpname, strerror(errno));
+ return;
+ }
+ cf.save_file = g_strdup(tmpname);
+ cf.user_saved = 0;
+
+ if( fork_mode ){ /* use fork() for capture */
+ int fork_child;
+ char ssnap[24];
+ char scount[24]; /* need a constant for len of numbers */
+ char save_file_fd[24];
+ int err;
+
+ sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
+ sprintf(scount,"%d",cf.count);
+ sprintf(save_file_fd,"%d",cf.save_file_fd);
+ signal(SIGCHLD, SIG_IGN);
+ if (sync_mode) pipe(sync_pipe);
+ if((fork_child = fork()) == 0){
+ /* args: -k -- capture
+ * -i interface specification
+ * -w file to write
+ * -W file descriptor to write
+ * -c count to capture
+ * -Q quit after capture (forces -k)
+ * -s snaplen
+ * -S sync mode
+ * -m / -b fonts
+ * -f "filter expression"
+ */
+ if (sync_mode) {
+ close(1);
+ dup(sync_pipe[1]);
+ close(sync_pipe[0]);
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
+ "-c", scount, "-s", ssnap, "-S",
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
+ }
+ else {
+ execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
+ "-w", cf.save_file, "-W", save_file_fd,
+ "-c", scount, "-s", ssnap,
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f",
+ (cf.cfilter == NULL)? 0 : cf.cfilter,
+ (const char *)NULL);
+ }
+ }
+ else {
+ cf.filename = cf.save_file;
+ if (sync_mode) {
+ close(sync_pipe[1]);
+
+ /* Read a byte count from "sync_pipe[0]", terminated with a
+ colon; if the count is 0, the child process created the
+ capture file and we should start reading from it, otherwise
+ the capture couldn't start and the count is a count of bytes
+ of error message, and we should display the message. */
+ byte_count = 0;
+ for (;;) {
+ i = read(sync_pipe[0], &c, 1);
+ if (i == 0) {
+ /* EOF - the child process died.
+ XXX - reap it and report the status. */
+ simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
+ return;
+ }
+ if (c == ';')
+ break;
+ if (!isdigit(c)) {
+ /* Child process handed us crap. */
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process sent us a bad message");
+ return;
+ }
+ byte_count = byte_count*10 + c - '0';
+ }
+ if (byte_count == 0) {
+ /* Success. */
+ err = tail_cap_file(cf.save_file, &cf);
+ if (err != 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ file_open_error_message(err, FALSE), cf.save_file);
+ }
+ } else {
+ /* Failure. */
+ msg = g_malloc(byte_count + 1);
+ if (msg == NULL) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed, but its error message was too big.");
+ } else {
+ i = read(sync_pipe[0], msg, byte_count);
+ if (i < 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed: Error %s reading its error message.",
+ strerror(errno));
+ } else if (i == 0) {
+ simple_dialog(ESD_TYPE_WARN, NULL,
+ "Capture child process failed: EOF reading its error message.");
+ } else
+ simple_dialog(ESD_TYPE_WARN, NULL, msg);
+ g_free(msg);
+ }
+ }
+ }
+ }
+ }
+ else
+ capture();
+}
+
+void
+capture(void)
+{
GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb, *icmp_lb,
*ospf_lb, *gre_lb, *netbios_lb, *other_lb, *stop_bt;
pcap_t *pch;
@@ -106,8 +241,7 @@ capture(void) {
bpf_u_int32 netnum, netmask;
time_t upd_time, cur_time;
int err, inpkts;
- char *errmsg;
- char errmsg_errno[1024+1];
+ char errmsg[1024+1];
ld.go = TRUE;
ld.counts.total = 0;
@@ -127,250 +261,264 @@ capture(void) {
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_str);
- if (pch) {
- ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
- if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
- errmsg = "The network you're capturing from is of a type"
- " that Ethereal doesn't support.";
- goto fail;
+ if (pch == NULL) {
+ /* Well, we couldn't start the capture. */
+ if (!fork_mode) {
+ /* In fork mode, we shouldn't do any UI stuff until we pop up the
+ capture-progress window, and, since we couldn't start the
+ capture, we haven't popped it up. */
+ while (gtk_events_pending()) gtk_main_iteration();
+ }
+ snprintf(errmsg, sizeof errmsg,
+ "The capture session could not be initiated (%s).\n"
+ "Please check to make sure you have sufficient permissions, and that\n"
+ "you have the proper interface specified.", err_str);
+ goto fatal_error;
+ }
+
+ if (cf.cfilter) {
+ if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
+ snprintf(errmsg, sizeof errmsg,
+ "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
+ goto fatal_error;
+ }
+ if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
+ snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
+ pcap_geterr(pch));
+ goto fatal_error;
}
- ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
+ if (pcap_setfilter(pch, &cf.fcode) < 0) {
+ snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
+ pcap_geterr(pch));
+ goto fatal_error;
+ }
+ }
+
+ ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
+ if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
+ strcpy(errmsg, "The network you're capturing from is of a type"
+ " that Ethereal doesn't support.");
+ goto fatal_error;
+ }
+ ld.pdh = wtap_dump_fdopen(cf.save_file_fd, WTAP_FILE_PCAP,
ld.linktype, pcap_snapshot(pch), &err);
- if (ld.pdh == NULL) { /* We have an error */
+ if (ld.pdh == NULL) { /* We have an error */
+ switch (err) {
+
+ case WTAP_ERR_CANT_OPEN:
+ strcpy(errmsg, "The file to which the capture would be saved"
+ " couldn't be created for some unknown reason.");
+ break;
+
+ case WTAP_ERR_SHORT_WRITE:
+ strcpy(errmsg, "A full header couldn't be written to the file"
+ " to which the capture would be saved.");
+ break;
+
+ default:
+ if (err < 0) {
+ sprintf(errmsg, "The file to which the capture would be"
+ " saved (\"%s\") could not be opened: Error %d.",
+ cf.save_file, err);
+ } else {
+ sprintf(errmsg, "The file to which the capture would be"
+ " saved (\"%s\") could not be opened: %s.",
+ cf.save_file, strerror(err));
+ }
+ break;
+ }
+ goto fatal_error;
+ }
+
+ if (sync_mode) {
+ /* Sync out the capture file, so the header makes it to the file
+ system, and send a "capture started successfully and capture
+ file created" message to our parent so that they'll open the
+ capture file and update its windows to indicate that we have
+ a live capture in progress. */
+ fflush(wtap_dump_file(ld.pdh));
+ write(1, "0;", 2);
+ }
+
+ cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
+
+ /* Container for capture display widgets */
+ main_vb = gtk_vbox_new(FALSE, 1);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ count_lb = gtk_label_new("Count: 0");
+ gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
+ gtk_widget_show(count_lb);
+
+ tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(tcp_lb);
+
+ udp_lb = gtk_label_new("UDP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(udp_lb);
+
+ icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
+ gtk_widget_show(icmp_lb);
+
+ ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
+ gtk_widget_show(ospf_lb);
+
+ gre_lb = gtk_label_new("GRE: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
+ gtk_widget_show(gre_lb);
+
+ netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
+ gtk_widget_show(netbios_lb);
+
+ other_lb = gtk_label_new("Other: 0 (0.0%)");
+ gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
+ gtk_widget_show(other_lb);
+
+ stop_bt = gtk_button_new_with_label ("Stop");
+ gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
+ GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
+ gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
+ GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(stop_bt);
+ GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(stop_bt);
+ gtk_widget_show(stop_bt);
+
+ gtk_widget_show(cap_w);
+ gtk_grab_add(cap_w);
+
+ upd_time = time(NULL);
+ while (ld.go) {
+ while (gtk_events_pending()) gtk_main_iteration();
+ inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
+ if (inpkts > 0)
+ ld.sync_packets += inpkts;
+ /* Only update once a second so as not to overload slow displays */
+ cur_time = time(NULL);
+ if (cur_time > upd_time) {
+ upd_time = cur_time;
+
+ sprintf(label_str, "Count: %d", ld.counts.total);
+ gtk_label_set(GTK_LABEL(count_lb), label_str);
+
+ sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
+ pct(ld.counts.tcp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(tcp_lb), label_str);
+
+ sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
+ pct(ld.counts.udp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(udp_lb), label_str);
+
+ sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
+ pct(ld.counts.icmp, ld.counts.total));
+ gtk_label_set(GTK_LABEL(icmp_lb), label_str);
+
+ sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
+ pct(ld.counts.ospf, ld.counts.total));
+ gtk_label_set(GTK_LABEL(ospf_lb), label_str);
+
+ sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
+ pct(ld.counts.gre, ld.counts.total));
+ gtk_label_set(GTK_LABEL(gre_lb), label_str);
+
+ sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
+ pct(ld.counts.netbios, ld.counts.total));
+ gtk_label_set(GTK_LABEL(netbios_lb), label_str);
+
+ sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
+ pct(ld.counts.other, ld.counts.total));
+ gtk_label_set(GTK_LABEL(other_lb), label_str);
+
+ /* do sync here, too */
+ fflush(wtap_dump_file(ld.pdh));
+ if (sync_mode && ld.sync_packets) {
+ char tmp[20];
+ sprintf(tmp, "%d*", ld.sync_packets);
+ write(1, tmp, strlen(tmp));
+ ld.sync_packets = 0;
+ }
+ }
+ }
+
+ if (ld.pdh) {
+ if (!wtap_dump_close(ld.pdh, &err)) {
switch (err) {
- case WTAP_ERR_CANT_OPEN:
- errmsg = "The file to which the capture would be saved"
- " couldn't be created for some unknown reason.";
+ case WTAP_ERR_CANT_CLOSE:
+ strcpy(errmsg, "The file to which the capture was being saved"
+ " couldn't be closed for some unknown reason.");
break;
case WTAP_ERR_SHORT_WRITE:
- errmsg = "A full header couldn't be written to the file"
- " to which the capture would be saved.";
+ strcpy(errmsg, "Not all the data could be written to the file"
+ " to which the capture was being saved.");
break;
default:
if (err < 0) {
- sprintf(errmsg_errno, "The file to which the capture would be"
- " saved (\"%%s\") could not be opened: Error %d.",
- err);
+ sprintf(errmsg, "The file to which the capture was being"
+ " saved (\"%s\") could not be closed: Error %d.",
+ cf.save_file, err);
} else {
- sprintf(errmsg_errno, "The file to which the capture would be"
- " saved (\"%%s\") could not be opened: %s.",
- strerror(err));
+ sprintf(errmsg, "The file to which the capture was being"
+ " saved (\"%s\") could not be closed: %s.",
+ cf.save_file, strerror(err));
}
- errmsg = errmsg_errno;
break;
}
-fail:
- snprintf(err_str, PCAP_ERRBUF_SIZE, errmsg, cf.save_file);
- simple_dialog(ESD_TYPE_WARN, NULL, err_str);
- pcap_close(pch);
- return;
- }
-
- if (cf.cfilter) {
- if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- } else if (pcap_compile(pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL, "Unable to parse filter string (%s).",
- pcap_geterr(pch));
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- } else if (pcap_setfilter(pch, &cf.fcode) < 0) {
- simple_dialog(ESD_TYPE_WARN, NULL, "Can't install filter (%s).",
- pcap_geterr(pch));
- wtap_dump_close(ld.pdh, NULL);
- unlink(cf.save_file); /* silently ignore error */
- pcap_close(pch);
- return;
- }
- }
-
- if (sync_mode) {
- /* Sync out the capture file, so the header makes it to the file
- system, and signal our parent so that they'll open the capture
- file and update its windows to indicate that we have a live
- capture in progress. */
- fflush(wtap_dump_file(ld.pdh));
- kill(getppid(), SIGUSR2);
- }
-
- cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
-
- /* Container for capture display widgets */
- main_vb = gtk_vbox_new(FALSE, 1);
- gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
- gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
- gtk_widget_show(main_vb);
-
- count_lb = gtk_label_new("Count: 0");
- gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
- gtk_widget_show(count_lb);
-
- tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
- gtk_widget_show(tcp_lb);
-
- udp_lb = gtk_label_new("UDP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
- gtk_widget_show(udp_lb);
-
- icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
- gtk_widget_show(icmp_lb);
-
- ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
- gtk_widget_show(ospf_lb);
-
- gre_lb = gtk_label_new("GRE: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
- gtk_widget_show(gre_lb);
-
- netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
- gtk_widget_show(netbios_lb);
-
- other_lb = gtk_label_new("Other: 0 (0.0%)");
- gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
- gtk_widget_show(other_lb);
-
- stop_bt = gtk_button_new_with_label ("Stop");
- gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
- GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
- gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
- GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
- gtk_widget_grab_default(stop_bt);
- GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
- gtk_widget_grab_default(stop_bt);
- gtk_widget_show(stop_bt);
-
- gtk_widget_show(cap_w);
- gtk_grab_add(cap_w);
-
- upd_time = time(NULL);
- while (ld.go) {
- while (gtk_events_pending()) gtk_main_iteration();
- inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
- if (inpkts > 0)
- ld.sync_packets += inpkts;
- /* Only update once a second so as not to overload slow displays */
- cur_time = time(NULL);
- if (cur_time > upd_time) {
-
- upd_time = cur_time;
-
- sprintf(label_str, "Count: %d", ld.counts.total);
- gtk_label_set(GTK_LABEL(count_lb), label_str);
-
- sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
- pct(ld.counts.tcp, ld.counts.total));
- gtk_label_set(GTK_LABEL(tcp_lb), label_str);
-
- sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
- pct(ld.counts.udp, ld.counts.total));
- gtk_label_set(GTK_LABEL(udp_lb), label_str);
-
- sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
- pct(ld.counts.icmp, ld.counts.total));
- gtk_label_set(GTK_LABEL(icmp_lb), label_str);
-
- sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
- pct(ld.counts.ospf, ld.counts.total));
- gtk_label_set(GTK_LABEL(ospf_lb), label_str);
-
- sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
- pct(ld.counts.gre, ld.counts.total));
- gtk_label_set(GTK_LABEL(gre_lb), label_str);
-
- sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
- pct(ld.counts.netbios, ld.counts.total));
- gtk_label_set(GTK_LABEL(netbios_lb), label_str);
-
- sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
- pct(ld.counts.other, ld.counts.total));
- gtk_label_set(GTK_LABEL(other_lb), label_str);
-
- /* do sync here, too */
- fflush(wtap_dump_file(ld.pdh));
- if (sync_mode && ld.sync_packets) {
- char tmp[20];
- sprintf(tmp, "%d*", ld.sync_packets);
- write(1, tmp, strlen(tmp));
- ld.sync_packets = 0;
- }
- }
- }
-
- if (ld.pdh) {
- if (!wtap_dump_close(ld.pdh, &err)) {
- switch (err) {
-
- case WTAP_ERR_CANT_CLOSE:
- errmsg = "The file to which the capture was being saved"
- " couldn't be closed for some unknown reason.";
- break;
-
- case WTAP_ERR_SHORT_WRITE:
- errmsg = "Not all the data could be written to the file"
- " to which the capture was being saved.";
- break;
-
- default:
- if (err < 0) {
- sprintf(errmsg_errno, "The file to which the capture was being"
- " saved (\"%%s\") could not be closed: Error %d.",
- err);
- } else {
- sprintf(errmsg_errno, "The file to which the capture was being"
- " saved (\"%%s\") could not be closed: %s.",
- strerror(err));
- }
- errmsg = errmsg_errno;
- break;
- }
- snprintf(err_str, PCAP_ERRBUF_SIZE, errmsg, cf.save_file);
- simple_dialog(ESD_TYPE_WARN, NULL, err_str);
- }
+ goto error;
}
- pcap_close(pch);
-
- gtk_grab_remove(GTK_WIDGET(cap_w));
- gtk_widget_destroy(GTK_WIDGET(cap_w));
- } else {
- while (gtk_events_pending()) gtk_main_iteration();
- simple_dialog(ESD_TYPE_WARN, NULL,
- "The capture session could not be initiated (%s).\n"
- "Please check to make sure you have sufficient permissions, and that\n"
- "you have the proper interface specified.", err_str);
}
+ pcap_close(pch);
+
+ gtk_grab_remove(GTK_WIDGET(cap_w));
+ gtk_widget_destroy(GTK_WIDGET(cap_w));
- if( quit_after_cap ){
+ if (quit_after_cap) {
/* DON'T unlink the save file. Presumably someone wants it. */
gtk_exit(0);
}
- if (pch) {
- /* "pch" is non-NULL only if we successfully started a capture.
- If we haven't, there's no capture file to load. */
- if ((err = open_cap_file(cf.save_file, &cf)) == 0) {
- /* Set the read filter to NULL. */
- cf.rfcode = NULL;
- err = read_cap_file(&cf);
- set_menu_sensitivity("/File/Save", TRUE);
- set_menu_sensitivity("/File/Save As...", FALSE);
- }
+ if ((err = open_cap_file(cf.save_file, &cf)) == 0) {
+ /* Set the read filter to NULL. */
+ cf.rfcode = NULL;
+ err = read_cap_file(&cf);
+ set_menu_sensitivity("/File/Save", TRUE);
+ set_menu_sensitivity("/File/Save As...", FALSE);
+ }
+ return;
+
+fatal_error:
+ /* We couldn't even start the capture, so get rid of the capture
+ file. */
+ unlink(cf.save_file); /* silently ignore error */
+
+error:
+ if (sync_mode) {
+ /* Send the error message to our parent, so they can display a
+ dialog box containing it. */
+ int msglen = strlen(errmsg);
+ char lenbuf[10+1+1];
+ sprintf(lenbuf, "%u;", msglen);
+ write(1, lenbuf, strlen(lenbuf));
+ write(1, errmsg, msglen);
+ } else {
+ /* Display the dialog box ourselves; there's no parent. */
+ simple_dialog(ESD_TYPE_WARN, NULL, errmsg);
}
+ if (pch != NULL)
+ pcap_close(pch);
+
+ if (quit_after_cap)
+ gtk_exit(0);
}
static float
diff --git a/capture.h b/capture.h
index 61cf251a96..52a23bf68f 100644
--- a/capture.h
+++ b/capture.h
@@ -1,7 +1,7 @@
/* capture.h
* Definitions for packet capture windows
*
- * $Id: capture.h,v 1.14 1999/09/09 03:31:50 gram Exp $
+ * $Id: capture.h,v 1.15 1999/09/23 06:27:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -48,6 +48,7 @@
#define DLT_PPP_BSDOS 14
#endif
+void do_capture(void);
void capture(void);
#endif /* HAVE_LIBPCAP */
diff --git a/globals.h b/globals.h
index 7bf742bd9f..b3166d36b6 100644
--- a/globals.h
+++ b/globals.h
@@ -1,7 +1,7 @@
/* globals.h
* Global defines, etc.
*
- * $Id: globals.h,v 1.5 1999/09/19 15:54:53 deniel Exp $
+ * $Id: globals.h,v 1.6 1999/09/23 06:27:19 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -101,7 +101,6 @@ extern GtkStyle *item_style;
extern int sync_mode; /* allow sync */
extern int sync_pipe[2]; /* used to sync father */
extern int fork_mode; /* fork a child to do the capture */
-extern int sigusr2_received;
extern int quit_after_cap; /* Makes a "capture only mode". Implies -k */
#endif
diff --git a/gtk/capture_dlg.c b/gtk/capture_dlg.c
index 793556e815..6d4e1159e0 100644
--- a/gtk/capture_dlg.c
+++ b/gtk/capture_dlg.c
@@ -1,7 +1,7 @@
/* capture_dlg.c
* Routines for packet capture windows
*
- * $Id: capture_dlg.c,v 1.2 1999/09/11 06:23:28 guy Exp $
+ * $Id: capture_dlg.c,v 1.3 1999/09/23 06:27:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -81,6 +81,7 @@
#define E_CAP_COUNT_KEY "cap_count"
#define E_CAP_OPEN_KEY "cap_open"
#define E_CAP_SNAP_KEY "cap_snap"
+#define E_CAP_SYNC_KEY "cap_sync"
/* Capture filter key */
#define E_CAP_FILT_TE_KEY "cap_filt_te"
@@ -106,7 +107,7 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
*count_lb, *count_cb, *main_vb, *if_hb, *count_hb,
*filter_hb, *filter_bt, *filter_te, *caplen_hb,
*bbox, *ok_bt, *cancel_bt, *snap_lb,
- *snap_sb;
+ *snap_sb, *sync_cb;
GtkAdjustment *adj;
GList *if_list, *count_list = NULL;
gchar *count_item1 = "0 (Infinite)", count_item2[16];
@@ -205,6 +206,11 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
gtk_box_pack_start (GTK_BOX(caplen_hb), snap_sb, FALSE, FALSE, 3);
gtk_widget_show(snap_sb);
+ sync_cb = gtk_check_button_new_with_label("Update list of packets in real time");
+ gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb), sync_mode);
+ gtk_container_add(GTK_CONTAINER(main_vb), sync_cb);
+ gtk_widget_show(sync_cb);
+
/* Button row: OK and cancel buttons */
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
@@ -232,30 +238,33 @@ capture_prep_cb(GtkWidget *w, gpointer d) {
gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILT_KEY, filter_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_SYNC_KEY, sync_cb);
gtk_widget_show(cap_open_w);
}
static void
capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
- GtkWidget *if_cb, *filter_te, *count_cb, *snap_sb;
+ GtkWidget *if_cb, *filter_te, *count_cb, *snap_sb, *sync_cb;
gchar *filter_text;
- char tmpname[128+1];
if_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY);
filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILT_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);
+ sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
- if (cf.iface) g_free(cf.iface);
+ if (cf.iface)
+ g_free(cf.iface);
cf.iface =
g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
- if (cf.cfilter) g_free(cf.cfilter);
+ if (cf.cfilter)
+ g_free(cf.cfilter);
cf.cfilter = NULL; /* ead 06/16/99 */
if (filter_text && filter_text[0]) {
- cf.cfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
+ cf.cfilter = g_strdup(filter_text);
}
cf.count = atoi(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(count_cb)->entry)));
cf.snap = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
@@ -263,87 +272,21 @@ capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w) {
cf.snap = WTAP_MAX_PACKET_SIZE;
else if (cf.snap < MIN_PACKET_SIZE)
cf.snap = MIN_PACKET_SIZE;
+ if (GTK_TOGGLE_BUTTON (sync_cb)->active) {
+ /* They requested that the summary window be updated as packets are
+ captured. */
+ sync_mode = TRUE;
+ fork_mode = TRUE; /* -S implies -F */
+ } else {
+ /* They requested that the summary window not be updated as packets are
+ captured. */
+ sync_mode = FALSE;
+ fork_mode = FALSE;
+ }
gtk_widget_destroy(GTK_WIDGET(parent_w));
- /* Choose a random name for the capture buffer */
- if (cf.save_file && !cf.user_saved) {
- unlink(cf.save_file); /* silently ignore error */
- g_free(cf.save_file);
- }
- cf.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
- cf.save_file = g_strdup(tmpname);
- cf.user_saved = 0;
-
- if( fork_mode ){ /* use fork() for capture */
- int fork_child;
- char ssnap[24];
- char scount[24]; /* need a constant for len of numbers */
- char save_file_fd[24];
- int err;
-
- sprintf(ssnap,"%d",cf.snap); /* in lieu of itoa */
- sprintf(scount,"%d",cf.count);
- sprintf(save_file_fd,"%d",cf.save_file_fd);
- signal(SIGCHLD, SIG_IGN);
- if (sync_mode) pipe(sync_pipe);
- if((fork_child = fork()) == 0){
- /* args: -k -- capture
- * -i interface specification
- * -w file to write
- * -W file descriptor to write
- * -c count to capture
- * -Q quit after capture (forces -k)
- * -s snaplen
- * -S sync mode
- * -m / -b fonts
- * -f "filter expression"
- */
- if (sync_mode) {
- close(1);
- dup(sync_pipe[1]);
- close(sync_pipe[0]);
- execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
- "-w", cf.save_file, "-W", save_file_fd,
- "-c", scount, "-s", ssnap, "-S",
- "-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f",
- (cf.cfilter == NULL)? 0 : cf.cfilter,
- (const char *)NULL);
- }
- else {
- execlp(ethereal_path, "ethereal", "-k", "-Q", "-i", cf.iface,
- "-w", cf.save_file, "-W", save_file_fd,
- "-c", scount, "-s", ssnap,
- "-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f",
- (cf.cfilter == NULL)? 0 : cf.cfilter,
- (const char *)NULL);
- }
- }
- else {
- cf.filename = cf.save_file;
- if (sync_mode) {
- close(sync_pipe[1]);
- while (!sigusr2_received) {
- struct timeval timeout = {1,0};
- select(0, NULL, NULL, NULL, &timeout);
- if (kill(fork_child, 0) == -1 && errno == ESRCH)
- break;
- }
- if (sigusr2_received) {
- err = tail_cap_file(cf.save_file, &cf);
- if (err != 0) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- file_open_error_message(err, FALSE), cf.save_file);
- }
- }
- sigusr2_received = FALSE;
- }
- }
- }
- else
- capture();
+ do_capture();
}
static void
diff --git a/gtk/main.c b/gtk/main.c
index 50c9b15d56..3c1405c36f 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1,6 +1,6 @@
/* main.c
*
- * $Id: main.c,v 1.6 1999/09/22 01:26:33 ashokn Exp $
+ * $Id: main.c,v 1.7 1999/09/23 06:27:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -118,7 +118,6 @@ GtkStyle *item_style;
int sync_mode; /* allow sync */
int sync_pipe[2]; /* used to sync father */
int fork_mode; /* fork a child to do the capture */
-int sigusr2_received = 0;
int quit_after_cap; /* Makes a "capture only mode". Implies -k */
#endif
@@ -444,14 +443,6 @@ main_realize_cb(GtkWidget *w, gpointer data) {
#endif
}
-#ifdef HAVE_LIBPCAP
-static void
-sigusr2_handler(int sig) {
- sigusr2_received = 1;
- signal(SIGUSR2, sigusr2_handler);
-}
-#endif
-
/* call initialization routines at program startup time */
static void
ethereal_proto_init(void) {
@@ -690,11 +681,6 @@ main(int argc, char *argv[])
#endif
}
-#ifdef HAVE_LIBPCAP
- if (sync_mode)
- signal(SIGUSR2, sigusr2_handler);
-#endif
-
/* Build the column format array */
for (i = 0; i < cf.cinfo.num_cols; i++) {
cf.cinfo.col_fmt[i] = get_column_format(i);