#include <signal.h>
#ifdef _WIN32
-#include "epan/unicode-utils.h"
+#include <wsutil/unicode-utils.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include "globals.h"
#include "file.h"
#include <epan/filesystem.h>
+#include <epan/report_err.h>
#include "capture.h"
#include "capture_sync.h"
-#include "simple_dialog.h"
#include "sync_pipe.h"
#include "capture-wpcap.h"
#endif
#include "ui_util.h"
-#include "file_util.h"
+#include <wsutil/file_util.h>
#include "log.h"
#ifdef _WIN32
argv = init_pipe_args(&argc);
if (!argv) {
/* We don't know where to find dumpcap. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
+ report_failure("We don't know where to find dumpcap.");
return FALSE;
}
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
+
argv = sync_pipe_add_arg(argv, &argc, "-i");
argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
if (capture_opts->linktype != -1) {
argv = sync_pipe_add_arg(argv, &argc, "-y");
-#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
-#else
- /* we can't get the type name, just treat it as a number */
- g_snprintf(sdlt, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
-#endif
argv = sync_pipe_add_arg(argv, &argc, sdlt);
}
#ifdef _WIN32
argv = sync_pipe_add_arg(argv, &argc, "-B");
+#ifdef HAVE_PCAP_REMOTE
+ if (capture_opts->src_type == CAPTURE_IFREMOTE)
+ /* No buffer size when using remote interfaces */
+ g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
+ else
+#endif
g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
argv = sync_pipe_add_arg(argv, &argc, buffer_size);
#endif
/* (increase this value if you have trouble while fast capture file switches) */
if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
/* Couldn't create the pipe between parent and child. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
- strerror(errno));
+ report_failure("Couldn't create sync pipe: %s", strerror(errno));
g_free( (gpointer) argv[0]);
g_free( (gpointer) argv);
return FALSE;
if (signal_pipe == INVALID_HANDLE_VALUE) {
/* Couldn't create the signal pipe between parent and child. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
- strerror(errno));
+ report_failure("Couldn't create signal pipe: %s", strerror(errno));
g_free( (gpointer) argv[0]);
g_free( (gpointer) argv);
return FALSE;
/* call dumpcap */
if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Couldn't run %s in child process: error %u",
- args->str, GetLastError());
+ report_failure("Couldn't run %s in child process: error %u",
+ args->str, GetLastError());
CloseHandle(sync_pipe_read);
CloseHandle(sync_pipe_write);
g_free( (gpointer) argv[0]);
#else /* _WIN32 */
if (pipe(sync_pipe) < 0) {
/* Couldn't create the pipe between parent and child. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
- strerror(errno));
+ report_failure("Couldn't create sync pipe: %s", strerror(errno));
g_free( (gpointer) argv[0]);
g_free(argv);
return FALSE;
* it just capture with the specified capture parameters
*/
dup2(sync_pipe[PIPE_WRITE], 2);
- eth_close(sync_pipe[PIPE_READ]);
+ ws_close(sync_pipe[PIPE_READ]);
execv(argv[0], (gpointer)argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], strerror(errno));
#ifdef _WIN32
CloseHandle(sync_pipe_write);
#else
- eth_close(sync_pipe[PIPE_WRITE]);
+ ws_close(sync_pipe[PIPE_WRITE]);
#endif
if (capture_opts->fork_child == -1) {
/* We couldn't even create the child process. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Couldn't create child process: %s", strerror(errno));
- eth_close(sync_pipe_read_fd);
+ report_failure("Couldn't create child process: %s", strerror(errno));
+ ws_close(sync_pipe_read_fd);
#ifdef _WIN32
- eth_close(capture_opts->signal_pipe_write_fd);
+ ws_close(capture_opts->signal_pipe_write_fd);
#endif
return FALSE;
}
* it just capture with the specified capture parameters
*/
dup2(sync_pipe[PIPE_WRITE], 1);
- eth_close(sync_pipe[PIPE_READ]);
+ ws_close(sync_pipe[PIPE_READ]);
execv(argv[0], (gpointer)argv);
g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
argv[0], strerror(errno));
#ifdef _WIN32
CloseHandle(sync_pipe_write);
#else
- eth_close(sync_pipe[PIPE_WRITE]);
+ ws_close(sync_pipe[PIPE_WRITE]);
#endif
if (*fork_child == -1) {
/* We couldn't even create the child process. */
*msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
- eth_close(*read_fd);
+ ws_close(*read_fd);
return CANT_RUN_DUMPCAP;
}
#endif
int fork_child_status;
- eth_close(*read_fd);
+ ws_close(*read_fd);
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
/* We were able to set up to read dumpcap's output. Do so and
return its exit value. */
msg_buf = g_string_new("");
- while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
+ while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
buf[count] = '\0';
g_string_append(msg_buf, buf);
}
argv = sync_pipe_add_arg(argv, &argc, "-D");
argv = sync_pipe_add_arg(argv, &argc, "-M");
- /* dumpcap should be running in capture child mode (hidden feature) */
+#if 0
+ /* dumpcap should be running in capture child mode (hidden feature) */
+ /* XXX: Actually: don't run dumpcap in capture_child_mode. */
+ /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
+ /* stderr in normal format and are then sent to whereever our stderr goes. */
+ /* Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
+ /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
+ /* msgs to stderr in a special type/len/string format which would then */
+ /* currently be sent as is to stderr resulting in garbled output. */
+ /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
+ /* special format error messages to stderr are captured and returned to caller */
+ /* (eg: so can be processed and displayed in a pop-up box). */
#ifndef DEBUG_CHILD
argv = sync_pipe_add_arg(argv, &argc, "-Z");
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
+#endif
#endif
return sync_pipe_run_command(argv, msg);
argv = sync_pipe_add_arg(argv, &argc, "-L");
argv = sync_pipe_add_arg(argv, &argc, "-M");
- /* dumpcap should be running in capture child mode (hidden feature) */
+#if 0
+ /* dumpcap should be running in capture child mode (hidden feature) */
+ /* XXX: Actually: don't run dumpcap in capture_child_mode. */
+ /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
+ /* stderr in normal format and are then sent to whereever our stderr goes. */
+ /* Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
+ /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
+ /* msgs to stderr in a special type/len/string format which would then */
+ /* currently be sent as is to stderr resulting in garbled output. */
+ /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
+ /* special format error messages to stderr are captured and returned to caller */
+ /* (eg: so can be processed and displayed in a pop-up box). */
#ifndef DEBUG_CHILD
argv = sync_pipe_add_arg(argv, &argc, "-Z");
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
-
+#endif
return sync_pipe_run_command(argv, msg);
}
return -1;
}
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
argv = init_pipe_args(&argc);
return CANT_RUN_DUMPCAP;
}
- /* Ask for the linktype list */
+ /* Ask for the interface statistics */
argv = sync_pipe_add_arg(argv, &argc, "-S");
argv = sync_pipe_add_arg(argv, &argc, "-M");
- /* dumpcap should be running in capture child mode (hidden feature) */
+#if 0
+ /* dumpcap should be running in capture child mode (hidden feature) */
+ /* XXX: Actually: don't run dumpcap in capture_child_mode. */
+ /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
+ /* stderr in normal format and are then sent to whereever our stderr goes. */
+ /* Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
+ /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
+ /* msgs to stderr in a special type/len/string format which would then */
+ /* currently be sent as is to stderr resulting in garbled output. */
+ /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
+ /* special format error messages to stderr are captured and returned to caller */
+ /* (eg: so can be processed and displayed in a pop-up box). */
#ifndef DEBUG_CHILD
argv = sync_pipe_add_arg(argv, &argc, "-Z");
argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
#endif
-
+#endif
return sync_pipe_open_command(argv, read_fd, fork_child, msg);
}
/* Read a line from a pipe, similar to fgets */
int
-sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
+sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
int newly;
int offset = -1;
while(offset < max - 1) {
offset++;
- if (! pipe_data_available(pipe))
+ if (! pipe_data_available(pipe_fd))
break;
- newly = read(pipe, &bytes[offset], 1);
+ newly = read(pipe_fd, &bytes[offset], 1);
if (newly == 0) {
/* EOF - not necessarily an error */
break;
} else if (newly < 0) {
/* error */
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
- "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
+ "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
return newly;
} else if (bytes[offset] == '\n') {
break;
return -1;
}
+ /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
"read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
len, msg);
sync_pipe_wait_for_child(capture_opts);
#ifdef _WIN32
- eth_close(capture_opts->signal_pipe_write_fd);
+ ws_close(capture_opts->signal_pipe_write_fd);
#endif
capture_input_closed(capture_opts);
return FALSE;
/* We weren't able to open the new capture file; user has been
alerted. Close the sync pipe. */
- eth_close(source);
+ ws_close(source);
/* the child has send us a filename which we couldn't open.
this probably means, the child is creating files faster than we can handle it.
/* the capture child will close the sync_pipe, nothing to do for now */
break;
case SP_DROPS:
- capture_input_drops(capture_opts, atoi(buffer));
+ capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
break;
default:
g_assert_not_reached();
#ifdef _WIN32
if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Child capture process stopped unexpectedly (errno:%u)", errno);
+ report_failure("Child capture process stopped unexpectedly (errno:%u)",
+ errno);
}
#else
if (wait(&wstatus) != -1) {
/* If there are situations where the child won't send us such an error message, */
/* this should be fixed in the child and not here! */
if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Child capture process exited: exit status %d",
- WEXITSTATUS(wstatus));
+ report_failure("Child capture process exited: exit status %d",
+ WEXITSTATUS(wstatus));
}
} else if (WIFSTOPPED(wstatus)) {
/* It stopped, rather than exiting. "Should not happen." */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Child capture process stopped: %s",
- sync_pipe_signame(WSTOPSIG(wstatus)));
+ report_failure("Child capture process stopped: %s",
+ sync_pipe_signame(WSTOPSIG(wstatus)));
} else if (WIFSIGNALED(wstatus)) {
/* It died with a signal. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Child capture process died: %s%s",
- sync_pipe_signame(WTERMSIG(wstatus)),
- WCOREDUMP(wstatus) ? " - core dumped" : "");
+ report_failure("Child capture process died: %s%s",
+ sync_pipe_signame(WTERMSIG(wstatus)),
+ WCOREDUMP(wstatus) ? " - core dumped" : "");
} else {
/* What? It had to either have exited, or stopped, or died with
a signal; what happened here? */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Child capture process died: wait status %#o", wstatus);
+ report_failure("Child capture process died: wait status %#o", wstatus);
}
}
#endif
if (capture_opts->fork_child != -1) {
#ifndef _WIN32
/* send the SIGUSR1 signal to close the capture child gracefully. */
- kill(capture_opts->fork_child, SIGUSR1);
+ int sts = kill(capture_opts->fork_child, SIGUSR1);
+ if (sts != 0) {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
+ "Sending SIGUSR1 to child failed: %s\n", strerror(errno));
+ }
#else
#define STOP_SLEEP_TIME 500 /* ms */
#define STOP_CHECK_TIME 50
void
sync_pipe_kill(int fork_child)
{
- if (fork_child != -1) {
+ if (fork_child != -1) {
#ifndef _WIN32
- kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
+ int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
+ if (sts != 0) {
+ g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
+ "Sending SIGTERM to child failed: %s\n", strerror(errno));
+ }
#else
/* Remark: This is not the preferred method of closing a process!
* the clean way would be getting the process id of the child process,
* us, as we might not be running in a console.
* And this also will require to have the process id.
*/
- TerminateProcess((HANDLE) (fork_child), 0);
+ TerminateProcess((HANDLE) (fork_child), 0);
#endif
- }
+ }
}
#endif /* HAVE_LIBPCAP */