aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-02-11 09:28:17 +0000
committerGuy Harris <guy@alum.mit.edu>2001-02-11 09:28:17 +0000
commitbf0a3a32d1135b4bc84a5051adfbf934d091ba61 (patch)
treee635f2f2c8a02e0c4ec19342b263e172495fd742
parent8cd8391b9aac60f8371ca5911330d6b8aacce996 (diff)
In Ethereal, attempt to get the packet statistics from libpcap when
capturing; if we succeed, display the packet drops count as the "Drops" value in the status line and as the "Dropped packets" statistics in the summary dialog box, otherwise don't display it at all. In Tethereal, attempt to get the packet statistics from libpcap when capturing; if we succeed, and if there were any dropped packets, print out the count of dropped packets when the capture finishes. svn path=/trunk/; revision=3016
-rw-r--r--capture.c92
-rw-r--r--capture.h4
-rw-r--r--file.c18
-rw-r--r--file.h3
-rw-r--r--gtk/main.c7
-rw-r--r--gtk/packet_win.c3
-rw-r--r--gtk/summary_dlg.c8
-rw-r--r--summary.c3
-rw-r--r--summary.h5
-rw-r--r--tethereal.c15
10 files changed, 113 insertions, 45 deletions
diff --git a/capture.c b/capture.c
index 44e2cd7853..b8a0fa2faf 100644
--- a/capture.c
+++ b/capture.c
@@ -1,7 +1,7 @@
/* capture.c
* Routines for packet capture windows
*
- * $Id: capture.c,v 1.138 2001/02/10 09:08:14 guy Exp $
+ * $Id: capture.c,v 1.139 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -268,6 +268,8 @@ do_capture(char *capfile_name)
char *msg;
int err;
int capture_succeeded;
+ gboolean stats_known;
+ struct pcap_stat stats;
if (capfile_name != NULL) {
/* Try to open/create the specified file for use as a capture buffer. */
@@ -556,7 +558,7 @@ do_capture(char *capfile_name)
}
} else {
/* Not sync mode. */
- capture_succeeded = capture();
+ capture_succeeded = capture(&stats_known, &stats);
if (quit_after_cap) {
/* DON'T unlink the save file. Presumably someone wants it. */
gtk_exit(0);
@@ -566,6 +568,39 @@ do_capture(char *capfile_name)
if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
/* Set the read filter to NULL. */
cfile.rfcode = NULL;
+
+ /* Get the packet-drop statistics.
+
+ XXX - there are currently no packet-drop statistics stored
+ in libpcap captures, and that's what we're reading.
+
+ At some point, we will add support in Wiretap to return
+ packet-drop statistics for capture file formats that store it,
+ and will make "read_cap_file()" get those statistics from
+ Wiretap. We clear the statistics (marking them as "not known")
+ in "open_cap_file()", and "read_cap_file()" will only fetch
+ them and mark them as known if Wiretap supplies them, so if
+ we get the statistics now, after calling "open_cap_file()" but
+ before calling "read_cap_file()", the values we store will
+ be used by "read_cap_file()".
+
+ If a future libpcap capture file format stores the statistics,
+ we'll put them into the capture file that we write, and will
+ thus not have to set them here - "read_cap_file()" will get
+ them from the file and use them. */
+ if (stats_known) {
+ cfile.drops_known = TRUE;
+
+ /* XXX - on some systems, libpcap doesn't bother filling in
+ "ps_ifdrop" - it doesn't even set it to zero - so we don't
+ bother looking at it.
+
+ Ideally, libpcap would have an interface that gave us
+ several statistics - perhaps including various interface
+ error statistics - and would tell us which of them it
+ supplies, allowing us to display only the ones it does. */
+ cfile.drops = stats.ps_drop;
+ }
switch (read_cap_file(&cfile, &err)) {
case READ_SUCCESS:
@@ -1111,7 +1146,7 @@ static loop_data ld;
/* Do the low-level work of a capture.
Returns TRUE if it succeeds, FALSE otherwise. */
int
-capture(void)
+capture(gboolean *stats_known, struct pcap_stat *stats)
{
GtkWidget *cap_w, *main_vb, *stop_bt, *counts_tb;
pcap_t *pch;
@@ -1144,7 +1179,7 @@ capture(void)
const gchar *title;
gint *value_ptr;
GtkWidget *label, *value, *percent;
- } stats[] = {
+ } counts[] = {
{ "Total", &ld.counts.total },
{ "SCTP", &ld.counts.sctp },
{ "TCP", &ld.counts.tcp },
@@ -1158,7 +1193,7 @@ capture(void)
{ "Other", &ld.counts.other }
};
-#define N_STATS (sizeof stats / sizeof stats[0])
+#define N_COUNTS (sizeof counts / sizeof counts[0])
/* Initialize Windows Socket if we are in a WIN32 OS
This needs to be done before querying the interface for network/netmask */
@@ -1192,6 +1227,9 @@ capture(void)
ld.counts.other = 0;
ld.pdh = NULL;
+ /* We haven't yet gotten the capture statistics. */
+ *stats_known = FALSE;
+
/* Open the network interface to capture from it. */
pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode,
CAP_READ_TIMEOUT, err_str);
@@ -1375,33 +1413,33 @@ capture(void)
gtk_widget_show(main_vb);
/* Individual statistic elements */
- counts_tb = gtk_table_new(N_STATS, 3, TRUE);
+ counts_tb = gtk_table_new(N_COUNTS, 3, TRUE);
gtk_box_pack_start(GTK_BOX(main_vb), counts_tb, TRUE, TRUE, 3);
gtk_widget_show(counts_tb);
- for (i = 0; i < N_STATS; i++) {
- stats[i].label = gtk_label_new(stats[i].title);
- gtk_misc_set_alignment(GTK_MISC(stats[i].label), 0.0f, 0.0f);
+ for (i = 0; i < N_COUNTS; i++) {
+ counts[i].label = gtk_label_new(counts[i].title);
+ gtk_misc_set_alignment(GTK_MISC(counts[i].label), 0.0f, 0.0f);
- stats[i].value = gtk_label_new("0");
- gtk_misc_set_alignment(GTK_MISC(stats[i].value), 0.0f, 0.0f);
+ counts[i].value = gtk_label_new("0");
+ gtk_misc_set_alignment(GTK_MISC(counts[i].value), 0.0f, 0.0f);
- stats[i].percent = gtk_label_new("0.0%");
- gtk_misc_set_alignment(GTK_MISC(stats[i].percent), 0.0f, 0.0f);
+ counts[i].percent = gtk_label_new("0.0%");
+ gtk_misc_set_alignment(GTK_MISC(counts[i].percent), 0.0f, 0.0f);
gtk_table_attach_defaults(GTK_TABLE(counts_tb),
- stats[i].label, 0, 1, i, i + 1);
+ counts[i].label, 0, 1, i, i + 1);
gtk_table_attach(GTK_TABLE(counts_tb),
- stats[i].value,
+ counts[i].value,
1, 2, i, i + 1, 0, 0, 5, 0);
gtk_table_attach_defaults(GTK_TABLE(counts_tb),
- stats[i].percent, 2, 3, i, i + 1);
+ counts[i].percent, 2, 3, i, i + 1);
- gtk_widget_show(stats[i].label);
- gtk_widget_show(stats[i].value);
- gtk_widget_show(stats[i].percent);
+ gtk_widget_show(counts[i].label);
+ gtk_widget_show(counts[i].value);
+ gtk_widget_show(counts[i].percent);
}
/* allow user to either click a stop button, or the close button on
@@ -1506,16 +1544,16 @@ capture(void)
if (cur_time > upd_time) {
upd_time = cur_time;
- for (i = 0; i < N_STATS; i++) {
+ for (i = 0; i < N_COUNTS; i++) {
snprintf(label_str, sizeof(label_str), "%d",
- *stats[i].value_ptr);
+ *counts[i].value_ptr);
- gtk_label_set(GTK_LABEL(stats[i].value), label_str);
+ gtk_label_set(GTK_LABEL(counts[i].value), label_str);
snprintf(label_str, sizeof(label_str), "(%.1f%%)",
- pct(*stats[i].value_ptr, ld.counts.total));
+ pct(*counts[i].value_ptr, ld.counts.total));
- gtk_label_set(GTK_LABEL(stats[i].percent), label_str);
+ gtk_label_set(GTK_LABEL(counts[i].percent), label_str);
}
/* do sync here, too */
@@ -1561,7 +1599,13 @@ capture(void)
close(pipe_fd);
else
#endif
+ {
+ /* Get the capture statistics, so we know how many packets were
+ dropped. */
+ if (pcap_stats(pch, stats) >= 0)
+ *stats_known = TRUE;
pcap_close(pch);
+ }
#ifdef WIN32
/* Shut down windows sockets */
diff --git a/capture.h b/capture.h
index bc65142e32..ec173e75bd 100644
--- a/capture.h
+++ b/capture.h
@@ -1,7 +1,7 @@
/* capture.h
* Definitions for packet capture windows
*
- * $Id: capture.h,v 1.24 2000/10/11 06:01:14 guy Exp $
+ * $Id: capture.h,v 1.25 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -42,7 +42,7 @@ extern gboolean capture_child; /* if this is the child for "-S" */
void do_capture(char *capfile_name);
/* Do the low-level work of a capture. */
-int capture(void);
+int capture(gboolean *stats_known, struct pcap_stat *stats);
/* Stop a capture from a menu item. */
void capture_stop(void);
diff --git a/file.c b/file.c
index 67470101f0..2cf10d547b 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.231 2001/02/10 09:08:14 guy Exp $
+ * $Id: file.c,v 1.232 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -170,6 +170,7 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
cf->cd_t = wtap_file_type(cf->wth);
cf->count = 0;
+ cf->drops_known = FALSE;
cf->drops = 0;
cf->esec = 0;
cf->eusec = 0;
@@ -265,7 +266,8 @@ set_display_filename(capture_file *cf)
{
gchar *name_ptr;
size_t msg_len;
- gchar *done_fmt = " File: %s Drops: %u";
+ static const gchar done_fmt_nodrops[] = " File: %s";
+ static const gchar done_fmt_drops[] = " File: %s Drops: %u";
gchar *done_msg;
gchar *win_name_fmt = "%s - Ethereal";
gchar *win_name;
@@ -280,9 +282,15 @@ set_display_filename(capture_file *cf)
name_ptr = "<capture>";
}
- msg_len = strlen(name_ptr) + strlen(done_fmt) + 64;
- done_msg = g_malloc(msg_len);
- snprintf(done_msg, msg_len, done_fmt, name_ptr, cf->drops);
+ if (cf->drops_known) {
+ msg_len = strlen(name_ptr) + strlen(done_fmt_drops) + 64;
+ done_msg = g_malloc(msg_len);
+ snprintf(done_msg, msg_len, done_fmt_drops, name_ptr, cf->drops);
+ } else {
+ msg_len = strlen(name_ptr) + strlen(done_fmt_nodrops);
+ done_msg = g_malloc(msg_len);
+ snprintf(done_msg, msg_len, done_fmt_nodrops, name_ptr);
+ }
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, done_msg);
g_free(done_msg);
diff --git a/file.h b/file.h
index b42cd582df..a71c7e556a 100644
--- a/file.h
+++ b/file.h
@@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
- * $Id: file.h,v 1.80 2001/02/01 20:21:13 gram Exp $
+ * $Id: file.h,v 1.81 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -68,6 +68,7 @@ typedef struct _capture_file {
int lnk_t; /* Link-layer type with which to save capture */
guint32 vers; /* Version. For tcpdump minor is appended to major */
guint32 count; /* Packet count */
+ gboolean drops_known; /* TRUE if we know how many packets were dropped */
guint32 drops; /* Dropped packets */
guint32 esec; /* Elapsed seconds */
guint32 eusec; /* Elapsed microseconds */
diff --git a/gtk/main.c b/gtk/main.c
index a956fc7c40..cf9859ebd1 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1,6 +1,6 @@
/* main.c
*
- * $Id: main.c,v 1.178 2001/02/08 03:55:45 guy Exp $
+ * $Id: main.c,v 1.179 2001/02/11 09:28:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -693,6 +693,8 @@ main(int argc, char *argv[])
gchar *save_file = NULL;
GList *if_list;
gchar err_str[PCAP_ERRBUF_SIZE];
+ gboolean stats_known;
+ struct pcap_stat stats;
#else
gboolean capture_option_specified = FALSE;
#endif
@@ -1226,7 +1228,8 @@ main(int argc, char *argv[])
a temporary file and fork off *another* child process (so don't
call "do_capture()"). */
- capture();
+ /* XXX - hand these stats to the parent process */
+ capture(&stats_known, &stats);
/* The capture is done; there's nothing more for us to do. */
gtk_exit(0);
diff --git a/gtk/packet_win.c b/gtk/packet_win.c
index 760033f8d8..09a649c49c 100644
--- a/gtk/packet_win.c
+++ b/gtk/packet_win.c
@@ -3,7 +3,7 @@
*
* Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
*
- * $Id: packet_win.c,v 1.17 2001/02/01 20:21:22 gram Exp $
+ * $Id: packet_win.c,v 1.18 2001/02/11 09:28:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -50,7 +50,6 @@
#include "main.h"
#include "timestamp.h"
#include "packet.h"
-#include "capture.h"
#include "summary.h"
#include "file.h"
#include "menu.h"
diff --git a/gtk/summary_dlg.c b/gtk/summary_dlg.c
index 08e0cbb9b2..64c50371a0 100644
--- a/gtk/summary_dlg.c
+++ b/gtk/summary_dlg.c
@@ -1,7 +1,7 @@
/* summary_dlg.c
* Routines for capture file summary window
*
- * $Id: summary_dlg.c,v 1.8 2000/08/21 18:20:19 deniel Exp $
+ * $Id: summary_dlg.c,v 1.9 2001/02/11 09:28:17 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -142,8 +142,10 @@ summary_open_cb(GtkWidget *w, gpointer d)
}
/* Dropped count */
- snprintf(string_buff, SUM_STR_MAX, "Dropped packets: %i", summary.drops);
- add_string_to_box(string_buff, data_box);
+ if (summary.drops_known) {
+ snprintf(string_buff, SUM_STR_MAX, "Dropped packets: %u", summary.drops);
+ add_string_to_box(string_buff, data_box);
+ }
/* Byte count */
snprintf(string_buff, SUM_STR_MAX, "Bytes of traffic: %d", summary.bytes);
diff --git a/summary.c b/summary.c
index 90717a91f0..3da60a62b1 100644
--- a/summary.c
+++ b/summary.c
@@ -1,7 +1,7 @@
/* summary.c
* Routines for capture file summary info
*
- * $Id: summary.c,v 1.19 2000/08/21 18:20:11 deniel Exp $
+ * $Id: summary.c,v 1.20 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -94,6 +94,7 @@ summary_fill_in(summary_tally *st)
st->snap = cfile.snap;
st->elapsed_time = secs_usecs(cfile.esec, cfile.eusec);
st->packet_count = cfile.count;
+ st->drops_known = cfile.drops_known;
st->drops = cfile.drops;
st->iface = cfile.iface;
st->dfilter = cfile.dfilter;
diff --git a/summary.h b/summary.h
index ed64ae669a..c12d27c9d2 100644
--- a/summary.h
+++ b/summary.h
@@ -1,7 +1,7 @@
/* summary.h
* Definitions for capture file summary data
*
- * $Id: summary.h,v 1.5 2000/08/21 18:20:12 deniel Exp $
+ * $Id: summary.h,v 1.6 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -40,7 +40,8 @@ typedef struct _summary_tally {
long file_length; /* file length in bytes */
int encap_type; /* wiretap encapsulation type */
int snap; /* snapshot length */
- int drops; /* number of packet drops */
+ gboolean drops_known; /* TRUE if number of packet drops is known */
+ guint32 drops; /* number of packet drops */
const char *iface; /* interface name */
const char *dfilter; /* display filter */
const char *cfilter; /* capture filter */
diff --git a/tethereal.c b/tethereal.c
index ee96b8328f..6b91df1925 100644
--- a/tethereal.c
+++ b/tethereal.c
@@ -1,6 +1,6 @@
/* tethereal.c
*
- * $Id: tethereal.c,v 1.65 2001/02/10 09:08:14 guy Exp $
+ * $Id: tethereal.c,v 1.66 2001/02/11 09:28:15 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -544,6 +544,7 @@ capture(int packet_count, int out_file_type)
static const char ppamsg[] = "can't find PPA for ";
char *libpcap_warn;
#endif
+ struct pcap_stat stats;
/* Initialize the table of conversations. */
epan_conversation_init();
@@ -660,13 +661,20 @@ capture(int packet_count, int out_file_type)
printf("Capturing on %s\n", cfile.iface);
inpkts = pcap_loop(ld.pch, packet_count, capture_pcap_cb, (u_char *) &ld);
- pcap_close(ld.pch);
- /* Send a newline if we were printing packet counts to stdout */
if (cfile.save_file != NULL) {
+ /* We're saving to a file, which means we're printing packet counts
+ to the standard output. Send a newline so that we move to the
+ line after the packet count. */
printf("\n");
}
+ /* Get the capture statistics, and, if any packets were dropped, report
+ that. */
+ if (pcap_stats(ld.pch, &stats) >= 0)
+ printf("%u packets dropped\n", stats.ps_drop);
+ pcap_close(ld.pch);
+
return TRUE;
error:
@@ -1364,6 +1372,7 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
cf->cd_t = wtap_file_type(cf->wth);
cf->count = 0;
+ cf->drops_known = FALSE;
cf->drops = 0;
cf->esec = 0;
cf->eusec = 0;