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(ws_process_id 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)(ws_process_id) = NULL;
130 capture_session_init(capture_session *cap_session, struct _capture_file *cf)
132 cap_session->cf = cf;
133 cap_session->fork_child = WS_INVALID_PID; /* 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->count = 0;
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" */
333 exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
335 exename = g_strdup_printf("%s/dumpcap", progfile_dir);
338 /* Make that the first argument in the argument list (argv[0]). */
339 argv = sync_pipe_add_arg(argv, argc, exename);
341 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
347 #define ARGV_NUMBER_LEN 24
348 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
350 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
352 char ssnap[ARGV_NUMBER_LEN];
353 char scount[ARGV_NUMBER_LEN];
354 char sfilesize[ARGV_NUMBER_LEN];
355 char sfile_duration[ARGV_NUMBER_LEN];
356 char sring_num_files[ARGV_NUMBER_LEN];
357 char sautostop_files[ARGV_NUMBER_LEN];
358 char sautostop_filesize[ARGV_NUMBER_LEN];
359 char sautostop_duration[ARGV_NUMBER_LEN];
360 #ifdef HAVE_PCAP_REMOTE
363 #ifdef HAVE_PCAP_SETSAMPLING
364 char ssampling[ARGV_NUMBER_LEN];
367 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
368 char buffer_size[ARGV_NUMBER_LEN];
372 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
373 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
374 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
375 GString *args = g_string_sized_new(200);
377 SECURITY_ATTRIBUTES sa;
379 PROCESS_INFORMATION pi;
380 char control_id[ARGV_NUMBER_LEN];
381 gchar *signal_pipe_name;
384 int sync_pipe[2]; /* pipe used to send messages from child to parent */
385 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
387 int sync_pipe_read_fd;
392 interface_options interface_opts;
394 if (capture_opts->ifaces->len > 1)
395 capture_opts->use_pcapng = TRUE;
396 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
397 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
399 cap_session->fork_child = WS_INVALID_PID;
402 if (!extcaps_init_initerfaces(capture_opts)) {
403 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
409 argv = init_pipe_args(&argc);
411 /* We don't know where to find dumpcap. */
412 report_failure("We don't know where to find dumpcap.");
416 if (capture_opts->ifaces->len > 1)
417 argv = sync_pipe_add_arg(argv, &argc, "-t");
419 if (capture_opts->use_pcapng)
420 argv = sync_pipe_add_arg(argv, &argc, "-n");
422 argv = sync_pipe_add_arg(argv, &argc, "-P");
424 if (capture_opts->capture_comment) {
425 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
426 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
429 if (capture_opts->multi_files_on) {
430 if (capture_opts->has_autostop_filesize) {
431 argv = sync_pipe_add_arg(argv, &argc, "-b");
432 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
433 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
436 if (capture_opts->has_file_duration) {
437 argv = sync_pipe_add_arg(argv, &argc, "-b");
438 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
439 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
442 if (capture_opts->has_ring_num_files) {
443 argv = sync_pipe_add_arg(argv, &argc, "-b");
444 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
445 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
448 if (capture_opts->has_autostop_files) {
449 argv = sync_pipe_add_arg(argv, &argc, "-a");
450 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
451 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
454 if (capture_opts->has_autostop_filesize) {
455 argv = sync_pipe_add_arg(argv, &argc, "-a");
456 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
457 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
461 if (capture_opts->has_autostop_packets) {
462 argv = sync_pipe_add_arg(argv, &argc, "-c");
463 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
464 argv = sync_pipe_add_arg(argv, &argc, scount);
467 if (capture_opts->has_autostop_duration) {
468 argv = sync_pipe_add_arg(argv, &argc, "-a");
469 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
470 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
473 if (capture_opts->group_read_access) {
474 argv = sync_pipe_add_arg(argv, &argc, "-g");
477 for (j = 0; j < capture_opts->ifaces->len; j++) {
478 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
480 argv = sync_pipe_add_arg(argv, &argc, "-i");
482 if (interface_opts.extcap_fifo != NULL)
483 argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
486 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
488 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
489 argv = sync_pipe_add_arg(argv, &argc, "-f");
490 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
492 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
493 argv = sync_pipe_add_arg(argv, &argc, "-s");
494 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
495 argv = sync_pipe_add_arg(argv, &argc, ssnap);
498 if (interface_opts.linktype != -1) {
499 const char *linktype = linktype_val_to_name(interface_opts.linktype);
500 if ( linktype != NULL )
502 argv = sync_pipe_add_arg(argv, &argc, "-y");
503 argv = sync_pipe_add_arg(argv, &argc, linktype);
507 if (!interface_opts.promisc_mode) {
508 argv = sync_pipe_add_arg(argv, &argc, "-p");
511 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
512 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
513 argv = sync_pipe_add_arg(argv, &argc, "-B");
514 if(interface_opts.buffer_size == 0x00)
515 interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
516 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
517 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
521 #ifdef HAVE_PCAP_CREATE
522 if (interface_opts.monitor_mode) {
523 argv = sync_pipe_add_arg(argv, &argc, "-I");
527 #ifdef HAVE_PCAP_REMOTE
528 if (interface_opts.datatx_udp)
529 argv = sync_pipe_add_arg(argv, &argc, "-u");
531 if (!interface_opts.nocap_rpcap)
532 argv = sync_pipe_add_arg(argv, &argc, "-r");
534 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
535 argv = sync_pipe_add_arg(argv, &argc, "-A");
536 g_snprintf(sauth, sizeof(sauth), "%s:%s",
537 interface_opts.auth_username,
538 interface_opts.auth_password);
539 argv = sync_pipe_add_arg(argv, &argc, sauth);
543 #ifdef HAVE_PCAP_SETSAMPLING
544 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
545 argv = sync_pipe_add_arg(argv, &argc, "-m");
546 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
547 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
548 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
550 interface_opts.sampling_param);
551 argv = sync_pipe_add_arg(argv, &argc, ssampling);
556 /* dumpcap should be running in capture child mode (hidden feature) */
558 argv = sync_pipe_add_arg(argv, &argc, "-Z");
560 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
561 argv = sync_pipe_add_arg(argv, &argc, control_id);
563 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
567 if (capture_opts->save_file) {
568 argv = sync_pipe_add_arg(argv, &argc, "-w");
569 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
571 for (i = 0; i < argc; i++) {
572 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
576 /* init SECURITY_ATTRIBUTES */
577 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
578 sa.bInheritHandle = TRUE;
579 sa.lpSecurityDescriptor = NULL;
581 /* Create a pipe for the child process */
582 /* (increase this value if you have trouble while fast capture file switches) */
583 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
584 /* Couldn't create the pipe between parent and child. */
585 report_failure("Couldn't create sync pipe: %s",
586 win32strerror(GetLastError()));
587 for (i = 0; i < argc; i++) {
588 g_free( (gpointer) argv[i]);
590 g_free( (gpointer) argv);
594 /* Create the signal pipe */
595 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
596 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
597 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
598 g_free(signal_pipe_name);
600 if (signal_pipe == INVALID_HANDLE_VALUE) {
601 /* Couldn't create the signal pipe between parent and child. */
602 report_failure("Couldn't create signal pipe: %s",
603 win32strerror(GetLastError()));
604 for (i = 0; i < argc; i++) {
605 g_free( (gpointer) argv[i]);
607 g_free( (gpointer) argv);
611 /* init STARTUPINFO */
612 memset(&si, 0, sizeof(si));
615 si.dwFlags = STARTF_USESHOWWINDOW;
616 si.wShowWindow = SW_SHOW;
618 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
619 si.wShowWindow = SW_HIDE; /* this hides the console window */
621 /* needs first a check if NULL *
622 * otherwise wouldn't work with non extcap interfaces */
623 if(interface_opts.extcap_fifo != NULL)
625 if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
627 si.hStdInput = extcap_get_win32_handle();
632 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
634 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
635 si.hStdError = sync_pipe_write;
636 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
639 /* convert args array into a single string */
640 /* XXX - could change sync_pipe_add_arg() instead */
641 /* there is a drawback here: the length is internally limited to 1024 bytes */
642 for(i=0; argv[i] != 0; i++) {
643 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
644 quoted_arg = protect_arg(argv[i]);
645 g_string_append(args, quoted_arg);
650 if(!CreateProcess(utf_8to16(argv[0]), utf_8to16(args->str), NULL, NULL, TRUE,
651 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
652 report_failure("Couldn't run %s in child process: %s",
653 args->str, win32strerror(GetLastError()));
654 CloseHandle(sync_pipe_read);
655 CloseHandle(sync_pipe_write);
656 for (i = 0; i < argc; i++) {
657 g_free( (gpointer) argv[i]);
659 g_free( (gpointer) argv);
662 cap_session->fork_child = pi.hProcess;
663 g_string_free(args, TRUE);
665 /* associate the operating system filehandle to a C run-time file handle */
666 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
667 sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
669 /* associate the operating system filehandle to a C run-time file handle */
670 cap_session->signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
673 if (pipe(sync_pipe) < 0) {
674 /* Couldn't create the pipe between parent and child. */
675 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
676 for (i = 0; i < argc; i++) {
677 g_free( (gpointer) argv[i]);
683 if ((cap_session->fork_child = fork()) == 0) {
685 * Child process - run dumpcap with the right arguments to make
686 * it just capture with the specified capture parameters
688 dup2(sync_pipe[PIPE_WRITE], 2);
689 ws_close(sync_pipe[PIPE_READ]);
690 execv(argv[0], argv);
691 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
692 argv[0], g_strerror(errno));
693 sync_pipe_errmsg_to_parent(2, errmsg, "");
695 /* Exit with "_exit()", so that we don't close the connection
696 to the X server (and cause stuff buffered up by our parent but
697 not yet sent to be sent, as that stuff should only be sent by
698 our parent). We've sent an error message to the parent, so
699 we exit with an exit status of 1 (any exit status other than
700 0 or 1 will cause an additional message to report that exit
701 status, over and above the error message we sent to the parent). */
705 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
706 fetch_dumpcap_pid(cap_session->fork_child);
708 sync_pipe_read_fd = sync_pipe[PIPE_READ];
711 for (i = 0; i < argc; i++) {
712 g_free( (gpointer) argv[i]);
715 /* Parent process - read messages from the child process over the
717 g_free( (gpointer) argv); /* free up arg array */
719 /* Close the write side of the pipe, so that only the child has it
720 open, and thus it completely closes, and thus returns to us
721 an EOF indication, if the child closes it (either deliberately
722 or by exiting abnormally). */
724 CloseHandle(sync_pipe_write);
726 ws_close(sync_pipe[PIPE_WRITE]);
729 if (cap_session->fork_child == WS_INVALID_PID) {
730 /* We couldn't even create the child process. */
731 report_failure("Couldn't create child process: %s", g_strerror(errno));
732 ws_close(sync_pipe_read_fd);
734 ws_close(cap_session->signal_pipe_write_fd);
739 cap_session->fork_child_status = 0;
740 cap_session->capture_opts = capture_opts;
742 /* we might wait for a moment till child is ready, so update screen now */
743 if (update_cb) update_cb();
745 /* We were able to set up to read the capture file;
746 arrange that our callback be called whenever it's possible
747 to read from the sync pipe, so that it's called when
748 the child process wants to tell us something. */
750 /* we have a running capture, now wait for the real capture filename */
751 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
752 &cap_session->fork_child, sync_pipe_input_cb);
758 * Open two pipes to dumpcap with the supplied arguments, one for its
759 * standard output and one for its standard error.
761 * On success, *msg is unchanged and 0 is returned; data_read_fd,
762 * messsage_read_fd, and fork_child point to the standard output pipe's
763 * file descriptor, the standard error pipe's file descriptor, and
764 * the child's PID/handle, respectively.
766 * On failure, *msg points to an error message for the failure, and -1 is
767 * returned, in which case *msg must be freed with g_free().
769 /* XXX - This duplicates a lot of code in sync_pipe_start() */
770 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
771 #define PIPE_BUF_SIZE 5120
773 sync_pipe_open_command(char** argv, int *data_read_fd,
774 int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
776 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
778 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
779 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
780 GString *args = g_string_sized_new(200);
782 SECURITY_ATTRIBUTES sa;
784 PROCESS_INFORMATION pi;
787 int sync_pipe[2]; /* pipe used to send messages from child to parent */
788 int data_pipe[2]; /* pipe used to send data from child to parent */
791 *fork_child = WS_INVALID_PID;
793 *message_read_fd = -1;
794 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
797 /* We can't return anything */
799 g_string_free(args, TRUE);
805 /* init SECURITY_ATTRIBUTES */
806 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
807 sa.bInheritHandle = TRUE;
808 sa.lpSecurityDescriptor = NULL;
810 /* Create a pipe for the child process to send us messages */
811 /* (increase this value if you have trouble while fast capture file switches) */
812 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
813 /* Couldn't create the message pipe between parent and child. */
814 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
815 win32strerror(GetLastError()));
816 for (i = 0; argv[i] != NULL; i++) {
817 g_free( (gpointer) argv[i]);
819 g_free( (gpointer) argv);
823 /* Create a pipe for the child process to send us data */
824 /* (increase this value if you have trouble while fast capture file switches) */
825 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
826 /* Couldn't create the message pipe between parent and child. */
827 *msg = g_strdup_printf("Couldn't create data pipe: %s",
828 win32strerror(GetLastError()));
829 CloseHandle(sync_pipe[PIPE_READ]);
830 CloseHandle(sync_pipe[PIPE_WRITE]);
831 for (i = 0; argv[i] != NULL; i++) {
832 g_free( (gpointer) argv[i]);
834 g_free( (gpointer) argv);
838 /* init STARTUPINFO */
839 memset(&si, 0, sizeof(si));
842 si.dwFlags = STARTF_USESHOWWINDOW;
843 si.wShowWindow = SW_SHOW;
845 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
846 si.wShowWindow = SW_HIDE; /* this hides the console window */
847 si.hStdInput = NULL; /* handle for named pipe*/
849 si.hStdOutput = data_pipe[PIPE_WRITE];
850 si.hStdError = sync_pipe[PIPE_WRITE];
853 /* convert args array into a single string */
854 /* XXX - could change sync_pipe_add_arg() instead */
855 /* there is a drawback here: the length is internally limited to 1024 bytes */
856 for(i=0; argv[i] != 0; i++) {
857 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
858 quoted_arg = protect_arg(argv[i]);
859 g_string_append(args, quoted_arg);
864 if(!CreateProcess(utf_8to16(argv[0]), utf_8to16(args->str), NULL, NULL, TRUE,
865 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
866 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
867 args->str, win32strerror(GetLastError()));
868 CloseHandle(data_pipe[PIPE_READ]);
869 CloseHandle(data_pipe[PIPE_WRITE]);
870 CloseHandle(sync_pipe[PIPE_READ]);
871 CloseHandle(sync_pipe[PIPE_WRITE]);
872 for (i = 0; argv[i] != NULL; i++) {
873 g_free( (gpointer) argv[i]);
875 g_free( (gpointer) argv);
878 *fork_child = pi.hProcess;
879 g_string_free(args, TRUE);
881 /* associate the operating system filehandles to C run-time file handles */
882 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
883 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
884 *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
886 /* Create a pipe for the child process to send us messages */
887 if (pipe(sync_pipe) < 0) {
888 /* Couldn't create the message pipe between parent and child. */
889 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
890 for (i = 0; argv[i] != NULL; i++) {
891 g_free( (gpointer) argv[i]);
897 /* Create a pipe for the child process to send us data */
898 if (pipe(data_pipe) < 0) {
899 /* Couldn't create the data pipe between parent and child. */
900 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
901 ws_close(sync_pipe[PIPE_READ]);
902 ws_close(sync_pipe[PIPE_WRITE]);
903 for (i = 0; argv[i] != NULL; i++) {
904 g_free( (gpointer) argv[i]);
910 if ((*fork_child = fork()) == 0) {
912 * Child process - run dumpcap with the right arguments to make
913 * it just capture with the specified capture parameters
915 dup2(data_pipe[PIPE_WRITE], 1);
916 ws_close(data_pipe[PIPE_READ]);
917 ws_close(data_pipe[PIPE_WRITE]);
918 dup2(sync_pipe[PIPE_WRITE], 2);
919 ws_close(sync_pipe[PIPE_READ]);
920 ws_close(sync_pipe[PIPE_WRITE]);
921 execv(argv[0], argv);
922 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
923 argv[0], g_strerror(errno));
924 sync_pipe_errmsg_to_parent(2, errmsg, "");
926 /* Exit with "_exit()", so that we don't close the connection
927 to the X server (and cause stuff buffered up by our parent but
928 not yet sent to be sent, as that stuff should only be sent by
929 our parent). We've sent an error message to the parent, so
930 we exit with an exit status of 1 (any exit status other than
931 0 or 1 will cause an additional message to report that exit
932 status, over and above the error message we sent to the parent). */
936 if (fetch_dumpcap_pid && *fork_child > 0)
937 fetch_dumpcap_pid(*fork_child);
939 *data_read_fd = data_pipe[PIPE_READ];
940 *message_read_fd = sync_pipe[PIPE_READ];
943 for (i = 0; argv[i] != NULL; i++) {
944 g_free( (gpointer) argv[i]);
947 /* Parent process - read messages from the child process over the
949 g_free( (gpointer) argv); /* free up arg array */
951 /* Close the write sides of the pipes, so that only the child has them
952 open, and thus they completely close, and thus return to us
953 an EOF indication, if the child closes them (either deliberately
954 or by exiting abnormally). */
956 CloseHandle(data_pipe[PIPE_WRITE]);
957 CloseHandle(sync_pipe[PIPE_WRITE]);
959 ws_close(data_pipe[PIPE_WRITE]);
960 ws_close(sync_pipe[PIPE_WRITE]);
963 if (*fork_child == WS_INVALID_PID) {
964 /* We couldn't even create the child process. */
965 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
966 ws_close(*data_read_fd);
967 ws_close(*message_read_fd);
971 /* we might wait for a moment till child is ready, so update screen now */
972 if (update_cb) update_cb();
977 * Close the pipes we're using to read from dumpcap, and wait for it
978 * to exit. On success, *msgp is unchanged, and the exit status of
979 * dumpcap is returned. On failure (which includes "dumpcap exited
980 * due to being killed by a signal or an exception"), *msgp points
981 * to an error message for the failure, and -1 is returned. In the
982 * latter case, *msgp must be freed with g_free().
985 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
986 ws_process_id *fork_child, gchar **msgp)
988 ws_close(*data_read_fd);
989 if (message_read_fd != NULL)
990 ws_close(*message_read_fd);
993 /* XXX - Should we signal the child somehow? */
994 sync_pipe_kill(*fork_child);
997 return sync_pipe_wait_for_child(*fork_child, msgp);
1001 * Run dumpcap with the supplied arguments.
1003 * On success, *data points to a buffer containing the dumpcap output,
1004 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
1005 * must be freed with g_free().
1007 * On failure, *data is NULL, *primary_msg points to an error message,
1008 * *secondary_msg either points to an additional error message or is
1009 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1010 * must be freed with g_free().
1012 /* XXX - This duplicates a lot of code in sync_pipe_start() */
1013 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
1014 #define PIPE_BUF_SIZE 5120
1016 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
1017 gchar **secondary_msg, void(*update_cb)(void))
1020 int data_pipe_read_fd, sync_pipe_read_fd, ret;
1021 ws_process_id fork_child;
1023 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1026 int primary_msg_len;
1027 char *primary_msg_text;
1028 int secondary_msg_len;
1029 char *secondary_msg_text;
1031 GString *data_buf = NULL;
1034 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
1035 &fork_child, &msg, update_cb);
1038 *secondary_msg = NULL;
1044 * We were able to set up to read dumpcap's output. Do so.
1046 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1048 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1049 buffer, primary_msg);
1051 /* We got a read error from the sync pipe, or we got no data at
1052 all from the sync pipe, so we're not going to be getting any
1053 data or error message from the child process. Pick up its
1054 exit status, and complain.
1056 We don't have to worry about killing the child, if the sync pipe
1057 returned an error. Usually this error is caused as the child killed
1058 itself while going down. Even in the rare cases that this isn't the
1059 case, the child will get an error when writing to the broken pipe
1060 the next time, cleaning itself up then. */
1061 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1063 /* We got an EOF from the sync pipe. That means that it exited
1064 before giving us any data to read. If ret is -1, we report
1065 that as a bad exit (e.g., exiting due to a signal); otherwise,
1066 we report it as a premature exit. */
1068 *primary_msg = wait_msg;
1070 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1072 /* We got an error from the sync pipe. If ret is -1, report
1073 both the sync pipe I/O error and the wait error. */
1075 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1076 g_free(*primary_msg);
1078 *primary_msg = combined_msg;
1081 *secondary_msg = NULL;
1087 /* we got a valid message block from the child, process it */
1092 * Error from dumpcap; there will be a primary message and a
1093 * secondary message.
1096 /* convert primary message */
1097 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1098 primary_msg_text = buffer+4;
1099 /* convert secondary message */
1100 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1101 &secondary_msg_len);
1102 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1103 /* the capture child will close the sync_pipe, nothing to do */
1106 * Pick up the child status.
1108 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1112 * Child process failed unexpectedly, or wait failed; msg is the
1116 *secondary_msg = NULL;
1119 * Child process failed, but returned the expected exit status.
1120 * Return the messages it gave us, and indicate failure.
1122 *primary_msg = g_strdup(primary_msg_text);
1123 *secondary_msg = g_strdup(secondary_msg_text);
1130 /* read the output from the command */
1131 data_buf = g_string_new("");
1132 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1133 buffer[count] = '\0';
1134 g_string_append(data_buf, buffer);
1138 * Pick up the child status.
1140 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1144 * Child process failed unexpectedly, or wait failed; msg is the
1148 *secondary_msg = NULL;
1149 g_string_free(data_buf, TRUE);
1153 * Child process succeeded.
1155 *primary_msg = NULL;
1156 *secondary_msg = NULL;
1157 *data = g_string_free(data_buf, FALSE);
1163 * Pick up the child status.
1165 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1169 * Child process failed unexpectedly, or wait failed; msg is the
1173 *secondary_msg = NULL;
1176 * Child process returned an unknown status.
1178 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1180 *secondary_msg = NULL;
1189 /* centralised logging and timing for sync_pipe_run_command_actual(),
1190 * redirects to sync_pipe_run_command_actual()
1193 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1194 gchar **secondary_msg, void (*update_cb)(void))
1197 GTimeVal start_time;
1200 int logging_enabled;
1202 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1203 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1204 if(logging_enabled){
1205 g_get_current_time(&start_time);
1206 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1207 for(i=0; argv[i] != 0; i++) {
1208 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1211 /* do the actual sync pipe run command */
1212 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1214 if(logging_enabled){
1215 g_get_current_time(&end_time);
1216 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1217 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1219 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1227 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1228 gchar **data, gchar **primary_msg,
1229 gchar **secondary_msg, void (*update_cb)(void))
1235 argv = init_pipe_args(&argc);
1238 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1239 *secondary_msg = NULL;
1244 argv = sync_pipe_add_arg(argv, &argc, "-i");
1245 argv = sync_pipe_add_arg(argv, &argc, iface);
1248 opt = g_strdup_printf("%s,%s", freq, type);
1250 opt = g_strdup_printf("%s", freq);
1253 *primary_msg = g_strdup("Out of mem.");
1254 *secondary_msg = NULL;
1259 argv = sync_pipe_add_arg(argv, &argc, "-k");
1260 argv = sync_pipe_add_arg(argv, &argc, opt);
1263 /* Run dumpcap in capture child mode */
1264 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1265 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1268 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1274 * Get the list of interfaces using dumpcap.
1276 * On success, *data points to a buffer containing the dumpcap output,
1277 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1278 * must be freed with g_free().
1280 * On failure, *data is NULL, *primary_msg points to an error message,
1281 * *secondary_msg either points to an additional error message or is
1282 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1283 * must be freed with g_free().
1286 sync_interface_list_open(gchar **data, gchar **primary_msg,
1287 gchar **secondary_msg, void (*update_cb)(void))
1292 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1294 argv = init_pipe_args(&argc);
1297 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1298 *secondary_msg = NULL;
1303 /* Ask for the interface list */
1304 argv = sync_pipe_add_arg(argv, &argc, "-D");
1307 /* Run dumpcap in capture child mode */
1308 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1309 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1311 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1315 * Get the capabilities of an interface using dumpcap.
1317 * On success, *data points to a buffer containing the dumpcap output,
1318 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1319 * must be freed with g_free().
1321 * On failure, *data is NULL, *primary_msg points to an error message,
1322 * *secondary_msg either points to an additional error message or is
1323 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1324 * must be freed with g_free().
1327 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1328 gchar **data, gchar **primary_msg,
1329 gchar **secondary_msg, void (*update_cb)(void))
1334 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1336 argv = init_pipe_args(&argc);
1339 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1340 *secondary_msg = NULL;
1345 /* Ask for the interface capabilities */
1346 argv = sync_pipe_add_arg(argv, &argc, "-i");
1347 argv = sync_pipe_add_arg(argv, &argc, ifname);
1348 argv = sync_pipe_add_arg(argv, &argc, "-L");
1350 argv = sync_pipe_add_arg(argv, &argc, "-I");
1353 /* Run dumpcap in capture child mode */
1354 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1355 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1357 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1361 * Start getting interface statistics using dumpcap. On success, read_fd
1362 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1363 * and zero is returned. On failure, *msg will point to an error message
1364 * that must be g_free()d, and -1 will be returned.
1367 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1371 int message_read_fd, ret;
1373 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1376 int primary_msg_len;
1377 char *primary_msg_text;
1378 int secondary_msg_len;
1379 /*char *secondary_msg_text;*/
1382 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1384 argv = init_pipe_args(&argc);
1387 *msg = g_strdup("We don't know where to find dumpcap.");
1391 /* Ask for the interface statistics */
1392 argv = sync_pipe_add_arg(argv, &argc, "-S");
1395 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1397 create_dummy_signal_pipe();
1398 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1400 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1403 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1404 fork_child, msg, update_cb);
1409 * We were able to set up to read dumpcap's output. Do so.
1411 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1413 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1416 /* We got a read error from the sync pipe, or we got no data at
1417 all from the sync pipe, so we're not going to be getting any
1418 data or error message from the child process. Pick up its
1419 exit status, and complain.
1421 We don't have to worry about killing the child, if the sync pipe
1422 returned an error. Usually this error is caused as the child killed
1423 itself while going down. Even in the rare cases that this isn't the
1424 case, the child will get an error when writing to the broken pipe
1425 the next time, cleaning itself up then. */
1426 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1428 /* We got an EOF from the sync pipe. That means that it exited
1429 before giving us any data to read. If ret is -1, we report
1430 that as a bad exit (e.g., exiting due to a signal); otherwise,
1431 we report it as a premature exit. */
1435 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1437 /* We got an error from the sync pipe. If ret is -1, report
1438 both the sync pipe I/O error and the wait error. */
1440 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1443 *msg = combined_msg;
1450 /* we got a valid message block from the child, process it */
1455 * Error from dumpcap; there will be a primary message and a
1456 * secondary message.
1459 /* convert primary message */
1460 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1461 primary_msg_text = buffer+4;
1462 /* convert secondary message */
1463 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1464 &secondary_msg_len);
1465 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1466 /* the capture child will close the sync_pipe, nothing to do */
1469 * Pick up the child status.
1471 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1475 * Child process failed unexpectedly, or wait failed; msg is the
1480 * Child process failed, but returned the expected exit status.
1481 * Return the messages it gave us, and indicate failure.
1483 *msg = g_strdup(primary_msg_text);
1489 /* Close the message pipe. */
1490 ws_close(message_read_fd);
1495 * Pick up the child status.
1497 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1501 * Child process failed unexpectedly, or wait failed; msg is the
1506 * Child process returned an unknown status.
1508 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1517 /* Close down the stats process */
1519 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1523 * Don't bother waiting for the child. sync_pipe_close_command
1524 * does this for us on Windows.
1526 sync_pipe_kill(*fork_child);
1528 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1531 /* read a number of bytes from a pipe */
1532 /* (blocks until enough bytes read or an error occurs) */
1534 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1541 newly = read(pipe_fd, &bytes[offset], required);
1544 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1545 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1552 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1553 "read from pipe %d: error(%u): %s", pipe_fd, error,
1555 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1560 required -= (int)newly;
1568 static gboolean pipe_data_available(int pipe_fd) {
1569 #ifdef _WIN32 /* PeekNamedPipe */
1570 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1573 if (hPipe == INVALID_HANDLE_VALUE)
1576 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1579 if (bytes_avail > 0)
1584 struct timeval timeout;
1587 FD_SET(pipe_fd, &rfds);
1589 timeout.tv_usec = 0;
1591 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1598 /* Read a line from a pipe, similar to fgets */
1600 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1604 while(offset < max - 1) {
1606 if (! pipe_data_available(pipe_fd))
1608 newly = read(pipe_fd, &bytes[offset], 1);
1610 /* EOF - not necessarily an error */
1612 } else if (newly == -1) {
1614 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1615 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1617 } else if (bytes[offset] == '\n') {
1623 bytes[offset] = '\0';
1629 /* convert header values (indicator and 3-byte length) */
1631 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1633 g_assert(header_len == 4);
1635 /* convert header values */
1636 *indicator = header[0];
1637 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1640 /* read a message from the sending pipe in the standard format
1641 (1-byte message indicator, 3-byte message length (excluding length
1642 and indicator field), and the rest is the message) */
1644 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1651 /* read header (indicator and 3-byte length) */
1652 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1656 * Immediate EOF; if the capture child exits normally, this
1657 * is an "I'm done" indication, so don't report it as an
1660 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1661 "read %d got an EOF", pipe_fd);
1664 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1665 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1668 * Short read, but not an immediate EOF.
1670 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1676 /* convert header values */
1677 pipe_convert_header((guchar*)header, 4, indicator, &required);
1679 /* only indicator with no value? */
1681 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1682 "read %d indicator: %c empty value", pipe_fd, *indicator);
1686 /* does the data fit into the given buffer? */
1687 if(required > len) {
1688 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1689 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1690 pipe_fd, required, len,
1691 header[0], header[1], header[2], header[3]);
1693 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1694 memcpy(msg, header, sizeof(header));
1695 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1696 if (newly < 0) { /* error */
1697 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1698 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1700 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1706 /* read the actual block data */
1707 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1708 if(newly != required) {
1710 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1716 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1717 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1718 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1725 /* There's stuff to read from the sync pipe, meaning the child has sent
1726 us a message, or the sync pipe has closed, meaning the child has
1727 closed it (perhaps because it exited). */
1729 sync_pipe_input_cb(gint source, gpointer user_data)
1731 capture_session *cap_session = (capture_session *)user_data;
1733 char buffer[SP_MAX_MSG_LEN+1] = {0};
1739 char *secondary_msg;
1740 char *wait_msg, *combined_msg;
1743 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1746 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1748 If we got a read error or a bad message, nread is -1 and
1749 primary_msg is set to point to an error message. We don't
1750 have to worry about killing the child; usually this error
1751 is caused as the child killed itself while going down.
1752 Even in the rare cases that this isn't the case, the child
1753 will get an error when writing to the broken pipe the next time,
1754 cleaning itself up then.
1756 If we got an EOF, nread is 0 and primary_msg isn't set. This
1757 is an indication that the capture is finished. */
1758 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1760 /* We got an EOF from the sync pipe. That means that the capture
1761 child exited, and not in the middle of a message; we treat
1762 that as an indication that it's done, and only report an
1763 error if ret is -1, in which case wait_msg is the error
1766 primary_msg = wait_msg;
1768 /* We got an error from the sync pipe. If ret is -1, report
1769 both the sync pipe I/O error and the wait error. */
1771 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1772 g_free(primary_msg);
1774 primary_msg = combined_msg;
1778 /* No more child process. */
1779 cap_session->fork_child = WS_INVALID_PID;
1780 cap_session->fork_child_status = ret;
1783 ws_close(cap_session->signal_pipe_write_fd);
1786 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1787 extcap_cleanup(cap_session->capture_opts);
1789 capture_input_closed(cap_session, primary_msg);
1790 g_free(primary_msg);
1794 /* we got a valid message block from the child, process it */
1797 if(!capture_input_new_file(cap_session, buffer)) {
1798 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1800 /* We weren't able to open the new capture file; user has been
1801 alerted. Close the sync pipe. */
1804 /* The child has sent us a filename which we couldn't open.
1806 This could mean that the child is creating and deleting files
1807 (ring buffer mode) faster than we can handle it.
1809 That should only be the case for very fast file switches;
1810 We can't do much more than telling the child to stop.
1811 (This is the "emergency brake" if the user e.g. wants to
1812 switch files every second).
1814 This can also happen if the user specified "-", meaning
1815 "standard output", as the capture file. */
1816 sync_pipe_stop(cap_session);
1817 capture_input_closed(cap_session, NULL);
1821 case SP_PACKET_COUNT:
1822 npackets = atoi(buffer);
1823 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1824 cap_session->count += npackets;
1825 capture_input_new_packets(cap_session, npackets);
1828 /* convert primary message */
1829 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1830 primary_msg = buffer+4;
1831 /* convert secondary message */
1832 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1833 secondary_msg = primary_msg + primary_len + 4;
1834 /* message output */
1835 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1836 /* the capture child will close the sync_pipe, nothing to do for now */
1837 /* (an error message doesn't mean we have to stop capturing) */
1839 case SP_BAD_FILTER: {
1843 ch = strtok(buffer, ":");
1845 indx = (int)strtol(ch, NULL, 10);
1846 ch = strtok(NULL, ":");
1848 capture_input_cfilter_error_message(cap_session, indx, ch);
1849 /* the capture child will close the sync_pipe, nothing to do for now */
1853 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1856 g_assert_not_reached();
1865 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1866 * unchanged, and the exit status of dumpcap is returned. On
1867 * failure (which includes "dumpcap exited due to being killed by
1868 * a signal or an exception"), *msgp points to an error message
1869 * for the failure, and -1 is returned. In the latter case, *msgp
1870 * must be freed with g_free().
1873 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1875 int fork_child_status;
1877 int retry_waitpid = 3;
1880 GTimeVal start_time;
1885 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1888 g_get_current_time(&start_time);
1890 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1891 g_assert(fork_child != WS_INVALID_PID);
1893 *msgp = NULL; /* assume no error */
1895 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1896 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1900 * The child exited; return its exit status. Do not treat this as
1903 ret = fork_child_status;
1904 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1905 /* Probably an exception code */
1906 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1907 win32strexception(fork_child_status));
1912 while (--retry_waitpid >= 0) {
1913 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1914 if (WIFEXITED(fork_child_status)) {
1916 * The child exited; return its exit status. Do not treat this as
1919 ret = WEXITSTATUS(fork_child_status);
1920 } else if (WIFSTOPPED(fork_child_status)) {
1921 /* It stopped, rather than exiting. "Should not happen." */
1922 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1923 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1925 } else if (WIFSIGNALED(fork_child_status)) {
1926 /* It died with a signal. */
1927 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1928 sync_pipe_signame(WTERMSIG(fork_child_status)),
1929 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1932 /* What? It had to either have exited, or stopped, or died with
1933 a signal; what happened here? */
1934 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1938 } else if (errno != ECHILD) {
1939 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1941 } else if (errno == EINTR) {
1942 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
1945 /* errno == ECHILD ; echld might have already reaped the child */
1946 ret = fetch_dumpcap_pid ? 0 : -1;
1952 g_get_current_time(&end_time);
1953 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1954 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1955 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1961 /* convert signal to corresponding name */
1963 sync_pipe_signame(int sig)
1966 static char sigmsg_buf[6+1+3+1];
1975 sigmsg = "Interrupted";
1983 sigmsg = "Illegal instruction";
1987 sigmsg = "Trace trap";
1995 sigmsg = "Arithmetic exception";
2003 sigmsg = "Bus error";
2007 sigmsg = "Segmentation violation";
2010 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
2011 Linux is POSIX compliant. These are not POSIX-defined signals ---
2012 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
2014 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
2015 were omitted from POSIX.1 because their behavior is
2016 implementation dependent and could not be adequately catego-
2017 rized. Conforming implementations may deliver these sig-
2018 nals, but must document the circumstances under which they
2019 are delivered and note any restrictions concerning their
2022 So we only check for SIGSYS on those systems that happen to
2023 implement them (a system can be POSIX-compliant and implement
2024 them, it's just that POSIX doesn't *require* a POSIX-compliant
2025 system to implement them).
2030 sigmsg = "Bad system call";
2035 sigmsg = "Broken pipe";
2039 sigmsg = "Alarm clock";
2043 sigmsg = "Terminated";
2047 /* Returning a static buffer is ok in the context we use it here */
2048 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2049 sigmsg = sigmsg_buf;
2059 static void create_dummy_signal_pipe() {
2060 gchar *dummy_signal_pipe_name;
2062 if (dummy_signal_pipe != NULL) return;
2064 if (!dummy_control_id) {
2065 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2068 /* Create the signal pipe */
2069 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2070 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2071 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2072 g_free(dummy_signal_pipe_name);
2075 /* tell the child through the signal pipe that we want to quit the capture */
2077 signal_pipe_capquit_to_child(capture_session *cap_session)
2079 const char quit_msg[] = "QUIT";
2082 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2084 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2085 /* simply sending a "QUIT" string */
2086 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2087 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2089 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2090 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2096 /* user wants to stop the capture run */
2098 sync_pipe_stop(capture_session *cap_session)
2103 gboolean terminate = TRUE;
2105 if (cap_session->fork_child != WS_INVALID_PID) {
2107 /* send the SIGINT signal to close the capture child gracefully. */
2108 int sts = kill(cap_session->fork_child, SIGINT);
2110 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2111 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2114 #define STOP_SLEEP_TIME 500 /* ms */
2115 #define STOP_CHECK_TIME 50
2116 /* First, use the special signal pipe to try to close the capture child
2119 signal_pipe_capquit_to_child(cap_session);
2121 /* Next, wait for the process to exit on its own */
2122 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2123 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2124 childstatus != STILL_ACTIVE) {
2128 Sleep(STOP_CHECK_TIME);
2131 /* Force the issue. */
2133 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2134 "sync_pipe_stop: forcing child to exit");
2135 sync_pipe_kill(cap_session->fork_child);
2142 /* Wireshark has to exit, force the capture child to close */
2144 sync_pipe_kill(ws_process_id fork_child)
2146 if (fork_child != WS_INVALID_PID) {
2148 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2150 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2151 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2154 /* Remark: This is not the preferred method of closing a process!
2155 * the clean way would be getting the process id of the child process,
2156 * then getting window handle hWnd of that process (using EnumChildWindows),
2157 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2159 * Unfortunately, I don't know how to get the process id from the
2160 * handle. OpenProcess will get an handle (not a window handle)
2161 * from the process ID; it will not get a window handle from the
2162 * process ID. (How could it? A process can have more than one
2163 * window. For that matter, a process might have *no* windows,
2164 * as a process running dumpcap, the normal child process program,
2167 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2168 * running in the same console; that's not necessarily the case for
2169 * us, as we might not be running in a console.
2170 * And this also will require to have the process id.
2172 TerminateProcess((HANDLE) (fork_child), 0);
2178 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2179 fetch_dumpcap_pid = cb;
2182 #endif /* HAVE_LIBPCAP */