Put the low-level sync routines into a common file so they can be shared
by dumpcap and Ethereal (so that, on UN*X, the child process can report a detailed "can't exec dumpcap" error). Rename most of the "sync_pipe_XXX_to_parent()" routines, as they're also in Tethereal, which doesn't have a sync pipe. svn path=/trunk/; revision=17789
This commit is contained in:
parent
d5585760e7
commit
d260003026
|
@ -151,6 +151,7 @@ ethereal_SOURCES = \
|
|||
g711.c \
|
||||
merge.c \
|
||||
proto_hier_stats.c \
|
||||
sync_pipe_write.c \
|
||||
summary.c \
|
||||
tempfile.c
|
||||
|
||||
|
@ -176,6 +177,7 @@ ethereal_INCLUDES = \
|
|||
stat_menu.h \
|
||||
statusbar.h \
|
||||
summary.h \
|
||||
sync_pipe.h \
|
||||
tap_dfilter_dlg.h \
|
||||
ui_util.h
|
||||
|
||||
|
@ -225,6 +227,7 @@ dumpcap_SOURCES = \
|
|||
dumpcap.c \
|
||||
pcapio.c \
|
||||
ringbuffer.c \
|
||||
sync_pipe_write.c \
|
||||
tempfile.c \
|
||||
version_info.c
|
||||
|
||||
|
|
|
@ -528,7 +528,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
|
|||
"\n"
|
||||
"Nonetheless, the capture is started.\n",
|
||||
capture_opts->buffer_size);
|
||||
sync_pipe_errmsg_to_parent("Couldn't set the capture buffer size!",
|
||||
report_capture_error("Couldn't set the capture buffer size!",
|
||||
sync_secondary_msg_str);
|
||||
g_free(sync_secondary_msg_str);
|
||||
}
|
||||
|
@ -643,7 +643,7 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
|
|||
returned a warning; print it, but keep capturing. */
|
||||
if (open_err_str[0] != '\0') {
|
||||
sync_msg_str = g_strdup_printf("%s.", open_err_str);
|
||||
sync_pipe_errmsg_to_parent(sync_msg_str, "");
|
||||
report_capture_error(sync_msg_str, "");
|
||||
g_free(sync_msg_str);
|
||||
}
|
||||
|
||||
|
@ -825,7 +825,7 @@ capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
|
|||
if (sel_ret < 0 && errno != EINTR) {
|
||||
g_snprintf(errmsg, errmsg_len,
|
||||
"Unexpected error from select: %s", strerror(errno));
|
||||
sync_pipe_errmsg_to_parent(errmsg, please_report);
|
||||
report_capture_error(errmsg, please_report);
|
||||
ld->go = FALSE;
|
||||
}
|
||||
} else {
|
||||
|
@ -904,7 +904,7 @@ capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
|
|||
if (sel_ret < 0 && errno != EINTR) {
|
||||
g_snprintf(errmsg, errmsg_len,
|
||||
"Unexpected error from select: %s", strerror(errno));
|
||||
sync_pipe_errmsg_to_parent(errmsg, please_report);
|
||||
report_capture_error(errmsg, please_report);
|
||||
ld->go = FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1174,7 +1174,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
update its windows to indicate that we have a live capture in
|
||||
progress. */
|
||||
libpcap_dump_flush(ld.pdh, NULL);
|
||||
sync_pipe_filename_to_parent(capture_opts->save_file);
|
||||
report_new_capture_file(capture_opts->save_file);
|
||||
}
|
||||
|
||||
/* initialize capture stop (and alike) conditions */
|
||||
|
@ -1240,9 +1240,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
cnd_reset(cnd_file_duration);
|
||||
}
|
||||
libpcap_dump_flush(ld.pdh, NULL);
|
||||
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
|
||||
report_packet_count(inpkts_to_sync_pipe);
|
||||
inpkts_to_sync_pipe = 0;
|
||||
sync_pipe_filename_to_parent(capture_opts->save_file);
|
||||
report_new_capture_file(capture_opts->save_file);
|
||||
} else {
|
||||
/* File switch failed: stop here */
|
||||
ld.go = FALSE;
|
||||
|
@ -1279,7 +1279,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
|
||||
/* Send our parent a message saying we've written out "inpkts_to_sync_pipe"
|
||||
packets to the capture file. */
|
||||
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
|
||||
report_packet_count(inpkts_to_sync_pipe);
|
||||
|
||||
inpkts_to_sync_pipe = 0;
|
||||
}
|
||||
|
@ -1309,9 +1309,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
if(cnd_autostop_size)
|
||||
cnd_reset(cnd_autostop_size);
|
||||
libpcap_dump_flush(ld.pdh, NULL);
|
||||
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
|
||||
report_packet_count(inpkts_to_sync_pipe);
|
||||
inpkts_to_sync_pipe = 0;
|
||||
sync_pipe_filename_to_parent(capture_opts->save_file);
|
||||
report_new_capture_file(capture_opts->save_file);
|
||||
} else {
|
||||
/* File switch failed: stop here */
|
||||
ld.go = FALSE;
|
||||
|
@ -1343,11 +1343,11 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
if (ld.pcap_err) {
|
||||
g_snprintf(errmsg, sizeof(errmsg), "Error while capturing packets: %s",
|
||||
pcap_geterr(ld.pcap_h));
|
||||
sync_pipe_errmsg_to_parent(errmsg, please_report);
|
||||
report_capture_error(errmsg, please_report);
|
||||
}
|
||||
#ifndef _WIN32
|
||||
else if (ld.from_cap_pipe && ld.cap_pipe_err == PIPERR)
|
||||
sync_pipe_errmsg_to_parent(errmsg, "");
|
||||
report_capture_error(errmsg, "");
|
||||
#endif
|
||||
|
||||
/* did we had an error while capturing? */
|
||||
|
@ -1356,7 +1356,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
} else {
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, ld.err,
|
||||
FALSE);
|
||||
sync_pipe_errmsg_to_parent(errmsg, please_report);
|
||||
report_capture_error(errmsg, please_report);
|
||||
write_ok = FALSE;
|
||||
}
|
||||
|
||||
|
@ -1369,7 +1369,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
/* there might be packets not yet notified to the parent */
|
||||
/* (do this after closing the file, so all packets are already flushed) */
|
||||
if(inpkts_to_sync_pipe) {
|
||||
sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
|
||||
report_packet_count(inpkts_to_sync_pipe);
|
||||
inpkts_to_sync_pipe = 0;
|
||||
}
|
||||
|
||||
|
@ -1378,7 +1378,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
if (!close_ok && write_ok) {
|
||||
capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, err_close,
|
||||
TRUE);
|
||||
sync_pipe_errmsg_to_parent(errmsg, "");
|
||||
report_capture_error(errmsg, "");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1398,12 +1398,12 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
|
|||
if (pcap_stats(ld.pcap_h, stats) >= 0) {
|
||||
*stats_known = TRUE;
|
||||
/* Let the parent process know. */
|
||||
sync_pipe_drops_to_parent(stats->ps_drop);
|
||||
report_packet_drops(stats->ps_drop);
|
||||
} else {
|
||||
g_snprintf(errmsg, sizeof(errmsg),
|
||||
"Can't get packet-drop statistics: %s",
|
||||
pcap_geterr(ld.pcap_h));
|
||||
sync_pipe_errmsg_to_parent(errmsg, please_report);
|
||||
report_capture_error(errmsg, please_report);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1435,9 +1435,9 @@ error:
|
|||
}
|
||||
capture_opts->save_file = NULL;
|
||||
if (cfilter_error)
|
||||
sync_pipe_cfilter_error_to_parent(capture_opts->cfilter, errmsg);
|
||||
report_cfilter_error(capture_opts->cfilter, errmsg);
|
||||
else
|
||||
sync_pipe_errmsg_to_parent(errmsg, secondary_errmsg);
|
||||
report_capture_error(errmsg, secondary_errmsg);
|
||||
|
||||
/* close the input file (pcap or cap_pipe) */
|
||||
capture_loop_close_input(&ld);
|
||||
|
|
|
@ -159,4 +159,29 @@ capture_loop_init_output(capture_options *capture_opts, int save_file_fd, loop_d
|
|||
extern gboolean
|
||||
capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close);
|
||||
|
||||
/*
|
||||
* Routines called by the capture loop code to report things.
|
||||
*/
|
||||
|
||||
/** Report a new capture file having been opened. */
|
||||
extern void
|
||||
report_new_capture_file(const char *filename);
|
||||
|
||||
/** Report a number of new packets captured. */
|
||||
extern void
|
||||
report_packet_count(int packet_count);
|
||||
|
||||
/** Report the packet drops once the capture finishes. */
|
||||
extern void
|
||||
report_packet_drops(int drops);
|
||||
|
||||
/** Report an error in the capture. */
|
||||
extern void
|
||||
report_capture_error(const char *error_msg, const char *secondary_error_msg);
|
||||
|
||||
/** Report an error with a capture filter. */
|
||||
extern void
|
||||
report_cfilter_error(const char *cfilter, const char *errmsg);
|
||||
|
||||
|
||||
#endif /* capture_loop.h */
|
||||
|
|
|
@ -89,6 +89,8 @@
|
|||
#include "capture_sync.h"
|
||||
#include "simple_dialog.h"
|
||||
|
||||
#include "sync_pipe.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "capture-wpcap.h"
|
||||
#endif
|
||||
|
@ -405,11 +407,12 @@ sync_pipe_start(capture_options *capture_opts) {
|
|||
/* call dumpcap */
|
||||
if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
|
||||
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
|
||||
g_warning("Couldn't open dumpcap (Error: %u): %s", GetLastError(), args->str);
|
||||
capture_opts->fork_child = -1;
|
||||
} else {
|
||||
capture_opts->fork_child = (int) pi.hProcess;
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
||||
"Couldn't run %s in child process: error %u",
|
||||
args->str, GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
capture_opts->fork_child = (int) pi.hProcess;
|
||||
g_string_free(args, TRUE);
|
||||
|
||||
/* associate the operating system filehandle to a C run-time file handle */
|
||||
|
@ -440,10 +443,9 @@ sync_pipe_start(capture_options *capture_opts) {
|
|||
dup(sync_pipe[PIPE_WRITE]);
|
||||
eth_close(sync_pipe[PIPE_READ]);
|
||||
execv(exename, argv);
|
||||
/* XXX - find a way to send this message to the parent in a clean way */
|
||||
/*g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
|
||||
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
|
||||
exename, strerror(errno));
|
||||
sync_pipe_errmsg_to_parent(errmsg, "");*/
|
||||
sync_pipe_errmsg_to_parent(errmsg, "");
|
||||
|
||||
/* Exit with "_exit()", so that we don't close the connection
|
||||
to the X server (and cause stuff buffered up by our parent but
|
||||
|
|
|
@ -35,36 +35,6 @@
|
|||
#define __CAPTURE_SYNC_H__
|
||||
|
||||
|
||||
/*
|
||||
* Maximum length of sync pipe message data. Must be < 2^24, as the
|
||||
* message length is 3 bytes.
|
||||
* XXX - this must be large enough to handle a Really Big Filter
|
||||
* Expression, as the error message for an incorrect filter expression
|
||||
* is a bit larger than the filter expression.
|
||||
*/
|
||||
#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_BAD_FILTER 'B' /* error message for bad capture filter */
|
||||
#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.
|
||||
|
@ -87,29 +57,6 @@ sync_pipe_stop(capture_options *capture_opts);
|
|||
extern void
|
||||
sync_pipe_kill(capture_options *capture_opts);
|
||||
|
||||
|
||||
/** the child has opened a new capture file, notify the parent */
|
||||
extern void
|
||||
sync_pipe_filename_to_parent(const char *filename);
|
||||
|
||||
/** the child captured some new packets, notify the parent */
|
||||
extern void
|
||||
sync_pipe_packet_count_to_parent(int packet_count);
|
||||
|
||||
/** the child stopped capturing, notify the parent */
|
||||
extern void
|
||||
sync_pipe_drops_to_parent(int drops);
|
||||
|
||||
/** the child encountered an error with a capture filter, notify the parent */
|
||||
extern void
|
||||
sync_pipe_cfilter_error_to_parent(const char *cfilter, const char *errmsg);
|
||||
|
||||
/** the child encountered an error, notify the parent */
|
||||
extern void
|
||||
sync_pipe_errmsg_to_parent(const char *error_msg,
|
||||
const char *secondary_error_msg);
|
||||
|
||||
|
||||
/** does the parent signalled the child to stop */
|
||||
#ifdef _WIN32
|
||||
extern gboolean
|
||||
|
|
86
dumpcap.c
86
dumpcap.c
|
@ -54,6 +54,8 @@
|
|||
#include "capture-wpcap.h"
|
||||
#endif
|
||||
|
||||
#include "sync_pipe.h"
|
||||
|
||||
#include "capture.h"
|
||||
#include "capture_loop.h"
|
||||
#include "capture_sync.h"
|
||||
|
@ -506,70 +508,11 @@ console_log_handler(const char *log_domain, GLogLevelFlags log_level,
|
|||
|
||||
|
||||
/****************************************************************************************************************/
|
||||
/* sync_pipe handling */
|
||||
|
||||
|
||||
/* write a single message header to the recipient pipe */
|
||||
static int
|
||||
pipe_write_header(int pipe, char indicator, int length)
|
||||
{
|
||||
guchar header[1+3]; /* indicator + 3-byte len */
|
||||
|
||||
|
||||
g_assert(length <= SP_MAX_MSG_LEN);
|
||||
|
||||
/* write header (indicator + 3-byte len) */
|
||||
header[0] = indicator;
|
||||
header[1] = (length >> 16) & 0xFF;
|
||||
header[2] = (length >> 8) & 0xFF;
|
||||
header[3] = (length >> 0) & 0xFF;
|
||||
|
||||
/* write header */
|
||||
return write(pipe, header, sizeof header);
|
||||
}
|
||||
|
||||
|
||||
/* 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).
|
||||
If msg is NULL, the message has only a length and indicator. */
|
||||
static void
|
||||
pipe_write_block(int pipe, char indicator, const char *msg)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/*g_warning("write %d enter", pipe);*/
|
||||
|
||||
if(msg != NULL) {
|
||||
len = strlen(msg) + 1; /* including the terminating '\0'! */
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/* write header (indicator + 3-byte len) */
|
||||
ret = pipe_write_header(pipe, indicator, len);
|
||||
if(ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* write value (if we have one) */
|
||||
if(len) {
|
||||
/*g_warning("write %d indicator: %c value len: %u msg: %s", pipe, indicator, len, msg);*/
|
||||
ret = write(pipe, msg, len);
|
||||
if(ret == -1) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/*g_warning("write %d indicator: %c no value", pipe, indicator);*/
|
||||
}
|
||||
|
||||
/*g_warning("write %d leave", pipe);*/
|
||||
}
|
||||
/* indication report routines */
|
||||
|
||||
|
||||
void
|
||||
sync_pipe_packet_count_to_parent(int packet_count)
|
||||
report_packet_count(int packet_count)
|
||||
{
|
||||
char tmp[SP_DECISIZE+1+1];
|
||||
static int count = 0;
|
||||
|
@ -588,10 +531,10 @@ sync_pipe_packet_count_to_parent(int packet_count)
|
|||
}
|
||||
|
||||
void
|
||||
sync_pipe_filename_to_parent(const char *filename)
|
||||
report_new_capture_file(const char *filename)
|
||||
{
|
||||
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_MESSAGE, "File: %s", filename);
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "File: %s", filename);
|
||||
|
||||
if(capture_child) {
|
||||
pipe_write_block(1, SP_FILE, filename);
|
||||
|
@ -599,7 +542,7 @@ sync_pipe_filename_to_parent(const char *filename)
|
|||
}
|
||||
|
||||
void
|
||||
sync_pipe_cfilter_error_to_parent(const char *cfilter _U_, const char *errmsg)
|
||||
report_cfilter_error(const char *cfilter _U_, const char *errmsg)
|
||||
{
|
||||
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Capture filter error: %s", errmsg);
|
||||
|
@ -610,30 +553,27 @@ sync_pipe_cfilter_error_to_parent(const char *cfilter _U_, const char *errmsg)
|
|||
}
|
||||
|
||||
void
|
||||
sync_pipe_errmsg_to_parent(const char *error_msg, const char *secondary_error_msg)
|
||||
report_capture_error(const char *error_msg, const char *secondary_error_msg)
|
||||
{
|
||||
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_MESSAGE,
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
|
||||
"Primary Error: %s", error_msg);
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_MESSAGE,
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
|
||||
"Secondary Error: %s", secondary_error_msg);
|
||||
|
||||
if(capture_child) {
|
||||
/* first write a "master header" with the length of the two messages plus their "slave headers" */
|
||||
pipe_write_header(1, SP_ERROR_MSG, strlen(error_msg) + 1 + 4 + strlen(secondary_error_msg) + 1 + 4);
|
||||
pipe_write_block(1, SP_ERROR_MSG, error_msg);
|
||||
pipe_write_block(1, SP_ERROR_MSG, secondary_error_msg);
|
||||
sync_pipe_errmsg_to_parent(error_msg, secondary_error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sync_pipe_drops_to_parent(int drops)
|
||||
report_packet_drops(int drops)
|
||||
{
|
||||
char tmp[SP_DECISIZE+1+1];
|
||||
|
||||
|
||||
g_snprintf(tmp, sizeof(tmp), "%d", drops);
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_MESSAGE, "Packets dropped: %s", tmp);
|
||||
g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "Packets dropped: %s", tmp);
|
||||
|
||||
if(capture_child) {
|
||||
pipe_write_block(1, SP_DROPS, tmp);
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/* sync_pipe.h
|
||||
* Low-level synchronization pipe routines for use by Ethereal and dumpcap
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Low-level sync pipe interfaces.
|
||||
*/
|
||||
|
||||
#ifndef __SYNC_PIPE_H__
|
||||
#define __SYNC_PIPE_H__
|
||||
|
||||
|
||||
/*
|
||||
* Maximum length of sync pipe message data. Must be < 2^24, as the
|
||||
* message length is 3 bytes.
|
||||
* XXX - this must be large enough to handle a Really Big Filter
|
||||
* Expression, as the error message for an incorrect filter expression
|
||||
* is a bit larger than the filter expression.
|
||||
*/
|
||||
#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_BAD_FILTER 'B' /* error message for bad capture filter */
|
||||
#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 single message header to the recipient pipe */
|
||||
extern int
|
||||
pipe_write_header(int pipe, char indicator, int length);
|
||||
|
||||
/* 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).
|
||||
If msg is NULL, the message has only a length and indicator. */
|
||||
extern void
|
||||
pipe_write_block(int pipe, char indicator, const char *msg);
|
||||
|
||||
/** the child encountered an error, notify the parent */
|
||||
extern void
|
||||
sync_pipe_errmsg_to_parent(const char *error_msg,
|
||||
const char *secondary_error_msg);
|
||||
|
||||
#endif /* sync_pipe.h */
|
|
@ -0,0 +1,110 @@
|
|||
/* sync_pipe_write.c
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "sync_pipe.h"
|
||||
#include "log.h"
|
||||
|
||||
/****************************************************************************************************************/
|
||||
/* sync_pipe handling */
|
||||
|
||||
|
||||
/* write a single message header to the recipient pipe */
|
||||
int
|
||||
pipe_write_header(int pipe, char indicator, int length)
|
||||
{
|
||||
guchar header[1+3]; /* indicator + 3-byte len */
|
||||
|
||||
|
||||
g_assert(length <= SP_MAX_MSG_LEN);
|
||||
|
||||
/* write header (indicator + 3-byte len) */
|
||||
header[0] = indicator;
|
||||
header[1] = (length >> 16) & 0xFF;
|
||||
header[2] = (length >> 8) & 0xFF;
|
||||
header[3] = (length >> 0) & 0xFF;
|
||||
|
||||
/* write header */
|
||||
return write(pipe, header, sizeof header);
|
||||
}
|
||||
|
||||
|
||||
/* 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).
|
||||
If msg is NULL, the message has only a length and indicator. */
|
||||
void
|
||||
pipe_write_block(int pipe, char indicator, const char *msg)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/*g_warning("write %d enter", pipe);*/
|
||||
|
||||
if(msg != NULL) {
|
||||
len = strlen(msg) + 1; /* including the terminating '\0'! */
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/* write header (indicator + 3-byte len) */
|
||||
ret = pipe_write_header(pipe, indicator, len);
|
||||
if(ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* write value (if we have one) */
|
||||
if(len) {
|
||||
/*g_warning("write %d indicator: %c value len: %u msg: %s", pipe, indicator, len, msg);*/
|
||||
ret = write(pipe, msg, len);
|
||||
if(ret == -1) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/*g_warning("write %d indicator: %c no value", pipe, indicator);*/
|
||||
}
|
||||
|
||||
/*g_warning("write %d leave", pipe);*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sync_pipe_errmsg_to_parent(const char *error_msg, const char *secondary_error_msg)
|
||||
{
|
||||
|
||||
/* first write a "master header" with the length of the two messages plus their "slave headers" */
|
||||
pipe_write_header(1, SP_ERROR_MSG, strlen(error_msg) + 1 + 4 + strlen(secondary_error_msg) + 1 + 4);
|
||||
pipe_write_block(1, SP_ERROR_MSG, error_msg);
|
||||
pipe_write_block(1, SP_ERROR_MSG, secondary_error_msg);
|
||||
}
|
40
tethereal.c
40
tethereal.c
|
@ -2995,37 +2995,45 @@ cmdarg_err_cont(const char *fmt, ...)
|
|||
|
||||
|
||||
/****************************************************************************************************************/
|
||||
/* sync pipe "dummies", needed for capture_loop.c */
|
||||
/* indication report "dummies", needed for capture_loop.c */
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
|
||||
/** the child has opened a new capture file, notify the parent */
|
||||
/** Report a new capture file having been opened. */
|
||||
void
|
||||
sync_pipe_filename_to_parent(const char *filename)
|
||||
report_new_capture_file(const char *filename)
|
||||
{
|
||||
/* shouldn't happen */
|
||||
g_assert(0);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/** the child captured some new packets, notify the parent */
|
||||
/** Report a number of new packets captured. */
|
||||
void
|
||||
sync_pipe_packet_count_to_parent(int packet_count)
|
||||
report_packet_count(int packet_count)
|
||||
{
|
||||
/* shouldn't happen */
|
||||
g_assert(0);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/** the child stopped capturing, notify the parent */
|
||||
/** Report the packet drops once the capture finishes. */
|
||||
void
|
||||
sync_pipe_drops_to_parent(int drops)
|
||||
report_packet_drops(int drops)
|
||||
{
|
||||
/* shouldn't happen */
|
||||
g_assert(0);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/** the child encountered an error with a capture filter, notify the parent */
|
||||
/** Report an error in the capture. */
|
||||
void
|
||||
report_capture_error(const char *errmsg, const char *secondary_error_msg)
|
||||
{
|
||||
cmdarg_err(errmsg);
|
||||
cmdarg_err_cont(secondary_error_msg);
|
||||
}
|
||||
|
||||
/** Report an error with a capture filter. */
|
||||
void
|
||||
sync_pipe_cfilter_error_to_parent(const char *cfilter, const char *errmsg)
|
||||
report_cfilter_error(const char *cfilter, const char *errmsg)
|
||||
{
|
||||
|
||||
cmdarg_err(
|
||||
|
@ -3036,14 +3044,6 @@ sync_pipe_cfilter_error_to_parent(const char *cfilter, const char *errmsg)
|
|||
cfilter, errmsg);
|
||||
}
|
||||
|
||||
/** the child encountered an error, notify the parent */
|
||||
void
|
||||
sync_pipe_errmsg_to_parent(const char *errmsg, const char *secondary_error_msg)
|
||||
{
|
||||
cmdarg_err(errmsg);
|
||||
cmdarg_err_cont(secondary_error_msg);
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBPCAP */
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue