From e829856c0c03666c5b9b917fba4716b88fd580e6 Mon Sep 17 00:00:00 2001 From: Ulf Lamping Date: Sun, 4 Dec 2005 02:04:18 +0000 Subject: move the complete functionality of the capture info dialog from capture_loop.c to capture_info.c and call it from capture.c (instead of capture_loop.c). 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). svn path=/trunk/; revision=16669 --- Makefile.common | 1 - capture.c | 16 ++++++- capture_info.c | 114 +++++++++++++++++++++++++++++++++++++++++-------- capture_info.h | 16 +++++-- capture_loop.c | 61 +++----------------------- capture_sync.c | 19 +-------- capture_sync.h | 19 +++++++++ dumpcap.c | 42 ++++-------------- gtk/capture_info_dlg.c | 33 +++++++++++--- 9 files changed, 185 insertions(+), 136 deletions(-) diff --git a/Makefile.common b/Makefile.common index a1322f1d9f..e950b5df93 100644 --- a/Makefile.common +++ b/Makefile.common @@ -217,7 +217,6 @@ dumpcap_SOURCES = \ version_info.c \ capture_opts.c \ capture_loop.c \ - capture_info.c \ dumpcap.c diff --git a/capture.c b/capture.c index 074acc3fe7..f1cb5501aa 100644 --- 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 */ diff --git a/capture_info.c b/capture_info.c index 473b93a6ec..05a09542d2 100644 --- a/capture_info.c +++ b/capture_info.c @@ -56,26 +56,106 @@ #include -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); diff --git a/capture_info.h b/capture_info.h index 02e1f210aa..fefedbf564 100644 --- a/capture_info.h +++ b/capture_info.h @@ -33,10 +33,18 @@ #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( diff --git a/capture_loop.c b/capture_loop.c index bfa078b710..08073b5eb7 100644 --- a/capture_loop.c +++ b/capture_loop.c @@ -62,18 +62,16 @@ #include #include -#include #include -#include +#include +#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" @@ -82,12 +80,8 @@ #include "wiretap/wtap.h" #include "wiretap/wtap-capture.h" -/* XXX - try to remove this later */ -#include -#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 */ diff --git a/capture_sync.c b/capture_sync.c index 888f4dbceb..d291df4886 100644 --- a/capture_sync.c +++ b/capture_sync.c @@ -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 diff --git a/capture_sync.h b/capture_sync.h index d734641d41..6e8dea1a09 100644 --- a/capture_sync.h +++ b/capture_sync.h @@ -38,6 +38,25 @@ #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. diff --git a/dumpcap.c b/dumpcap.c index 8c5ec096af..82241f404a 100644 --- a/dumpcap.c +++ b/dumpcap.c @@ -42,9 +42,7 @@ #include #endif -#include "simple_dialog.h" #include "ringbuffer.h" -#include "util.h" #include "clopts_common.h" #include "cmdarg_err.h" #include "version_info.h" @@ -52,15 +50,17 @@ #include #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 * diff --git a/gtk/capture_info_dlg.c b/gtk/capture_info_dlg.c index 8dc7b26f46..6b503792b7 100644 --- a/gtk/capture_info_dlg.c +++ b/gtk/capture_info_dlg.c @@ -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)); -- cgit v1.2.3