*
* 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
#ifdef HAVE_LIBPCAP
static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
-static int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
+static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
char **err_msg);
pointers, *not* counting the NULL pointer at the end, so we have
to add 2 in order to get the new size of the array, including the
new pointer and the terminating NULL pointer. */
- args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
+ args = (const char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
/* Stuff the pointer into the penultimate element of the array, which
is the one at the index specified by "*argc". */
/* Allocate the string pointer array with enough space for the
terminating NULL pointer. */
*argc = 0;
- argv = g_malloc(sizeof (char *));
+ argv = (const char **)g_malloc(sizeof (char *));
*argv = NULL;
/* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
gboolean
sync_pipe_start(capture_options *capture_opts) {
char ssnap[ARGV_NUMBER_LEN];
- char sdlt[ARGV_NUMBER_LEN];
char scount[ARGV_NUMBER_LEN];
char sfilesize[ARGV_NUMBER_LEN];
char sfile_duration[ARGV_NUMBER_LEN];
argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
}
+ if (capture_opts->group_read_access) {
+ argv = sync_pipe_add_arg(argv, &argc, "-g");
+ }
+
for (j = 0; j < capture_opts->ifaces->len; j++) {
interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
if (interface_opts.linktype != -1) {
argv = sync_pipe_add_arg(argv, &argc, "-y");
- g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
- argv = sync_pipe_add_arg(argv, &argc, sdlt);
+ argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
}
if (!interface_opts.promisc_mode) {
}
#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
- if (interface_opts.buffer_size != 1) {
+ if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
argv = sync_pipe_add_arg(argv, &argc, "-B");
g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
argv = sync_pipe_add_arg(argv, &argc, buffer_size);
*/
dup2(sync_pipe[PIPE_WRITE], 2);
ws_close(sync_pipe[PIPE_READ]);
- execv(argv[0], (gpointer)argv);
+ execv(argv[0], (char * const*)argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], g_strerror(errno));
sync_pipe_errmsg_to_parent(2, errmsg, "");
dup2(sync_pipe[PIPE_WRITE], 2);
ws_close(sync_pipe[PIPE_READ]);
ws_close(sync_pipe[PIPE_WRITE]);
- execv(argv[0], (gpointer)argv);
+ execv(argv[0], (char * const*)argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], g_strerror(errno));
sync_pipe_errmsg_to_parent(2, errmsg, "");
int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
char *wait_msg;
gchar buffer[PIPE_BUF_SIZE+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_msg_len;
char *primary_msg_text;
char *secondary_msg_text;
char *combined_msg;
GString *data_buf = NULL;
- int count;
+ ssize_t count;
ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
&fork_child, &msg);
*/
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
primary_msg_text = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+ pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
&secondary_msg_len);
secondary_msg_text = primary_msg_text + primary_msg_len + 4;
/* the capture child will close the sync_pipe, nothing to do */
return ret;
}
+int
+sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
+ gchar **data, gchar **primary_msg,
+ gchar **secondary_msg)
+{
+ int argc, ret;
+ const char **argv;
+ gchar *opt;
+
+ argv = init_pipe_args(&argc);
+
+ if (!argv) {
+ *primary_msg = g_strdup("We don't know where to find dumpcap.");
+ *secondary_msg = NULL;
+ *data = NULL;
+ return -1;
+ }
+
+ argv = sync_pipe_add_arg(argv, &argc, "-i");
+ argv = sync_pipe_add_arg(argv, &argc, iface);
+
+ if (type)
+ opt = g_strdup_printf("%s,%s", freq, type);
+ else
+ opt = g_strdup_printf("%s", freq);
+
+ if (!opt) {
+ *primary_msg = g_strdup("Out of mem.");
+ *secondary_msg = NULL;
+ *data = NULL;
+ return -1;
+ }
+
+ argv = sync_pipe_add_arg(argv, &argc, "-k");
+ argv = sync_pipe_add_arg(argv, &argc, opt);
+
+#ifndef DEBUG_CHILD
+ /* Run dumpcap in capture child mode */
+ argv = sync_pipe_add_arg(argv, &argc, "-Z");
+ argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
+#endif
+
+ ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
+ g_free(opt);
+ return ret;
+}
+
/*
* Get the list of interfaces using dumpcap.
*
int message_read_fd, ret;
char *wait_msg;
gchar buffer[PIPE_BUF_SIZE+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_msg_len;
char *primary_msg_text;
*/
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
primary_msg_text = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
+ pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
&secondary_msg_len);
/*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
/* the capture child will close the sync_pipe, nothing to do */
int
sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
{
+#ifndef _WIN32
+ /*
+ * Don't bother waiting for the child. sync_pipe_close_command
+ * does this for us on Windows.
+ */
+ sync_pipe_kill(*fork_child);
+#endif
return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
}
/* read a number of bytes from a pipe */
/* (blocks until enough bytes read or an error occurs) */
-static int
+static ssize_t
pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
{
- int newly;
- int offset = 0;
+ ssize_t newly;
+ ssize_t offset = 0;
int error;
while(required) {
return newly;
}
- required -= newly;
+ required -= (int)newly;
offset += newly;
}
/* Read a line from a pipe, similar to fgets */
int
sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
- int newly;
+ ssize_t newly;
int offset = -1;
while(offset < max - 1) {
if (newly == 0) {
/* EOF - not necessarily an error */
break;
- } else if (newly < 0) {
+ } else if (newly == -1) {
/* error */
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
"read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
- return newly;
+ return -1;
} else if (bytes[offset] == '\n') {
break;
}
/* convert header values */
*indicator = header[0];
- *block_len = header[1]<<16 | header[2]<<8 | header[3];
+ *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
}
/* read a message from the sending pipe in the standard format
(1-byte message indicator, 3-byte message length (excluding length
and indicator field), and the rest is the message) */
-static int
+static ssize_t
pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
char **err_msg)
{
int required;
- int newly;
- guchar header[4];
+ ssize_t newly;
+ gchar header[4];
/* read header (indicator and 3-byte length) */
newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
return 0;
}
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
- "read %d failed to read header: %u", pipe_fd, newly);
+ "read %d failed to read header: %lu", pipe_fd, (long)newly);
if (newly != -1) {
/*
* Short read, but not an immediate EOF.
*/
- *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
- newly);
+ *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
+ (long)newly);
}
return -1;
}
/* convert header values */
- pipe_convert_header(header, 4, indicator, &required);
+ pipe_convert_header((guchar*)header, 4, indicator, &required);
/* only indicator with no value? */
if(required == 0) {
/* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
memcpy(msg, header, sizeof(header));
newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
+ if (newly < 0) { /* error */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
+ "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
+ }
*err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
msg);
return -1;
capture_options *capture_opts = (capture_options *)user_data;
int ret;
char buffer[SP_MAX_MSG_LEN+1];
- int nread;
+ ssize_t nread;
char indicator;
int primary_len;
char *primary_msg;
int secondary_len;
char *secondary_msg;
char *wait_msg, *combined_msg;
+ int npackets;
nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
&primary_msg);
}
break;
case SP_PACKET_COUNT:
- nread = atoi(buffer);
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
- capture_input_new_packets(capture_opts, nread);
+ npackets = atoi(buffer);
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
+ capture_input_new_packets(capture_opts, npackets);
break;
case SP_ERROR_MSG:
/* convert primary message */
- pipe_convert_header(buffer, 4, &indicator, &primary_len);
+ pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
primary_msg = buffer+4;
/* convert secondary message */
- pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
+ pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
secondary_msg = primary_msg + primary_len + 4;
/* message output */
capture_input_error_message(capture_opts, primary_msg, secondary_msg);
break;
case SP_BAD_FILTER: {
char *ch;
- int index;
+ int indx;
ch = strtok(buffer, ":");
- index = (int)strtol(ch, NULL, 10);
+ indx = (int)strtol(ch, NULL, 10);
ch = strtok(NULL, ":");
- capture_input_cfilter_error_message(capture_opts, index, ch);
+ capture_input_cfilter_error_message(capture_opts, indx, ch);
/* the capture child will close the sync_pipe, nothing to do for now */
break;
}
{
int fork_child_status;
int ret;
+ GTimeVal start_time;
+ GTimeVal end_time;
+ float elapsed;
+
+ /*
+ * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
+ * replace this
+ */
+ g_get_current_time(&start_time);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
g_assert(fork_child != -1);
}
#endif
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
+ g_get_current_time(&end_time);
+ elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
+ ((end_time.tv_usec - start_time.tv_usec) / 1e6));
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
return ret;
}