2 * Synchronisation between Wireshark capture parent and child instances
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
44 #include <wsutil/unicode-utils.h>
47 #ifdef HAVE_SYS_WAIT_H
48 # include <sys/wait.h>
51 #include "caputils/capture-pcap-util.h"
55 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
56 * macros) on UNIX systems that don't have them.
59 # define WIFEXITED(status) (((status) & 0177) == 0)
62 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
65 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
68 # define WEXITSTATUS(status) ((status) >> 8)
71 # define WTERMSIG(status) ((status) & 0177)
74 # define WCOREDUMP(status) ((status) & 0200)
77 # define WSTOPSIG(status) ((status) >> 8)
81 #include <epan/packet.h>
82 #include <epan/prefs.h>
87 #include "ui/capture.h"
88 #include <capchild/capture_sync.h>
90 #include "sync_pipe.h"
93 #include "caputils/capture-wpcap.h"
96 #include "ui/ui_util.h"
98 #include <wsutil/filesystem.h>
99 #include <wsutil/file_util.h>
100 #include <wsutil/report_err.h>
107 #include <process.h> /* For spawning child process */
113 static void create_dummy_signal_pipe();
114 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
115 static gchar *dummy_control_id;
117 static const char *sync_pipe_signame(int);
121 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
122 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
123 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
124 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
127 static void (*fetch_dumpcap_pid)(int) = NULL;
131 capture_session_init(capture_session *cap_session, void *cf)
133 cap_session->cf = cf;
134 cap_session->fork_child = -1; /* invalid process handle */
136 cap_session->signal_pipe_write_fd = -1;
138 cap_session->state = CAPTURE_STOPPED;
140 cap_session->owner = getuid();
141 cap_session->group = getgid();
143 cap_session->session_started = FALSE;
146 /* Append an arg (realloc) to an argc/argv array */
147 /* (add a string pointer to a NULL-terminated array of string pointers) */
149 sync_pipe_add_arg(char **args, int *argc, const char *arg)
151 /* Grow the array; "*argc" currently contains the number of string
152 pointers, *not* counting the NULL pointer at the end, so we have
153 to add 2 in order to get the new size of the array, including the
154 new pointer and the terminating NULL pointer. */
155 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
157 /* Stuff the pointer into the penultimate element of the array, which
158 is the one at the index specified by "*argc". */
159 args[*argc] = g_strdup(arg);
160 /* Now bump the count. */
163 /* We overwrite the NULL pointer; put it back right after the
173 /* Quote the argument element if necessary, so that it will get
174 * reconstructed correctly in the C runtime startup code. Note that
175 * the unquoting algorithm in the C runtime is really weird, and
176 * rather different than what Unix shells do. See stdargv.c in the C
177 * runtime sources (in the Platform SDK, in src/crt).
179 * Stolen from GLib's protect_argv(), an internal routine that quotes
180 * string in an argument list so that they arguments will be handled
181 * correctly in the command-line string passed to CreateProcess()
182 * if that string is constructed by gluing those strings together.
185 protect_arg (const gchar *argv)
188 const gchar *p = argv;
191 gboolean need_dblquotes = FALSE;
194 if (*p == ' ' || *p == '\t')
195 need_dblquotes = TRUE;
198 else if (*p == '\\') {
201 while (*pp && *pp == '\\')
210 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
219 else if (*p == '\\') {
222 while (*pp && *pp == '\\')
239 * Generate a string for a Win32 error.
241 #define ERRBUF_SIZE 1024
243 win32strerror(DWORD error)
245 static char errbuf[ERRBUF_SIZE+1];
249 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
250 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
253 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
254 * message. Get rid of it.
256 errlen = strlen(errbuf);
258 errbuf[errlen - 1] = '\0';
259 errbuf[errlen - 2] = '\0';
261 p = strchr(errbuf, '\0');
262 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
267 * Generate a string for a Win32 exception code.
270 win32strexception(DWORD exception)
272 static char errbuf[ERRBUF_SIZE+1];
273 static const struct exception_msg {
277 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
278 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
279 { EXCEPTION_BREAKPOINT, "Breakpoint" },
280 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
281 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
282 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
283 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
284 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
285 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
286 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
287 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
288 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
289 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
290 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
291 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
292 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
293 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
294 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
295 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
296 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
297 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
298 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
301 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
304 for (i = 0; i < N_EXCEPTIONS; i++) {
305 if (exceptions[i].code == exception)
306 return exceptions[i].msg;
308 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
313 /* Initialize an argument list and add dumpcap to it. */
315 init_pipe_args(int *argc) {
317 const char *progfile_dir;
320 progfile_dir = get_progfile_dir();
321 if (progfile_dir == NULL) {
325 /* Allocate the string pointer array with enough space for the
326 terminating NULL pointer. */
328 argv = (char **)g_malloc(sizeof (char *));
331 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
332 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
334 /* Make that the first argument in the argument list (argv[0]). */
335 argv = sync_pipe_add_arg(argv, argc, exename);
337 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
343 #define ARGV_NUMBER_LEN 24
344 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
346 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
348 char ssnap[ARGV_NUMBER_LEN];
349 char scount[ARGV_NUMBER_LEN];
350 char sfilesize[ARGV_NUMBER_LEN];
351 char sfile_duration[ARGV_NUMBER_LEN];
352 char sring_num_files[ARGV_NUMBER_LEN];
353 char sautostop_files[ARGV_NUMBER_LEN];
354 char sautostop_filesize[ARGV_NUMBER_LEN];
355 char sautostop_duration[ARGV_NUMBER_LEN];
356 #ifdef HAVE_PCAP_REMOTE
359 #ifdef HAVE_PCAP_SETSAMPLING
360 char ssampling[ARGV_NUMBER_LEN];
363 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
364 char buffer_size[ARGV_NUMBER_LEN];
368 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
369 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
370 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
371 GString *args = g_string_sized_new(200);
373 SECURITY_ATTRIBUTES sa;
375 PROCESS_INFORMATION pi;
376 char control_id[ARGV_NUMBER_LEN];
377 gchar *signal_pipe_name;
380 int sync_pipe[2]; /* pipe used to send messages from child to parent */
381 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
383 int sync_pipe_read_fd;
388 interface_options interface_opts;
390 if (capture_opts->ifaces->len > 1)
391 capture_opts->use_pcapng = TRUE;
392 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
393 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
395 cap_session->fork_child = -1;
398 if (!extcaps_init_initerfaces(capture_opts)) {
399 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
405 argv = init_pipe_args(&argc);
407 /* We don't know where to find dumpcap. */
408 report_failure("We don't know where to find dumpcap.");
412 if (capture_opts->ifaces->len > 1)
413 argv = sync_pipe_add_arg(argv, &argc, "-t");
415 if (capture_opts->use_pcapng)
416 argv = sync_pipe_add_arg(argv, &argc, "-n");
418 argv = sync_pipe_add_arg(argv, &argc, "-P");
420 if (capture_opts->capture_comment) {
421 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
422 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
425 if (capture_opts->multi_files_on) {
426 if (capture_opts->has_autostop_filesize) {
427 argv = sync_pipe_add_arg(argv, &argc, "-b");
428 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
429 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
432 if (capture_opts->has_file_duration) {
433 argv = sync_pipe_add_arg(argv, &argc, "-b");
434 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
435 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
438 if (capture_opts->has_ring_num_files) {
439 argv = sync_pipe_add_arg(argv, &argc, "-b");
440 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
441 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
444 if (capture_opts->has_autostop_files) {
445 argv = sync_pipe_add_arg(argv, &argc, "-a");
446 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
447 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
450 if (capture_opts->has_autostop_filesize) {
451 argv = sync_pipe_add_arg(argv, &argc, "-a");
452 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
453 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
457 if (capture_opts->has_autostop_packets) {
458 argv = sync_pipe_add_arg(argv, &argc, "-c");
459 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
460 argv = sync_pipe_add_arg(argv, &argc, scount);
463 if (capture_opts->has_autostop_duration) {
464 argv = sync_pipe_add_arg(argv, &argc, "-a");
465 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
466 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
469 if (capture_opts->group_read_access) {
470 argv = sync_pipe_add_arg(argv, &argc, "-g");
473 for (j = 0; j < capture_opts->ifaces->len; j++) {
474 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
476 argv = sync_pipe_add_arg(argv, &argc, "-i");
478 if (interface_opts.extcap_fifo != NULL)
479 argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
482 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
484 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
485 argv = sync_pipe_add_arg(argv, &argc, "-f");
486 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
488 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
489 argv = sync_pipe_add_arg(argv, &argc, "-s");
490 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
491 argv = sync_pipe_add_arg(argv, &argc, ssnap);
494 if (interface_opts.linktype != -1) {
495 const char *linktype = linktype_val_to_name(interface_opts.linktype);
496 if ( linktype != NULL )
498 argv = sync_pipe_add_arg(argv, &argc, "-y");
499 argv = sync_pipe_add_arg(argv, &argc, linktype);
503 if (!interface_opts.promisc_mode) {
504 argv = sync_pipe_add_arg(argv, &argc, "-p");
507 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
508 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
509 argv = sync_pipe_add_arg(argv, &argc, "-B");
510 if(interface_opts.buffer_size == 0x00)
511 interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
512 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
513 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
517 #ifdef HAVE_PCAP_CREATE
518 if (interface_opts.monitor_mode) {
519 argv = sync_pipe_add_arg(argv, &argc, "-I");
523 #ifdef HAVE_PCAP_REMOTE
524 if (interface_opts.datatx_udp)
525 argv = sync_pipe_add_arg(argv, &argc, "-u");
527 if (!interface_opts.nocap_rpcap)
528 argv = sync_pipe_add_arg(argv, &argc, "-r");
530 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
531 argv = sync_pipe_add_arg(argv, &argc, "-A");
532 g_snprintf(sauth, sizeof(sauth), "%s:%s",
533 interface_opts.auth_username,
534 interface_opts.auth_password);
535 argv = sync_pipe_add_arg(argv, &argc, sauth);
539 #ifdef HAVE_PCAP_SETSAMPLING
540 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
541 argv = sync_pipe_add_arg(argv, &argc, "-m");
542 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
543 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
544 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
546 interface_opts.sampling_param);
547 argv = sync_pipe_add_arg(argv, &argc, ssampling);
552 /* dumpcap should be running in capture child mode (hidden feature) */
554 argv = sync_pipe_add_arg(argv, &argc, "-Z");
556 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
557 argv = sync_pipe_add_arg(argv, &argc, control_id);
559 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
563 if (capture_opts->save_file) {
564 argv = sync_pipe_add_arg(argv, &argc, "-w");
565 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
567 for (i = 0; i < argc; i++) {
568 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
572 /* init SECURITY_ATTRIBUTES */
573 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
574 sa.bInheritHandle = TRUE;
575 sa.lpSecurityDescriptor = NULL;
577 /* Create a pipe for the child process */
578 /* (increase this value if you have trouble while fast capture file switches) */
579 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
580 /* Couldn't create the pipe between parent and child. */
581 report_failure("Couldn't create sync pipe: %s",
582 win32strerror(GetLastError()));
583 for (i = 0; i < argc; i++) {
584 g_free( (gpointer) argv[i]);
586 g_free( (gpointer) argv);
590 /* Create the signal pipe */
591 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
592 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
593 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
594 g_free(signal_pipe_name);
596 if (signal_pipe == INVALID_HANDLE_VALUE) {
597 /* Couldn't create the signal pipe between parent and child. */
598 report_failure("Couldn't create signal pipe: %s",
599 win32strerror(GetLastError()));
600 for (i = 0; i < argc; i++) {
601 g_free( (gpointer) argv[i]);
603 g_free( (gpointer) argv);
607 /* init STARTUPINFO */
608 memset(&si, 0, sizeof(si));
611 si.dwFlags = STARTF_USESHOWWINDOW;
612 si.wShowWindow = SW_SHOW;
614 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
615 si.wShowWindow = SW_HIDE; /* this hides the console window */
617 /* needs first a check if NULL *
618 * otherwise wouldnt work with non extcap interfaces */
619 if(interface_opts.extcap_fifo != NULL)
621 if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
623 si.hStdInput = extcap_get_win32_handle();
628 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
630 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
631 si.hStdError = sync_pipe_write;
632 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
635 /* convert args array into a single string */
636 /* XXX - could change sync_pipe_add_arg() instead */
637 /* there is a drawback here: the length is internally limited to 1024 bytes */
638 for(i=0; argv[i] != 0; i++) {
639 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
640 quoted_arg = protect_arg(argv[i]);
641 g_string_append(args, quoted_arg);
646 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
647 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
648 report_failure("Couldn't run %s in child process: %s",
649 args->str, win32strerror(GetLastError()));
650 CloseHandle(sync_pipe_read);
651 CloseHandle(sync_pipe_write);
652 for (i = 0; i < argc; i++) {
653 g_free( (gpointer) argv[i]);
655 g_free( (gpointer) argv);
658 cap_session->fork_child = (int) pi.hProcess;
659 g_string_free(args, TRUE);
661 /* associate the operating system filehandle to a C run-time file handle */
662 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
663 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
665 /* associate the operating system filehandle to a C run-time file handle */
666 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
669 if (pipe(sync_pipe) < 0) {
670 /* Couldn't create the pipe between parent and child. */
671 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
672 for (i = 0; i < argc; i++) {
673 g_free( (gpointer) argv[i]);
679 if ((cap_session->fork_child = fork()) == 0) {
681 * Child process - run dumpcap with the right arguments to make
682 * it just capture with the specified capture parameters
684 dup2(sync_pipe[PIPE_WRITE], 2);
685 ws_close(sync_pipe[PIPE_READ]);
686 execv(argv[0], argv);
687 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
688 argv[0], g_strerror(errno));
689 sync_pipe_errmsg_to_parent(2, errmsg, "");
691 /* Exit with "_exit()", so that we don't close the connection
692 to the X server (and cause stuff buffered up by our parent but
693 not yet sent to be sent, as that stuff should only be sent by
694 our parent). We've sent an error message to the parent, so
695 we exit with an exit status of 1 (any exit status other than
696 0 or 1 will cause an additional message to report that exit
697 status, over and above the error message we sent to the parent). */
701 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
702 fetch_dumpcap_pid(cap_session->fork_child);
704 sync_pipe_read_fd = sync_pipe[PIPE_READ];
707 for (i = 0; i < argc; i++) {
708 g_free( (gpointer) argv[i]);
711 /* Parent process - read messages from the child process over the
713 g_free( (gpointer) argv); /* free up arg array */
715 /* Close the write side of the pipe, so that only the child has it
716 open, and thus it completely closes, and thus returns to us
717 an EOF indication, if the child closes it (either deliberately
718 or by exiting abnormally). */
720 CloseHandle(sync_pipe_write);
722 ws_close(sync_pipe[PIPE_WRITE]);
725 if (cap_session->fork_child == -1) {
726 /* We couldn't even create the child process. */
727 report_failure("Couldn't create child process: %s", g_strerror(errno));
728 ws_close(sync_pipe_read_fd);
730 ws_close(cap_session->signal_pipe_write_fd);
735 cap_session->fork_child_status = 0;
736 cap_session->capture_opts = capture_opts;
738 /* we might wait for a moment till child is ready, so update screen now */
739 if (update_cb) update_cb();
741 /* We were able to set up to read the capture file;
742 arrange that our callback be called whenever it's possible
743 to read from the sync pipe, so that it's called when
744 the child process wants to tell us something. */
746 /* we have a running capture, now wait for the real capture filename */
747 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
748 &cap_session->fork_child, sync_pipe_input_cb);
754 * Open two pipes to dumpcap with the supplied arguments, one for its
755 * standard output and one for its standard error.
757 * On success, *msg is unchanged and 0 is returned; data_read_fd,
758 * messsage_read_fd, and fork_child point to the standard output pipe's
759 * file descriptor, the standard error pipe's file descriptor, and
760 * the child's PID/handle, respectively.
762 * On failure, *msg points to an error message for the failure, and -1 is
763 * returned, in which case *msg must be freed with g_free().
765 /* XXX - This duplicates a lot of code in sync_pipe_start() */
766 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
767 #define PIPE_BUF_SIZE 5120
769 sync_pipe_open_command(char** argv, int *data_read_fd,
770 int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
772 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
774 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
775 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
776 GString *args = g_string_sized_new(200);
778 SECURITY_ATTRIBUTES sa;
780 PROCESS_INFORMATION pi;
783 int sync_pipe[2]; /* pipe used to send messages from child to parent */
784 int data_pipe[2]; /* pipe used to send data from child to parent */
789 *message_read_fd = -1;
790 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
793 /* We can't return anything */
795 g_string_free(args, TRUE);
801 /* init SECURITY_ATTRIBUTES */
802 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
803 sa.bInheritHandle = TRUE;
804 sa.lpSecurityDescriptor = NULL;
806 /* Create a pipe for the child process to send us messages */
807 /* (increase this value if you have trouble while fast capture file switches) */
808 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
809 /* Couldn't create the message pipe between parent and child. */
810 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
811 win32strerror(GetLastError()));
812 for (i = 0; argv[i] != NULL; i++) {
813 g_free( (gpointer) argv[i]);
815 g_free( (gpointer) argv);
819 /* Create a pipe for the child process to send us data */
820 /* (increase this value if you have trouble while fast capture file switches) */
821 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
822 /* Couldn't create the message pipe between parent and child. */
823 *msg = g_strdup_printf("Couldn't create data pipe: %s",
824 win32strerror(GetLastError()));
825 CloseHandle(sync_pipe[PIPE_READ]);
826 CloseHandle(sync_pipe[PIPE_WRITE]);
827 for (i = 0; argv[i] != NULL; i++) {
828 g_free( (gpointer) argv[i]);
830 g_free( (gpointer) argv);
834 /* init STARTUPINFO */
835 memset(&si, 0, sizeof(si));
838 si.dwFlags = STARTF_USESHOWWINDOW;
839 si.wShowWindow = SW_SHOW;
841 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
842 si.wShowWindow = SW_HIDE; /* this hides the console window */
843 si.hStdInput = NULL; /* handle for named pipe*/
845 si.hStdOutput = data_pipe[PIPE_WRITE];
846 si.hStdError = sync_pipe[PIPE_WRITE];
849 /* convert args array into a single string */
850 /* XXX - could change sync_pipe_add_arg() instead */
851 /* there is a drawback here: the length is internally limited to 1024 bytes */
852 for(i=0; argv[i] != 0; i++) {
853 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
854 quoted_arg = protect_arg(argv[i]);
855 g_string_append(args, quoted_arg);
860 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
861 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
862 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
863 args->str, win32strerror(GetLastError()));
864 CloseHandle(data_pipe[PIPE_READ]);
865 CloseHandle(data_pipe[PIPE_WRITE]);
866 CloseHandle(sync_pipe[PIPE_READ]);
867 CloseHandle(sync_pipe[PIPE_WRITE]);
868 for (i = 0; argv[i] != NULL; i++) {
869 g_free( (gpointer) argv[i]);
871 g_free( (gpointer) argv);
874 *fork_child = (int) pi.hProcess;
875 g_string_free(args, TRUE);
877 /* associate the operating system filehandles to C run-time file handles */
878 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
879 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
880 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
882 /* Create a pipe for the child process to send us messages */
883 if (pipe(sync_pipe) < 0) {
884 /* Couldn't create the message pipe between parent and child. */
885 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
886 for (i = 0; argv[i] != NULL; i++) {
887 g_free( (gpointer) argv[i]);
893 /* Create a pipe for the child process to send us data */
894 if (pipe(data_pipe) < 0) {
895 /* Couldn't create the data pipe between parent and child. */
896 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
897 ws_close(sync_pipe[PIPE_READ]);
898 ws_close(sync_pipe[PIPE_WRITE]);
899 for (i = 0; argv[i] != NULL; i++) {
900 g_free( (gpointer) argv[i]);
906 if ((*fork_child = fork()) == 0) {
908 * Child process - run dumpcap with the right arguments to make
909 * it just capture with the specified capture parameters
911 dup2(data_pipe[PIPE_WRITE], 1);
912 ws_close(data_pipe[PIPE_READ]);
913 ws_close(data_pipe[PIPE_WRITE]);
914 dup2(sync_pipe[PIPE_WRITE], 2);
915 ws_close(sync_pipe[PIPE_READ]);
916 ws_close(sync_pipe[PIPE_WRITE]);
917 execv(argv[0], argv);
918 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
919 argv[0], g_strerror(errno));
920 sync_pipe_errmsg_to_parent(2, errmsg, "");
922 /* Exit with "_exit()", so that we don't close the connection
923 to the X server (and cause stuff buffered up by our parent but
924 not yet sent to be sent, as that stuff should only be sent by
925 our parent). We've sent an error message to the parent, so
926 we exit with an exit status of 1 (any exit status other than
927 0 or 1 will cause an additional message to report that exit
928 status, over and above the error message we sent to the parent). */
932 if (fetch_dumpcap_pid && *fork_child > 0)
933 fetch_dumpcap_pid(*fork_child);
935 *data_read_fd = data_pipe[PIPE_READ];
936 *message_read_fd = sync_pipe[PIPE_READ];
939 for (i = 0; argv[i] != NULL; i++) {
940 g_free( (gpointer) argv[i]);
943 /* Parent process - read messages from the child process over the
945 g_free( (gpointer) argv); /* free up arg array */
947 /* Close the write sides of the pipes, so that only the child has them
948 open, and thus they completely close, and thus return to us
949 an EOF indication, if the child closes them (either deliberately
950 or by exiting abnormally). */
952 CloseHandle(data_pipe[PIPE_WRITE]);
953 CloseHandle(sync_pipe[PIPE_WRITE]);
955 ws_close(data_pipe[PIPE_WRITE]);
956 ws_close(sync_pipe[PIPE_WRITE]);
959 if (*fork_child == -1) {
960 /* We couldn't even create the child process. */
961 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
962 ws_close(*data_read_fd);
963 ws_close(*message_read_fd);
967 /* we might wait for a moment till child is ready, so update screen now */
968 if (update_cb) update_cb();
973 * Close the pipes we're using to read from dumpcap, and wait for it
974 * to exit. On success, *msgp is unchanged, and the exit status of
975 * dumpcap is returned. On failure (which includes "dumpcap exited
976 * due to being killed by a signal or an exception"), *msgp points
977 * to an error message for the failure, and -1 is returned. In the
978 * latter case, *msgp must be freed with g_free().
981 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
982 int *fork_child, gchar **msgp)
984 ws_close(*data_read_fd);
985 if (message_read_fd != NULL)
986 ws_close(*message_read_fd);
989 /* XXX - Should we signal the child somehow? */
990 sync_pipe_kill(*fork_child);
993 return sync_pipe_wait_for_child(*fork_child, msgp);
997 * Run dumpcap with the supplied arguments.
999 * On success, *data points to a buffer containing the dumpcap output,
1000 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
1001 * must be freed with g_free().
1003 * On failure, *data is NULL, *primary_msg points to an error message,
1004 * *secondary_msg either points to an additional error message or is
1005 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1006 * must be freed with g_free().
1008 /* XXX - This duplicates a lot of code in sync_pipe_start() */
1009 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
1010 #define PIPE_BUF_SIZE 5120
1012 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
1013 gchar **secondary_msg, void(*update_cb)(void))
1016 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
1018 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1021 int primary_msg_len;
1022 char *primary_msg_text;
1023 int secondary_msg_len;
1024 char *secondary_msg_text;
1026 GString *data_buf = NULL;
1029 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
1030 &fork_child, &msg, update_cb);
1033 *secondary_msg = NULL;
1039 * We were able to set up to read dumpcap's output. Do so.
1041 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1043 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1044 buffer, primary_msg);
1046 /* We got a read error from the sync pipe, or we got no data at
1047 all from the sync pipe, so we're not going to be getting any
1048 data or error message from the child process. Pick up its
1049 exit status, and complain.
1051 We don't have to worry about killing the child, if the sync pipe
1052 returned an error. Usually this error is caused as the child killed
1053 itself while going down. Even in the rare cases that this isn't the
1054 case, the child will get an error when writing to the broken pipe
1055 the next time, cleaning itself up then. */
1056 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1058 /* We got an EOF from the sync pipe. That means that it exited
1059 before giving us any data to read. If ret is -1, we report
1060 that as a bad exit (e.g., exiting due to a signal); otherwise,
1061 we report it as a premature exit. */
1063 *primary_msg = wait_msg;
1065 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1067 /* We got an error from the sync pipe. If ret is -1, report
1068 both the sync pipe I/O error and the wait error. */
1070 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1071 g_free(*primary_msg);
1073 *primary_msg = combined_msg;
1076 *secondary_msg = NULL;
1081 /* we got a valid message block from the child, process it */
1086 * Error from dumpcap; there will be a primary message and a
1087 * secondary message.
1090 /* convert primary message */
1091 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1092 primary_msg_text = buffer+4;
1093 /* convert secondary message */
1094 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1095 &secondary_msg_len);
1096 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1097 /* the capture child will close the sync_pipe, nothing to do */
1100 * Pick up the child status.
1102 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1106 * Child process failed unexpectedly, or wait failed; msg is the
1110 *secondary_msg = NULL;
1113 * Child process failed, but returned the expected exit status.
1114 * Return the messages it gave us, and indicate failure.
1116 *primary_msg = g_strdup(primary_msg_text);
1117 *secondary_msg = g_strdup(secondary_msg_text);
1124 /* read the output from the command */
1125 data_buf = g_string_new("");
1126 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1127 buffer[count] = '\0';
1128 g_string_append(data_buf, buffer);
1132 * Pick up the child status.
1134 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1138 * Child process failed unexpectedly, or wait failed; msg is the
1142 *secondary_msg = NULL;
1143 g_string_free(data_buf, TRUE);
1147 * Child process succeeded.
1149 *primary_msg = NULL;
1150 *secondary_msg = NULL;
1151 *data = data_buf->str;
1152 g_string_free(data_buf, FALSE);
1158 * Pick up the child status.
1160 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1164 * Child process failed unexpectedly, or wait failed; msg is the
1168 *secondary_msg = NULL;
1171 * Child process returned an unknown status.
1173 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1175 *secondary_msg = NULL;
1184 /* centralised logging and timing for sync_pipe_run_command_actual(),
1185 * redirects to sync_pipe_run_command_actual()
1188 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1189 gchar **secondary_msg, void (*update_cb)(void))
1192 GTimeVal start_time;
1195 int logging_enabled;
1197 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1198 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1199 if(logging_enabled){
1200 g_get_current_time(&start_time);
1201 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1202 for(i=0; argv[i] != 0; i++) {
1203 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1206 /* do the actual sync pipe run command */
1207 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1209 if(logging_enabled){
1210 g_get_current_time(&end_time);
1211 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1212 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1214 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1222 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1223 gchar **data, gchar **primary_msg,
1224 gchar **secondary_msg, void (*update_cb)(void))
1230 argv = init_pipe_args(&argc);
1233 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1234 *secondary_msg = NULL;
1239 argv = sync_pipe_add_arg(argv, &argc, "-i");
1240 argv = sync_pipe_add_arg(argv, &argc, iface);
1243 opt = g_strdup_printf("%s,%s", freq, type);
1245 opt = g_strdup_printf("%s", freq);
1248 *primary_msg = g_strdup("Out of mem.");
1249 *secondary_msg = NULL;
1254 argv = sync_pipe_add_arg(argv, &argc, "-k");
1255 argv = sync_pipe_add_arg(argv, &argc, opt);
1258 /* Run dumpcap in capture child mode */
1259 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1260 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1263 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1269 * Get the list of interfaces using dumpcap.
1271 * On success, *data points to a buffer containing the dumpcap output,
1272 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1273 * must be freed with g_free().
1275 * On failure, *data is NULL, *primary_msg points to an error message,
1276 * *secondary_msg either points to an additional error message or is
1277 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1278 * must be freed with g_free().
1281 sync_interface_list_open(gchar **data, gchar **primary_msg,
1282 gchar **secondary_msg, void (*update_cb)(void))
1287 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1289 argv = init_pipe_args(&argc);
1292 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1293 *secondary_msg = NULL;
1298 /* Ask for the interface list */
1299 argv = sync_pipe_add_arg(argv, &argc, "-D");
1302 /* Run dumpcap in capture child mode */
1303 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1304 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1306 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1310 * Get the capabilities of an interface using dumpcap.
1312 * On success, *data points to a buffer containing the dumpcap output,
1313 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1314 * must be freed with g_free().
1316 * On failure, *data is NULL, *primary_msg points to an error message,
1317 * *secondary_msg either points to an additional error message or is
1318 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1319 * must be freed with g_free().
1322 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1323 gchar **data, gchar **primary_msg,
1324 gchar **secondary_msg, void (*update_cb)(void))
1329 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1331 argv = init_pipe_args(&argc);
1334 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1335 *secondary_msg = NULL;
1340 /* Ask for the interface capabilities */
1341 argv = sync_pipe_add_arg(argv, &argc, "-i");
1342 argv = sync_pipe_add_arg(argv, &argc, ifname);
1343 argv = sync_pipe_add_arg(argv, &argc, "-L");
1345 argv = sync_pipe_add_arg(argv, &argc, "-I");
1348 /* Run dumpcap in capture child mode */
1349 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1350 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1352 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1356 * Start getting interface statistics using dumpcap. On success, read_fd
1357 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1358 * and zero is returned. On failure, *msg will point to an error message
1359 * that must be g_free()d, and -1 will be returned.
1362 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
1366 int message_read_fd, ret;
1368 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1371 int primary_msg_len;
1372 char *primary_msg_text;
1373 int secondary_msg_len;
1374 /*char *secondary_msg_text;*/
1377 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1379 argv = init_pipe_args(&argc);
1382 *msg = g_strdup("We don't know where to find dumpcap.");
1386 /* Ask for the interface statistics */
1387 argv = sync_pipe_add_arg(argv, &argc, "-S");
1390 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1392 create_dummy_signal_pipe();
1393 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1395 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1398 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1399 fork_child, msg, update_cb);
1404 * We were able to set up to read dumpcap's output. Do so.
1406 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1408 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1411 /* We got a read error from the sync pipe, or we got no data at
1412 all from the sync pipe, so we're not going to be getting any
1413 data or error message from the child process. Pick up its
1414 exit status, and complain.
1416 We don't have to worry about killing the child, if the sync pipe
1417 returned an error. Usually this error is caused as the child killed
1418 itself while going down. Even in the rare cases that this isn't the
1419 case, the child will get an error when writing to the broken pipe
1420 the next time, cleaning itself up then. */
1421 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1423 /* We got an EOF from the sync pipe. That means that it exited
1424 before giving us any data to read. If ret is -1, we report
1425 that as a bad exit (e.g., exiting due to a signal); otherwise,
1426 we report it as a premature exit. */
1430 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1432 /* We got an error from the sync pipe. If ret is -1, report
1433 both the sync pipe I/O error and the wait error. */
1435 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1438 *msg = combined_msg;
1445 /* we got a valid message block from the child, process it */
1450 * Error from dumpcap; there will be a primary message and a
1451 * secondary message.
1454 /* convert primary message */
1455 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1456 primary_msg_text = buffer+4;
1457 /* convert secondary message */
1458 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1459 &secondary_msg_len);
1460 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1461 /* the capture child will close the sync_pipe, nothing to do */
1464 * Pick up the child status.
1466 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1470 * Child process failed unexpectedly, or wait failed; msg is the
1475 * Child process failed, but returned the expected exit status.
1476 * Return the messages it gave us, and indicate failure.
1478 *msg = g_strdup(primary_msg_text);
1484 /* Close the message pipe. */
1485 ws_close(message_read_fd);
1490 * Pick up the child status.
1492 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1496 * Child process failed unexpectedly, or wait failed; msg is the
1501 * Child process returned an unknown status.
1503 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1512 /* Close down the stats process */
1514 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1518 * Don't bother waiting for the child. sync_pipe_close_command
1519 * does this for us on Windows.
1521 sync_pipe_kill(*fork_child);
1523 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1526 /* read a number of bytes from a pipe */
1527 /* (blocks until enough bytes read or an error occurs) */
1529 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1536 newly = read(pipe_fd, &bytes[offset], required);
1539 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1540 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1547 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1548 "read from pipe %d: error(%u): %s", pipe_fd, error,
1550 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1555 required -= (int)newly;
1563 static gboolean pipe_data_available(int pipe_fd) {
1564 #ifdef _WIN32 /* PeekNamedPipe */
1565 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1568 if (hPipe == INVALID_HANDLE_VALUE)
1571 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1574 if (bytes_avail > 0)
1579 struct timeval timeout;
1582 FD_SET(pipe_fd, &rfds);
1584 timeout.tv_usec = 0;
1586 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1593 /* Read a line from a pipe, similar to fgets */
1595 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1599 while(offset < max - 1) {
1601 if (! pipe_data_available(pipe_fd))
1603 newly = read(pipe_fd, &bytes[offset], 1);
1605 /* EOF - not necessarily an error */
1607 } else if (newly == -1) {
1609 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1610 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1612 } else if (bytes[offset] == '\n') {
1618 bytes[offset] = '\0';
1624 /* convert header values (indicator and 3-byte length) */
1626 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1628 g_assert(header_len == 4);
1630 /* convert header values */
1631 *indicator = header[0];
1632 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1635 /* read a message from the sending pipe in the standard format
1636 (1-byte message indicator, 3-byte message length (excluding length
1637 and indicator field), and the rest is the message) */
1639 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1646 /* read header (indicator and 3-byte length) */
1647 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1651 * Immediate EOF; if the capture child exits normally, this
1652 * is an "I'm done" indication, so don't report it as an
1655 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1656 "read %d got an EOF", pipe_fd);
1659 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1660 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1663 * Short read, but not an immediate EOF.
1665 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1671 /* convert header values */
1672 pipe_convert_header((guchar*)header, 4, indicator, &required);
1674 /* only indicator with no value? */
1676 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1677 "read %d indicator: %c empty value", pipe_fd, *indicator);
1681 /* does the data fit into the given buffer? */
1682 if(required > len) {
1683 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1684 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1685 pipe_fd, required, len,
1686 header[0], header[1], header[2], header[3]);
1688 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1689 memcpy(msg, header, sizeof(header));
1690 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1691 if (newly < 0) { /* error */
1692 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1693 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1695 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1701 /* read the actual block data */
1702 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1703 if(newly != required) {
1705 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1711 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1712 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1713 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1720 /* There's stuff to read from the sync pipe, meaning the child has sent
1721 us a message, or the sync pipe has closed, meaning the child has
1722 closed it (perhaps because it exited). */
1724 sync_pipe_input_cb(gint source, gpointer user_data)
1726 capture_session *cap_session = (capture_session *)user_data;
1728 char buffer[SP_MAX_MSG_LEN+1] = {0};
1734 char *secondary_msg;
1735 char *wait_msg, *combined_msg;
1738 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1741 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1743 If we got a read error or a bad message, nread is -1 and
1744 primary_msg is set to point to an error message. We don't
1745 have to worry about killing the child; usually this error
1746 is caused as the child killed itself while going down.
1747 Even in the rare cases that this isn't the case, the child
1748 will get an error when writing to the broken pipe the next time,
1749 cleaning itself up then.
1751 If we got an EOF, nread is 0 and primary_msg isn't set. This
1752 is an indication that the capture is finished. */
1753 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1755 /* We got an EOF from the sync pipe. That means that the capture
1756 child exited, and not in the middle of a message; we treat
1757 that as an indication that it's done, and only report an
1758 error if ret is -1, in which case wait_msg is the error
1761 primary_msg = wait_msg;
1763 /* We got an error from the sync pipe. If ret is -1, report
1764 both the sync pipe I/O error and the wait error. */
1766 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1767 g_free(primary_msg);
1769 primary_msg = combined_msg;
1773 /* No more child process. */
1774 cap_session->fork_child = -1;
1775 cap_session->fork_child_status = ret;
1778 ws_close(cap_session->signal_pipe_write_fd);
1781 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1782 extcap_cleanup(cap_session->capture_opts);
1784 capture_input_closed(cap_session, primary_msg);
1785 g_free(primary_msg);
1789 /* we got a valid message block from the child, process it */
1792 if(!capture_input_new_file(cap_session, buffer)) {
1793 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1795 /* We weren't able to open the new capture file; user has been
1796 alerted. Close the sync pipe. */
1799 /* The child has sent us a filename which we couldn't open.
1801 This could mean that the child is creating and deleting files
1802 (ring buffer mode) faster than we can handle it.
1804 That should only be the case for very fast file switches;
1805 We can't do much more than telling the child to stop.
1806 (This is the "emergency brake" if the user e.g. wants to
1807 switch files every second).
1809 This can also happen if the user specified "-", meaning
1810 "standard output", as the capture file. */
1811 sync_pipe_stop(cap_session);
1812 capture_input_closed(cap_session, NULL);
1816 case SP_PACKET_COUNT:
1817 npackets = atoi(buffer);
1818 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1819 capture_input_new_packets(cap_session, npackets);
1822 /* convert primary message */
1823 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1824 primary_msg = buffer+4;
1825 /* convert secondary message */
1826 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1827 secondary_msg = primary_msg + primary_len + 4;
1828 /* message output */
1829 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1830 /* the capture child will close the sync_pipe, nothing to do for now */
1831 /* (an error message doesn't mean we have to stop capturing) */
1833 case SP_BAD_FILTER: {
1837 ch = strtok(buffer, ":");
1839 indx = (int)strtol(ch, NULL, 10);
1840 ch = strtok(NULL, ":");
1842 capture_input_cfilter_error_message(cap_session, indx, ch);
1843 /* the capture child will close the sync_pipe, nothing to do for now */
1847 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1850 g_assert_not_reached();
1859 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1860 * unchanged, and the exit status of dumpcap is returned. On
1861 * failure (which includes "dumpcap exited due to being killed by
1862 * a signal or an exception"), *msgp points to an error message
1863 * for the failure, and -1 is returned. In the latter case, *msgp
1864 * must be freed with g_free().
1867 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1869 int fork_child_status;
1871 GTimeVal start_time;
1876 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1879 g_get_current_time(&start_time);
1881 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1882 g_assert(fork_child != -1);
1884 *msgp = NULL; /* assume no error */
1886 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1887 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1891 * The child exited; return its exit status. Do not treat this as
1894 ret = fork_child_status;
1895 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1896 /* Probably an exception code */
1897 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1898 win32strexception(fork_child_status));
1903 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1904 if (WIFEXITED(fork_child_status)) {
1906 * The child exited; return its exit status. Do not treat this as
1909 ret = WEXITSTATUS(fork_child_status);
1910 } else if (WIFSTOPPED(fork_child_status)) {
1911 /* It stopped, rather than exiting. "Should not happen." */
1912 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1913 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1915 } else if (WIFSIGNALED(fork_child_status)) {
1916 /* It died with a signal. */
1917 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1918 sync_pipe_signame(WTERMSIG(fork_child_status)),
1919 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1922 /* What? It had to either have exited, or stopped, or died with
1923 a signal; what happened here? */
1924 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1928 } else if (errno != ECHILD) {
1929 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1932 /* errno == ECHILD ; echld might have already reaped the child */
1933 ret = fetch_dumpcap_pid ? 0 : -1;
1937 g_get_current_time(&end_time);
1938 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1939 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1940 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1946 /* convert signal to corresponding name */
1948 sync_pipe_signame(int sig)
1951 static char sigmsg_buf[6+1+3+1];
1960 sigmsg = "Interrupted";
1968 sigmsg = "Illegal instruction";
1972 sigmsg = "Trace trap";
1980 sigmsg = "Arithmetic exception";
1988 sigmsg = "Bus error";
1992 sigmsg = "Segmentation violation";
1995 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1996 Linux is POSIX compliant. These are not POSIX-defined signals ---
1997 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1999 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
2000 were omitted from POSIX.1 because their behavior is
2001 implementation dependent and could not be adequately catego-
2002 rized. Conforming implementations may deliver these sig-
2003 nals, but must document the circumstances under which they
2004 are delivered and note any restrictions concerning their
2007 So we only check for SIGSYS on those systems that happen to
2008 implement them (a system can be POSIX-compliant and implement
2009 them, it's just that POSIX doesn't *require* a POSIX-compliant
2010 system to implement them).
2015 sigmsg = "Bad system call";
2020 sigmsg = "Broken pipe";
2024 sigmsg = "Alarm clock";
2028 sigmsg = "Terminated";
2032 /* Returning a static buffer is ok in the context we use it here */
2033 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2034 sigmsg = sigmsg_buf;
2044 static void create_dummy_signal_pipe() {
2045 gchar *dummy_signal_pipe_name;
2047 if (dummy_signal_pipe != NULL) return;
2049 if (!dummy_control_id) {
2050 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2053 /* Create the signal pipe */
2054 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2055 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2056 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2057 g_free(dummy_signal_pipe_name);
2060 /* tell the child through the signal pipe that we want to quit the capture */
2062 signal_pipe_capquit_to_child(capture_session *cap_session)
2064 const char quit_msg[] = "QUIT";
2067 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2069 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2070 /* simply sending a "QUIT" string */
2071 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2072 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2074 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2075 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2081 /* user wants to stop the capture run */
2083 sync_pipe_stop(capture_session *cap_session)
2088 gboolean terminate = TRUE;
2090 if (cap_session->fork_child != -1) {
2092 /* send the SIGINT signal to close the capture child gracefully. */
2093 int sts = kill(cap_session->fork_child, SIGINT);
2095 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2096 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2099 #define STOP_SLEEP_TIME 500 /* ms */
2100 #define STOP_CHECK_TIME 50
2101 /* First, use the special signal pipe to try to close the capture child
2104 signal_pipe_capquit_to_child(cap_session);
2106 /* Next, wait for the process to exit on its own */
2107 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2108 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2109 childstatus != STILL_ACTIVE) {
2113 Sleep(STOP_CHECK_TIME);
2116 /* Force the issue. */
2118 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2119 "sync_pipe_stop: forcing child to exit");
2120 sync_pipe_kill(cap_session->fork_child);
2127 /* Wireshark has to exit, force the capture child to close */
2129 sync_pipe_kill(int fork_child)
2131 if (fork_child != -1) {
2133 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2135 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2136 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2139 /* Remark: This is not the preferred method of closing a process!
2140 * the clean way would be getting the process id of the child process,
2141 * then getting window handle hWnd of that process (using EnumChildWindows),
2142 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2144 * Unfortunately, I don't know how to get the process id from the
2145 * handle. OpenProcess will get an handle (not a window handle)
2146 * from the process ID; it will not get a window handle from the
2147 * process ID. (How could it? A process can have more than one
2148 * window. For that matter, a process might have *no* windows,
2149 * as a process running dumpcap, the normal child process program,
2152 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2153 * running in the same console; that's not necessarily the case for
2154 * us, as we might not be running in a console.
2155 * And this also will require to have the process id.
2157 TerminateProcess((HANDLE) (fork_child), 0);
2163 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
2164 fetch_dumpcap_pid = cb;
2167 #endif /* HAVE_LIBPCAP */