move the complete functionality of the capture info dialog from capture_loop.c to...
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 4 Dec 2005 02:04:18 +0000 (02:04 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 4 Dec 2005 02:04:18 +0000 (02:04 +0000)
This way, the capture child don't need to now any of the packet_counter things (no epan/packet.h and all alike).

Currently the capture_info code will always open another wiretap file instance to build it's own counter values. This isn't optimized for now (next step: use data from cf_continue_tail() somehow).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@16669 f5534014-38df-0310-8fa8-9805f1628bb7

Makefile.common
capture.c
capture_info.c
capture_info.h
capture_loop.c
capture_sync.c
capture_sync.h
dumpcap.c
gtk/capture_info_dlg.c

index a1322f1d9f00add5f8fa6b1eec79c233fba1619d..e950b5df935e1ff8fe31e0866e3c98bbb2c35a4a 100644 (file)
@@ -217,7 +217,6 @@ dumpcap_SOURCES =   \
        version_info.c \
        capture_opts.c \
        capture_loop.c  \
-       capture_info.c  \
        dumpcap.c
 
 
index 074acc3fe78a6b287a80389e3703feac8b91864d..f1cb5501aa906e0b7da5d485dd524950ffd7001f 100644 (file)
--- a/capture.c
+++ b/capture.c
@@ -52,6 +52,7 @@
 #include "file.h"
 #include "capture.h"
 #include "capture_sync.h"
+#include "capture_info.h"
 #include "capture_ui_utils.h"
 #include "util.h"
 #include "pcap-util.h"
@@ -105,6 +106,9 @@ capture_start(capture_options *capture_opts)
       /* to prevent problems, bring the main GUI into "capture mode" right after successfully */
       /* spawn/exec the capture child, without waiting for any response from it */
       cf_callback_invoke(cf_cb_live_capture_prepared, capture_opts);
+
+      if(capture_opts->show_info)
+        capture_info_open(capture_opts->iface);
   }
 
   return ret;
@@ -293,6 +297,9 @@ capture_input_new_file(capture_options *capture_opts, gchar *new_file)
     cf_callback_invoke(cf_cb_live_capture_fixed_started, capture_opts);
   }
 
+  if(capture_opts->show_info)
+    capture_info_new_file(new_file);
+
   capture_opts->state = CAPTURE_RUNNING;
 
   return TRUE;
@@ -320,7 +327,8 @@ capture_input_new_packets(capture_options *capture_opts, int to_read)
 
          XXX - abort on a read error? */
          cf_callback_invoke(cf_cb_live_capture_update_continue, capture_opts->cf);
-                /* update the main window, so we get events (e.g. from the stop toolbar button) */
+
+         /* update the main window, so we get events (e.g. from the stop toolbar button) */
          main_window_update();
       break;
 
@@ -331,6 +339,9 @@ capture_input_new_packets(capture_options *capture_opts, int to_read)
       break;
     }
   }
+
+  if(capture_opts->show_info)
+    capture_info_new_packets(to_read);
 }
 
 
@@ -441,6 +452,9 @@ capture_input_closed(capture_options *capture_opts)
         }
     }
 
+    if(capture_opts->show_info)
+      capture_info_close();
+
     capture_opts->state = CAPTURE_STOPPED;
 
     /* if we couldn't open a capture file, there's nothing more for us to do */
index 473b93a6ece585f513350da81899a4ef97443b3f..05a09542d2bee1440a99f8018d77e4bed29db75c 100644 (file)
 #include <epan/dissectors/packet-arcnet.h>
 
 
-void
-capture_info_init(packet_counts *counts)
+
+void capture_info_packet(
+packet_counts *counts, gint wtap_linktype, const u_char *pd, guint32 caplen, union wtap_pseudo_header *pseudo_header);
+
+
+
+typedef struct _info_data {
+    packet_counts     counts;     /* several packet type counters */
+    struct wtap*      wtap;       /* current wtap file */
+    capture_info      ui;         /* user interface data */
+} info_data_t;
+
+
+info_data_t info_data;
+
+
+/* open the info */
+void capture_info_open(const char *iface)
+{
+    info_data.counts.total      = 0;
+    info_data.counts.sctp       = 0;
+    info_data.counts.tcp        = 0;
+    info_data.counts.udp        = 0;
+    info_data.counts.icmp       = 0;
+    info_data.counts.ospf       = 0;
+    info_data.counts.gre        = 0;
+    info_data.counts.ipx        = 0;
+    info_data.counts.netbios    = 0;
+    info_data.counts.vines      = 0;
+    info_data.counts.other      = 0;
+    info_data.counts.arp        = 0;
+
+    info_data.wtap = NULL;
+    info_data.ui.counts = &info_data.counts;
+
+    capture_info_ui_create(&info_data.ui, iface);
+}
+
+
+/* new file arrived */
+void capture_info_new_file(const char *new_filename)
+{
+    int err;
+    gchar *err_info;
+
+
+    if(info_data.wtap != NULL) {
+        wtap_close(info_data.wtap);
+    }
+
+    info_data.wtap = wtap_open_offline(new_filename, &err, &err_info, FALSE);
+    if (!info_data.wtap) {
+        g_warning("capture_info_new_file: wtap open failed: %s", err_info);
+    }
+
+}
+
+
+/* new packets arrived */
+void capture_info_new_packets(int to_read)
+{
+    int err;
+    gchar *err_info;
+    long data_offset;
+    const struct wtap_pkthdr *phdr;
+    union wtap_pseudo_header *pseudo_header;
+    int wtap_linktype;
+    const guchar *buf;
+
+
+    info_data.ui.new_packets = to_read;
+
+    /*g_warning("new packets: %u", to_read);*/
+
+    while (to_read != 0 && (wtap_read(info_data.wtap, &err, &err_info, &data_offset))) {
+        phdr = wtap_phdr(info_data.wtap);
+        pseudo_header = wtap_pseudoheader(info_data.wtap);
+        wtap_linktype = phdr->pkt_encap;
+        buf = wtap_buf_ptr(info_data.wtap);
+
+        capture_info_packet(&info_data.counts, wtap_linktype, buf, phdr->caplen, pseudo_header);
+
+        /*g_warning("new packet");*/
+        to_read--;
+    }
+
+    capture_info_ui_update(&info_data.ui);
+}
+
+
+/* close the info */
+void capture_info_close(void)
 {
-  counts->total       = 0;
-  counts->sctp        = 0;
-  counts->tcp         = 0;
-  counts->udp         = 0;
-  counts->icmp        = 0;
-  counts->ospf        = 0;
-  counts->gre         = 0;
-  counts->ipx         = 0;
-  counts->netbios     = 0;
-  counts->vines       = 0;
-  counts->other       = 0;
-  counts->arp         = 0;
+    capture_info_ui_destroy(&info_data.ui);
+    wtap_close(info_data.wtap);
 }
 
 
-void
-capture_info_packet(packet_counts *counts, gint wtap_linktype, const u_char *pd, guint32 caplen, union wtap_pseudo_header pseudo_header)
+static void
+capture_info_packet(packet_counts *counts, gint wtap_linktype, const u_char *pd, guint32 caplen, union wtap_pseudo_header *pseudo_header)
 {
   counts->total++;
   switch (wtap_linktype) {
@@ -118,7 +198,7 @@ capture_info_packet(packet_counts *counts, gint wtap_linktype, const u_char *pd,
       capture_llap(counts);
       break;
     case WTAP_ENCAP_ATM_PDUS:
-      capture_atm(&pseudo_header, pd, caplen, counts);
+      capture_atm(pseudo_header, pd, caplen, counts);
       break;
     case WTAP_ENCAP_IP_OVER_FC:
       capture_ipfc(pd, caplen, counts);
index 02e1f210aaa847e84d94e01130f545282ae3f539..fefedbf564c58e7ef9640de91eb60468646dfb8d 100644 (file)
 #define __CAPTURE_INFO_H__
 
 
-extern void capture_info_init(packet_counts *counts);
+/* open the info - init values (wtap, counts), create dialog */
+extern void capture_info_open(const char *iface);
+
+/* new file arrived - (eventually close old wtap), open wtap */
+extern void capture_info_new_file(const char *new_filename);
+
+/* new packets arrived - read from wtap, count */
+extern void capture_info_new_packets(int to_read);
+
+/* close the info - close wtap, destroy dialog */
+extern void capture_info_close(void);
 
-extern void capture_info_packet(
-packet_counts *counts, gint wtap_linktype, const u_char *pd, guint32 caplen, union wtap_pseudo_header pseudo_header);
 
 
 /** Current Capture info. */
@@ -54,7 +62,7 @@ typedef struct {
 /** Create the capture info dialog */
 extern void capture_info_ui_create(
 capture_info    *cinfo,
-gchar           *iface);
+const gchar     *iface);
 
 /** Update the capture info counters in the dialog */
 extern void capture_info_ui_update(
index bfa078b7101118000a6f63ab4d7153d4c017f9c7..08073b5eb7746a7c9e63641394e4bf90af10fe25 100644 (file)
 #include <signal.h>
 #include <errno.h>
 
-#include <pcap.h>
 
 #include <glib.h>
 
-#include <epan/packet.h>
+#include <pcap.h>
+#include "pcap-util.h"
+
 #include "capture.h"
 #include "capture_loop.h"
-#include "capture_info.h"
 #include "capture_sync.h"
-#include "pcap-util.h"
 
-#include "simple_dialog.h"
 #include "conditions.h"
 #include "capture_stop_conditions.h"
 #include "ringbuffer.h"
 #include "wiretap/wtap.h"
 #include "wiretap/wtap-capture.h"
 
-/* XXX - try to remove this later */
-#include <epan/prefs.h>
-#include "ui_util.h"
-/* XXX - try to remove this later */
+#include "simple_dialog.h"
 #include "util.h"
-#include "alert_box.h"
 #include "log.h"
 #include "file_util.h"
 
@@ -125,8 +119,6 @@ typedef struct _loop_data {
   gint           packets_curr;          /* Number of packets we have already captured */
   gint           packets_max;           /* Number of packets we're supposed to capture - 0 means infinite */
   gint           packets_sync_pipe;     /* packets not already send out to the sync_pipe */
-  packet_counts  counts;                /* several packet type counters */
-  gboolean       show_info;             /* show(hide) capture info dialog */
 
   /* pcap "input file" */
   pcap_t        *pcap_h;                /* pcap handle */
@@ -1103,8 +1095,6 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
            "The file to which the capture would be saved (\"%s\") "
         "could not be opened: %s.", capfile_name, 
         strerror(errno));
-
-      /*open_failure_alert_box(capfile_name, errno, TRUE);*/
     }
     g_free(capfile_name);
     return FALSE;
@@ -1156,7 +1146,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   guint32     autostop_files = 0;
   gboolean    write_ok;
   gboolean    close_ok;
-  capture_info   capture_ui;
   char        errmsg[4096+1];
   int         save_file_fd;
 
@@ -1180,7 +1169,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
 #ifdef MUST_DO_SELECT
   ld.pcap_fd            = 0;
 #endif
-  ld.show_info          = capture_opts->show_info;
 
 #ifndef _WIN32
   /*
@@ -1252,30 +1240,18 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
            cnd_new(CND_CLASS_CAPTURESIZE, capture_opts->autostop_files);
   }
 
-  /* start capture info dialog */
-  if(capture_opts->show_info) {
-      capture_info_init(&ld.counts);
-      capture_ui.counts = &ld.counts;
-      capture_info_ui_create(&capture_ui, capture_opts->iface);
-  }
-
   /* init the time values */
   start_time = TIME_GET();
   upd_time = TIME_GET();
 
-
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture child running!");
 
   /* WOW, everything is prepared! */
   /* please fasten your seat belts, we will enter now the actual capture loop */
   while (ld.go) {
-    main_window_update();
-
     /* dispatch incoming packets */
     inpkts = capture_loop_dispatch(capture_opts, &ld, errmsg, sizeof(errmsg));
 
-    main_window_update();
-
 #ifdef _WIN32
       /* some news from our parent (signal pipe)? -> just stop the capture */
       {
@@ -1287,13 +1263,14 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
           handle = (HANDLE) _get_osfhandle (0);
           result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
 
+          /*g_warning("check pipe: handle: %x result: %u avail: %u", handle, result, avail);*/
+
           if(!result || avail > 0) {
             /* XXX - doesn't work with dumpcap as a command line tool */
             /* as we have no input pipe, need to find a way to circumvent this */
 #ifndef DUMPCAP
             ld.go = FALSE;
 #endif
-            /*g_warning("loop closing");*/
           }
       }
 #endif
@@ -1348,18 +1325,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
         *stats_known = TRUE;
       }*/
 
-      /* calculate and display running time */
-      if(capture_opts->show_info) {
-          cur_time -= start_time;
-#ifdef _WIN32
-          capture_ui.running_time   = cur_time / 1000;
-#else
-          capture_ui.running_time   = cur_time;
-#endif
-          capture_ui.new_packets    = ld.packets_sync_pipe;
-          capture_info_ui_update(&capture_ui);
-      }
-
       /* Let the parent process know. */
       if (ld.packets_sync_pipe) {
         /* do sync here */
@@ -1415,11 +1380,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
 
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture child stopping ...");
 
-  /* close capture info dialog */
-  if(capture_opts->show_info) {
-    capture_info_ui_destroy(&capture_ui);
-  }
-
   /* delete stop conditions */
   if (cnd_file_duration != NULL)
     cnd_delete(cnd_file_duration);
@@ -1624,15 +1584,6 @@ capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr,
       ld->err = err;
     }
   }
-
-#ifndef DUMPCAP
-  /* if the capture info dialog is hidden, no need to create the packet info */
-  if(!ld->show_info) {
-      return;
-  }
-
-  capture_info_packet(&ld->counts, ld->wtap_linktype, pd, whdr.caplen, pseudo_header);
-#endif
 }
 
 #endif /* HAVE_LIBPCAP */
index 888f4dbcebc29ca3f3b1aa71adc3d8cd9ca8b194..d291df4886ec705728cf22a475fd3c076e3961e5 100644 (file)
@@ -112,25 +112,8 @@ static void sync_pipe_wait_for_child(capture_options *capture_opts);
  */
 #define SP_MAX_MSG_LEN 4096
 
-/* Size of buffer to hold decimal representation of
-   signed/unsigned 64-bit int */
-#define SP_DECISIZE 20
 
-/*
- * Indications sent out on the sync pipe (from child to parent).
- */
-#define SP_FILE         'F'     /* the name of the recently opened file */
-#define SP_ERROR_MSG    'E'     /* error message */
-#define SP_PACKET_COUNT 'P'     /* count of packets captured since last message */
-#define SP_DROPS        'D'     /* count of packets dropped in capture */
-/*
- * Win32 only: Indications sent out on the signal pipe (from parent to child)
- * (UNIX-like sends signals for this)
- */
-#define SP_QUIT         'Q'     /* "gracefully" capture quit message (SIGUSR1) */
-
-
-/* write a message to the recipient pipe in the standard format 
+ /* write a message to the recipient pipe in the standard format 
    (3 digit message length (excluding length and indicator field), 
    1 byte message indicator and the rest is the message) */
 static void
index d734641d41abea19797453a80cd8a798ae5451e8..6e8dea1a09d5d548e9dd63042ae86e73cf8cf4f2 100644 (file)
 #define        CHILD_NAME      "ethereal-capture"
 
 
+/* Size of buffer to hold decimal representation of
+   signed/unsigned 64-bit int */
+#define SP_DECISIZE 20
+
+/*
+ * Indications sent out on the sync pipe (from child to parent).
+ */
+#define SP_FILE         'F'     /* the name of the recently opened file */
+#define SP_ERROR_MSG    'E'     /* error message */
+#define SP_PACKET_COUNT 'P'     /* count of packets captured since last message */
+#define SP_DROPS        'D'     /* count of packets dropped in capture */
+/*
+ * Win32 only: Indications sent out on the signal pipe (from parent to child)
+ * (UNIX-like sends signals for this)
+ */
+#define SP_QUIT         'Q'     /* "gracefully" capture quit message (SIGUSR1) */
+
+
+
 /** 
  * Start a new capture session.
  *  Create a capture child which is doing the real capture work.
index 8c5ec096af6a8d84bab9cafb5f4e8e810088c4d5..82241f404a1a166059717d5132cba76b865bcc49 100644 (file)
--- a/dumpcap.c
+++ b/dumpcap.c
@@ -42,9 +42,7 @@
 #include <conio.h>
 #endif
 
-#include "simple_dialog.h"
 #include "ringbuffer.h"
-#include "util.h"
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 #include "version_info.h"
 #include <pcap.h>
 #include "pcap-util.h"
 
-#include "capture.h"
-#include "capture_loop.h"
-#include "capture_info.h"
-
 #ifdef _WIN32
 #include "capture-wpcap.h"
 #include "capture_wpcap_packet.h"
 #endif
 
+#include "capture.h"
+#include "capture_loop.h"
+#include "capture_sync.h"
+
+#include "simple_dialog.h"
+#include "util.h"
 #include "log.h"
 #include "file_util.h"
 
@@ -601,19 +601,8 @@ console_log_handler(const char *log_domain, GLogLevelFlags log_level,
 #endif
 }
 
-
-/* Size of buffer to hold decimal representation of
-   signed/unsigned 64-bit int */
-#define SP_DECISIZE 20
-
-/*
- * Indications sent out on the sync pipe.
- */
-#define SP_FILE         'F'     /* the name of the recently opened file */
-#define SP_ERROR_MSG    'E'     /* error message */
-#define SP_PACKET_COUNT 'P'     /* count of packets captured since last message */
-#define SP_DROPS        'D'     /* count of packets dropped in capture */
-#define SP_QUIT         'Q'     /* capture quit message (from parent to child) */
+/****************************************************************************************************************/
+/* sync_pipe "dummies" */
 
 static void
 pipe_write_block(int pipe, char indicator, int len, const char *msg)
@@ -664,20 +653,7 @@ sync_pipe_drops_to_parent(int drops)
 
 
 /****************************************************************************************************************/
-/* link "dummies" */
-
-
-void main_window_update(void) {}
-
-
-
-void capture_info_ui_create(capture_info *cinfo, gchar *iface) {}
-
-void capture_info_ui_update(capture_info *cinfo) {
-    printf("Packets: %u\r", cinfo->counts->total);
-}
-
-void capture_info_ui_destroy(capture_info *cinfo) {}
+/* simple_dialog "dummies" */
 
 
 static gpointer *
index 8dc7b26f4624944d025b82b68be4dd967339d89e..6b503792b759f21833408172464b396e6f8f0cde 100644 (file)
@@ -61,6 +61,8 @@ typedef struct {
     GtkWidget               *cap_w;
     GtkWidget               *running_time_lb;
     capture_info_counts_t   counts[PACKET_COUNTS_SIZE];
+    guint                   timer_id;
+    time_t                  start_time;
 } capture_info_ui_t;
 
 
@@ -77,7 +79,18 @@ pct(gint num, gint denom) {
 
 static void
 capture_info_delete_cb(GtkWidget *w _U_, GdkEvent *event _U_, gpointer data _U_) {
-  capture_loop_stop();
+  capture_stop(capture_opts);
+}
+
+static gint
+capture_info_ui_update_cb(gpointer data)
+{
+  capture_info *cinfo = data;
+  capture_info_ui_t *info = cinfo->ui;
+
+  cinfo->running_time = time(NULL) - info->start_time;
+  capture_info_ui_update(cinfo);
+  return 1;   /* call the timer again */
 }
 
 
@@ -85,7 +98,7 @@ capture_info_delete_cb(GtkWidget *w _U_, GdkEvent *event _U_, gpointer data _U_)
 /* will keep pointers to the fields in the counts parameter */
 void capture_info_ui_create(
 capture_info    *cinfo,
-gchar           *iface)
+const gchar     *iface)
 {
   unsigned int      i;
   GtkWidget         *main_vb, *stop_bt, *counts_tb;
@@ -139,8 +152,6 @@ gchar           *iface)
   info->cap_w = dlg_window_new(cap_w_title);
   g_free(cap_w_title);
 
-  gtk_window_set_modal(GTK_WINDOW(info->cap_w), TRUE);
-
   /* Container for capture display widgets */
   main_vb = gtk_vbox_new(FALSE, 1);
   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
@@ -229,15 +240,20 @@ gchar           *iface)
 
   stop_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_STOP);
   window_set_cancel_button(info->cap_w, stop_bt, NULL);
-  SIGNAL_CONNECT(stop_bt, "clicked", capture_info_delete_cb, NULL);
+  SIGNAL_CONNECT(stop_bt, "clicked", capture_info_delete_cb, capture_opts);
 
   SIGNAL_CONNECT(info->cap_w, "delete_event", capture_info_delete_cb,
-                 NULL);
+                 capture_opts);
 
   gtk_widget_show(info->cap_w);
   window_present(info->cap_w);
 
+  info->start_time = time(NULL);
+
   cinfo->ui = info;
+
+  /* update the dialog once a second, even if no packets rushing in */
+  info->timer_id = gtk_timeout_add(1000, (GtkFunction)capture_info_ui_update_cb,(gpointer)cinfo);
 }
 
 
@@ -252,12 +268,13 @@ capture_info    *cinfo)
   capture_info_ui_t *info = cinfo->ui;
 
 
-  /* calculate and display running time */
+  /* display running time */
   g_snprintf(label_str, sizeof(label_str), "%02ld:%02ld:%02ld", 
            (long)(cinfo->running_time/3600), (long)((cinfo->running_time%3600)/60),
            (long)(cinfo->running_time%60));
   gtk_label_set(GTK_LABEL(info->running_time_lb), label_str);
 
+  /* if we have new packets, update all rows */
   if (cinfo->new_packets) {
 
     for (i = 0; i < PACKET_COUNTS_SIZE; i++) {
@@ -286,6 +303,8 @@ capture_info    *cinfo)
 {
   capture_info_ui_t *info = cinfo->ui;
 
+  gtk_timeout_remove(info->timer_id);
+
   /* called from capture engine, so it's ok to destroy the dialog here */
   gtk_grab_remove(GTK_WIDGET(info->cap_w));
   window_destroy(GTK_WIDGET(info->cap_w));