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.
43 #include <wsutil/unicode-utils.h>
46 #ifdef HAVE_SYS_WAIT_H
47 # include <sys/wait.h>
50 #include "caputils/capture-pcap-util.h"
54 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
55 * macros) on UNIX systems that don't have them.
58 # define WIFEXITED(status) (((status) & 0177) == 0)
61 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
64 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
67 # define WEXITSTATUS(status) ((status) >> 8)
70 # define WTERMSIG(status) ((status) & 0177)
73 # define WCOREDUMP(status) ((status) & 0200)
76 # define WSTOPSIG(status) ((status) >> 8)
80 #include <epan/packet.h>
81 #include <epan/prefs.h>
86 #include "ui/capture.h"
87 #include <capchild/capture_sync.h>
89 #include "sync_pipe.h"
92 #include "caputils/capture-wpcap.h"
95 #include "ui/ui_util.h"
97 #include <wsutil/filesystem.h>
98 #include <wsutil/file_util.h>
99 #include <wsutil/report_err.h>
106 #include <process.h> /* For spawning child process */
112 static void create_dummy_signal_pipe();
113 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
114 static gchar *dummy_control_id;
116 static const char *sync_pipe_signame(int);
120 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
121 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
122 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
123 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
126 static void (*fetch_dumpcap_pid)(int) = NULL;
130 capture_session_init(capture_session *cap_session, struct _capture_file *cf)
132 cap_session->cf = cf;
133 cap_session->fork_child = -1; /* invalid process handle */
135 cap_session->signal_pipe_write_fd = -1;
137 cap_session->state = CAPTURE_STOPPED;
139 cap_session->owner = getuid();
140 cap_session->group = getgid();
142 cap_session->session_started = FALSE;
145 /* Append an arg (realloc) to an argc/argv array */
146 /* (add a string pointer to a NULL-terminated array of string pointers) */
148 sync_pipe_add_arg(char **args, int *argc, const char *arg)
150 /* Grow the array; "*argc" currently contains the number of string
151 pointers, *not* counting the NULL pointer at the end, so we have
152 to add 2 in order to get the new size of the array, including the
153 new pointer and the terminating NULL pointer. */
154 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
156 /* Stuff the pointer into the penultimate element of the array, which
157 is the one at the index specified by "*argc". */
158 args[*argc] = g_strdup(arg);
159 /* Now bump the count. */
162 /* We overwrite the NULL pointer; put it back right after the
172 /* Quote the argument element if necessary, so that it will get
173 * reconstructed correctly in the C runtime startup code. Note that
174 * the unquoting algorithm in the C runtime is really weird, and
175 * rather different than what Unix shells do. See stdargv.c in the C
176 * runtime sources (in the Platform SDK, in src/crt).
178 * Stolen from GLib's protect_argv(), an internal routine that quotes
179 * string in an argument list so that they arguments will be handled
180 * correctly in the command-line string passed to CreateProcess()
181 * if that string is constructed by gluing those strings together.
184 protect_arg (const gchar *argv)
187 const gchar *p = argv;
190 gboolean need_dblquotes = FALSE;
193 if (*p == ' ' || *p == '\t')
194 need_dblquotes = TRUE;
197 else if (*p == '\\') {
200 while (*pp && *pp == '\\')
209 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
218 else if (*p == '\\') {
221 while (*pp && *pp == '\\')
238 * Generate a string for a Win32 error.
240 #define ERRBUF_SIZE 1024
242 win32strerror(DWORD error)
244 static char errbuf[ERRBUF_SIZE+1];
248 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
249 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
252 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
253 * message. Get rid of it.
255 errlen = strlen(errbuf);
257 errbuf[errlen - 1] = '\0';
258 errbuf[errlen - 2] = '\0';
260 p = strchr(errbuf, '\0');
261 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
266 * Generate a string for a Win32 exception code.
269 win32strexception(DWORD exception)
271 static char errbuf[ERRBUF_SIZE+1];
272 static const struct exception_msg {
276 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
277 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
278 { EXCEPTION_BREAKPOINT, "Breakpoint" },
279 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
280 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
281 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
282 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
283 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
284 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
285 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
286 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
287 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
288 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
289 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
290 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
291 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
292 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
293 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
294 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
295 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
296 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
297 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
300 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
303 for (i = 0; i < N_EXCEPTIONS; i++) {
304 if (exceptions[i].code == exception)
305 return exceptions[i].msg;
307 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
312 /* Initialize an argument list and add dumpcap to it. */
314 init_pipe_args(int *argc) {
316 const char *progfile_dir;
319 progfile_dir = get_progfile_dir();
320 if (progfile_dir == NULL) {
324 /* Allocate the string pointer array with enough space for the
325 terminating NULL pointer. */
327 argv = (char **)g_malloc(sizeof (char *));
330 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
331 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
333 /* Make that the first argument in the argument list (argv[0]). */
334 argv = sync_pipe_add_arg(argv, argc, exename);
336 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
342 #define ARGV_NUMBER_LEN 24
343 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
345 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
347 char ssnap[ARGV_NUMBER_LEN];
348 char scount[ARGV_NUMBER_LEN];
349 char sfilesize[ARGV_NUMBER_LEN];
350 char sfile_duration[ARGV_NUMBER_LEN];
351 char sring_num_files[ARGV_NUMBER_LEN];
352 char sautostop_files[ARGV_NUMBER_LEN];
353 char sautostop_filesize[ARGV_NUMBER_LEN];
354 char sautostop_duration[ARGV_NUMBER_LEN];
355 #ifdef HAVE_PCAP_REMOTE
358 #ifdef HAVE_PCAP_SETSAMPLING
359 char ssampling[ARGV_NUMBER_LEN];
362 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
363 char buffer_size[ARGV_NUMBER_LEN];
367 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
368 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
369 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
370 GString *args = g_string_sized_new(200);
372 SECURITY_ATTRIBUTES sa;
374 PROCESS_INFORMATION pi;
375 char control_id[ARGV_NUMBER_LEN];
376 gchar *signal_pipe_name;
379 int sync_pipe[2]; /* pipe used to send messages from child to parent */
380 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
382 int sync_pipe_read_fd;
387 interface_options interface_opts;
389 if (capture_opts->ifaces->len > 1)
390 capture_opts->use_pcapng = TRUE;
391 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
392 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
394 cap_session->fork_child = -1;
397 if (!extcaps_init_initerfaces(capture_opts)) {
398 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
404 argv = init_pipe_args(&argc);
406 /* We don't know where to find dumpcap. */
407 report_failure("We don't know where to find dumpcap.");
411 if (capture_opts->ifaces->len > 1)
412 argv = sync_pipe_add_arg(argv, &argc, "-t");
414 if (capture_opts->use_pcapng)
415 argv = sync_pipe_add_arg(argv, &argc, "-n");
417 argv = sync_pipe_add_arg(argv, &argc, "-P");
419 if (capture_opts->capture_comment) {
420 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
421 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
424 if (capture_opts->multi_files_on) {
425 if (capture_opts->has_autostop_filesize) {
426 argv = sync_pipe_add_arg(argv, &argc, "-b");
427 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
428 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
431 if (capture_opts->has_file_duration) {
432 argv = sync_pipe_add_arg(argv, &argc, "-b");
433 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
434 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
437 if (capture_opts->has_ring_num_files) {
438 argv = sync_pipe_add_arg(argv, &argc, "-b");
439 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
440 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
443 if (capture_opts->has_autostop_files) {
444 argv = sync_pipe_add_arg(argv, &argc, "-a");
445 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
446 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
449 if (capture_opts->has_autostop_filesize) {
450 argv = sync_pipe_add_arg(argv, &argc, "-a");
451 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
452 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
456 if (capture_opts->has_autostop_packets) {
457 argv = sync_pipe_add_arg(argv, &argc, "-c");
458 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
459 argv = sync_pipe_add_arg(argv, &argc, scount);
462 if (capture_opts->has_autostop_duration) {
463 argv = sync_pipe_add_arg(argv, &argc, "-a");
464 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
465 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
468 if (capture_opts->group_read_access) {
469 argv = sync_pipe_add_arg(argv, &argc, "-g");
472 for (j = 0; j < capture_opts->ifaces->len; j++) {
473 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
475 argv = sync_pipe_add_arg(argv, &argc, "-i");
477 if (interface_opts.extcap_fifo != NULL)
478 argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
481 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
483 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
484 argv = sync_pipe_add_arg(argv, &argc, "-f");
485 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
487 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
488 argv = sync_pipe_add_arg(argv, &argc, "-s");
489 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
490 argv = sync_pipe_add_arg(argv, &argc, ssnap);
493 if (interface_opts.linktype != -1) {
494 const char *linktype = linktype_val_to_name(interface_opts.linktype);
495 if ( linktype != NULL )
497 argv = sync_pipe_add_arg(argv, &argc, "-y");
498 argv = sync_pipe_add_arg(argv, &argc, linktype);
502 if (!interface_opts.promisc_mode) {
503 argv = sync_pipe_add_arg(argv, &argc, "-p");
506 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
507 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
508 argv = sync_pipe_add_arg(argv, &argc, "-B");
509 if(interface_opts.buffer_size == 0x00)
510 interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
511 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
512 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
516 #ifdef HAVE_PCAP_CREATE
517 if (interface_opts.monitor_mode) {
518 argv = sync_pipe_add_arg(argv, &argc, "-I");
522 #ifdef HAVE_PCAP_REMOTE
523 if (interface_opts.datatx_udp)
524 argv = sync_pipe_add_arg(argv, &argc, "-u");
526 if (!interface_opts.nocap_rpcap)
527 argv = sync_pipe_add_arg(argv, &argc, "-r");
529 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
530 argv = sync_pipe_add_arg(argv, &argc, "-A");
531 g_snprintf(sauth, sizeof(sauth), "%s:%s",
532 interface_opts.auth_username,
533 interface_opts.auth_password);
534 argv = sync_pipe_add_arg(argv, &argc, sauth);
538 #ifdef HAVE_PCAP_SETSAMPLING
539 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
540 argv = sync_pipe_add_arg(argv, &argc, "-m");
541 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
542 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
543 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
545 interface_opts.sampling_param);
546 argv = sync_pipe_add_arg(argv, &argc, ssampling);
551 /* dumpcap should be running in capture child mode (hidden feature) */
553 argv = sync_pipe_add_arg(argv, &argc, "-Z");
555 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
556 argv = sync_pipe_add_arg(argv, &argc, control_id);
558 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
562 if (capture_opts->save_file) {
563 argv = sync_pipe_add_arg(argv, &argc, "-w");
564 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
566 for (i = 0; i < argc; i++) {
567 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
571 /* init SECURITY_ATTRIBUTES */
572 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
573 sa.bInheritHandle = TRUE;
574 sa.lpSecurityDescriptor = NULL;
576 /* Create a pipe for the child process */
577 /* (increase this value if you have trouble while fast capture file switches) */
578 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
579 /* Couldn't create the pipe between parent and child. */
580 report_failure("Couldn't create sync pipe: %s",
581 win32strerror(GetLastError()));
582 for (i = 0; i < argc; i++) {
583 g_free( (gpointer) argv[i]);
585 g_free( (gpointer) argv);
589 /* Create the signal pipe */
590 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
591 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
592 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
593 g_free(signal_pipe_name);
595 if (signal_pipe == INVALID_HANDLE_VALUE) {
596 /* Couldn't create the signal pipe between parent and child. */
597 report_failure("Couldn't create signal pipe: %s",
598 win32strerror(GetLastError()));
599 for (i = 0; i < argc; i++) {
600 g_free( (gpointer) argv[i]);
602 g_free( (gpointer) argv);
606 /* init STARTUPINFO */
607 memset(&si, 0, sizeof(si));
610 si.dwFlags = STARTF_USESHOWWINDOW;
611 si.wShowWindow = SW_SHOW;
613 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
614 si.wShowWindow = SW_HIDE; /* this hides the console window */
616 /* needs first a check if NULL *
617 * otherwise wouldn't work with non extcap interfaces */
618 if(interface_opts.extcap_fifo != NULL)
620 if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
622 si.hStdInput = extcap_get_win32_handle();
627 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
629 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
630 si.hStdError = sync_pipe_write;
631 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
634 /* convert args array into a single string */
635 /* XXX - could change sync_pipe_add_arg() instead */
636 /* there is a drawback here: the length is internally limited to 1024 bytes */
637 for(i=0; argv[i] != 0; i++) {
638 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
639 quoted_arg = protect_arg(argv[i]);
640 g_string_append(args, quoted_arg);
645 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
646 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
647 report_failure("Couldn't run %s in child process: %s",
648 args->str, win32strerror(GetLastError()));
649 CloseHandle(sync_pipe_read);
650 CloseHandle(sync_pipe_write);
651 for (i = 0; i < argc; i++) {
652 g_free( (gpointer) argv[i]);
654 g_free( (gpointer) argv);
657 cap_session->fork_child = (int) pi.hProcess;
658 g_string_free(args, TRUE);
660 /* associate the operating system filehandle to a C run-time file handle */
661 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
662 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
664 /* associate the operating system filehandle to a C run-time file handle */
665 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
668 if (pipe(sync_pipe) < 0) {
669 /* Couldn't create the pipe between parent and child. */
670 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
671 for (i = 0; i < argc; i++) {
672 g_free( (gpointer) argv[i]);
678 if ((cap_session->fork_child = fork()) == 0) {
680 * Child process - run dumpcap with the right arguments to make
681 * it just capture with the specified capture parameters
683 dup2(sync_pipe[PIPE_WRITE], 2);
684 ws_close(sync_pipe[PIPE_READ]);
685 execv(argv[0], argv);
686 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
687 argv[0], g_strerror(errno));
688 sync_pipe_errmsg_to_parent(2, errmsg, "");
690 /* Exit with "_exit()", so that we don't close the connection
691 to the X server (and cause stuff buffered up by our parent but
692 not yet sent to be sent, as that stuff should only be sent by
693 our parent). We've sent an error message to the parent, so
694 we exit with an exit status of 1 (any exit status other than
695 0 or 1 will cause an additional message to report that exit
696 status, over and above the error message we sent to the parent). */
700 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
701 fetch_dumpcap_pid(cap_session->fork_child);
703 sync_pipe_read_fd = sync_pipe[PIPE_READ];
706 for (i = 0; i < argc; i++) {
707 g_free( (gpointer) argv[i]);
710 /* Parent process - read messages from the child process over the
712 g_free( (gpointer) argv); /* free up arg array */
714 /* Close the write side of the pipe, so that only the child has it
715 open, and thus it completely closes, and thus returns to us
716 an EOF indication, if the child closes it (either deliberately
717 or by exiting abnormally). */
719 CloseHandle(sync_pipe_write);
721 ws_close(sync_pipe[PIPE_WRITE]);
724 if (cap_session->fork_child == -1) {
725 /* We couldn't even create the child process. */
726 report_failure("Couldn't create child process: %s", g_strerror(errno));
727 ws_close(sync_pipe_read_fd);
729 ws_close(cap_session->signal_pipe_write_fd);
734 cap_session->fork_child_status = 0;
735 cap_session->capture_opts = capture_opts;
737 /* we might wait for a moment till child is ready, so update screen now */
738 if (update_cb) update_cb();
740 /* We were able to set up to read the capture file;
741 arrange that our callback be called whenever it's possible
742 to read from the sync pipe, so that it's called when
743 the child process wants to tell us something. */
745 /* we have a running capture, now wait for the real capture filename */
746 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
747 &cap_session->fork_child, sync_pipe_input_cb);
753 * Open two pipes to dumpcap with the supplied arguments, one for its
754 * standard output and one for its standard error.
756 * On success, *msg is unchanged and 0 is returned; data_read_fd,
757 * messsage_read_fd, and fork_child point to the standard output pipe's
758 * file descriptor, the standard error pipe's file descriptor, and
759 * the child's PID/handle, respectively.
761 * On failure, *msg points to an error message for the failure, and -1 is
762 * returned, in which case *msg must be freed with g_free().
764 /* XXX - This duplicates a lot of code in sync_pipe_start() */
765 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
766 #define PIPE_BUF_SIZE 5120
768 sync_pipe_open_command(char** argv, int *data_read_fd,
769 int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
771 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
773 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
774 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
775 GString *args = g_string_sized_new(200);
777 SECURITY_ATTRIBUTES sa;
779 PROCESS_INFORMATION pi;
782 int sync_pipe[2]; /* pipe used to send messages from child to parent */
783 int data_pipe[2]; /* pipe used to send data from child to parent */
788 *message_read_fd = -1;
789 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
792 /* We can't return anything */
794 g_string_free(args, TRUE);
800 /* init SECURITY_ATTRIBUTES */
801 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
802 sa.bInheritHandle = TRUE;
803 sa.lpSecurityDescriptor = NULL;
805 /* Create a pipe for the child process to send us messages */
806 /* (increase this value if you have trouble while fast capture file switches) */
807 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
808 /* Couldn't create the message pipe between parent and child. */
809 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
810 win32strerror(GetLastError()));
811 for (i = 0; argv[i] != NULL; i++) {
812 g_free( (gpointer) argv[i]);
814 g_free( (gpointer) argv);
818 /* Create a pipe for the child process to send us data */
819 /* (increase this value if you have trouble while fast capture file switches) */
820 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
821 /* Couldn't create the message pipe between parent and child. */
822 *msg = g_strdup_printf("Couldn't create data pipe: %s",
823 win32strerror(GetLastError()));
824 CloseHandle(sync_pipe[PIPE_READ]);
825 CloseHandle(sync_pipe[PIPE_WRITE]);
826 for (i = 0; argv[i] != NULL; i++) {
827 g_free( (gpointer) argv[i]);
829 g_free( (gpointer) argv);
833 /* init STARTUPINFO */
834 memset(&si, 0, sizeof(si));
837 si.dwFlags = STARTF_USESHOWWINDOW;
838 si.wShowWindow = SW_SHOW;
840 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
841 si.wShowWindow = SW_HIDE; /* this hides the console window */
842 si.hStdInput = NULL; /* handle for named pipe*/
844 si.hStdOutput = data_pipe[PIPE_WRITE];
845 si.hStdError = sync_pipe[PIPE_WRITE];
848 /* convert args array into a single string */
849 /* XXX - could change sync_pipe_add_arg() instead */
850 /* there is a drawback here: the length is internally limited to 1024 bytes */
851 for(i=0; argv[i] != 0; i++) {
852 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
853 quoted_arg = protect_arg(argv[i]);
854 g_string_append(args, quoted_arg);
859 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
860 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
861 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
862 args->str, win32strerror(GetLastError()));
863 CloseHandle(data_pipe[PIPE_READ]);
864 CloseHandle(data_pipe[PIPE_WRITE]);
865 CloseHandle(sync_pipe[PIPE_READ]);
866 CloseHandle(sync_pipe[PIPE_WRITE]);
867 for (i = 0; argv[i] != NULL; i++) {
868 g_free( (gpointer) argv[i]);
870 g_free( (gpointer) argv);
873 *fork_child = (int) pi.hProcess;
874 g_string_free(args, TRUE);
876 /* associate the operating system filehandles to C run-time file handles */
877 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
878 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
879 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
881 /* Create a pipe for the child process to send us messages */
882 if (pipe(sync_pipe) < 0) {
883 /* Couldn't create the message pipe between parent and child. */
884 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
885 for (i = 0; argv[i] != NULL; i++) {
886 g_free( (gpointer) argv[i]);
892 /* Create a pipe for the child process to send us data */
893 if (pipe(data_pipe) < 0) {
894 /* Couldn't create the data pipe between parent and child. */
895 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
896 ws_close(sync_pipe[PIPE_READ]);
897 ws_close(sync_pipe[PIPE_WRITE]);
898 for (i = 0; argv[i] != NULL; i++) {
899 g_free( (gpointer) argv[i]);
905 if ((*fork_child = fork()) == 0) {
907 * Child process - run dumpcap with the right arguments to make
908 * it just capture with the specified capture parameters
910 dup2(data_pipe[PIPE_WRITE], 1);
911 ws_close(data_pipe[PIPE_READ]);
912 ws_close(data_pipe[PIPE_WRITE]);
913 dup2(sync_pipe[PIPE_WRITE], 2);
914 ws_close(sync_pipe[PIPE_READ]);
915 ws_close(sync_pipe[PIPE_WRITE]);
916 execv(argv[0], argv);
917 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
918 argv[0], g_strerror(errno));
919 sync_pipe_errmsg_to_parent(2, errmsg, "");
921 /* Exit with "_exit()", so that we don't close the connection
922 to the X server (and cause stuff buffered up by our parent but
923 not yet sent to be sent, as that stuff should only be sent by
924 our parent). We've sent an error message to the parent, so
925 we exit with an exit status of 1 (any exit status other than
926 0 or 1 will cause an additional message to report that exit
927 status, over and above the error message we sent to the parent). */
931 if (fetch_dumpcap_pid && *fork_child > 0)
932 fetch_dumpcap_pid(*fork_child);
934 *data_read_fd = data_pipe[PIPE_READ];
935 *message_read_fd = sync_pipe[PIPE_READ];
938 for (i = 0; argv[i] != NULL; i++) {
939 g_free( (gpointer) argv[i]);
942 /* Parent process - read messages from the child process over the
944 g_free( (gpointer) argv); /* free up arg array */
946 /* Close the write sides of the pipes, so that only the child has them
947 open, and thus they completely close, and thus return to us
948 an EOF indication, if the child closes them (either deliberately
949 or by exiting abnormally). */
951 CloseHandle(data_pipe[PIPE_WRITE]);
952 CloseHandle(sync_pipe[PIPE_WRITE]);
954 ws_close(data_pipe[PIPE_WRITE]);
955 ws_close(sync_pipe[PIPE_WRITE]);
958 if (*fork_child == -1) {
959 /* We couldn't even create the child process. */
960 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
961 ws_close(*data_read_fd);
962 ws_close(*message_read_fd);
966 /* we might wait for a moment till child is ready, so update screen now */
967 if (update_cb) update_cb();
972 * Close the pipes we're using to read from dumpcap, and wait for it
973 * to exit. On success, *msgp is unchanged, and the exit status of
974 * dumpcap is returned. On failure (which includes "dumpcap exited
975 * due to being killed by a signal or an exception"), *msgp points
976 * to an error message for the failure, and -1 is returned. In the
977 * latter case, *msgp must be freed with g_free().
980 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
981 int *fork_child, gchar **msgp)
983 ws_close(*data_read_fd);
984 if (message_read_fd != NULL)
985 ws_close(*message_read_fd);
988 /* XXX - Should we signal the child somehow? */
989 sync_pipe_kill(*fork_child);
992 return sync_pipe_wait_for_child(*fork_child, msgp);
996 * Run dumpcap with the supplied arguments.
998 * On success, *data points to a buffer containing the dumpcap output,
999 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
1000 * must be freed with g_free().
1002 * On failure, *data is NULL, *primary_msg points to an error message,
1003 * *secondary_msg either points to an additional error message or is
1004 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1005 * must be freed with g_free().
1007 /* XXX - This duplicates a lot of code in sync_pipe_start() */
1008 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
1009 #define PIPE_BUF_SIZE 5120
1011 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
1012 gchar **secondary_msg, void(*update_cb)(void))
1015 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
1017 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1020 int primary_msg_len;
1021 char *primary_msg_text;
1022 int secondary_msg_len;
1023 char *secondary_msg_text;
1025 GString *data_buf = NULL;
1028 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
1029 &fork_child, &msg, update_cb);
1032 *secondary_msg = NULL;
1038 * We were able to set up to read dumpcap's output. Do so.
1040 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1042 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1043 buffer, primary_msg);
1045 /* We got a read error from the sync pipe, or we got no data at
1046 all from the sync pipe, so we're not going to be getting any
1047 data or error message from the child process. Pick up its
1048 exit status, and complain.
1050 We don't have to worry about killing the child, if the sync pipe
1051 returned an error. Usually this error is caused as the child killed
1052 itself while going down. Even in the rare cases that this isn't the
1053 case, the child will get an error when writing to the broken pipe
1054 the next time, cleaning itself up then. */
1055 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1057 /* We got an EOF from the sync pipe. That means that it exited
1058 before giving us any data to read. If ret is -1, we report
1059 that as a bad exit (e.g., exiting due to a signal); otherwise,
1060 we report it as a premature exit. */
1062 *primary_msg = wait_msg;
1064 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1066 /* We got an error from the sync pipe. If ret is -1, report
1067 both the sync pipe I/O error and the wait error. */
1069 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1070 g_free(*primary_msg);
1072 *primary_msg = combined_msg;
1075 *secondary_msg = NULL;
1080 /* we got a valid message block from the child, process it */
1085 * Error from dumpcap; there will be a primary message and a
1086 * secondary message.
1089 /* convert primary message */
1090 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1091 primary_msg_text = buffer+4;
1092 /* convert secondary message */
1093 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1094 &secondary_msg_len);
1095 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1096 /* the capture child will close the sync_pipe, nothing to do */
1099 * Pick up the child status.
1101 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1105 * Child process failed unexpectedly, or wait failed; msg is the
1109 *secondary_msg = NULL;
1112 * Child process failed, but returned the expected exit status.
1113 * Return the messages it gave us, and indicate failure.
1115 *primary_msg = g_strdup(primary_msg_text);
1116 *secondary_msg = g_strdup(secondary_msg_text);
1123 /* read the output from the command */
1124 data_buf = g_string_new("");
1125 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1126 buffer[count] = '\0';
1127 g_string_append(data_buf, buffer);
1131 * Pick up the child status.
1133 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1137 * Child process failed unexpectedly, or wait failed; msg is the
1141 *secondary_msg = NULL;
1142 g_string_free(data_buf, TRUE);
1146 * Child process succeeded.
1148 *primary_msg = NULL;
1149 *secondary_msg = NULL;
1150 *data = data_buf->str;
1151 g_string_free(data_buf, FALSE);
1157 * Pick up the child status.
1159 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1163 * Child process failed unexpectedly, or wait failed; msg is the
1167 *secondary_msg = NULL;
1170 * Child process returned an unknown status.
1172 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1174 *secondary_msg = NULL;
1183 /* centralised logging and timing for sync_pipe_run_command_actual(),
1184 * redirects to sync_pipe_run_command_actual()
1187 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1188 gchar **secondary_msg, void (*update_cb)(void))
1191 GTimeVal start_time;
1194 int logging_enabled;
1196 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1197 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1198 if(logging_enabled){
1199 g_get_current_time(&start_time);
1200 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1201 for(i=0; argv[i] != 0; i++) {
1202 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1205 /* do the actual sync pipe run command */
1206 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1208 if(logging_enabled){
1209 g_get_current_time(&end_time);
1210 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1211 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1213 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1221 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1222 gchar **data, gchar **primary_msg,
1223 gchar **secondary_msg, void (*update_cb)(void))
1229 argv = init_pipe_args(&argc);
1232 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1233 *secondary_msg = NULL;
1238 argv = sync_pipe_add_arg(argv, &argc, "-i");
1239 argv = sync_pipe_add_arg(argv, &argc, iface);
1242 opt = g_strdup_printf("%s,%s", freq, type);
1244 opt = g_strdup_printf("%s", freq);
1247 *primary_msg = g_strdup("Out of mem.");
1248 *secondary_msg = NULL;
1253 argv = sync_pipe_add_arg(argv, &argc, "-k");
1254 argv = sync_pipe_add_arg(argv, &argc, opt);
1257 /* Run dumpcap in capture child mode */
1258 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1259 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1262 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1268 * Get the list of interfaces using dumpcap.
1270 * On success, *data points to a buffer containing the dumpcap output,
1271 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1272 * must be freed with g_free().
1274 * On failure, *data is NULL, *primary_msg points to an error message,
1275 * *secondary_msg either points to an additional error message or is
1276 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1277 * must be freed with g_free().
1280 sync_interface_list_open(gchar **data, gchar **primary_msg,
1281 gchar **secondary_msg, void (*update_cb)(void))
1286 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1288 argv = init_pipe_args(&argc);
1291 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1292 *secondary_msg = NULL;
1297 /* Ask for the interface list */
1298 argv = sync_pipe_add_arg(argv, &argc, "-D");
1301 /* Run dumpcap in capture child mode */
1302 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1303 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1305 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1309 * Get the capabilities of an interface using dumpcap.
1311 * On success, *data points to a buffer containing the dumpcap output,
1312 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1313 * must be freed with g_free().
1315 * On failure, *data is NULL, *primary_msg points to an error message,
1316 * *secondary_msg either points to an additional error message or is
1317 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1318 * must be freed with g_free().
1321 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1322 gchar **data, gchar **primary_msg,
1323 gchar **secondary_msg, void (*update_cb)(void))
1328 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1330 argv = init_pipe_args(&argc);
1333 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1334 *secondary_msg = NULL;
1339 /* Ask for the interface capabilities */
1340 argv = sync_pipe_add_arg(argv, &argc, "-i");
1341 argv = sync_pipe_add_arg(argv, &argc, ifname);
1342 argv = sync_pipe_add_arg(argv, &argc, "-L");
1344 argv = sync_pipe_add_arg(argv, &argc, "-I");
1347 /* Run dumpcap in capture child mode */
1348 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1349 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1351 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1355 * Start getting interface statistics using dumpcap. On success, read_fd
1356 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1357 * and zero is returned. On failure, *msg will point to an error message
1358 * that must be g_free()d, and -1 will be returned.
1361 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
1365 int message_read_fd, ret;
1367 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1370 int primary_msg_len;
1371 char *primary_msg_text;
1372 int secondary_msg_len;
1373 /*char *secondary_msg_text;*/
1376 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1378 argv = init_pipe_args(&argc);
1381 *msg = g_strdup("We don't know where to find dumpcap.");
1385 /* Ask for the interface statistics */
1386 argv = sync_pipe_add_arg(argv, &argc, "-S");
1389 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1391 create_dummy_signal_pipe();
1392 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1394 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1397 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1398 fork_child, msg, update_cb);
1403 * We were able to set up to read dumpcap's output. Do so.
1405 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1407 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1410 /* We got a read error from the sync pipe, or we got no data at
1411 all from the sync pipe, so we're not going to be getting any
1412 data or error message from the child process. Pick up its
1413 exit status, and complain.
1415 We don't have to worry about killing the child, if the sync pipe
1416 returned an error. Usually this error is caused as the child killed
1417 itself while going down. Even in the rare cases that this isn't the
1418 case, the child will get an error when writing to the broken pipe
1419 the next time, cleaning itself up then. */
1420 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1422 /* We got an EOF from the sync pipe. That means that it exited
1423 before giving us any data to read. If ret is -1, we report
1424 that as a bad exit (e.g., exiting due to a signal); otherwise,
1425 we report it as a premature exit. */
1429 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1431 /* We got an error from the sync pipe. If ret is -1, report
1432 both the sync pipe I/O error and the wait error. */
1434 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1437 *msg = combined_msg;
1444 /* we got a valid message block from the child, process it */
1449 * Error from dumpcap; there will be a primary message and a
1450 * secondary message.
1453 /* convert primary message */
1454 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1455 primary_msg_text = buffer+4;
1456 /* convert secondary message */
1457 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1458 &secondary_msg_len);
1459 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1460 /* the capture child will close the sync_pipe, nothing to do */
1463 * Pick up the child status.
1465 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1469 * Child process failed unexpectedly, or wait failed; msg is the
1474 * Child process failed, but returned the expected exit status.
1475 * Return the messages it gave us, and indicate failure.
1477 *msg = g_strdup(primary_msg_text);
1483 /* Close the message pipe. */
1484 ws_close(message_read_fd);
1489 * Pick up the child status.
1491 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1495 * Child process failed unexpectedly, or wait failed; msg is the
1500 * Child process returned an unknown status.
1502 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1511 /* Close down the stats process */
1513 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1517 * Don't bother waiting for the child. sync_pipe_close_command
1518 * does this for us on Windows.
1520 sync_pipe_kill(*fork_child);
1522 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1525 /* read a number of bytes from a pipe */
1526 /* (blocks until enough bytes read or an error occurs) */
1528 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1535 newly = read(pipe_fd, &bytes[offset], required);
1538 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1539 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1546 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1547 "read from pipe %d: error(%u): %s", pipe_fd, error,
1549 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1554 required -= (int)newly;
1562 static gboolean pipe_data_available(int pipe_fd) {
1563 #ifdef _WIN32 /* PeekNamedPipe */
1564 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1567 if (hPipe == INVALID_HANDLE_VALUE)
1570 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1573 if (bytes_avail > 0)
1578 struct timeval timeout;
1581 FD_SET(pipe_fd, &rfds);
1583 timeout.tv_usec = 0;
1585 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1592 /* Read a line from a pipe, similar to fgets */
1594 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1598 while(offset < max - 1) {
1600 if (! pipe_data_available(pipe_fd))
1602 newly = read(pipe_fd, &bytes[offset], 1);
1604 /* EOF - not necessarily an error */
1606 } else if (newly == -1) {
1608 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1609 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1611 } else if (bytes[offset] == '\n') {
1617 bytes[offset] = '\0';
1623 /* convert header values (indicator and 3-byte length) */
1625 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1627 g_assert(header_len == 4);
1629 /* convert header values */
1630 *indicator = header[0];
1631 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1634 /* read a message from the sending pipe in the standard format
1635 (1-byte message indicator, 3-byte message length (excluding length
1636 and indicator field), and the rest is the message) */
1638 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1645 /* read header (indicator and 3-byte length) */
1646 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1650 * Immediate EOF; if the capture child exits normally, this
1651 * is an "I'm done" indication, so don't report it as an
1654 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1655 "read %d got an EOF", pipe_fd);
1658 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1659 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1662 * Short read, but not an immediate EOF.
1664 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1670 /* convert header values */
1671 pipe_convert_header((guchar*)header, 4, indicator, &required);
1673 /* only indicator with no value? */
1675 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1676 "read %d indicator: %c empty value", pipe_fd, *indicator);
1680 /* does the data fit into the given buffer? */
1681 if(required > len) {
1682 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1683 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1684 pipe_fd, required, len,
1685 header[0], header[1], header[2], header[3]);
1687 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1688 memcpy(msg, header, sizeof(header));
1689 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1690 if (newly < 0) { /* error */
1691 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1692 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1694 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1700 /* read the actual block data */
1701 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1702 if(newly != required) {
1704 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1710 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1711 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1712 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1719 /* There's stuff to read from the sync pipe, meaning the child has sent
1720 us a message, or the sync pipe has closed, meaning the child has
1721 closed it (perhaps because it exited). */
1723 sync_pipe_input_cb(gint source, gpointer user_data)
1725 capture_session *cap_session = (capture_session *)user_data;
1727 char buffer[SP_MAX_MSG_LEN+1] = {0};
1733 char *secondary_msg;
1734 char *wait_msg, *combined_msg;
1737 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1740 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1742 If we got a read error or a bad message, nread is -1 and
1743 primary_msg is set to point to an error message. We don't
1744 have to worry about killing the child; usually this error
1745 is caused as the child killed itself while going down.
1746 Even in the rare cases that this isn't the case, the child
1747 will get an error when writing to the broken pipe the next time,
1748 cleaning itself up then.
1750 If we got an EOF, nread is 0 and primary_msg isn't set. This
1751 is an indication that the capture is finished. */
1752 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1754 /* We got an EOF from the sync pipe. That means that the capture
1755 child exited, and not in the middle of a message; we treat
1756 that as an indication that it's done, and only report an
1757 error if ret is -1, in which case wait_msg is the error
1760 primary_msg = wait_msg;
1762 /* We got an error from the sync pipe. If ret is -1, report
1763 both the sync pipe I/O error and the wait error. */
1765 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1766 g_free(primary_msg);
1768 primary_msg = combined_msg;
1772 /* No more child process. */
1773 cap_session->fork_child = -1;
1774 cap_session->fork_child_status = ret;
1777 ws_close(cap_session->signal_pipe_write_fd);
1780 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1781 extcap_cleanup(cap_session->capture_opts);
1783 capture_input_closed(cap_session, primary_msg);
1784 g_free(primary_msg);
1788 /* we got a valid message block from the child, process it */
1791 if(!capture_input_new_file(cap_session, buffer)) {
1792 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1794 /* We weren't able to open the new capture file; user has been
1795 alerted. Close the sync pipe. */
1798 /* The child has sent us a filename which we couldn't open.
1800 This could mean that the child is creating and deleting files
1801 (ring buffer mode) faster than we can handle it.
1803 That should only be the case for very fast file switches;
1804 We can't do much more than telling the child to stop.
1805 (This is the "emergency brake" if the user e.g. wants to
1806 switch files every second).
1808 This can also happen if the user specified "-", meaning
1809 "standard output", as the capture file. */
1810 sync_pipe_stop(cap_session);
1811 capture_input_closed(cap_session, NULL);
1815 case SP_PACKET_COUNT:
1816 npackets = atoi(buffer);
1817 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1818 capture_input_new_packets(cap_session, npackets);
1821 /* convert primary message */
1822 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1823 primary_msg = buffer+4;
1824 /* convert secondary message */
1825 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1826 secondary_msg = primary_msg + primary_len + 4;
1827 /* message output */
1828 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1829 /* the capture child will close the sync_pipe, nothing to do for now */
1830 /* (an error message doesn't mean we have to stop capturing) */
1832 case SP_BAD_FILTER: {
1836 ch = strtok(buffer, ":");
1838 indx = (int)strtol(ch, NULL, 10);
1839 ch = strtok(NULL, ":");
1841 capture_input_cfilter_error_message(cap_session, indx, ch);
1842 /* the capture child will close the sync_pipe, nothing to do for now */
1846 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1849 g_assert_not_reached();
1858 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1859 * unchanged, and the exit status of dumpcap is returned. On
1860 * failure (which includes "dumpcap exited due to being killed by
1861 * a signal or an exception"), *msgp points to an error message
1862 * for the failure, and -1 is returned. In the latter case, *msgp
1863 * must be freed with g_free().
1866 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1868 int fork_child_status;
1870 GTimeVal start_time;
1875 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1878 g_get_current_time(&start_time);
1880 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1881 g_assert(fork_child != -1);
1883 *msgp = NULL; /* assume no error */
1885 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1886 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1890 * The child exited; return its exit status. Do not treat this as
1893 ret = fork_child_status;
1894 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1895 /* Probably an exception code */
1896 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1897 win32strexception(fork_child_status));
1902 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1903 if (WIFEXITED(fork_child_status)) {
1905 * The child exited; return its exit status. Do not treat this as
1908 ret = WEXITSTATUS(fork_child_status);
1909 } else if (WIFSTOPPED(fork_child_status)) {
1910 /* It stopped, rather than exiting. "Should not happen." */
1911 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1912 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1914 } else if (WIFSIGNALED(fork_child_status)) {
1915 /* It died with a signal. */
1916 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1917 sync_pipe_signame(WTERMSIG(fork_child_status)),
1918 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1921 /* What? It had to either have exited, or stopped, or died with
1922 a signal; what happened here? */
1923 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1927 } else if (errno != ECHILD) {
1928 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1931 /* errno == ECHILD ; echld might have already reaped the child */
1932 ret = fetch_dumpcap_pid ? 0 : -1;
1936 g_get_current_time(&end_time);
1937 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1938 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1939 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1945 /* convert signal to corresponding name */
1947 sync_pipe_signame(int sig)
1950 static char sigmsg_buf[6+1+3+1];
1959 sigmsg = "Interrupted";
1967 sigmsg = "Illegal instruction";
1971 sigmsg = "Trace trap";
1979 sigmsg = "Arithmetic exception";
1987 sigmsg = "Bus error";
1991 sigmsg = "Segmentation violation";
1994 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1995 Linux is POSIX compliant. These are not POSIX-defined signals ---
1996 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1998 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1999 were omitted from POSIX.1 because their behavior is
2000 implementation dependent and could not be adequately catego-
2001 rized. Conforming implementations may deliver these sig-
2002 nals, but must document the circumstances under which they
2003 are delivered and note any restrictions concerning their
2006 So we only check for SIGSYS on those systems that happen to
2007 implement them (a system can be POSIX-compliant and implement
2008 them, it's just that POSIX doesn't *require* a POSIX-compliant
2009 system to implement them).
2014 sigmsg = "Bad system call";
2019 sigmsg = "Broken pipe";
2023 sigmsg = "Alarm clock";
2027 sigmsg = "Terminated";
2031 /* Returning a static buffer is ok in the context we use it here */
2032 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2033 sigmsg = sigmsg_buf;
2043 static void create_dummy_signal_pipe() {
2044 gchar *dummy_signal_pipe_name;
2046 if (dummy_signal_pipe != NULL) return;
2048 if (!dummy_control_id) {
2049 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2052 /* Create the signal pipe */
2053 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2054 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2055 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2056 g_free(dummy_signal_pipe_name);
2059 /* tell the child through the signal pipe that we want to quit the capture */
2061 signal_pipe_capquit_to_child(capture_session *cap_session)
2063 const char quit_msg[] = "QUIT";
2066 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2068 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2069 /* simply sending a "QUIT" string */
2070 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2071 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2073 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2074 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2080 /* user wants to stop the capture run */
2082 sync_pipe_stop(capture_session *cap_session)
2087 gboolean terminate = TRUE;
2089 if (cap_session->fork_child != -1) {
2091 /* send the SIGINT signal to close the capture child gracefully. */
2092 int sts = kill(cap_session->fork_child, SIGINT);
2094 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2095 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2098 #define STOP_SLEEP_TIME 500 /* ms */
2099 #define STOP_CHECK_TIME 50
2100 /* First, use the special signal pipe to try to close the capture child
2103 signal_pipe_capquit_to_child(cap_session);
2105 /* Next, wait for the process to exit on its own */
2106 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2107 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2108 childstatus != STILL_ACTIVE) {
2112 Sleep(STOP_CHECK_TIME);
2115 /* Force the issue. */
2117 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2118 "sync_pipe_stop: forcing child to exit");
2119 sync_pipe_kill(cap_session->fork_child);
2126 /* Wireshark has to exit, force the capture child to close */
2128 sync_pipe_kill(int fork_child)
2130 if (fork_child != -1) {
2132 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2134 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2135 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2138 /* Remark: This is not the preferred method of closing a process!
2139 * the clean way would be getting the process id of the child process,
2140 * then getting window handle hWnd of that process (using EnumChildWindows),
2141 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2143 * Unfortunately, I don't know how to get the process id from the
2144 * handle. OpenProcess will get an handle (not a window handle)
2145 * from the process ID; it will not get a window handle from the
2146 * process ID. (How could it? A process can have more than one
2147 * window. For that matter, a process might have *no* windows,
2148 * as a process running dumpcap, the normal child process program,
2151 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2152 * running in the same console; that's not necessarily the case for
2153 * us, as we might not be running in a console.
2154 * And this also will require to have the process id.
2156 TerminateProcess((HANDLE) (fork_child), 0);
2162 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
2163 fetch_dumpcap_pid = cb;
2166 #endif /* HAVE_LIBPCAP */