2 * Synchronisation between Wireshark capture parent and child instances
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
46 #include <wsutil/unicode-utils.h>
49 #ifdef HAVE_SYS_WAIT_H
50 # include <sys/wait.h>
53 #include "capture-pcap-util.h"
57 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
58 * macros) on UNIX systems that don't have them.
61 # define WIFEXITED(status) (((status) & 0177) == 0)
64 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
67 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
70 # define WEXITSTATUS(status) ((status) >> 8)
73 # define WTERMSIG(status) ((status) & 0177)
76 # define WCOREDUMP(status) ((status) & 0200)
79 # define WSTOPSIG(status) ((status) >> 8)
83 #include <epan/packet.h>
84 #include <epan/prefs.h>
90 #include "capture_sync.h"
92 #include "sync_pipe.h"
95 #include "capture-wpcap.h"
98 #include "ui/ui_util.h"
100 #include <wsutil/filesystem.h>
101 #include <wsutil/file_util.h>
102 #include <wsutil/report_err.h>
106 #include <process.h> /* For spawning child process */
112 static void create_dummy_signal_pipe();
113 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
114 static gchar *dummy_control_id;
116 static const char *sync_pipe_signame(int);
120 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
121 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
122 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
123 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
126 static void (*fetch_dumpcap_pid)(int) = NULL;
130 capture_session_init(capture_session *cap_session, void *cf)
132 cap_session->cf = cf;
133 cap_session->fork_child = -1; /* invalid process handle */
135 cap_session->signal_pipe_write_fd = -1;
137 cap_session->state = CAPTURE_STOPPED;
139 cap_session->owner = getuid();
140 cap_session->group = getgid();
142 cap_session->session_started = FALSE;
145 /* Append an arg (realloc) to an argc/argv array */
146 /* (add a string pointer to a NULL-terminated array of string pointers) */
148 sync_pipe_add_arg(char **args, int *argc, const char *arg)
150 /* Grow the array; "*argc" currently contains the number of string
151 pointers, *not* counting the NULL pointer at the end, so we have
152 to add 2 in order to get the new size of the array, including the
153 new pointer and the terminating NULL pointer. */
154 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
156 /* Stuff the pointer into the penultimate element of the array, which
157 is the one at the index specified by "*argc". */
158 args[*argc] = g_strdup(arg);
159 /* Now bump the count. */
162 /* We overwrite the NULL pointer; put it back right after the
172 /* Quote the argument element if necessary, so that it will get
173 * reconstructed correctly in the C runtime startup code. Note that
174 * the unquoting algorithm in the C runtime is really weird, and
175 * rather different than what Unix shells do. See stdargv.c in the C
176 * runtime sources (in the Platform SDK, in src/crt).
178 * Stolen from GLib's protect_argv(), an internal routine that quotes
179 * string in an argument list so that they arguments will be handled
180 * correctly in the command-line string passed to CreateProcess()
181 * if that string is constructed by gluing those strings together.
184 protect_arg (const gchar *argv)
187 const gchar *p = argv;
190 gboolean need_dblquotes = FALSE;
193 if (*p == ' ' || *p == '\t')
194 need_dblquotes = TRUE;
197 else if (*p == '\\') {
200 while (*pp && *pp == '\\')
209 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
218 else if (*p == '\\') {
221 while (*pp && *pp == '\\')
238 * Generate a string for a Win32 error.
240 #define ERRBUF_SIZE 1024
242 win32strerror(DWORD error)
244 static char errbuf[ERRBUF_SIZE+1];
248 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
249 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
252 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
253 * message. Get rid of it.
255 errlen = strlen(errbuf);
257 errbuf[errlen - 1] = '\0';
258 errbuf[errlen - 2] = '\0';
260 p = strchr(errbuf, '\0');
261 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
266 * Generate a string for a Win32 exception code.
269 win32strexception(DWORD exception)
271 static char errbuf[ERRBUF_SIZE+1];
272 static const struct exception_msg {
276 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
277 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
278 { EXCEPTION_BREAKPOINT, "Breakpoint" },
279 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
280 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
281 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
282 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
283 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
284 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
285 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
286 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
287 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
288 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
289 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
290 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
291 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
292 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
293 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
294 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
295 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
296 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
297 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
300 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
303 for (i = 0; i < N_EXCEPTIONS; i++) {
304 if (exceptions[i].code == exception)
305 return exceptions[i].msg;
307 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
312 /* Initialize an argument list and add dumpcap to it. */
314 init_pipe_args(int *argc) {
316 const char *progfile_dir;
319 progfile_dir = get_progfile_dir();
320 if (progfile_dir == NULL) {
324 /* Allocate the string pointer array with enough space for the
325 terminating NULL pointer. */
327 argv = (char **)g_malloc(sizeof (char *));
330 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
331 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
333 /* Make that the first argument in the argument list (argv[0]). */
334 argv = sync_pipe_add_arg(argv, argc, exename);
336 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
342 #define ARGV_NUMBER_LEN 24
343 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
345 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
347 char ssnap[ARGV_NUMBER_LEN];
348 char scount[ARGV_NUMBER_LEN];
349 char sfilesize[ARGV_NUMBER_LEN];
350 char sfile_duration[ARGV_NUMBER_LEN];
351 char sring_num_files[ARGV_NUMBER_LEN];
352 char sautostop_files[ARGV_NUMBER_LEN];
353 char sautostop_filesize[ARGV_NUMBER_LEN];
354 char sautostop_duration[ARGV_NUMBER_LEN];
355 #ifdef HAVE_PCAP_REMOTE
358 #ifdef HAVE_PCAP_SETSAMPLING
359 char ssampling[ARGV_NUMBER_LEN];
362 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
363 char buffer_size[ARGV_NUMBER_LEN];
367 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
368 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
369 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
370 GString *args = g_string_sized_new(200);
372 SECURITY_ATTRIBUTES sa;
374 PROCESS_INFORMATION pi;
375 char control_id[ARGV_NUMBER_LEN];
376 gchar *signal_pipe_name;
379 int sync_pipe[2]; /* pipe used to send messages from child to parent */
380 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
382 int sync_pipe_read_fd;
387 interface_options interface_opts;
389 if (capture_opts->ifaces->len > 1)
390 capture_opts->use_pcapng = TRUE;
391 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
392 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
394 cap_session->fork_child = -1;
396 argv = init_pipe_args(&argc);
398 /* We don't know where to find dumpcap. */
399 report_failure("We don't know where to find dumpcap.");
403 if (capture_opts->ifaces->len > 1)
404 argv = sync_pipe_add_arg(argv, &argc, "-t");
406 if (capture_opts->use_pcapng)
407 argv = sync_pipe_add_arg(argv, &argc, "-n");
409 argv = sync_pipe_add_arg(argv, &argc, "-P");
411 if (capture_opts->capture_comment) {
412 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
413 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
416 if (capture_opts->multi_files_on) {
417 if (capture_opts->has_autostop_filesize) {
418 argv = sync_pipe_add_arg(argv, &argc, "-b");
419 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
420 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
423 if (capture_opts->has_file_duration) {
424 argv = sync_pipe_add_arg(argv, &argc, "-b");
425 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
426 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
429 if (capture_opts->has_ring_num_files) {
430 argv = sync_pipe_add_arg(argv, &argc, "-b");
431 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
432 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
435 if (capture_opts->has_autostop_files) {
436 argv = sync_pipe_add_arg(argv, &argc, "-a");
437 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
438 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
441 if (capture_opts->has_autostop_filesize) {
442 argv = sync_pipe_add_arg(argv, &argc, "-a");
443 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
444 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
448 if (capture_opts->has_autostop_packets) {
449 argv = sync_pipe_add_arg(argv, &argc, "-c");
450 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
451 argv = sync_pipe_add_arg(argv, &argc, scount);
454 if (capture_opts->has_autostop_duration) {
455 argv = sync_pipe_add_arg(argv, &argc, "-a");
456 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
457 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
460 if (capture_opts->group_read_access) {
461 argv = sync_pipe_add_arg(argv, &argc, "-g");
464 for (j = 0; j < capture_opts->ifaces->len; j++) {
465 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
467 argv = sync_pipe_add_arg(argv, &argc, "-i");
468 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
470 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
471 argv = sync_pipe_add_arg(argv, &argc, "-f");
472 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
474 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
475 argv = sync_pipe_add_arg(argv, &argc, "-s");
476 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
477 argv = sync_pipe_add_arg(argv, &argc, ssnap);
480 if (interface_opts.linktype != -1) {
481 argv = sync_pipe_add_arg(argv, &argc, "-y");
482 argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
485 if (!interface_opts.promisc_mode) {
486 argv = sync_pipe_add_arg(argv, &argc, "-p");
489 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
490 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
491 argv = sync_pipe_add_arg(argv, &argc, "-B");
492 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
493 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
497 #ifdef HAVE_PCAP_CREATE
498 if (interface_opts.monitor_mode) {
499 argv = sync_pipe_add_arg(argv, &argc, "-I");
503 #ifdef HAVE_PCAP_REMOTE
504 if (interface_opts.datatx_udp)
505 argv = sync_pipe_add_arg(argv, &argc, "-u");
507 if (!interface_opts.nocap_rpcap)
508 argv = sync_pipe_add_arg(argv, &argc, "-r");
510 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
511 argv = sync_pipe_add_arg(argv, &argc, "-A");
512 g_snprintf(sauth, sizeof(sauth), "%s:%s",
513 interface_opts.auth_username,
514 interface_opts.auth_password);
515 argv = sync_pipe_add_arg(argv, &argc, sauth);
519 #ifdef HAVE_PCAP_SETSAMPLING
520 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
521 argv = sync_pipe_add_arg(argv, &argc, "-m");
522 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
523 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
524 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
526 interface_opts.sampling_param);
527 argv = sync_pipe_add_arg(argv, &argc, ssampling);
532 /* dumpcap should be running in capture child mode (hidden feature) */
534 argv = sync_pipe_add_arg(argv, &argc, "-Z");
536 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
537 argv = sync_pipe_add_arg(argv, &argc, control_id);
539 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
543 if (capture_opts->save_file) {
544 argv = sync_pipe_add_arg(argv, &argc, "-w");
545 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
547 for (i = 0; i < argc; i++) {
548 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
552 /* init SECURITY_ATTRIBUTES */
553 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
554 sa.bInheritHandle = TRUE;
555 sa.lpSecurityDescriptor = NULL;
557 /* Create a pipe for the child process */
558 /* (increase this value if you have trouble while fast capture file switches) */
559 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
560 /* Couldn't create the pipe between parent and child. */
561 report_failure("Couldn't create sync pipe: %s",
562 win32strerror(GetLastError()));
563 for (i = 0; i < argc; i++) {
564 g_free( (gpointer) argv[i]);
566 g_free( (gpointer) argv);
570 /* Create the signal pipe */
571 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
572 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
573 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
574 g_free(signal_pipe_name);
576 if (signal_pipe == INVALID_HANDLE_VALUE) {
577 /* Couldn't create the signal pipe between parent and child. */
578 report_failure("Couldn't create signal pipe: %s",
579 win32strerror(GetLastError()));
580 for (i = 0; i < argc; i++) {
581 g_free( (gpointer) argv[i]);
583 g_free( (gpointer) argv);
587 /* init STARTUPINFO */
588 memset(&si, 0, sizeof(si));
591 si.dwFlags = STARTF_USESHOWWINDOW;
592 si.wShowWindow = SW_SHOW;
594 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
595 si.wShowWindow = SW_HIDE; /* this hides the console window */
596 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
597 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
598 si.hStdError = sync_pipe_write;
599 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
602 /* convert args array into a single string */
603 /* XXX - could change sync_pipe_add_arg() instead */
604 /* there is a drawback here: the length is internally limited to 1024 bytes */
605 for(i=0; argv[i] != 0; i++) {
606 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
607 quoted_arg = protect_arg(argv[i]);
608 g_string_append(args, quoted_arg);
613 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
614 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
615 report_failure("Couldn't run %s in child process: %s",
616 args->str, win32strerror(GetLastError()));
617 CloseHandle(sync_pipe_read);
618 CloseHandle(sync_pipe_write);
619 for (i = 0; i < argc; i++) {
620 g_free( (gpointer) argv[i]);
622 g_free( (gpointer) argv);
625 cap_session->fork_child = (int) pi.hProcess;
626 g_string_free(args, TRUE);
628 /* associate the operating system filehandle to a C run-time file handle */
629 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
630 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
632 /* associate the operating system filehandle to a C run-time file handle */
633 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
636 if (pipe(sync_pipe) < 0) {
637 /* Couldn't create the pipe between parent and child. */
638 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
639 for (i = 0; i < argc; i++) {
640 g_free( (gpointer) argv[i]);
646 if ((cap_session->fork_child = fork()) == 0) {
648 * Child process - run dumpcap with the right arguments to make
649 * it just capture with the specified capture parameters
651 dup2(sync_pipe[PIPE_WRITE], 2);
652 ws_close(sync_pipe[PIPE_READ]);
653 execv(argv[0], argv);
654 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
655 argv[0], g_strerror(errno));
656 sync_pipe_errmsg_to_parent(2, errmsg, "");
658 /* Exit with "_exit()", so that we don't close the connection
659 to the X server (and cause stuff buffered up by our parent but
660 not yet sent to be sent, as that stuff should only be sent by
661 our parent). We've sent an error message to the parent, so
662 we exit with an exit status of 1 (any exit status other than
663 0 or 1 will cause an additional message to report that exit
664 status, over and above the error message we sent to the parent). */
668 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
669 fetch_dumpcap_pid(cap_session->fork_child);
671 sync_pipe_read_fd = sync_pipe[PIPE_READ];
674 for (i = 0; i < argc; i++) {
675 g_free( (gpointer) argv[i]);
678 /* Parent process - read messages from the child process over the
680 g_free( (gpointer) argv); /* free up arg array */
682 /* Close the write side of the pipe, so that only the child has it
683 open, and thus it completely closes, and thus returns to us
684 an EOF indication, if the child closes it (either deliberately
685 or by exiting abnormally). */
687 CloseHandle(sync_pipe_write);
689 ws_close(sync_pipe[PIPE_WRITE]);
692 if (cap_session->fork_child == -1) {
693 /* We couldn't even create the child process. */
694 report_failure("Couldn't create child process: %s", g_strerror(errno));
695 ws_close(sync_pipe_read_fd);
697 ws_close(cap_session->signal_pipe_write_fd);
702 cap_session->fork_child_status = 0;
703 cap_session->capture_opts = capture_opts;
705 /* we might wait for a moment till child is ready, so update screen now */
706 if (update_cb) update_cb();
708 /* We were able to set up to read the capture file;
709 arrange that our callback be called whenever it's possible
710 to read from the sync pipe, so that it's called when
711 the child process wants to tell us something. */
713 /* we have a running capture, now wait for the real capture filename */
714 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
715 &cap_session->fork_child, sync_pipe_input_cb);
721 * Open two pipes to dumpcap with the supplied arguments, one for its
722 * standard output and one for its standard error.
724 * On success, *msg is unchanged and 0 is returned; data_read_fd,
725 * messsage_read_fd, and fork_child point to the standard output pipe's
726 * file descriptor, the standard error pipe's file descriptor, and
727 * the child's PID/handle, respectively.
729 * On failure, *msg points to an error message for the failure, and -1 is
730 * returned, in which case *msg must be freed with g_free().
732 /* XXX - This duplicates a lot of code in sync_pipe_start() */
733 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
734 #define PIPE_BUF_SIZE 5120
736 sync_pipe_open_command(char** argv, int *data_read_fd,
737 int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
739 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
741 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
742 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
743 GString *args = g_string_sized_new(200);
745 SECURITY_ATTRIBUTES sa;
747 PROCESS_INFORMATION pi;
750 int sync_pipe[2]; /* pipe used to send messages from child to parent */
751 int data_pipe[2]; /* pipe used to send data from child to parent */
756 *message_read_fd = -1;
757 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
760 /* We can't return anything */
762 g_string_free(args, TRUE);
768 /* init SECURITY_ATTRIBUTES */
769 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
770 sa.bInheritHandle = TRUE;
771 sa.lpSecurityDescriptor = NULL;
773 /* Create a pipe for the child process to send us messages */
774 /* (increase this value if you have trouble while fast capture file switches) */
775 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
776 /* Couldn't create the message pipe between parent and child. */
777 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
778 win32strerror(GetLastError()));
779 for (i = 0; argv[i] != NULL; i++) {
780 g_free( (gpointer) argv[i]);
782 g_free( (gpointer) argv);
786 /* Create a pipe for the child process to send us data */
787 /* (increase this value if you have trouble while fast capture file switches) */
788 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
789 /* Couldn't create the message pipe between parent and child. */
790 *msg = g_strdup_printf("Couldn't create data pipe: %s",
791 win32strerror(GetLastError()));
792 CloseHandle(sync_pipe[PIPE_READ]);
793 CloseHandle(sync_pipe[PIPE_WRITE]);
794 for (i = 0; argv[i] != NULL; i++) {
795 g_free( (gpointer) argv[i]);
797 g_free( (gpointer) argv);
801 /* init STARTUPINFO */
802 memset(&si, 0, sizeof(si));
805 si.dwFlags = STARTF_USESHOWWINDOW;
806 si.wShowWindow = SW_SHOW;
808 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
809 si.wShowWindow = SW_HIDE; /* this hides the console window */
811 si.hStdOutput = data_pipe[PIPE_WRITE];
812 si.hStdError = sync_pipe[PIPE_WRITE];
815 /* convert args array into a single string */
816 /* XXX - could change sync_pipe_add_arg() instead */
817 /* there is a drawback here: the length is internally limited to 1024 bytes */
818 for(i=0; argv[i] != 0; i++) {
819 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
820 quoted_arg = protect_arg(argv[i]);
821 g_string_append(args, quoted_arg);
826 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
827 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
828 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
829 args->str, win32strerror(GetLastError()));
830 CloseHandle(data_pipe[PIPE_READ]);
831 CloseHandle(data_pipe[PIPE_WRITE]);
832 CloseHandle(sync_pipe[PIPE_READ]);
833 CloseHandle(sync_pipe[PIPE_WRITE]);
834 for (i = 0; argv[i] != NULL; i++) {
835 g_free( (gpointer) argv[i]);
837 g_free( (gpointer) argv);
840 *fork_child = (int) pi.hProcess;
841 g_string_free(args, TRUE);
843 /* associate the operating system filehandles to C run-time file handles */
844 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
845 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
846 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
848 /* Create a pipe for the child process to send us messages */
849 if (pipe(sync_pipe) < 0) {
850 /* Couldn't create the message pipe between parent and child. */
851 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
852 for (i = 0; argv[i] != NULL; i++) {
853 g_free( (gpointer) argv[i]);
859 /* Create a pipe for the child process to send us data */
860 if (pipe(data_pipe) < 0) {
861 /* Couldn't create the data pipe between parent and child. */
862 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
863 ws_close(sync_pipe[PIPE_READ]);
864 ws_close(sync_pipe[PIPE_WRITE]);
865 for (i = 0; argv[i] != NULL; i++) {
866 g_free( (gpointer) argv[i]);
872 if ((*fork_child = fork()) == 0) {
874 * Child process - run dumpcap with the right arguments to make
875 * it just capture with the specified capture parameters
877 dup2(data_pipe[PIPE_WRITE], 1);
878 ws_close(data_pipe[PIPE_READ]);
879 ws_close(data_pipe[PIPE_WRITE]);
880 dup2(sync_pipe[PIPE_WRITE], 2);
881 ws_close(sync_pipe[PIPE_READ]);
882 ws_close(sync_pipe[PIPE_WRITE]);
883 execv(argv[0], argv);
884 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
885 argv[0], g_strerror(errno));
886 sync_pipe_errmsg_to_parent(2, errmsg, "");
888 /* Exit with "_exit()", so that we don't close the connection
889 to the X server (and cause stuff buffered up by our parent but
890 not yet sent to be sent, as that stuff should only be sent by
891 our parent). We've sent an error message to the parent, so
892 we exit with an exit status of 1 (any exit status other than
893 0 or 1 will cause an additional message to report that exit
894 status, over and above the error message we sent to the parent). */
898 if (fetch_dumpcap_pid && *fork_child > 0)
899 fetch_dumpcap_pid(*fork_child);
901 *data_read_fd = data_pipe[PIPE_READ];
902 *message_read_fd = sync_pipe[PIPE_READ];
905 for (i = 0; argv[i] != NULL; i++) {
906 g_free( (gpointer) argv[i]);
909 /* Parent process - read messages from the child process over the
911 g_free( (gpointer) argv); /* free up arg array */
913 /* Close the write sides of the pipes, so that only the child has them
914 open, and thus they completely close, and thus return to us
915 an EOF indication, if the child closes them (either deliberately
916 or by exiting abnormally). */
918 CloseHandle(data_pipe[PIPE_WRITE]);
919 CloseHandle(sync_pipe[PIPE_WRITE]);
921 ws_close(data_pipe[PIPE_WRITE]);
922 ws_close(sync_pipe[PIPE_WRITE]);
925 if (*fork_child == -1) {
926 /* We couldn't even create the child process. */
927 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
928 ws_close(*data_read_fd);
929 ws_close(*message_read_fd);
933 /* we might wait for a moment till child is ready, so update screen now */
934 if (update_cb) update_cb();
939 * Close the pipes we're using to read from dumpcap, and wait for it
940 * to exit. On success, *msgp is unchanged, and the exit status of
941 * dumpcap is returned. On failure (which includes "dumpcap exited
942 * due to being killed by a signal or an exception"), *msgp points
943 * to an error message for the failure, and -1 is returned. In the
944 * latter case, *msgp must be freed with g_free().
947 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
948 int *fork_child, gchar **msgp)
950 ws_close(*data_read_fd);
951 if (message_read_fd != NULL)
952 ws_close(*message_read_fd);
955 /* XXX - Should we signal the child somehow? */
956 sync_pipe_kill(*fork_child);
959 return sync_pipe_wait_for_child(*fork_child, msgp);
963 * Run dumpcap with the supplied arguments.
965 * On success, *data points to a buffer containing the dumpcap output,
966 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
967 * must be freed with g_free().
969 * On failure, *data is NULL, *primary_msg points to an error message,
970 * *secondary_msg either points to an additional error message or is
971 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
972 * must be freed with g_free().
974 /* XXX - This duplicates a lot of code in sync_pipe_start() */
975 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
976 #define PIPE_BUF_SIZE 5120
978 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
979 gchar **secondary_msg, void(*update_cb)(void))
982 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
984 gchar buffer[PIPE_BUF_SIZE+1];
988 char *primary_msg_text;
989 int secondary_msg_len;
990 char *secondary_msg_text;
992 GString *data_buf = NULL;
995 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
996 &fork_child, &msg, update_cb);
999 *secondary_msg = NULL;
1005 * We were able to set up to read dumpcap's output. Do so.
1007 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1009 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1010 buffer, primary_msg);
1012 /* We got a read error from the sync pipe, or we got no data at
1013 all from the sync pipe, so we're not going to be getting any
1014 data or error message from the child process. Pick up its
1015 exit status, and complain.
1017 We don't have to worry about killing the child, if the sync pipe
1018 returned an error. Usually this error is caused as the child killed
1019 itself while going down. Even in the rare cases that this isn't the
1020 case, the child will get an error when writing to the broken pipe
1021 the next time, cleaning itself up then. */
1022 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1024 /* We got an EOF from the sync pipe. That means that it exited
1025 before giving us any data to read. If ret is -1, we report
1026 that as a bad exit (e.g., exiting due to a signal); otherwise,
1027 we report it as a premature exit. */
1029 *primary_msg = wait_msg;
1031 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1033 /* We got an error from the sync pipe. If ret is -1, report
1034 both the sync pipe I/O error and the wait error. */
1036 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1037 g_free(*primary_msg);
1039 *primary_msg = combined_msg;
1042 *secondary_msg = NULL;
1047 /* we got a valid message block from the child, process it */
1052 * Error from dumpcap; there will be a primary message and a
1053 * secondary message.
1056 /* convert primary message */
1057 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1058 primary_msg_text = buffer+4;
1059 /* convert secondary message */
1060 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1061 &secondary_msg_len);
1062 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1063 /* the capture child will close the sync_pipe, nothing to do */
1066 * Pick up the child status.
1068 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1072 * Child process failed unexpectedly, or wait failed; msg is the
1076 *secondary_msg = NULL;
1079 * Child process failed, but returned the expected exit status.
1080 * Return the messages it gave us, and indicate failure.
1082 *primary_msg = g_strdup(primary_msg_text);
1083 *secondary_msg = g_strdup(secondary_msg_text);
1090 /* read the output from the command */
1091 data_buf = g_string_new("");
1092 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1093 buffer[count] = '\0';
1094 g_string_append(data_buf, buffer);
1098 * Pick up the child status.
1100 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1104 * Child process failed unexpectedly, or wait failed; msg is the
1108 *secondary_msg = NULL;
1109 g_string_free(data_buf, TRUE);
1113 * Child process succeeded.
1115 *primary_msg = NULL;
1116 *secondary_msg = NULL;
1117 *data = data_buf->str;
1118 g_string_free(data_buf, FALSE);
1124 * Pick up the child status.
1126 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1130 * Child process failed unexpectedly, or wait failed; msg is the
1134 *secondary_msg = NULL;
1137 * Child process returned an unknown status.
1139 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1141 *secondary_msg = NULL;
1150 /* centralised logging and timing for sync_pipe_run_command_actual(),
1151 * redirects to sync_pipe_run_command_actual()
1154 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1155 gchar **secondary_msg, void (*update_cb)(void))
1158 GTimeVal start_time;
1161 int logging_enabled;
1163 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1164 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1165 if(logging_enabled){
1166 g_get_current_time(&start_time);
1167 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1168 for(i=0; argv[i] != 0; i++) {
1169 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1172 /* do the actual sync pipe run command */
1173 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1175 if(logging_enabled){
1176 g_get_current_time(&end_time);
1177 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1178 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1180 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1188 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1189 gchar **data, gchar **primary_msg,
1190 gchar **secondary_msg, void (*update_cb)(void))
1196 argv = init_pipe_args(&argc);
1199 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1200 *secondary_msg = NULL;
1205 argv = sync_pipe_add_arg(argv, &argc, "-i");
1206 argv = sync_pipe_add_arg(argv, &argc, iface);
1209 opt = g_strdup_printf("%s,%s", freq, type);
1211 opt = g_strdup_printf("%s", freq);
1214 *primary_msg = g_strdup("Out of mem.");
1215 *secondary_msg = NULL;
1220 argv = sync_pipe_add_arg(argv, &argc, "-k");
1221 argv = sync_pipe_add_arg(argv, &argc, opt);
1224 /* Run dumpcap in capture child mode */
1225 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1226 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1229 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1235 * Get the list of interfaces using dumpcap.
1237 * On success, *data points to a buffer containing the dumpcap output,
1238 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1239 * must be freed with g_free().
1241 * On failure, *data is NULL, *primary_msg points to an error message,
1242 * *secondary_msg either points to an additional error message or is
1243 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1244 * must be freed with g_free().
1247 sync_interface_list_open(gchar **data, gchar **primary_msg,
1248 gchar **secondary_msg, void (*update_cb)(void))
1253 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1255 argv = init_pipe_args(&argc);
1258 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1259 *secondary_msg = NULL;
1264 /* Ask for the interface list */
1265 argv = sync_pipe_add_arg(argv, &argc, "-D");
1268 /* Run dumpcap in capture child mode */
1269 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1270 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1272 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1276 * Get the capabilities of an interface using dumpcap.
1278 * On success, *data points to a buffer containing the dumpcap output,
1279 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1280 * must be freed with g_free().
1282 * On failure, *data is NULL, *primary_msg points to an error message,
1283 * *secondary_msg either points to an additional error message or is
1284 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1285 * must be freed with g_free().
1288 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1289 gchar **data, gchar **primary_msg,
1290 gchar **secondary_msg, void (*update_cb)(void))
1295 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1297 argv = init_pipe_args(&argc);
1300 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1301 *secondary_msg = NULL;
1306 /* Ask for the interface capabilities */
1307 argv = sync_pipe_add_arg(argv, &argc, "-i");
1308 argv = sync_pipe_add_arg(argv, &argc, ifname);
1309 argv = sync_pipe_add_arg(argv, &argc, "-L");
1311 argv = sync_pipe_add_arg(argv, &argc, "-I");
1314 /* Run dumpcap in capture child mode */
1315 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1316 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1318 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1322 * Start getting interface statistics using dumpcap. On success, read_fd
1323 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1324 * and zero is returned. On failure, *msg will point to an error message
1325 * that must be g_free()d, and -1 will be returned.
1328 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
1332 int message_read_fd, ret;
1334 gchar buffer[PIPE_BUF_SIZE+1];
1337 int primary_msg_len;
1338 char *primary_msg_text;
1339 int secondary_msg_len;
1340 /*char *secondary_msg_text;*/
1343 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1345 argv = init_pipe_args(&argc);
1348 *msg = g_strdup("We don't know where to find dumpcap.");
1352 /* Ask for the interface statistics */
1353 argv = sync_pipe_add_arg(argv, &argc, "-S");
1356 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1358 create_dummy_signal_pipe();
1359 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1361 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1364 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1365 fork_child, msg, update_cb);
1370 * We were able to set up to read dumpcap's output. Do so.
1372 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1374 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1377 /* We got a read error from the sync pipe, or we got no data at
1378 all from the sync pipe, so we're not going to be getting any
1379 data or error message from the child process. Pick up its
1380 exit status, and complain.
1382 We don't have to worry about killing the child, if the sync pipe
1383 returned an error. Usually this error is caused as the child killed
1384 itself while going down. Even in the rare cases that this isn't the
1385 case, the child will get an error when writing to the broken pipe
1386 the next time, cleaning itself up then. */
1387 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1389 /* We got an EOF from the sync pipe. That means that it exited
1390 before giving us any data to read. If ret is -1, we report
1391 that as a bad exit (e.g., exiting due to a signal); otherwise,
1392 we report it as a premature exit. */
1396 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1398 /* We got an error from the sync pipe. If ret is -1, report
1399 both the sync pipe I/O error and the wait error. */
1401 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1404 *msg = combined_msg;
1411 /* we got a valid message block from the child, process it */
1416 * Error from dumpcap; there will be a primary message and a
1417 * secondary message.
1420 /* convert primary message */
1421 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1422 primary_msg_text = buffer+4;
1423 /* convert secondary message */
1424 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1425 &secondary_msg_len);
1426 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1427 /* the capture child will close the sync_pipe, nothing to do */
1430 * Pick up the child status.
1432 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1436 * Child process failed unexpectedly, or wait failed; msg is the
1441 * Child process failed, but returned the expected exit status.
1442 * Return the messages it gave us, and indicate failure.
1444 *msg = g_strdup(primary_msg_text);
1450 /* Close the message pipe. */
1451 ws_close(message_read_fd);
1456 * Pick up the child status.
1458 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1462 * Child process failed unexpectedly, or wait failed; msg is the
1467 * Child process returned an unknown status.
1469 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1478 /* Close down the stats process */
1480 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1484 * Don't bother waiting for the child. sync_pipe_close_command
1485 * does this for us on Windows.
1487 sync_pipe_kill(*fork_child);
1489 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1492 /* read a number of bytes from a pipe */
1493 /* (blocks until enough bytes read or an error occurs) */
1495 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1502 newly = read(pipe_fd, &bytes[offset], required);
1505 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1506 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1513 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1514 "read from pipe %d: error(%u): %s", pipe_fd, error,
1516 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1521 required -= (int)newly;
1529 static gboolean pipe_data_available(int pipe_fd) {
1530 #ifdef _WIN32 /* PeekNamedPipe */
1531 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1534 if (hPipe == INVALID_HANDLE_VALUE)
1537 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1540 if (bytes_avail > 0)
1545 struct timeval timeout;
1548 FD_SET(pipe_fd, &rfds);
1550 timeout.tv_usec = 0;
1552 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1559 /* Read a line from a pipe, similar to fgets */
1561 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1565 while(offset < max - 1) {
1567 if (! pipe_data_available(pipe_fd))
1569 newly = read(pipe_fd, &bytes[offset], 1);
1571 /* EOF - not necessarily an error */
1573 } else if (newly == -1) {
1575 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1576 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1578 } else if (bytes[offset] == '\n') {
1584 bytes[offset] = '\0';
1590 /* convert header values (indicator and 3-byte length) */
1592 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1594 g_assert(header_len == 4);
1596 /* convert header values */
1597 *indicator = header[0];
1598 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1601 /* read a message from the sending pipe in the standard format
1602 (1-byte message indicator, 3-byte message length (excluding length
1603 and indicator field), and the rest is the message) */
1605 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1612 /* read header (indicator and 3-byte length) */
1613 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1617 * Immediate EOF; if the capture child exits normally, this
1618 * is an "I'm done" indication, so don't report it as an
1621 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1622 "read %d got an EOF", pipe_fd);
1625 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1626 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1629 * Short read, but not an immediate EOF.
1631 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1637 /* convert header values */
1638 pipe_convert_header((guchar*)header, 4, indicator, &required);
1640 /* only indicator with no value? */
1642 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1643 "read %d indicator: %c empty value", pipe_fd, *indicator);
1647 /* does the data fit into the given buffer? */
1648 if(required > len) {
1649 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1650 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1651 pipe_fd, required, len,
1652 header[0], header[1], header[2], header[3]);
1654 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1655 memcpy(msg, header, sizeof(header));
1656 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1657 if (newly < 0) { /* error */
1658 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1659 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1661 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1667 /* read the actual block data */
1668 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1669 if(newly != required) {
1671 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1677 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1678 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1679 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1686 /* There's stuff to read from the sync pipe, meaning the child has sent
1687 us a message, or the sync pipe has closed, meaning the child has
1688 closed it (perhaps because it exited). */
1690 sync_pipe_input_cb(gint source, gpointer user_data)
1692 capture_session *cap_session = (capture_session *)user_data;
1694 char buffer[SP_MAX_MSG_LEN+1];
1700 char *secondary_msg;
1701 char *wait_msg, *combined_msg;
1704 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1707 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1709 If we got a read error or a bad message, nread is -1 and
1710 primary_msg is set to point to an error message. We don't
1711 have to worry about killing the child; usually this error
1712 is caused as the child killed itself while going down.
1713 Even in the rare cases that this isn't the case, the child
1714 will get an error when writing to the broken pipe the next time,
1715 cleaning itself up then.
1717 If we got an EOF, nread is 0 and primary_msg isn't set. This
1718 is an indication that the capture is finished. */
1719 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1721 /* We got an EOF from the sync pipe. That means that the capture
1722 child exited, and not in the middle of a message; we treat
1723 that as an indication that it's done, and only report an
1724 error if ret is -1, in which case wait_msg is the error
1727 primary_msg = wait_msg;
1729 /* We got an error from the sync pipe. If ret is -1, report
1730 both the sync pipe I/O error and the wait error. */
1732 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1733 g_free(primary_msg);
1735 primary_msg = combined_msg;
1739 /* No more child process. */
1740 cap_session->fork_child = -1;
1741 cap_session->fork_child_status = ret;
1744 ws_close(cap_session->signal_pipe_write_fd);
1746 capture_input_closed(cap_session, primary_msg);
1747 g_free(primary_msg);
1751 /* we got a valid message block from the child, process it */
1754 if(!capture_input_new_file(cap_session, buffer)) {
1755 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1757 /* We weren't able to open the new capture file; user has been
1758 alerted. Close the sync pipe. */
1761 /* The child has sent us a filename which we couldn't open.
1763 This could mean that the child is creating and deleting files
1764 (ring buffer mode) faster than we can handle it.
1766 That should only be the case for very fast file switches;
1767 We can't do much more than telling the child to stop.
1768 (This is the "emergency brake" if the user e.g. wants to
1769 switch files every second).
1771 This can also happen if the user specified "-", meaning
1772 "standard output", as the capture file. */
1773 sync_pipe_stop(cap_session);
1774 capture_input_closed(cap_session, NULL);
1778 case SP_PACKET_COUNT:
1779 npackets = atoi(buffer);
1780 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1781 capture_input_new_packets(cap_session, npackets);
1784 /* convert primary message */
1785 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1786 primary_msg = buffer+4;
1787 /* convert secondary message */
1788 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1789 secondary_msg = primary_msg + primary_len + 4;
1790 /* message output */
1791 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1792 /* the capture child will close the sync_pipe, nothing to do for now */
1793 /* (an error message doesn't mean we have to stop capturing) */
1795 case SP_BAD_FILTER: {
1799 ch = strtok(buffer, ":");
1801 indx = (int)strtol(ch, NULL, 10);
1802 ch = strtok(NULL, ":");
1804 capture_input_cfilter_error_message(cap_session, indx, ch);
1805 /* the capture child will close the sync_pipe, nothing to do for now */
1809 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1812 g_assert_not_reached();
1821 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1822 * unchanged, and the exit status of dumpcap is returned. On
1823 * failure (which includes "dumpcap exited due to being killed by
1824 * a signal or an exception"), *msgp points to an error message
1825 * for the failure, and -1 is returned. In the latter case, *msgp
1826 * must be freed with g_free().
1829 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1831 int fork_child_status;
1833 GTimeVal start_time;
1838 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1841 g_get_current_time(&start_time);
1843 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1844 g_assert(fork_child != -1);
1846 *msgp = NULL; /* assume no error */
1848 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1849 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1853 * The child exited; return its exit status. Do not treat this as
1856 ret = fork_child_status;
1857 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1858 /* Probably an exception code */
1859 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1860 win32strexception(fork_child_status));
1865 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1866 if (WIFEXITED(fork_child_status)) {
1868 * The child exited; return its exit status. Do not treat this as
1871 ret = WEXITSTATUS(fork_child_status);
1872 } else if (WIFSTOPPED(fork_child_status)) {
1873 /* It stopped, rather than exiting. "Should not happen." */
1874 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1875 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1877 } else if (WIFSIGNALED(fork_child_status)) {
1878 /* It died with a signal. */
1879 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1880 sync_pipe_signame(WTERMSIG(fork_child_status)),
1881 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1884 /* What? It had to either have exited, or stopped, or died with
1885 a signal; what happened here? */
1886 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1890 } else if (errno != ECHILD) {
1891 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1894 /* errno == ECHILD ; echld might have already reaped the child */
1895 ret = fetch_dumpcap_pid ? 0 : -1;
1899 g_get_current_time(&end_time);
1900 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1901 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1902 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1908 /* convert signal to corresponding name */
1910 sync_pipe_signame(int sig)
1913 static char sigmsg_buf[6+1+3+1];
1922 sigmsg = "Interrupted";
1930 sigmsg = "Illegal instruction";
1934 sigmsg = "Trace trap";
1942 sigmsg = "Arithmetic exception";
1950 sigmsg = "Bus error";
1954 sigmsg = "Segmentation violation";
1957 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1958 Linux is POSIX compliant. These are not POSIX-defined signals ---
1959 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1961 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1962 were omitted from POSIX.1 because their behavior is
1963 implementation dependent and could not be adequately catego-
1964 rized. Conforming implementations may deliver these sig-
1965 nals, but must document the circumstances under which they
1966 are delivered and note any restrictions concerning their
1969 So we only check for SIGSYS on those systems that happen to
1970 implement them (a system can be POSIX-compliant and implement
1971 them, it's just that POSIX doesn't *require* a POSIX-compliant
1972 system to implement them).
1977 sigmsg = "Bad system call";
1982 sigmsg = "Broken pipe";
1986 sigmsg = "Alarm clock";
1990 sigmsg = "Terminated";
1994 /* Returning a static buffer is ok in the context we use it here */
1995 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1996 sigmsg = sigmsg_buf;
2006 static void create_dummy_signal_pipe() {
2007 gchar *dummy_signal_pipe_name;
2009 if (dummy_signal_pipe != NULL) return;
2011 if (!dummy_control_id) {
2012 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2015 /* Create the signal pipe */
2016 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2017 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2018 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2019 g_free(dummy_signal_pipe_name);
2022 /* tell the child through the signal pipe that we want to quit the capture */
2024 signal_pipe_capquit_to_child(capture_session *cap_session)
2026 const char quit_msg[] = "QUIT";
2029 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2031 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2032 /* simply sending a "QUIT" string */
2033 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2034 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2036 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2037 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2043 /* user wants to stop the capture run */
2045 sync_pipe_stop(capture_session *cap_session)
2050 gboolean terminate = TRUE;
2053 if (cap_session->fork_child != -1) {
2055 /* send the SIGINT signal to close the capture child gracefully. */
2056 int sts = kill(cap_session->fork_child, SIGINT);
2058 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2059 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2062 #define STOP_SLEEP_TIME 500 /* ms */
2063 #define STOP_CHECK_TIME 50
2064 /* First, use the special signal pipe to try to close the capture child
2067 signal_pipe_capquit_to_child(cap_session);
2069 /* Next, wait for the process to exit on its own */
2070 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2071 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2072 childstatus != STILL_ACTIVE) {
2076 Sleep(STOP_CHECK_TIME);
2079 /* Force the issue. */
2081 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2082 "sync_pipe_stop: forcing child to exit");
2083 sync_pipe_kill(cap_session->fork_child);
2090 /* Wireshark has to exit, force the capture child to close */
2092 sync_pipe_kill(int fork_child)
2094 if (fork_child != -1) {
2096 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2098 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2099 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2102 /* Remark: This is not the preferred method of closing a process!
2103 * the clean way would be getting the process id of the child process,
2104 * then getting window handle hWnd of that process (using EnumChildWindows),
2105 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2107 * Unfortunately, I don't know how to get the process id from the
2108 * handle. OpenProcess will get an handle (not a window handle)
2109 * from the process ID; it will not get a window handle from the
2110 * process ID. (How could it? A process can have more than one
2111 * window. For that matter, a process might have *no* windows,
2112 * as a process running dumpcap, the normal child process program,
2115 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2116 * running in the same console; that's not necessarily the case for
2117 * us, as we might not be running in a console.
2118 * And this also will require to have the process id.
2120 TerminateProcess((HANDLE) (fork_child), 0);
2125 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
2126 fetch_dumpcap_pid = cb;
2129 #endif /* HAVE_LIBPCAP */