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.
35 #include <wsutil/unicode-utils.h>
38 #ifdef HAVE_SYS_WAIT_H
39 # include <sys/wait.h>
42 #include "caputils/capture-pcap-util.h"
46 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
47 * macros) on UNIX systems that don't have them.
50 # define WIFEXITED(status) (((status) & 0177) == 0)
53 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
56 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
59 # define WEXITSTATUS(status) ((status) >> 8)
62 # define WTERMSIG(status) ((status) & 0177)
65 # define WCOREDUMP(status) ((status) & 0200)
68 # define WSTOPSIG(status) ((status) >> 8)
72 #include <epan/packet.h>
73 #include <epan/prefs.h>
78 #include "ui/capture.h"
79 #include <capchild/capture_sync.h>
81 #include "sync_pipe.h"
84 #include "caputils/capture-wpcap.h"
87 #include "ui/ui_util.h"
89 #include <wsutil/filesystem.h>
90 #include <wsutil/file_util.h>
91 #include <wsutil/report_err.h>
98 #include <process.h> /* For spawning child process */
104 static void create_dummy_signal_pipe();
105 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
106 static gchar *dummy_control_id;
108 static const char *sync_pipe_signame(int);
112 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
113 static int sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp);
114 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
115 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
118 static void (*fetch_dumpcap_pid)(ws_process_id) = NULL;
122 capture_session_init(capture_session *cap_session, struct _capture_file *cf)
124 cap_session->cf = cf;
125 cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
127 cap_session->signal_pipe_write_fd = -1;
129 cap_session->state = CAPTURE_STOPPED;
131 cap_session->owner = getuid();
132 cap_session->group = getgid();
134 cap_session->count = 0;
135 cap_session->session_started = FALSE;
138 /* Append an arg (realloc) to an argc/argv array */
139 /* (add a string pointer to a NULL-terminated array of string pointers) */
141 sync_pipe_add_arg(char **args, int *argc, const char *arg)
143 /* Grow the array; "*argc" currently contains the number of string
144 pointers, *not* counting the NULL pointer at the end, so we have
145 to add 2 in order to get the new size of the array, including the
146 new pointer and the terminating NULL pointer. */
147 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
149 /* Stuff the pointer into the penultimate element of the array, which
150 is the one at the index specified by "*argc". */
151 args[*argc] = g_strdup(arg);
152 /* Now bump the count. */
155 /* We overwrite the NULL pointer; put it back right after the
165 /* Quote the argument element if necessary, so that it will get
166 * reconstructed correctly in the C runtime startup code. Note that
167 * the unquoting algorithm in the C runtime is really weird, and
168 * rather different than what Unix shells do. See stdargv.c in the C
169 * runtime sources (in the Platform SDK, in src/crt).
171 * Stolen from GLib's protect_argv(), an internal routine that quotes
172 * string in an argument list so that they arguments will be handled
173 * correctly in the command-line string passed to CreateProcess()
174 * if that string is constructed by gluing those strings together.
177 protect_arg (const gchar *argv)
180 const gchar *p = argv;
183 gboolean need_dblquotes = FALSE;
186 if (*p == ' ' || *p == '\t')
187 need_dblquotes = TRUE;
190 else if (*p == '\\') {
193 while (*pp && *pp == '\\')
202 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
211 else if (*p == '\\') {
214 while (*pp && *pp == '\\')
231 * Generate a string for a Win32 error.
233 #define ERRBUF_SIZE 1024
235 win32strerror(DWORD error)
237 static char errbuf[ERRBUF_SIZE+1];
241 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
242 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
245 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
246 * message. Get rid of it.
248 errlen = strlen(errbuf);
250 errbuf[errlen - 1] = '\0';
251 errbuf[errlen - 2] = '\0';
253 p = strchr(errbuf, '\0');
254 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
259 * Generate a string for a Win32 exception code.
262 win32strexception(DWORD exception)
264 static char errbuf[ERRBUF_SIZE+1];
265 static const struct exception_msg {
269 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
270 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
271 { EXCEPTION_BREAKPOINT, "Breakpoint" },
272 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
273 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
274 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
275 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
276 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
277 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
278 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
279 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
280 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
281 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
282 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
283 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
284 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
285 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
286 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
287 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
288 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
289 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
290 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
293 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
296 for (i = 0; i < N_EXCEPTIONS; i++) {
297 if (exceptions[i].code == exception)
298 return exceptions[i].msg;
300 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
305 /* Initialize an argument list and add dumpcap to it. */
307 init_pipe_args(int *argc) {
309 const char *progfile_dir;
312 progfile_dir = get_progfile_dir();
313 if (progfile_dir == NULL) {
317 /* Allocate the string pointer array with enough space for the
318 terminating NULL pointer. */
320 argv = (char **)g_malloc(sizeof (char *));
323 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
325 exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
327 exename = g_strdup_printf("%s/dumpcap", progfile_dir);
330 /* Make that the first argument in the argument list (argv[0]). */
331 argv = sync_pipe_add_arg(argv, argc, exename);
333 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
339 #define ARGV_NUMBER_LEN 24
340 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
342 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void (*update_cb)(void))
344 char ssnap[ARGV_NUMBER_LEN];
345 char scount[ARGV_NUMBER_LEN];
346 char sfilesize[ARGV_NUMBER_LEN];
347 char sfile_duration[ARGV_NUMBER_LEN];
348 char sring_num_files[ARGV_NUMBER_LEN];
349 char sautostop_files[ARGV_NUMBER_LEN];
350 char sautostop_filesize[ARGV_NUMBER_LEN];
351 char sautostop_duration[ARGV_NUMBER_LEN];
352 #ifdef HAVE_PCAP_REMOTE
355 #ifdef HAVE_PCAP_SETSAMPLING
356 char ssampling[ARGV_NUMBER_LEN];
359 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
360 char buffer_size[ARGV_NUMBER_LEN];
364 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
365 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
366 int signal_pipe_write_fd;
367 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
368 GString *args = g_string_sized_new(200);
370 gunichar2 *wcommandline;
371 SECURITY_ATTRIBUTES sa;
373 PROCESS_INFORMATION pi;
374 char control_id[ARGV_NUMBER_LEN];
375 gchar *signal_pipe_name;
378 int sync_pipe[2]; /* pipe used to send messages from child to parent */
379 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
381 int sync_pipe_read_fd;
386 interface_options interface_opts;
388 if (capture_opts->ifaces->len > 1)
389 capture_opts->use_pcapng = TRUE;
390 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
391 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
393 cap_session->fork_child = WS_INVALID_PID;
396 if (!extcap_init_interfaces(capture_opts)) {
397 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
403 argv = init_pipe_args(&argc);
405 /* We don't know where to find dumpcap. */
406 report_failure("We don't know where to find dumpcap.");
410 if (capture_opts->ifaces->len > 1)
411 argv = sync_pipe_add_arg(argv, &argc, "-t");
413 if (capture_opts->use_pcapng)
414 argv = sync_pipe_add_arg(argv, &argc, "-n");
416 argv = sync_pipe_add_arg(argv, &argc, "-P");
418 if (capture_opts->capture_comment) {
419 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
420 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
423 if (capture_opts->multi_files_on) {
424 if (capture_opts->has_autostop_filesize) {
425 argv = sync_pipe_add_arg(argv, &argc, "-b");
426 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
427 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
430 if (capture_opts->has_file_duration) {
431 argv = sync_pipe_add_arg(argv, &argc, "-b");
432 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
433 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
436 if (capture_opts->has_ring_num_files) {
437 argv = sync_pipe_add_arg(argv, &argc, "-b");
438 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
439 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
442 if (capture_opts->has_autostop_files) {
443 argv = sync_pipe_add_arg(argv, &argc, "-a");
444 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
445 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
448 if (capture_opts->has_autostop_filesize) {
449 argv = sync_pipe_add_arg(argv, &argc, "-a");
450 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
451 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
455 if (capture_opts->has_autostop_packets) {
456 argv = sync_pipe_add_arg(argv, &argc, "-c");
457 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
458 argv = sync_pipe_add_arg(argv, &argc, scount);
461 if (capture_opts->has_autostop_duration) {
462 argv = sync_pipe_add_arg(argv, &argc, "-a");
463 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
464 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
467 if (capture_opts->group_read_access) {
468 argv = sync_pipe_add_arg(argv, &argc, "-g");
471 for (j = 0; j < capture_opts->ifaces->len; j++) {
472 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
474 argv = sync_pipe_add_arg(argv, &argc, "-i");
476 if (interface_opts.extcap_fifo != NULL)
477 argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
480 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
482 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
483 argv = sync_pipe_add_arg(argv, &argc, "-f");
484 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
486 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
487 argv = sync_pipe_add_arg(argv, &argc, "-s");
488 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
489 argv = sync_pipe_add_arg(argv, &argc, ssnap);
492 if (interface_opts.linktype != -1) {
493 const char *linktype = linktype_val_to_name(interface_opts.linktype);
494 if ( linktype != NULL )
496 argv = sync_pipe_add_arg(argv, &argc, "-y");
497 argv = sync_pipe_add_arg(argv, &argc, linktype);
501 if (!interface_opts.promisc_mode) {
502 argv = sync_pipe_add_arg(argv, &argc, "-p");
505 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
506 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
507 argv = sync_pipe_add_arg(argv, &argc, "-B");
508 if(interface_opts.buffer_size == 0x00)
509 interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
510 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
511 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
515 #ifdef HAVE_PCAP_CREATE
516 if (interface_opts.monitor_mode) {
517 argv = sync_pipe_add_arg(argv, &argc, "-I");
521 #ifdef HAVE_PCAP_REMOTE
522 if (interface_opts.datatx_udp)
523 argv = sync_pipe_add_arg(argv, &argc, "-u");
525 if (!interface_opts.nocap_rpcap)
526 argv = sync_pipe_add_arg(argv, &argc, "-r");
528 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
529 argv = sync_pipe_add_arg(argv, &argc, "-A");
530 g_snprintf(sauth, sizeof(sauth), "%s:%s",
531 interface_opts.auth_username,
532 interface_opts.auth_password);
533 argv = sync_pipe_add_arg(argv, &argc, sauth);
537 #ifdef HAVE_PCAP_SETSAMPLING
538 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
539 argv = sync_pipe_add_arg(argv, &argc, "-m");
540 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
541 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
542 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
544 interface_opts.sampling_param);
545 argv = sync_pipe_add_arg(argv, &argc, ssampling);
550 /* dumpcap should be running in capture child mode (hidden feature) */
552 argv = sync_pipe_add_arg(argv, &argc, "-Z");
554 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
555 argv = sync_pipe_add_arg(argv, &argc, control_id);
557 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
561 if (capture_opts->save_file) {
562 argv = sync_pipe_add_arg(argv, &argc, "-w");
563 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
565 for (i = 0; i < argc; i++) {
566 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
570 /* init SECURITY_ATTRIBUTES */
571 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
572 sa.bInheritHandle = TRUE;
573 sa.lpSecurityDescriptor = NULL;
575 /* Create a pipe for the child process */
576 /* (increase this value if you have trouble while fast capture file switches) */
577 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
578 /* Couldn't create the pipe between parent and child. */
579 report_failure("Couldn't create sync pipe: %s",
580 win32strerror(GetLastError()));
581 for (i = 0; i < argc; i++) {
582 g_free( (gpointer) argv[i]);
584 g_free( (gpointer) argv);
589 * Associate a C run-time file handle with the Windows HANDLE for the
590 * read side of the message pipe.
592 * (See http://www.flounder.com/handles.htm for information on various
593 * types of file handle in C/C++ on Windows.)
595 sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
596 if (sync_pipe_read_fd == -1) {
597 /* Couldn't create the pipe between parent and child. */
598 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
599 CloseHandle(sync_pipe_read);
600 CloseHandle(sync_pipe_write);
601 for (i = 0; i < argc; i++) {
602 g_free( (gpointer) argv[i]);
608 /* Create the signal pipe */
609 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
610 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
611 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
612 g_free(signal_pipe_name);
614 if (signal_pipe == INVALID_HANDLE_VALUE) {
615 /* Couldn't create the signal pipe between parent and child. */
616 report_failure("Couldn't create signal pipe: %s",
617 win32strerror(GetLastError()));
618 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
619 CloseHandle(sync_pipe_write);
620 for (i = 0; i < argc; i++) {
621 g_free( (gpointer) argv[i]);
623 g_free( (gpointer) argv);
628 * Associate a C run-time file handle with the Windows HANDLE for the
629 * read side of the message pipe.
631 * (See http://www.flounder.com/handles.htm for information on various
632 * types of file handle in C/C++ on Windows.)
634 signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
635 if (sync_pipe_read_fd == -1) {
636 /* Couldn't create the pipe between parent and child. */
637 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
638 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
639 CloseHandle(sync_pipe_write);
640 CloseHandle(signal_pipe);
641 for (i = 0; i < argc; i++) {
642 g_free( (gpointer) argv[i]);
648 /* init STARTUPINFO */
649 memset(&si, 0, sizeof(si));
652 si.dwFlags = STARTF_USESHOWWINDOW;
653 si.wShowWindow = SW_SHOW;
655 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
656 si.wShowWindow = SW_HIDE; /* this hides the console window */
658 /* needs first a check if NULL *
659 * otherwise wouldn't work with non extcap interfaces */
660 if(interface_opts.extcap_fifo != NULL)
662 if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
664 si.hStdInput = extcap_get_win32_handle();
669 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
671 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
672 si.hStdError = sync_pipe_write;
673 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
676 /* convert args array into a single string */
677 /* XXX - could change sync_pipe_add_arg() instead */
678 /* there is a drawback here: the length is internally limited to 1024 bytes */
679 for(i=0; argv[i] != 0; i++) {
680 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
681 quoted_arg = protect_arg(argv[i]);
682 g_string_append(args, quoted_arg);
685 wcommandline = g_utf8_to_utf16(args->str, (glong)args->len, NULL, NULL, NULL);
688 if(!CreateProcess(utf_8to16(argv[0]), wcommandline, NULL, NULL, TRUE,
689 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
690 report_failure("Couldn't run %s in child process: %s",
691 args->str, win32strerror(GetLastError()));
692 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
693 CloseHandle(sync_pipe_write);
694 CloseHandle(signal_pipe);
695 for (i = 0; i < argc; i++) {
696 g_free( (gpointer) argv[i]);
698 g_free( (gpointer) argv);
699 g_string_free(args, TRUE);
700 g_free(wcommandline);
703 cap_session->fork_child = pi.hProcess;
704 /* We may need to store this and close it later */
705 CloseHandle(pi.hThread);
706 g_string_free(args, TRUE);
707 g_free(wcommandline);
709 cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
712 if (pipe(sync_pipe) < 0) {
713 /* Couldn't create the pipe between parent and child. */
714 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
715 for (i = 0; i < argc; i++) {
716 g_free( (gpointer) argv[i]);
722 if ((cap_session->fork_child = fork()) == 0) {
724 * Child process - run dumpcap with the right arguments to make
725 * it just capture with the specified capture parameters
727 dup2(sync_pipe[PIPE_WRITE], 2);
728 ws_close(sync_pipe[PIPE_READ]);
729 execv(argv[0], argv);
730 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
731 argv[0], g_strerror(errno));
732 sync_pipe_errmsg_to_parent(2, errmsg, "");
734 /* Exit with "_exit()", so that we don't close the connection
735 to the X server (and cause stuff buffered up by our parent but
736 not yet sent to be sent, as that stuff should only be sent by
737 our parent). We've sent an error message to the parent, so
738 we exit with an exit status of 1 (any exit status other than
739 0 or 1 will cause an additional message to report that exit
740 status, over and above the error message we sent to the parent). */
744 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
745 fetch_dumpcap_pid(cap_session->fork_child);
747 sync_pipe_read_fd = sync_pipe[PIPE_READ];
750 for (i = 0; i < argc; i++) {
751 g_free( (gpointer) argv[i]);
754 /* Parent process - read messages from the child process over the
756 g_free( (gpointer) argv); /* free up arg array */
758 /* Close the write side of the pipe, so that only the child has it
759 open, and thus it completely closes, and thus returns to us
760 an EOF indication, if the child closes it (either deliberately
761 or by exiting abnormally). */
763 CloseHandle(sync_pipe_write);
765 ws_close(sync_pipe[PIPE_WRITE]);
768 if (cap_session->fork_child == WS_INVALID_PID) {
769 /* We couldn't even create the child process. */
770 report_failure("Couldn't create child process: %s", g_strerror(errno));
771 ws_close(sync_pipe_read_fd);
773 ws_close(cap_session->signal_pipe_write_fd);
778 cap_session->fork_child_status = 0;
779 cap_session->capture_opts = capture_opts;
780 cap_session->cap_data_info = cap_data;
782 /* we might wait for a moment till child is ready, so update screen now */
783 if (update_cb) update_cb();
785 /* We were able to set up to read the capture file;
786 arrange that our callback be called whenever it's possible
787 to read from the sync pipe, so that it's called when
788 the child process wants to tell us something. */
790 /* we have a running capture, now wait for the real capture filename */
791 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
792 &cap_session->fork_child, sync_pipe_input_cb);
798 * Open two pipes to dumpcap with the supplied arguments, one for its
799 * standard output and one for its standard error.
801 * On success, *msg is unchanged and 0 is returned; data_read_fd,
802 * message_read_fd, and fork_child point to the standard output pipe's
803 * file descriptor, the standard error pipe's file descriptor, and
804 * the child's PID/handle, respectively.
806 * On failure, *msg points to an error message for the failure, and -1 is
807 * returned, in which case *msg must be freed with g_free().
809 /* XXX - This duplicates a lot of code in sync_pipe_start() */
810 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
811 #define PIPE_BUF_SIZE 5120
813 sync_pipe_open_command(char** argv, int *data_read_fd,
814 int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
816 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
818 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
819 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
820 GString *args = g_string_sized_new(200);
822 gunichar2 *wcommandline;
823 SECURITY_ATTRIBUTES sa;
825 PROCESS_INFORMATION pi;
828 int sync_pipe[2]; /* pipe used to send messages from child to parent */
829 int data_pipe[2]; /* pipe used to send data from child to parent */
832 *fork_child = WS_INVALID_PID;
834 *message_read_fd = -1;
835 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
838 /* We can't return anything */
840 g_string_free(args, TRUE);
846 /* init SECURITY_ATTRIBUTES */
847 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
848 sa.bInheritHandle = TRUE;
849 sa.lpSecurityDescriptor = NULL;
851 /* Create a pipe for the child process to send us messages */
852 /* (increase this value if you have trouble while fast capture file switches) */
853 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
854 /* Couldn't create the message pipe between parent and child. */
855 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
856 win32strerror(GetLastError()));
857 for (i = 0; argv[i] != NULL; i++) {
858 g_free( (gpointer) argv[i]);
860 g_free( (gpointer) argv);
865 * Associate a C run-time file handle with the Windows HANDLE for the
866 * read side of the message pipe.
868 * (See http://www.flounder.com/handles.htm for information on various
869 * types of file handle in C/C++ on Windows.)
871 *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
872 if (*message_read_fd == -1) {
873 *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
874 CloseHandle(sync_pipe[PIPE_READ]);
875 CloseHandle(sync_pipe[PIPE_WRITE]);
876 for (i = 0; argv[i] != NULL; i++) {
877 g_free( (gpointer) argv[i]);
879 g_free( (gpointer) argv);
883 /* Create a pipe for the child process to send us data */
884 /* (increase this value if you have trouble while fast capture file switches) */
885 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
886 /* Couldn't create the message pipe between parent and child. */
887 *msg = g_strdup_printf("Couldn't create data pipe: %s",
888 win32strerror(GetLastError()));
889 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
890 CloseHandle(sync_pipe[PIPE_WRITE]);
891 for (i = 0; argv[i] != NULL; i++) {
892 g_free( (gpointer) argv[i]);
894 g_free( (gpointer) argv);
899 * Associate a C run-time file handle with the Windows HANDLE for the
900 * read side of the data pipe.
902 * (See http://www.flounder.com/handles.htm for information on various
903 * types of file handle in C/C++ on Windows.)
905 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
906 if (*data_read_fd == -1) {
907 *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
908 CloseHandle(data_pipe[PIPE_READ]);
909 CloseHandle(data_pipe[PIPE_WRITE]);
910 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
911 CloseHandle(sync_pipe[PIPE_WRITE]);
912 for (i = 0; argv[i] != NULL; i++) {
913 g_free( (gpointer) argv[i]);
915 g_free( (gpointer) argv);
919 /* init STARTUPINFO */
920 memset(&si, 0, sizeof(si));
923 si.dwFlags = STARTF_USESHOWWINDOW;
924 si.wShowWindow = SW_SHOW;
926 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
927 si.wShowWindow = SW_HIDE; /* this hides the console window */
928 si.hStdInput = NULL; /* handle for named pipe*/
930 si.hStdOutput = data_pipe[PIPE_WRITE];
931 si.hStdError = sync_pipe[PIPE_WRITE];
934 /* convert args array into a single string */
935 /* XXX - could change sync_pipe_add_arg() instead */
936 /* there is a drawback here: the length is internally limited to 1024 bytes */
937 for(i=0; argv[i] != 0; i++) {
938 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
939 quoted_arg = protect_arg(argv[i]);
940 g_string_append(args, quoted_arg);
943 wcommandline = g_utf8_to_utf16(args->str, (glong)args->len, NULL, NULL, NULL);
946 if(!CreateProcess(utf_8to16(argv[0]), wcommandline, NULL, NULL, TRUE,
947 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
948 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
949 args->str, win32strerror(GetLastError()));
950 ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
951 CloseHandle(data_pipe[PIPE_WRITE]);
952 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
953 CloseHandle(sync_pipe[PIPE_WRITE]);
954 for (i = 0; argv[i] != NULL; i++) {
955 g_free( (gpointer) argv[i]);
957 g_free( (gpointer) argv);
958 g_string_free(args, TRUE);
959 g_free(wcommandline);
962 *fork_child = pi.hProcess;
963 /* We may need to store this and close it later */
964 CloseHandle(pi.hThread);
965 g_string_free(args, TRUE);
966 g_free(wcommandline);
968 /* Create a pipe for the child process to send us messages */
969 if (pipe(sync_pipe) < 0) {
970 /* Couldn't create the message pipe between parent and child. */
971 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
972 for (i = 0; argv[i] != NULL; i++) {
973 g_free( (gpointer) argv[i]);
979 /* Create a pipe for the child process to send us data */
980 if (pipe(data_pipe) < 0) {
981 /* Couldn't create the data pipe between parent and child. */
982 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
983 ws_close(sync_pipe[PIPE_READ]);
984 ws_close(sync_pipe[PIPE_WRITE]);
985 for (i = 0; argv[i] != NULL; i++) {
986 g_free( (gpointer) argv[i]);
992 if ((*fork_child = fork()) == 0) {
994 * Child process - run dumpcap with the right arguments to make
995 * it just capture with the specified capture parameters
997 dup2(data_pipe[PIPE_WRITE], 1);
998 ws_close(data_pipe[PIPE_READ]);
999 ws_close(data_pipe[PIPE_WRITE]);
1000 dup2(sync_pipe[PIPE_WRITE], 2);
1001 ws_close(sync_pipe[PIPE_READ]);
1002 ws_close(sync_pipe[PIPE_WRITE]);
1003 execv(argv[0], argv);
1004 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
1005 argv[0], g_strerror(errno));
1006 sync_pipe_errmsg_to_parent(2, errmsg, "");
1008 /* Exit with "_exit()", so that we don't close the connection
1009 to the X server (and cause stuff buffered up by our parent but
1010 not yet sent to be sent, as that stuff should only be sent by
1011 our parent). We've sent an error message to the parent, so
1012 we exit with an exit status of 1 (any exit status other than
1013 0 or 1 will cause an additional message to report that exit
1014 status, over and above the error message we sent to the parent). */
1018 if (fetch_dumpcap_pid && *fork_child > 0)
1019 fetch_dumpcap_pid(*fork_child);
1021 *data_read_fd = data_pipe[PIPE_READ];
1022 *message_read_fd = sync_pipe[PIPE_READ];
1025 for (i = 0; argv[i] != NULL; i++) {
1026 g_free( (gpointer) argv[i]);
1029 /* Parent process - read messages from the child process over the
1031 g_free( (gpointer) argv); /* free up arg array */
1033 /* Close the write sides of the pipes, so that only the child has them
1034 open, and thus they completely close, and thus return to us
1035 an EOF indication, if the child closes them (either deliberately
1036 or by exiting abnormally). */
1038 CloseHandle(data_pipe[PIPE_WRITE]);
1039 CloseHandle(sync_pipe[PIPE_WRITE]);
1041 ws_close(data_pipe[PIPE_WRITE]);
1042 ws_close(sync_pipe[PIPE_WRITE]);
1045 if (*fork_child == WS_INVALID_PID) {
1046 /* We couldn't even create the child process. */
1047 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
1048 ws_close(*data_read_fd);
1049 ws_close(*message_read_fd);
1053 /* we might wait for a moment till child is ready, so update screen now */
1054 if (update_cb) update_cb();
1059 * Close the pipes we're using to read from dumpcap, and wait for it
1060 * to exit. On success, *msgp is unchanged, and the exit status of
1061 * dumpcap is returned. On failure (which includes "dumpcap exited
1062 * due to being killed by a signal or an exception"), *msgp points
1063 * to an error message for the failure, and -1 is returned. In the
1064 * latter case, *msgp must be freed with g_free().
1067 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
1068 ws_process_id *fork_child, gchar **msgp)
1070 ws_close(*data_read_fd);
1071 if (message_read_fd != NULL)
1072 ws_close(*message_read_fd);
1075 /* XXX - Should we signal the child somehow? */
1076 sync_pipe_kill(*fork_child);
1079 return sync_pipe_wait_for_child(*fork_child, msgp);
1083 * Run dumpcap with the supplied arguments.
1085 * On success, *data points to a buffer containing the dumpcap output,
1086 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
1087 * must be freed with g_free().
1089 * On failure, *data is NULL, *primary_msg points to an error message,
1090 * *secondary_msg either points to an additional error message or is
1091 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1092 * must be freed with g_free().
1094 /* XXX - This duplicates a lot of code in sync_pipe_start() */
1095 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
1096 #define PIPE_BUF_SIZE 5120
1098 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
1099 gchar **secondary_msg, void(*update_cb)(void))
1102 int data_pipe_read_fd, sync_pipe_read_fd, ret;
1103 ws_process_id fork_child;
1105 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1108 int primary_msg_len;
1109 char *primary_msg_text;
1110 int secondary_msg_len;
1111 char *secondary_msg_text;
1113 GString *data_buf = NULL;
1116 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
1117 &fork_child, &msg, update_cb);
1120 *secondary_msg = NULL;
1126 * We were able to set up to read dumpcap's output. Do so.
1128 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1130 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1131 buffer, primary_msg);
1133 /* We got a read error from the sync pipe, or we got no data at
1134 all from the sync pipe, so we're not going to be getting any
1135 data or error message from the child process. Pick up its
1136 exit status, and complain.
1138 We don't have to worry about killing the child, if the sync pipe
1139 returned an error. Usually this error is caused as the child killed
1140 itself while going down. Even in the rare cases that this isn't the
1141 case, the child will get an error when writing to the broken pipe
1142 the next time, cleaning itself up then. */
1143 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1145 /* We got an EOF from the sync pipe. That means that it exited
1146 before giving us any data to read. If ret is -1, we report
1147 that as a bad exit (e.g., exiting due to a signal); otherwise,
1148 we report it as a premature exit. */
1150 *primary_msg = wait_msg;
1152 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1154 /* We got an error from the sync pipe. If ret is -1, report
1155 both the sync pipe I/O error and the wait error. */
1157 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1158 g_free(*primary_msg);
1160 *primary_msg = combined_msg;
1163 *secondary_msg = NULL;
1169 /* we got a valid message block from the child, process it */
1174 * Error from dumpcap; there will be a primary message and a
1175 * secondary message.
1178 /* convert primary message */
1179 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1180 primary_msg_text = buffer+4;
1181 /* convert secondary message */
1182 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1183 &secondary_msg_len);
1184 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1185 /* the capture child will close the sync_pipe, nothing to do */
1188 * Pick up the child status.
1190 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1194 * Child process failed unexpectedly, or wait failed; msg is the
1198 *secondary_msg = NULL;
1201 * Child process failed, but returned the expected exit status.
1202 * Return the messages it gave us, and indicate failure.
1204 *primary_msg = g_strdup(primary_msg_text);
1205 *secondary_msg = g_strdup(secondary_msg_text);
1212 /* read the output from the command */
1213 data_buf = g_string_new("");
1214 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1215 buffer[count] = '\0';
1216 g_string_append(data_buf, buffer);
1220 * Pick up the child status.
1222 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1226 * Child process failed unexpectedly, or wait failed; msg is the
1230 *secondary_msg = NULL;
1231 g_string_free(data_buf, TRUE);
1235 * Child process succeeded.
1237 *primary_msg = NULL;
1238 *secondary_msg = NULL;
1239 *data = g_string_free(data_buf, FALSE);
1245 * Pick up the child status.
1247 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1251 * Child process failed unexpectedly, or wait failed; msg is the
1255 *secondary_msg = NULL;
1258 * Child process returned an unknown status.
1260 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1262 *secondary_msg = NULL;
1271 /* centralised logging and timing for sync_pipe_run_command_actual(),
1272 * redirects to sync_pipe_run_command_actual()
1275 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1276 gchar **secondary_msg, void (*update_cb)(void))
1279 GTimeVal start_time;
1282 int logging_enabled;
1284 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1285 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1286 if(logging_enabled){
1287 g_get_current_time(&start_time);
1288 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1289 for(i=0; argv[i] != 0; i++) {
1290 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1293 /* do the actual sync pipe run command */
1294 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1296 if(logging_enabled){
1297 g_get_current_time(&end_time);
1298 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1299 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1301 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1309 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1310 const gchar *center_freq1, const gchar *center_freq2,
1311 gchar **data, gchar **primary_msg,
1312 gchar **secondary_msg, void (*update_cb)(void))
1318 argv = init_pipe_args(&argc);
1321 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1322 *secondary_msg = NULL;
1327 argv = sync_pipe_add_arg(argv, &argc, "-i");
1328 argv = sync_pipe_add_arg(argv, &argc, iface);
1331 opt = g_strdup_printf("%s,%s,%s,%s", freq, type, center_freq1, center_freq2);
1333 opt = g_strdup_printf("%s", freq);
1336 *primary_msg = g_strdup("Out of mem.");
1337 *secondary_msg = NULL;
1342 argv = sync_pipe_add_arg(argv, &argc, "-k");
1343 argv = sync_pipe_add_arg(argv, &argc, opt);
1346 /* Run dumpcap in capture child mode */
1347 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1348 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1351 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1357 * Get the list of interfaces using dumpcap.
1359 * On success, *data points to a buffer containing the dumpcap output,
1360 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1361 * must be freed with g_free().
1363 * On failure, *data is NULL, *primary_msg points to an error message,
1364 * *secondary_msg either points to an additional error message or is
1365 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1366 * must be freed with g_free().
1369 sync_interface_list_open(gchar **data, gchar **primary_msg,
1370 gchar **secondary_msg, void (*update_cb)(void))
1375 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1377 argv = init_pipe_args(&argc);
1380 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1381 *secondary_msg = NULL;
1386 /* Ask for the interface list */
1387 argv = sync_pipe_add_arg(argv, &argc, "-D");
1390 /* Run dumpcap in capture child mode */
1391 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1392 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1394 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1398 * Get the capabilities of an interface using dumpcap.
1400 * On success, *data points to a buffer containing the dumpcap output,
1401 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1402 * must be freed with g_free().
1404 * On failure, *data is NULL, *primary_msg points to an error message,
1405 * *secondary_msg either points to an additional error message or is
1406 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1407 * must be freed with g_free().
1410 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gchar* auth,
1411 gchar **data, gchar **primary_msg,
1412 gchar **secondary_msg, void (*update_cb)(void))
1417 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1419 argv = init_pipe_args(&argc);
1422 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1423 *secondary_msg = NULL;
1428 /* Ask for the interface capabilities */
1429 argv = sync_pipe_add_arg(argv, &argc, "-i");
1430 argv = sync_pipe_add_arg(argv, &argc, ifname);
1431 argv = sync_pipe_add_arg(argv, &argc, "-L");
1433 argv = sync_pipe_add_arg(argv, &argc, "-I");
1435 argv = sync_pipe_add_arg(argv, &argc, "-A");
1436 argv = sync_pipe_add_arg(argv, &argc, auth);
1440 /* Run dumpcap in capture child mode */
1441 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1442 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1444 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1448 * Start getting interface statistics using dumpcap. On success, read_fd
1449 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1450 * and zero is returned. On failure, *msg will point to an error message
1451 * that must be g_free()d, and -1 will be returned.
1454 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1458 int message_read_fd, ret;
1460 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1463 int primary_msg_len;
1464 char *primary_msg_text;
1465 int secondary_msg_len;
1466 /*char *secondary_msg_text;*/
1469 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1471 argv = init_pipe_args(&argc);
1474 *msg = g_strdup("We don't know where to find dumpcap.");
1478 /* Ask for the interface statistics */
1479 argv = sync_pipe_add_arg(argv, &argc, "-S");
1482 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1484 create_dummy_signal_pipe();
1485 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1487 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1490 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1491 fork_child, msg, update_cb);
1496 * We were able to set up to read dumpcap's output. Do so.
1498 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1500 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1503 /* We got a read error from the sync pipe, or we got no data at
1504 all from the sync pipe, so we're not going to be getting any
1505 data or error message from the child process. Pick up its
1506 exit status, and complain.
1508 We don't have to worry about killing the child, if the sync pipe
1509 returned an error. Usually this error is caused as the child killed
1510 itself while going down. Even in the rare cases that this isn't the
1511 case, the child will get an error when writing to the broken pipe
1512 the next time, cleaning itself up then. */
1513 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1514 ws_close(message_read_fd);
1515 ws_close(*data_read_fd);
1517 /* We got an EOF from the sync pipe. That means that it exited
1518 before giving us any data to read. If ret is -1, we report
1519 that as a bad exit (e.g., exiting due to a signal); otherwise,
1520 we report it as a premature exit. */
1524 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1526 /* We got an error from the sync pipe. If ret is -1, report
1527 both the sync pipe I/O error and the wait error. */
1529 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1532 *msg = combined_msg;
1539 /* we got a valid message block from the child, process it */
1544 * Error from dumpcap; there will be a primary message and a
1545 * secondary message.
1548 /* convert primary message */
1549 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1550 primary_msg_text = buffer+4;
1551 /* convert secondary message */
1552 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1553 &secondary_msg_len);
1554 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1555 /* the capture child will close the sync_pipe, nothing to do */
1558 * Pick up the child status.
1560 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1564 * Child process failed unexpectedly, or wait failed; msg is the
1569 * Child process failed, but returned the expected exit status.
1570 * Return the messages it gave us, and indicate failure.
1572 *msg = g_strdup(primary_msg_text);
1578 /* Close the message pipe. */
1579 ws_close(message_read_fd);
1584 * Pick up the child status.
1586 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1590 * Child process failed unexpectedly, or wait failed; msg is the
1595 * Child process returned an unknown status.
1597 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1606 /* Close down the stats process */
1608 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1612 * Don't bother waiting for the child. sync_pipe_close_command
1613 * does this for us on Windows.
1615 sync_pipe_kill(*fork_child);
1617 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1620 /* read a number of bytes from a pipe */
1621 /* (blocks until enough bytes read or an error occurs) */
1623 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1630 newly = ws_read(pipe_fd, &bytes[offset], required);
1633 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1634 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1641 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1642 "read from pipe %d: error(%u): %s", pipe_fd, error,
1644 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1649 required -= (int)newly;
1657 static gboolean pipe_data_available(int pipe_fd) {
1658 #ifdef _WIN32 /* PeekNamedPipe */
1659 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1662 if (hPipe == INVALID_HANDLE_VALUE)
1665 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1668 if (bytes_avail > 0)
1673 struct timeval timeout;
1676 FD_SET(pipe_fd, &rfds);
1678 timeout.tv_usec = 0;
1680 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1687 /* Read a line from a pipe, similar to fgets */
1689 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1693 while(offset < max - 1) {
1695 if (! pipe_data_available(pipe_fd))
1697 newly = ws_read(pipe_fd, &bytes[offset], 1);
1699 /* EOF - not necessarily an error */
1701 } else if (newly == -1) {
1703 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1704 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1706 } else if (bytes[offset] == '\n') {
1712 bytes[offset] = '\0';
1718 /* convert header values (indicator and 3-byte length) */
1720 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1722 g_assert(header_len == 4);
1724 /* convert header values */
1725 *indicator = header[0];
1726 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1729 /* read a message from the sending pipe in the standard format
1730 (1-byte message indicator, 3-byte message length (excluding length
1731 and indicator field), and the rest is the message) */
1733 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1740 /* read header (indicator and 3-byte length) */
1741 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1745 * Immediate EOF; if the capture child exits normally, this
1746 * is an "I'm done" indication, so don't report it as an
1749 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1750 "read %d got an EOF", pipe_fd);
1753 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1754 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1757 * Short read, but not an immediate EOF.
1759 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1765 /* convert header values */
1766 pipe_convert_header((guchar*)header, 4, indicator, &required);
1768 /* only indicator with no value? */
1770 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1771 "read %d indicator: %c empty value", pipe_fd, *indicator);
1775 /* does the data fit into the given buffer? */
1776 if(required > len) {
1777 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1778 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1779 pipe_fd, required, len,
1780 header[0], header[1], header[2], header[3]);
1782 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1783 memcpy(msg, header, sizeof(header));
1784 newly = ws_read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1785 if (newly < 0) { /* error */
1786 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1787 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1789 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1795 /* read the actual block data */
1796 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1797 if(newly != required) {
1799 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1805 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1806 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1807 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1814 /* There's stuff to read from the sync pipe, meaning the child has sent
1815 us a message, or the sync pipe has closed, meaning the child has
1816 closed it (perhaps because it exited). */
1818 sync_pipe_input_cb(gint source, gpointer user_data)
1820 capture_session *cap_session = (capture_session *)user_data;
1822 char buffer[SP_MAX_MSG_LEN+1] = {0};
1828 char *secondary_msg;
1829 char *wait_msg, *combined_msg;
1832 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1835 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1837 If we got a read error or a bad message, nread is -1 and
1838 primary_msg is set to point to an error message. We don't
1839 have to worry about killing the child; usually this error
1840 is caused as the child killed itself while going down.
1841 Even in the rare cases that this isn't the case, the child
1842 will get an error when writing to the broken pipe the next time,
1843 cleaning itself up then.
1845 If we got an EOF, nread is 0 and primary_msg isn't set. This
1846 is an indication that the capture is finished. */
1847 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1849 /* We got an EOF from the sync pipe. That means that the capture
1850 child exited, and not in the middle of a message; we treat
1851 that as an indication that it's done, and only report an
1852 error if ret is -1, in which case wait_msg is the error
1855 primary_msg = wait_msg;
1857 /* We got an error from the sync pipe. If ret is -1, report
1858 both the sync pipe I/O error and the wait error. */
1860 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1861 g_free(primary_msg);
1863 primary_msg = combined_msg;
1867 /* No more child process. */
1868 cap_session->fork_child = WS_INVALID_PID;
1869 cap_session->fork_child_status = ret;
1872 ws_close(cap_session->signal_pipe_write_fd);
1875 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1876 extcap_cleanup(cap_session->capture_opts);
1878 capture_input_closed(cap_session, primary_msg);
1879 g_free(primary_msg);
1883 /* we got a valid message block from the child, process it */
1886 if(!capture_input_new_file(cap_session, buffer)) {
1887 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1889 /* We weren't able to open the new capture file; user has been
1890 alerted. Close the sync pipe. */
1893 /* The child has sent us a filename which we couldn't open.
1895 This could mean that the child is creating and deleting files
1896 (ring buffer mode) faster than we can handle it.
1898 That should only be the case for very fast file switches;
1899 We can't do much more than telling the child to stop.
1900 (This is the "emergency brake" if the user e.g. wants to
1901 switch files every second).
1903 This can also happen if the user specified "-", meaning
1904 "standard output", as the capture file. */
1905 sync_pipe_stop(cap_session);
1906 capture_input_closed(cap_session, NULL);
1910 case SP_PACKET_COUNT:
1911 npackets = atoi(buffer);
1912 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1913 cap_session->count += npackets;
1914 capture_input_new_packets(cap_session, npackets);
1917 /* convert primary message */
1918 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1919 primary_msg = buffer+4;
1920 /* convert secondary message */
1921 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1922 secondary_msg = primary_msg + primary_len + 4;
1923 /* message output */
1924 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1925 /* the capture child will close the sync_pipe, nothing to do for now */
1926 /* (an error message doesn't mean we have to stop capturing) */
1928 case SP_BAD_FILTER: {
1932 ch = strtok(buffer, ":");
1934 indx = (int)strtol(ch, NULL, 10);
1935 ch = strtok(NULL, ":");
1937 capture_input_cfilter_error_message(cap_session, indx, ch);
1938 /* the capture child will close the sync_pipe, nothing to do for now */
1942 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1945 g_assert_not_reached();
1954 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1955 * unchanged, and the exit status of dumpcap is returned. On
1956 * failure (which includes "dumpcap exited due to being killed by
1957 * a signal or an exception"), *msgp points to an error message
1958 * for the failure, and -1 is returned. In the latter case, *msgp
1959 * must be freed with g_free().
1962 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1964 int fork_child_status;
1966 int retry_waitpid = 3;
1969 GTimeVal start_time;
1974 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1977 g_get_current_time(&start_time);
1979 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1980 g_assert(fork_child != WS_INVALID_PID);
1982 *msgp = NULL; /* assume no error */
1984 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1985 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1989 * The child exited; return its exit status. Do not treat this as
1992 ret = fork_child_status;
1993 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1994 /* Probably an exception code */
1995 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1996 win32strexception(fork_child_status));
2001 while (--retry_waitpid >= 0) {
2002 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
2003 /* waitpid() succeeded */
2004 if (WIFEXITED(fork_child_status)) {
2006 * The child exited; return its exit status. Do not treat this as
2009 ret = WEXITSTATUS(fork_child_status);
2010 } else if (WIFSTOPPED(fork_child_status)) {
2011 /* It stopped, rather than exiting. "Should not happen." */
2012 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
2013 sync_pipe_signame(WSTOPSIG(fork_child_status)));
2015 } else if (WIFSIGNALED(fork_child_status)) {
2016 /* It died with a signal. */
2017 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
2018 sync_pipe_signame(WTERMSIG(fork_child_status)),
2019 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
2022 /* What? It had to either have exited, or stopped, or died with
2023 a signal; what happened here? */
2024 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
2029 /* waitpid() failed */
2030 if (errno == EINTR) {
2032 * Signal interrupted waitpid().
2034 * If it's SIGALRM, we just want to keep waiting, in case
2035 * there's some timer using it (e.g., in a GUI toolkit).
2037 * If you ^C TShark (or Wireshark), that should deliver
2038 * SIGINT to dumpcap as well. dumpcap catches SIGINT,
2039 * and should clean up and exit, so we should eventually
2040 * see that and clean up and terminate.
2042 * If we're sent a SIGTERM, we should (and do) catch it,
2043 * and TShark, at least, calls sync_pipe_stop(). which
2044 * kills dumpcap, so we should eventually see that and
2045 * clean up and terminate.
2047 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
2049 } else if (errno == ECHILD) {
2051 * The process identified by fork_child either doesn't
2052 * exist any more or isn't our child process (anymore?).
2054 * echld might have already reaped the child.
2056 ret = fetch_dumpcap_pid ? 0 : -1;
2058 /* Unknown error. */
2059 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
2067 g_get_current_time(&end_time);
2068 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
2069 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
2070 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
2076 /* convert signal to corresponding name */
2078 sync_pipe_signame(int sig)
2081 static char sigmsg_buf[6+1+3+1];
2090 sigmsg = "Interrupted";
2098 sigmsg = "Illegal instruction";
2102 sigmsg = "Trace trap";
2110 sigmsg = "Arithmetic exception";
2118 sigmsg = "Bus error";
2122 sigmsg = "Segmentation violation";
2125 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
2126 Linux is POSIX compliant. These are not POSIX-defined signals ---
2127 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
2129 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
2130 were omitted from POSIX.1 because their behavior is
2131 implementation dependent and could not be adequately catego-
2132 rized. Conforming implementations may deliver these sig-
2133 nals, but must document the circumstances under which they
2134 are delivered and note any restrictions concerning their
2137 So we only check for SIGSYS on those systems that happen to
2138 implement them (a system can be POSIX-compliant and implement
2139 them, it's just that POSIX doesn't *require* a POSIX-compliant
2140 system to implement them).
2145 sigmsg = "Bad system call";
2150 sigmsg = "Broken pipe";
2154 sigmsg = "Alarm clock";
2158 sigmsg = "Terminated";
2162 /* Returning a static buffer is ok in the context we use it here */
2163 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2164 sigmsg = sigmsg_buf;
2174 static void create_dummy_signal_pipe() {
2175 gchar *dummy_signal_pipe_name;
2177 if (dummy_signal_pipe != NULL) return;
2179 if (!dummy_control_id) {
2180 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2183 /* Create the signal pipe */
2184 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2185 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2186 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2187 g_free(dummy_signal_pipe_name);
2190 /* tell the child through the signal pipe that we want to quit the capture */
2192 signal_pipe_capquit_to_child(capture_session *cap_session)
2194 const char quit_msg[] = "QUIT";
2197 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2199 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2200 /* simply sending a "QUIT" string */
2201 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2202 ret = ws_write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2204 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2205 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2211 /* user wants to stop the capture run */
2213 sync_pipe_stop(capture_session *cap_session)
2218 gboolean terminate = TRUE;
2220 if (cap_session->fork_child != WS_INVALID_PID) {
2222 /* send the SIGINT signal to close the capture child gracefully. */
2223 int sts = kill(cap_session->fork_child, SIGINT);
2225 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2226 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2229 #define STOP_SLEEP_TIME 500 /* ms */
2230 #define STOP_CHECK_TIME 50
2231 /* First, use the special signal pipe to try to close the capture child
2234 signal_pipe_capquit_to_child(cap_session);
2236 /* Next, wait for the process to exit on its own */
2237 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2238 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2239 childstatus != STILL_ACTIVE) {
2243 Sleep(STOP_CHECK_TIME);
2246 /* Force the issue. */
2248 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2249 "sync_pipe_stop: forcing child to exit");
2250 sync_pipe_kill(cap_session->fork_child);
2257 /* Wireshark has to exit, force the capture child to close */
2259 sync_pipe_kill(ws_process_id fork_child)
2261 if (fork_child != WS_INVALID_PID) {
2263 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2265 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2266 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2269 /* Remark: This is not the preferred method of closing a process!
2270 * the clean way would be getting the process id of the child process,
2271 * then getting window handle hWnd of that process (using EnumChildWindows),
2272 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2274 * Unfortunately, I don't know how to get the process id from the
2275 * handle. OpenProcess will get an handle (not a window handle)
2276 * from the process ID; it will not get a window handle from the
2277 * process ID. (How could it? A process can have more than one
2278 * window. For that matter, a process might have *no* windows,
2279 * as a process running dumpcap, the normal child process program,
2282 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2283 * running in the same console; that's not necessarily the case for
2284 * us, as we might not be running in a console.
2285 * And this also will require to have the process id.
2287 TerminateProcess((HANDLE) (fork_child), 0);
2293 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2294 fetch_dumpcap_pid = cb;
2297 #endif /* HAVE_LIBPCAP */