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;
1086 /* we got a valid message block from the child, process it */
1091 * Error from dumpcap; there will be a primary message and a
1092 * secondary message.
1095 /* convert primary message */
1096 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1097 primary_msg_text = buffer+4;
1098 /* convert secondary message */
1099 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1100 &secondary_msg_len);
1101 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1102 /* the capture child will close the sync_pipe, nothing to do */
1105 * Pick up the child status.
1107 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1111 * Child process failed unexpectedly, or wait failed; msg is the
1115 *secondary_msg = NULL;
1118 * Child process failed, but returned the expected exit status.
1119 * Return the messages it gave us, and indicate failure.
1121 *primary_msg = g_strdup(primary_msg_text);
1122 *secondary_msg = g_strdup(secondary_msg_text);
1129 /* read the output from the command */
1130 data_buf = g_string_new("");
1131 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1132 buffer[count] = '\0';
1133 g_string_append(data_buf, buffer);
1137 * Pick up the child status.
1139 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1143 * Child process failed unexpectedly, or wait failed; msg is the
1147 *secondary_msg = NULL;
1148 g_string_free(data_buf, TRUE);
1152 * Child process succeeded.
1154 *primary_msg = NULL;
1155 *secondary_msg = NULL;
1156 *data = g_string_free(data_buf, FALSE);
1162 * Pick up the child status.
1164 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1168 * Child process failed unexpectedly, or wait failed; msg is the
1172 *secondary_msg = NULL;
1175 * Child process returned an unknown status.
1177 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1179 *secondary_msg = NULL;
1188 /* centralised logging and timing for sync_pipe_run_command_actual(),
1189 * redirects to sync_pipe_run_command_actual()
1192 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1193 gchar **secondary_msg, void (*update_cb)(void))
1196 GTimeVal start_time;
1199 int logging_enabled;
1201 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1202 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1203 if(logging_enabled){
1204 g_get_current_time(&start_time);
1205 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1206 for(i=0; argv[i] != 0; i++) {
1207 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1210 /* do the actual sync pipe run command */
1211 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1213 if(logging_enabled){
1214 g_get_current_time(&end_time);
1215 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1216 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1218 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1226 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1227 gchar **data, gchar **primary_msg,
1228 gchar **secondary_msg, void (*update_cb)(void))
1234 argv = init_pipe_args(&argc);
1237 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1238 *secondary_msg = NULL;
1243 argv = sync_pipe_add_arg(argv, &argc, "-i");
1244 argv = sync_pipe_add_arg(argv, &argc, iface);
1247 opt = g_strdup_printf("%s,%s", freq, type);
1249 opt = g_strdup_printf("%s", freq);
1252 *primary_msg = g_strdup("Out of mem.");
1253 *secondary_msg = NULL;
1258 argv = sync_pipe_add_arg(argv, &argc, "-k");
1259 argv = sync_pipe_add_arg(argv, &argc, opt);
1262 /* Run dumpcap in capture child mode */
1263 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1264 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1267 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1273 * Get the list of interfaces using dumpcap.
1275 * On success, *data points to a buffer containing the dumpcap output,
1276 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1277 * must be freed with g_free().
1279 * On failure, *data is NULL, *primary_msg points to an error message,
1280 * *secondary_msg either points to an additional error message or is
1281 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1282 * must be freed with g_free().
1285 sync_interface_list_open(gchar **data, gchar **primary_msg,
1286 gchar **secondary_msg, void (*update_cb)(void))
1291 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1293 argv = init_pipe_args(&argc);
1296 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1297 *secondary_msg = NULL;
1302 /* Ask for the interface list */
1303 argv = sync_pipe_add_arg(argv, &argc, "-D");
1306 /* Run dumpcap in capture child mode */
1307 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1308 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1310 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1314 * Get the capabilities of an interface using dumpcap.
1316 * On success, *data points to a buffer containing the dumpcap output,
1317 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1318 * must be freed with g_free().
1320 * On failure, *data is NULL, *primary_msg points to an error message,
1321 * *secondary_msg either points to an additional error message or is
1322 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1323 * must be freed with g_free().
1326 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1327 gchar **data, gchar **primary_msg,
1328 gchar **secondary_msg, void (*update_cb)(void))
1333 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1335 argv = init_pipe_args(&argc);
1338 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1339 *secondary_msg = NULL;
1344 /* Ask for the interface capabilities */
1345 argv = sync_pipe_add_arg(argv, &argc, "-i");
1346 argv = sync_pipe_add_arg(argv, &argc, ifname);
1347 argv = sync_pipe_add_arg(argv, &argc, "-L");
1349 argv = sync_pipe_add_arg(argv, &argc, "-I");
1352 /* Run dumpcap in capture child mode */
1353 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1354 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1356 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1360 * Start getting interface statistics using dumpcap. On success, read_fd
1361 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1362 * and zero is returned. On failure, *msg will point to an error message
1363 * that must be g_free()d, and -1 will be returned.
1366 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1370 int message_read_fd, ret;
1372 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1375 int primary_msg_len;
1376 char *primary_msg_text;
1377 int secondary_msg_len;
1378 /*char *secondary_msg_text;*/
1381 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1383 argv = init_pipe_args(&argc);
1386 *msg = g_strdup("We don't know where to find dumpcap.");
1390 /* Ask for the interface statistics */
1391 argv = sync_pipe_add_arg(argv, &argc, "-S");
1394 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1396 create_dummy_signal_pipe();
1397 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1399 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1402 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1403 fork_child, msg, update_cb);
1408 * We were able to set up to read dumpcap's output. Do so.
1410 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1412 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1415 /* We got a read error from the sync pipe, or we got no data at
1416 all from the sync pipe, so we're not going to be getting any
1417 data or error message from the child process. Pick up its
1418 exit status, and complain.
1420 We don't have to worry about killing the child, if the sync pipe
1421 returned an error. Usually this error is caused as the child killed
1422 itself while going down. Even in the rare cases that this isn't the
1423 case, the child will get an error when writing to the broken pipe
1424 the next time, cleaning itself up then. */
1425 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1427 /* We got an EOF from the sync pipe. That means that it exited
1428 before giving us any data to read. If ret is -1, we report
1429 that as a bad exit (e.g., exiting due to a signal); otherwise,
1430 we report it as a premature exit. */
1434 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1436 /* We got an error from the sync pipe. If ret is -1, report
1437 both the sync pipe I/O error and the wait error. */
1439 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1442 *msg = combined_msg;
1449 /* we got a valid message block from the child, process it */
1454 * Error from dumpcap; there will be a primary message and a
1455 * secondary message.
1458 /* convert primary message */
1459 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1460 primary_msg_text = buffer+4;
1461 /* convert secondary message */
1462 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1463 &secondary_msg_len);
1464 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1465 /* the capture child will close the sync_pipe, nothing to do */
1468 * Pick up the child status.
1470 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1474 * Child process failed unexpectedly, or wait failed; msg is the
1479 * Child process failed, but returned the expected exit status.
1480 * Return the messages it gave us, and indicate failure.
1482 *msg = g_strdup(primary_msg_text);
1488 /* Close the message pipe. */
1489 ws_close(message_read_fd);
1494 * Pick up the child status.
1496 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1500 * Child process failed unexpectedly, or wait failed; msg is the
1505 * Child process returned an unknown status.
1507 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1516 /* Close down the stats process */
1518 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1522 * Don't bother waiting for the child. sync_pipe_close_command
1523 * does this for us on Windows.
1525 sync_pipe_kill(*fork_child);
1527 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1530 /* read a number of bytes from a pipe */
1531 /* (blocks until enough bytes read or an error occurs) */
1533 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1540 newly = read(pipe_fd, &bytes[offset], required);
1543 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1544 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1551 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1552 "read from pipe %d: error(%u): %s", pipe_fd, error,
1554 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1559 required -= (int)newly;
1567 static gboolean pipe_data_available(int pipe_fd) {
1568 #ifdef _WIN32 /* PeekNamedPipe */
1569 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1572 if (hPipe == INVALID_HANDLE_VALUE)
1575 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1578 if (bytes_avail > 0)
1583 struct timeval timeout;
1586 FD_SET(pipe_fd, &rfds);
1588 timeout.tv_usec = 0;
1590 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1597 /* Read a line from a pipe, similar to fgets */
1599 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1603 while(offset < max - 1) {
1605 if (! pipe_data_available(pipe_fd))
1607 newly = read(pipe_fd, &bytes[offset], 1);
1609 /* EOF - not necessarily an error */
1611 } else if (newly == -1) {
1613 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1614 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1616 } else if (bytes[offset] == '\n') {
1622 bytes[offset] = '\0';
1628 /* convert header values (indicator and 3-byte length) */
1630 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1632 g_assert(header_len == 4);
1634 /* convert header values */
1635 *indicator = header[0];
1636 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1639 /* read a message from the sending pipe in the standard format
1640 (1-byte message indicator, 3-byte message length (excluding length
1641 and indicator field), and the rest is the message) */
1643 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1650 /* read header (indicator and 3-byte length) */
1651 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1655 * Immediate EOF; if the capture child exits normally, this
1656 * is an "I'm done" indication, so don't report it as an
1659 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1660 "read %d got an EOF", pipe_fd);
1663 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1664 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1667 * Short read, but not an immediate EOF.
1669 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1675 /* convert header values */
1676 pipe_convert_header((guchar*)header, 4, indicator, &required);
1678 /* only indicator with no value? */
1680 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1681 "read %d indicator: %c empty value", pipe_fd, *indicator);
1685 /* does the data fit into the given buffer? */
1686 if(required > len) {
1687 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1688 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1689 pipe_fd, required, len,
1690 header[0], header[1], header[2], header[3]);
1692 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1693 memcpy(msg, header, sizeof(header));
1694 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1695 if (newly < 0) { /* error */
1696 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1697 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1699 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1705 /* read the actual block data */
1706 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1707 if(newly != required) {
1709 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1715 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1716 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1717 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1724 /* There's stuff to read from the sync pipe, meaning the child has sent
1725 us a message, or the sync pipe has closed, meaning the child has
1726 closed it (perhaps because it exited). */
1728 sync_pipe_input_cb(gint source, gpointer user_data)
1730 capture_session *cap_session = (capture_session *)user_data;
1732 char buffer[SP_MAX_MSG_LEN+1] = {0};
1738 char *secondary_msg;
1739 char *wait_msg, *combined_msg;
1742 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1745 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1747 If we got a read error or a bad message, nread is -1 and
1748 primary_msg is set to point to an error message. We don't
1749 have to worry about killing the child; usually this error
1750 is caused as the child killed itself while going down.
1751 Even in the rare cases that this isn't the case, the child
1752 will get an error when writing to the broken pipe the next time,
1753 cleaning itself up then.
1755 If we got an EOF, nread is 0 and primary_msg isn't set. This
1756 is an indication that the capture is finished. */
1757 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1759 /* We got an EOF from the sync pipe. That means that the capture
1760 child exited, and not in the middle of a message; we treat
1761 that as an indication that it's done, and only report an
1762 error if ret is -1, in which case wait_msg is the error
1765 primary_msg = wait_msg;
1767 /* We got an error from the sync pipe. If ret is -1, report
1768 both the sync pipe I/O error and the wait error. */
1770 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1771 g_free(primary_msg);
1773 primary_msg = combined_msg;
1777 /* No more child process. */
1778 cap_session->fork_child = WS_INVALID_PID;
1779 cap_session->fork_child_status = ret;
1782 ws_close(cap_session->signal_pipe_write_fd);
1785 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1786 extcap_cleanup(cap_session->capture_opts);
1788 capture_input_closed(cap_session, primary_msg);
1789 g_free(primary_msg);
1793 /* we got a valid message block from the child, process it */
1796 if(!capture_input_new_file(cap_session, buffer)) {
1797 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1799 /* We weren't able to open the new capture file; user has been
1800 alerted. Close the sync pipe. */
1803 /* The child has sent us a filename which we couldn't open.
1805 This could mean that the child is creating and deleting files
1806 (ring buffer mode) faster than we can handle it.
1808 That should only be the case for very fast file switches;
1809 We can't do much more than telling the child to stop.
1810 (This is the "emergency brake" if the user e.g. wants to
1811 switch files every second).
1813 This can also happen if the user specified "-", meaning
1814 "standard output", as the capture file. */
1815 sync_pipe_stop(cap_session);
1816 capture_input_closed(cap_session, NULL);
1820 case SP_PACKET_COUNT:
1821 npackets = atoi(buffer);
1822 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1823 cap_session->count += npackets;
1824 capture_input_new_packets(cap_session, npackets);
1827 /* convert primary message */
1828 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1829 primary_msg = buffer+4;
1830 /* convert secondary message */
1831 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1832 secondary_msg = primary_msg + primary_len + 4;
1833 /* message output */
1834 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1835 /* the capture child will close the sync_pipe, nothing to do for now */
1836 /* (an error message doesn't mean we have to stop capturing) */
1838 case SP_BAD_FILTER: {
1842 ch = strtok(buffer, ":");
1844 indx = (int)strtol(ch, NULL, 10);
1845 ch = strtok(NULL, ":");
1847 capture_input_cfilter_error_message(cap_session, indx, ch);
1848 /* the capture child will close the sync_pipe, nothing to do for now */
1852 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1855 g_assert_not_reached();
1864 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1865 * unchanged, and the exit status of dumpcap is returned. On
1866 * failure (which includes "dumpcap exited due to being killed by
1867 * a signal or an exception"), *msgp points to an error message
1868 * for the failure, and -1 is returned. In the latter case, *msgp
1869 * must be freed with g_free().
1872 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1874 int fork_child_status;
1876 int retry_waitpid = 3;
1879 GTimeVal start_time;
1884 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1887 g_get_current_time(&start_time);
1889 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1890 g_assert(fork_child != WS_INVALID_PID);
1892 *msgp = NULL; /* assume no error */
1894 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1895 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1899 * The child exited; return its exit status. Do not treat this as
1902 ret = fork_child_status;
1903 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1904 /* Probably an exception code */
1905 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1906 win32strexception(fork_child_status));
1911 while (--retry_waitpid >= 0) {
1912 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1913 if (WIFEXITED(fork_child_status)) {
1915 * The child exited; return its exit status. Do not treat this as
1918 ret = WEXITSTATUS(fork_child_status);
1919 } else if (WIFSTOPPED(fork_child_status)) {
1920 /* It stopped, rather than exiting. "Should not happen." */
1921 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1922 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1924 } else if (WIFSIGNALED(fork_child_status)) {
1925 /* It died with a signal. */
1926 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1927 sync_pipe_signame(WTERMSIG(fork_child_status)),
1928 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1931 /* What? It had to either have exited, or stopped, or died with
1932 a signal; what happened here? */
1933 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1937 } else if (errno != ECHILD) {
1938 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1940 } else if (errno == EINTR) {
1941 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
1944 /* errno == ECHILD ; echld might have already reaped the child */
1945 ret = fetch_dumpcap_pid ? 0 : -1;
1951 g_get_current_time(&end_time);
1952 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1953 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1954 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1960 /* convert signal to corresponding name */
1962 sync_pipe_signame(int sig)
1965 static char sigmsg_buf[6+1+3+1];
1974 sigmsg = "Interrupted";
1982 sigmsg = "Illegal instruction";
1986 sigmsg = "Trace trap";
1994 sigmsg = "Arithmetic exception";
2002 sigmsg = "Bus error";
2006 sigmsg = "Segmentation violation";
2009 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
2010 Linux is POSIX compliant. These are not POSIX-defined signals ---
2011 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
2013 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
2014 were omitted from POSIX.1 because their behavior is
2015 implementation dependent and could not be adequately catego-
2016 rized. Conforming implementations may deliver these sig-
2017 nals, but must document the circumstances under which they
2018 are delivered and note any restrictions concerning their
2021 So we only check for SIGSYS on those systems that happen to
2022 implement them (a system can be POSIX-compliant and implement
2023 them, it's just that POSIX doesn't *require* a POSIX-compliant
2024 system to implement them).
2029 sigmsg = "Bad system call";
2034 sigmsg = "Broken pipe";
2038 sigmsg = "Alarm clock";
2042 sigmsg = "Terminated";
2046 /* Returning a static buffer is ok in the context we use it here */
2047 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2048 sigmsg = sigmsg_buf;
2058 static void create_dummy_signal_pipe() {
2059 gchar *dummy_signal_pipe_name;
2061 if (dummy_signal_pipe != NULL) return;
2063 if (!dummy_control_id) {
2064 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2067 /* Create the signal pipe */
2068 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2069 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2070 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2071 g_free(dummy_signal_pipe_name);
2074 /* tell the child through the signal pipe that we want to quit the capture */
2076 signal_pipe_capquit_to_child(capture_session *cap_session)
2078 const char quit_msg[] = "QUIT";
2081 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2083 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2084 /* simply sending a "QUIT" string */
2085 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2086 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2088 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2089 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2095 /* user wants to stop the capture run */
2097 sync_pipe_stop(capture_session *cap_session)
2102 gboolean terminate = TRUE;
2104 if (cap_session->fork_child != WS_INVALID_PID) {
2106 /* send the SIGINT signal to close the capture child gracefully. */
2107 int sts = kill(cap_session->fork_child, SIGINT);
2109 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2110 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2113 #define STOP_SLEEP_TIME 500 /* ms */
2114 #define STOP_CHECK_TIME 50
2115 /* First, use the special signal pipe to try to close the capture child
2118 signal_pipe_capquit_to_child(cap_session);
2120 /* Next, wait for the process to exit on its own */
2121 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2122 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2123 childstatus != STILL_ACTIVE) {
2127 Sleep(STOP_CHECK_TIME);
2130 /* Force the issue. */
2132 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2133 "sync_pipe_stop: forcing child to exit");
2134 sync_pipe_kill(cap_session->fork_child);
2141 /* Wireshark has to exit, force the capture child to close */
2143 sync_pipe_kill(ws_process_id fork_child)
2145 if (fork_child != WS_INVALID_PID) {
2147 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2149 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2150 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2153 /* Remark: This is not the preferred method of closing a process!
2154 * the clean way would be getting the process id of the child process,
2155 * then getting window handle hWnd of that process (using EnumChildWindows),
2156 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2158 * Unfortunately, I don't know how to get the process id from the
2159 * handle. OpenProcess will get an handle (not a window handle)
2160 * from the process ID; it will not get a window handle from the
2161 * process ID. (How could it? A process can have more than one
2162 * window. For that matter, a process might have *no* windows,
2163 * as a process running dumpcap, the normal child process program,
2166 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2167 * running in the same console; that's not necessarily the case for
2168 * us, as we might not be running in a console.
2169 * And this also will require to have the process id.
2171 TerminateProcess((HANDLE) (fork_child), 0);
2177 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2178 fetch_dumpcap_pid = cb;
2181 #endif /* HAVE_LIBPCAP */