/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.28 1999/06/21 19:04:34 gram Exp $
+ * $Id: capture.c,v 1.48 1999/08/15 00:26:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
# include "config.h"
#endif
+#ifdef HAVE_LIBPCAP
+
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#include <gtk/gtk.h>
-#include <pcap.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <gtk/gtk.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
+
#include <time.h>
+
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_NET_IF_H
#include <net/if.h>
+#endif
+
#include <signal.h>
#include <errno.h>
filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
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)));
}
close(1);
dup(sync_pipe[1]);
close(sync_pipe[0]);
- execl(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
- "-c", scount, "-s", ssnap, "-S",
- "-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
- 0);
+ execlp(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
+ "-c", scount, "-s", ssnap, "-S",
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
+ 0);
}
else {
- execl(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
- "-c", scount, "-s", ssnap,
- "-m", medium_font, "-b", bold_font,
- (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
- 0);
+ execlp(ethereal_path,"ethereal","-k","-Q","-i",cf.iface,"-w",cf.save_file,
+ "-c", scount, "-s", ssnap,
+ "-m", medium_font, "-b", bold_font,
+ (cf.cfilter == NULL)? 0 : "-f", (cf.cfilter == NULL)? 0 : cf.cfilter,
+ 0);
}
}
else {
void
capture(void) {
- GtkWidget *cap_w, *main_vb, *count_lb, *tcp_lb, *udp_lb,
- *ospf_lb, *gre_lb, *other_lb, *stop_bt;
+ 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;
gchar err_str[PCAP_ERRBUF_SIZE], label_str[32];
loop_data ld;
bpf_u_int32 netnum, netmask;
time_t upd_time, cur_time;
- int err;
+ int err, inpkts;
- ld.go = TRUE;
- ld.counts.total = 0;
- ld.max = cf.count;
- ld.linktype = DLT_NULL;
- ld.signal_sent = 0;
- ld.sync_time = 0;
- ld.counts.tcp = 0;
- ld.counts.udp = 0;
- ld.counts.ospf = 0;
- ld.counts.gre = 0;
- ld.counts.other = 0;
- ld.pdh = NULL;
+ ld.go = TRUE;
+ ld.counts.total = 0;
+ ld.max = cf.count;
+ ld.linktype = DLT_NULL;
+ ld.sync_packets = 0;
+ ld.counts.tcp = 0;
+ ld.counts.udp = 0;
+ ld.counts.icmp = 0;
+ ld.counts.ospf = 0;
+ ld.counts.gre = 0;
+ ld.counts.netbios = 0;
+ ld.counts.other = 0;
+ ld.pdh = NULL;
close_cap_file(&cf, info_bar, file_ctx);
pch = pcap_open_live(cf.iface, cf.snap, 1, 250, err_str);
if (pch) {
+ /* save the old new umask and set the new one to readable only by the user */
+ mode_t old_umask = umask(0066);
+
+ /* Have libpcap create the empty dumpfile */
ld.pdh = pcap_dump_open(pch, cf.save_file);
+ /* reset the umask to the original value */
+ (void) umask(old_umask);
+
if (ld.pdh == NULL) { /* We have an error */
snprintf(err_str, PCAP_ERRBUF_SIZE, "Error trying to save capture to "
"file:\n%s", pcap_geterr(pch));
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.");
+ pcap_dump_close(ld.pdh);
+ 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.");
+ pcap_dump_close(ld.pdh);
+ 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.");
+ pcap_dump_close(ld.pdh);
+ 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((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");
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);
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);
upd_time = time(NULL);
while (ld.go) {
while (gtk_events_pending()) gtk_main_iteration();
- pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
-
+ 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) {
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);
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((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;
+ }
}
}
gtk_exit(0);
}
- if (cf.save_file) {
- err = load_cap_file(cf.save_file, &cf);
- if (err != 0) {
- simple_dialog(ESD_TYPE_WARN, NULL,
- file_open_error_message(err, FALSE), cf.save_file);
+ 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 &&
+ (err = read_cap_file(cf.save_file, NULL, &cf)) == 0) {
+ set_menu_sensitivity("/File/Save", TRUE);
+ set_menu_sensitivity("/File/Save As...", FALSE);
}
}
-#ifdef USE_ITEM
- set_menu_sensitivity("/File/Save", TRUE);
- set_menu_sensitivity("/File/Save as", FALSE);
-#else
- set_menu_sensitivity("<Main>/File/Save", TRUE);
- set_menu_sensitivity("<Main>/File/Save as", FALSE);
-#endif
}
static float
const u_char *pd) {
loop_data *ld = (loop_data *) user;
- time_t *sync_time= &ld->sync_time, cur_time;
if ((++ld->counts.total >= ld->max) && (ld->max > 0))
{
}
/* Currently, pcap_dumper_t is a FILE *. Let's hope that doesn't change. */
if (ld->pdh) pcap_dump((u_char *) ld->pdh, phdr, pd);
-
- cur_time = time(NULL);
- if (cur_time > *sync_time) {
- /* sync every seconds */
- *sync_time = cur_time;
- fflush((FILE *)ld->pdh);
- if (sync_mode)
- write(1, "D", 1);
- }
-
+
switch (ld->linktype) {
case DLT_EN10MB :
capture_eth(pd, phdr->caplen, &ld->counts);
capture_raw(pd, phdr->caplen, &ld->counts);
break;
}
-
- if (sync_mode && !ld->signal_sent) {
- /* will trigger the father to open the cap file which contains
- at least one complete packet */
- fflush((FILE *)ld->pdh);
- kill(getppid(), SIGUSR2);
- ld->signal_sent = 1;
- }
-
}
+
+#endif /* HAVE_LIBPCAP */