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.
45 #include <wsutil/unicode-utils.h>
48 #ifdef HAVE_SYS_WAIT_H
49 # include <sys/wait.h>
52 #include "capture-pcap-util.h"
56 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
57 * macros) on UNIX systems that don't have them.
60 # define WIFEXITED(status) (((status) & 0177) == 0)
63 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
66 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
69 # define WEXITSTATUS(status) ((status) >> 8)
72 # define WTERMSIG(status) ((status) & 0177)
75 # define WCOREDUMP(status) ((status) & 0200)
78 # define WSTOPSIG(status) ((status) >> 8)
82 #include <epan/packet.h>
83 #include <epan/prefs.h>
87 #include <epan/filesystem.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/file_util.h>
101 #include <wsutil/report_err.h>
105 #include <process.h> /* For spawning child process */
111 static const char *sync_pipe_signame(int);
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
117 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
118 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
121 static void (*fetch_dumpcap_pid)(int) = NULL;
125 capture_session_init(capture_session *cap_session, void *cf)
127 cap_session->cf = cf;
128 cap_session->fork_child = -1; /* invalid process handle */
130 cap_session->signal_pipe_write_fd = -1;
132 cap_session->state = CAPTURE_STOPPED;
134 cap_session->owner = getuid();
135 cap_session->group = getgid();
137 cap_session->session_started = FALSE;
140 /* Append an arg (realloc) to an argc/argv array */
141 /* (add a string pointer to a NULL-terminated array of string pointers) */
143 sync_pipe_add_arg(char **args, int *argc, const char *arg)
145 /* Grow the array; "*argc" currently contains the number of string
146 pointers, *not* counting the NULL pointer at the end, so we have
147 to add 2 in order to get the new size of the array, including the
148 new pointer and the terminating NULL pointer. */
149 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
151 /* Stuff the pointer into the penultimate element of the array, which
152 is the one at the index specified by "*argc". */
153 args[*argc] = g_strdup(arg);
154 /* Now bump the count. */
157 /* We overwrite the NULL pointer; put it back right after the
167 /* Quote the argument element if necessary, so that it will get
168 * reconstructed correctly in the C runtime startup code. Note that
169 * the unquoting algorithm in the C runtime is really weird, and
170 * rather different than what Unix shells do. See stdargv.c in the C
171 * runtime sources (in the Platform SDK, in src/crt).
173 * Stolen from GLib's protect_argv(), an internal routine that quotes
174 * string in an argument list so that they arguments will be handled
175 * correctly in the command-line string passed to CreateProcess()
176 * if that string is constructed by gluing those strings together.
179 protect_arg (const gchar *argv)
182 const gchar *p = argv;
185 gboolean need_dblquotes = FALSE;
188 if (*p == ' ' || *p == '\t')
189 need_dblquotes = TRUE;
192 else if (*p == '\\') {
195 while (*pp && *pp == '\\')
204 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
213 else if (*p == '\\') {
216 while (*pp && *pp == '\\')
233 * Generate a string for a Win32 error.
235 #define ERRBUF_SIZE 1024
237 win32strerror(DWORD error)
239 static char errbuf[ERRBUF_SIZE+1];
243 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
244 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
247 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
248 * message. Get rid of it.
250 errlen = strlen(errbuf);
252 errbuf[errlen - 1] = '\0';
253 errbuf[errlen - 2] = '\0';
255 p = strchr(errbuf, '\0');
256 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
261 * Generate a string for a Win32 exception code.
264 win32strexception(DWORD exception)
266 static char errbuf[ERRBUF_SIZE+1];
267 static const struct exception_msg {
271 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
272 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
273 { EXCEPTION_BREAKPOINT, "Breakpoint" },
274 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
275 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
276 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
277 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
278 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
279 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
280 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
281 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
282 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
283 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
284 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
285 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
286 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
287 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
288 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
289 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
290 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
291 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
292 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
295 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
298 for (i = 0; i < N_EXCEPTIONS; i++) {
299 if (exceptions[i].code == exception)
300 return exceptions[i].msg;
302 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
307 /* Initialize an argument list and add dumpcap to it. */
309 init_pipe_args(int *argc) {
311 const char *progfile_dir;
314 progfile_dir = get_progfile_dir();
315 if (progfile_dir == NULL) {
319 /* Allocate the string pointer array with enough space for the
320 terminating NULL pointer. */
322 argv = (char **)g_malloc(sizeof (char *));
325 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
326 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
328 /* Make that the first argument in the argument list (argv[0]). */
329 argv = sync_pipe_add_arg(argv, argc, exename);
331 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
337 #define ARGV_NUMBER_LEN 24
338 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
340 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
342 char ssnap[ARGV_NUMBER_LEN];
343 char scount[ARGV_NUMBER_LEN];
344 char sfilesize[ARGV_NUMBER_LEN];
345 char sfile_duration[ARGV_NUMBER_LEN];
346 char sring_num_files[ARGV_NUMBER_LEN];
347 char sautostop_files[ARGV_NUMBER_LEN];
348 char sautostop_filesize[ARGV_NUMBER_LEN];
349 char sautostop_duration[ARGV_NUMBER_LEN];
350 #ifdef HAVE_PCAP_REMOTE
353 #ifdef HAVE_PCAP_SETSAMPLING
354 char ssampling[ARGV_NUMBER_LEN];
357 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
358 char buffer_size[ARGV_NUMBER_LEN];
362 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
363 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
364 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
365 GString *args = g_string_sized_new(200);
367 SECURITY_ATTRIBUTES sa;
369 PROCESS_INFORMATION pi;
370 char control_id[ARGV_NUMBER_LEN];
371 gchar *signal_pipe_name;
374 int sync_pipe[2]; /* pipe used to send messages from child to parent */
375 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
377 int sync_pipe_read_fd;
382 interface_options interface_opts;
384 if (capture_opts->ifaces->len > 1)
385 capture_opts->use_pcapng = TRUE;
386 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
387 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
389 cap_session->fork_child = -1;
391 argv = init_pipe_args(&argc);
393 /* We don't know where to find dumpcap. */
394 report_failure("We don't know where to find dumpcap.");
398 if (capture_opts->ifaces->len > 1)
399 argv = sync_pipe_add_arg(argv, &argc, "-t");
401 if (capture_opts->use_pcapng)
402 argv = sync_pipe_add_arg(argv, &argc, "-n");
404 argv = sync_pipe_add_arg(argv, &argc, "-P");
406 if (capture_opts->multi_files_on) {
407 if (capture_opts->has_autostop_filesize) {
408 argv = sync_pipe_add_arg(argv, &argc, "-b");
409 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
410 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
413 if (capture_opts->has_file_duration) {
414 argv = sync_pipe_add_arg(argv, &argc, "-b");
415 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
416 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
419 if (capture_opts->has_ring_num_files) {
420 argv = sync_pipe_add_arg(argv, &argc, "-b");
421 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
422 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
425 if (capture_opts->has_autostop_files) {
426 argv = sync_pipe_add_arg(argv, &argc, "-a");
427 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
428 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
431 if (capture_opts->has_autostop_filesize) {
432 argv = sync_pipe_add_arg(argv, &argc, "-a");
433 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
434 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
438 if (capture_opts->has_autostop_packets) {
439 argv = sync_pipe_add_arg(argv, &argc, "-c");
440 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
441 argv = sync_pipe_add_arg(argv, &argc, scount);
444 if (capture_opts->has_autostop_duration) {
445 argv = sync_pipe_add_arg(argv, &argc, "-a");
446 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
447 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
450 if (capture_opts->group_read_access) {
451 argv = sync_pipe_add_arg(argv, &argc, "-g");
454 for (j = 0; j < capture_opts->ifaces->len; j++) {
455 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
457 argv = sync_pipe_add_arg(argv, &argc, "-i");
458 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
460 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
461 argv = sync_pipe_add_arg(argv, &argc, "-f");
462 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
464 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
465 argv = sync_pipe_add_arg(argv, &argc, "-s");
466 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
467 argv = sync_pipe_add_arg(argv, &argc, ssnap);
470 if (interface_opts.linktype != -1) {
471 argv = sync_pipe_add_arg(argv, &argc, "-y");
472 argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
475 if (!interface_opts.promisc_mode) {
476 argv = sync_pipe_add_arg(argv, &argc, "-p");
479 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
480 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
481 argv = sync_pipe_add_arg(argv, &argc, "-B");
482 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
483 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
487 #ifdef HAVE_PCAP_CREATE
488 if (interface_opts.monitor_mode) {
489 argv = sync_pipe_add_arg(argv, &argc, "-I");
493 #ifdef HAVE_PCAP_REMOTE
494 if (interface_opts.datatx_udp)
495 argv = sync_pipe_add_arg(argv, &argc, "-u");
497 if (!interface_opts.nocap_rpcap)
498 argv = sync_pipe_add_arg(argv, &argc, "-r");
500 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
501 argv = sync_pipe_add_arg(argv, &argc, "-A");
502 g_snprintf(sauth, sizeof(sauth), "%s:%s",
503 interface_opts.auth_username,
504 interface_opts.auth_password);
505 argv = sync_pipe_add_arg(argv, &argc, sauth);
509 #ifdef HAVE_PCAP_SETSAMPLING
510 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
511 argv = sync_pipe_add_arg(argv, &argc, "-m");
512 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
513 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
514 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
516 interface_opts.sampling_param);
517 argv = sync_pipe_add_arg(argv, &argc, ssampling);
522 /* dumpcap should be running in capture child mode (hidden feature) */
524 argv = sync_pipe_add_arg(argv, &argc, "-Z");
526 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
527 argv = sync_pipe_add_arg(argv, &argc, control_id);
529 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
533 if (capture_opts->save_file) {
534 argv = sync_pipe_add_arg(argv, &argc, "-w");
535 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
537 for (i = 0; i < argc; i++) {
538 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
542 /* init SECURITY_ATTRIBUTES */
543 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
544 sa.bInheritHandle = TRUE;
545 sa.lpSecurityDescriptor = NULL;
547 /* Create a pipe for the child process */
548 /* (increase this value if you have trouble while fast capture file switches) */
549 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
550 /* Couldn't create the pipe between parent and child. */
551 report_failure("Couldn't create sync pipe: %s",
552 win32strerror(GetLastError()));
553 for (i = 0; i < argc; i++) {
554 g_free( (gpointer) argv[i]);
556 g_free( (gpointer) argv);
560 /* Create the signal pipe */
561 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
562 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
563 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
564 g_free(signal_pipe_name);
566 if (signal_pipe == INVALID_HANDLE_VALUE) {
567 /* Couldn't create the signal pipe between parent and child. */
568 report_failure("Couldn't create signal pipe: %s",
569 win32strerror(GetLastError()));
570 for (i = 0; i < argc; i++) {
571 g_free( (gpointer) argv[i]);
573 g_free( (gpointer) argv);
577 /* init STARTUPINFO */
578 memset(&si, 0, sizeof(si));
581 si.dwFlags = STARTF_USESHOWWINDOW;
582 si.wShowWindow = SW_SHOW;
584 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
585 si.wShowWindow = SW_HIDE; /* this hides the console window */
586 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
587 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
588 si.hStdError = sync_pipe_write;
589 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
592 /* convert args array into a single string */
593 /* XXX - could change sync_pipe_add_arg() instead */
594 /* there is a drawback here: the length is internally limited to 1024 bytes */
595 for(i=0; argv[i] != 0; i++) {
596 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
597 quoted_arg = protect_arg(argv[i]);
598 g_string_append(args, quoted_arg);
603 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
604 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
605 report_failure("Couldn't run %s in child process: %s",
606 args->str, win32strerror(GetLastError()));
607 CloseHandle(sync_pipe_read);
608 CloseHandle(sync_pipe_write);
609 for (i = 0; i < argc; i++) {
610 g_free( (gpointer) argv[i]);
612 g_free( (gpointer) argv);
615 cap_session->fork_child = (int) pi.hProcess;
616 g_string_free(args, TRUE);
618 /* associate the operating system filehandle to a C run-time file handle */
619 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
620 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
622 /* associate the operating system filehandle to a C run-time file handle */
623 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
626 if (pipe(sync_pipe) < 0) {
627 /* Couldn't create the pipe between parent and child. */
628 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
629 for (i = 0; i < argc; i++) {
630 g_free( (gpointer) argv[i]);
636 if ((cap_session->fork_child = fork()) == 0) {
638 * Child process - run dumpcap with the right arguments to make
639 * it just capture with the specified capture parameters
641 dup2(sync_pipe[PIPE_WRITE], 2);
642 ws_close(sync_pipe[PIPE_READ]);
643 execv(argv[0], argv);
644 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
645 argv[0], g_strerror(errno));
646 sync_pipe_errmsg_to_parent(2, errmsg, "");
648 /* Exit with "_exit()", so that we don't close the connection
649 to the X server (and cause stuff buffered up by our parent but
650 not yet sent to be sent, as that stuff should only be sent by
651 our parent). We've sent an error message to the parent, so
652 we exit with an exit status of 1 (any exit status other than
653 0 or 1 will cause an additional message to report that exit
654 status, over and above the error message we sent to the parent). */
658 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
659 fetch_dumpcap_pid(cap_session->fork_child);
661 sync_pipe_read_fd = sync_pipe[PIPE_READ];
664 for (i = 0; i < argc; i++) {
665 g_free( (gpointer) argv[i]);
668 /* Parent process - read messages from the child process over the
670 g_free( (gpointer) argv); /* free up arg array */
672 /* Close the write side of the pipe, so that only the child has it
673 open, and thus it completely closes, and thus returns to us
674 an EOF indication, if the child closes it (either deliberately
675 or by exiting abnormally). */
677 CloseHandle(sync_pipe_write);
679 ws_close(sync_pipe[PIPE_WRITE]);
682 if (cap_session->fork_child == -1) {
683 /* We couldn't even create the child process. */
684 report_failure("Couldn't create child process: %s", g_strerror(errno));
685 ws_close(sync_pipe_read_fd);
687 ws_close(cap_session->signal_pipe_write_fd);
692 cap_session->fork_child_status = 0;
693 cap_session->capture_opts = capture_opts;
695 /* we might wait for a moment till child is ready, so update screen now */
696 if (update_cb) update_cb();
698 /* We were able to set up to read the capture file;
699 arrange that our callback be called whenever it's possible
700 to read from the sync pipe, so that it's called when
701 the child process wants to tell us something. */
703 /* we have a running capture, now wait for the real capture filename */
704 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
705 &cap_session->fork_child, sync_pipe_input_cb);
711 * Open two pipes to dumpcap with the supplied arguments, one for its
712 * standard output and one for its standard error.
714 * On success, *msg is unchanged and 0 is returned; data_read_fd,
715 * messsage_read_fd, and fork_child point to the standard output pipe's
716 * file descriptor, the standard error pipe's file descriptor, and
717 * the child's PID/handle, respectively.
719 * On failure, *msg points to an error message for the failure, and -1 is
720 * returned, in which case *msg must be freed with g_free().
722 /* XXX - This duplicates a lot of code in sync_pipe_start() */
723 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
724 #define PIPE_BUF_SIZE 5120
726 sync_pipe_open_command(char** argv, int *data_read_fd,
727 int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
729 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
731 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
732 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
733 GString *args = g_string_sized_new(200);
735 SECURITY_ATTRIBUTES sa;
737 PROCESS_INFORMATION pi;
740 int sync_pipe[2]; /* pipe used to send messages from child to parent */
741 int data_pipe[2]; /* pipe used to send data from child to parent */
746 *message_read_fd = -1;
747 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
750 /* We can't return anything */
752 g_string_free(args, TRUE);
758 /* init SECURITY_ATTRIBUTES */
759 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
760 sa.bInheritHandle = TRUE;
761 sa.lpSecurityDescriptor = NULL;
763 /* Create a pipe for the child process to send us messages */
764 /* (increase this value if you have trouble while fast capture file switches) */
765 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
766 /* Couldn't create the message pipe between parent and child. */
767 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
768 win32strerror(GetLastError()));
769 for (i = 0; argv[i] != NULL; i++) {
770 g_free( (gpointer) argv[i]);
772 g_free( (gpointer) argv);
776 /* Create a pipe for the child process to send us data */
777 /* (increase this value if you have trouble while fast capture file switches) */
778 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
779 /* Couldn't create the message pipe between parent and child. */
780 *msg = g_strdup_printf("Couldn't create data pipe: %s",
781 win32strerror(GetLastError()));
782 CloseHandle(sync_pipe[PIPE_READ]);
783 CloseHandle(sync_pipe[PIPE_WRITE]);
784 for (i = 0; argv[i] != NULL; i++) {
785 g_free( (gpointer) argv[i]);
787 g_free( (gpointer) argv);
791 /* init STARTUPINFO */
792 memset(&si, 0, sizeof(si));
795 si.dwFlags = STARTF_USESHOWWINDOW;
796 si.wShowWindow = SW_SHOW;
798 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
799 si.wShowWindow = SW_HIDE; /* this hides the console window */
801 si.hStdOutput = data_pipe[PIPE_WRITE];
802 si.hStdError = sync_pipe[PIPE_WRITE];
805 /* convert args array into a single string */
806 /* XXX - could change sync_pipe_add_arg() instead */
807 /* there is a drawback here: the length is internally limited to 1024 bytes */
808 for(i=0; argv[i] != 0; i++) {
809 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
810 quoted_arg = protect_arg(argv[i]);
811 g_string_append(args, quoted_arg);
816 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
817 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
818 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
819 args->str, win32strerror(GetLastError()));
820 CloseHandle(data_pipe[PIPE_READ]);
821 CloseHandle(data_pipe[PIPE_WRITE]);
822 CloseHandle(sync_pipe[PIPE_READ]);
823 CloseHandle(sync_pipe[PIPE_WRITE]);
824 for (i = 0; argv[i] != NULL; i++) {
825 g_free( (gpointer) argv[i]);
827 g_free( (gpointer) argv);
830 *fork_child = (int) pi.hProcess;
831 g_string_free(args, TRUE);
833 /* associate the operating system filehandles to C run-time file handles */
834 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
835 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
836 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
838 /* Create a pipe for the child process to send us messages */
839 if (pipe(sync_pipe) < 0) {
840 /* Couldn't create the message pipe between parent and child. */
841 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
842 for (i = 0; argv[i] != NULL; i++) {
843 g_free( (gpointer) argv[i]);
849 /* Create a pipe for the child process to send us data */
850 if (pipe(data_pipe) < 0) {
851 /* Couldn't create the data pipe between parent and child. */
852 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
853 ws_close(sync_pipe[PIPE_READ]);
854 ws_close(sync_pipe[PIPE_WRITE]);
855 for (i = 0; argv[i] != NULL; i++) {
856 g_free( (gpointer) argv[i]);
862 if ((*fork_child = fork()) == 0) {
864 * Child process - run dumpcap with the right arguments to make
865 * it just capture with the specified capture parameters
867 dup2(data_pipe[PIPE_WRITE], 1);
868 ws_close(data_pipe[PIPE_READ]);
869 ws_close(data_pipe[PIPE_WRITE]);
870 dup2(sync_pipe[PIPE_WRITE], 2);
871 ws_close(sync_pipe[PIPE_READ]);
872 ws_close(sync_pipe[PIPE_WRITE]);
873 execv(argv[0], argv);
874 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
875 argv[0], g_strerror(errno));
876 sync_pipe_errmsg_to_parent(2, errmsg, "");
878 /* Exit with "_exit()", so that we don't close the connection
879 to the X server (and cause stuff buffered up by our parent but
880 not yet sent to be sent, as that stuff should only be sent by
881 our parent). We've sent an error message to the parent, so
882 we exit with an exit status of 1 (any exit status other than
883 0 or 1 will cause an additional message to report that exit
884 status, over and above the error message we sent to the parent). */
888 if (fetch_dumpcap_pid && *fork_child > 0)
889 fetch_dumpcap_pid(*fork_child);
891 *data_read_fd = data_pipe[PIPE_READ];
892 *message_read_fd = sync_pipe[PIPE_READ];
895 for (i = 0; argv[i] != NULL; i++) {
896 g_free( (gpointer) argv[i]);
899 /* Parent process - read messages from the child process over the
901 g_free( (gpointer) argv); /* free up arg array */
903 /* Close the write sides of the pipes, so that only the child has them
904 open, and thus they completely close, and thus return to us
905 an EOF indication, if the child closes them (either deliberately
906 or by exiting abnormally). */
908 CloseHandle(data_pipe[PIPE_WRITE]);
909 CloseHandle(sync_pipe[PIPE_WRITE]);
911 ws_close(data_pipe[PIPE_WRITE]);
912 ws_close(sync_pipe[PIPE_WRITE]);
915 if (*fork_child == -1) {
916 /* We couldn't even create the child process. */
917 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
918 ws_close(*data_read_fd);
919 ws_close(*message_read_fd);
923 /* we might wait for a moment till child is ready, so update screen now */
924 if (update_cb) update_cb();
929 * Close the pipes we're using to read from dumpcap, and wait for it
930 * to exit. On success, *msgp is unchanged, and the exit status of
931 * dumpcap is returned. On failure (which includes "dumpcap exited
932 * due to being killed by a signal or an exception"), *msgp points
933 * to an error message for the failure, and -1 is returned. In the
934 * latter case, *msgp must be freed with g_free().
937 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
938 int *fork_child, gchar **msgp)
940 ws_close(*data_read_fd);
941 if (message_read_fd != NULL)
942 ws_close(*message_read_fd);
945 /* XXX - Should we signal the child somehow? */
946 sync_pipe_kill(*fork_child);
949 return sync_pipe_wait_for_child(*fork_child, msgp);
953 * Run dumpcap with the supplied arguments.
955 * On success, *data points to a buffer containing the dumpcap output,
956 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
957 * must be freed with g_free().
959 * On failure, *data is NULL, *primary_msg points to an error message,
960 * *secondary_msg either points to an additional error message or is
961 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
962 * must be freed with g_free().
964 /* XXX - This duplicates a lot of code in sync_pipe_start() */
965 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
966 #define PIPE_BUF_SIZE 5120
968 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
969 gchar **secondary_msg, void(*update_cb)(void))
972 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
974 gchar buffer[PIPE_BUF_SIZE+1];
978 char *primary_msg_text;
979 int secondary_msg_len;
980 char *secondary_msg_text;
982 GString *data_buf = NULL;
985 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
986 &fork_child, &msg, update_cb);
989 *secondary_msg = NULL;
995 * We were able to set up to read dumpcap's output. Do so.
997 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
999 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1000 buffer, primary_msg);
1002 /* We got a read error from the sync pipe, or we got no data at
1003 all from the sync pipe, so we're not going to be getting any
1004 data or error message from the child process. Pick up its
1005 exit status, and complain.
1007 We don't have to worry about killing the child, if the sync pipe
1008 returned an error. Usually this error is caused as the child killed
1009 itself while going down. Even in the rare cases that this isn't the
1010 case, the child will get an error when writing to the broken pipe
1011 the next time, cleaning itself up then. */
1012 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1014 /* We got an EOF from the sync pipe. That means that it exited
1015 before giving us any data to read. If ret is -1, we report
1016 that as a bad exit (e.g., exiting due to a signal); otherwise,
1017 we report it as a premature exit. */
1019 *primary_msg = wait_msg;
1021 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1023 /* We got an error from the sync pipe. If ret is -1, report
1024 both the sync pipe I/O error and the wait error. */
1026 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1027 g_free(*primary_msg);
1029 *primary_msg = combined_msg;
1032 *secondary_msg = NULL;
1037 /* we got a valid message block from the child, process it */
1042 * Error from dumpcap; there will be a primary message and a
1043 * secondary message.
1046 /* convert primary message */
1047 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1048 primary_msg_text = buffer+4;
1049 /* convert secondary message */
1050 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1051 &secondary_msg_len);
1052 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1053 /* the capture child will close the sync_pipe, nothing to do */
1056 * Pick up the child status.
1058 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1062 * Child process failed unexpectedly, or wait failed; msg is the
1066 *secondary_msg = NULL;
1069 * Child process failed, but returned the expected exit status.
1070 * Return the messages it gave us, and indicate failure.
1072 *primary_msg = g_strdup(primary_msg_text);
1073 *secondary_msg = g_strdup(secondary_msg_text);
1080 /* read the output from the command */
1081 data_buf = g_string_new("");
1082 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1083 buffer[count] = '\0';
1084 g_string_append(data_buf, buffer);
1088 * Pick up the child status.
1090 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1094 * Child process failed unexpectedly, or wait failed; msg is the
1098 *secondary_msg = NULL;
1099 g_string_free(data_buf, TRUE);
1103 * Child process succeeded.
1105 *primary_msg = NULL;
1106 *secondary_msg = NULL;
1107 *data = data_buf->str;
1108 g_string_free(data_buf, FALSE);
1114 * Pick up the child status.
1116 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1120 * Child process failed unexpectedly, or wait failed; msg is the
1124 *secondary_msg = NULL;
1127 * Child process returned an unknown status.
1129 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1131 *secondary_msg = NULL;
1140 /* centralised logging and timing for sync_pipe_run_command_actual(),
1141 * redirects to sync_pipe_run_command_actual()
1144 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1145 gchar **secondary_msg, void (*update_cb)(void))
1148 GTimeVal start_time;
1151 int logging_enabled;
1153 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1154 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1155 if(logging_enabled){
1156 g_get_current_time(&start_time);
1157 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1158 for(i=0; argv[i] != 0; i++) {
1159 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1162 /* do the actual sync pipe run command */
1163 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1165 if(logging_enabled){
1166 g_get_current_time(&end_time);
1167 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1168 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1170 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1178 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1179 gchar **data, gchar **primary_msg,
1180 gchar **secondary_msg, void (*update_cb)(void))
1186 argv = init_pipe_args(&argc);
1189 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1190 *secondary_msg = NULL;
1195 argv = sync_pipe_add_arg(argv, &argc, "-i");
1196 argv = sync_pipe_add_arg(argv, &argc, iface);
1199 opt = g_strdup_printf("%s,%s", freq, type);
1201 opt = g_strdup_printf("%s", freq);
1204 *primary_msg = g_strdup("Out of mem.");
1205 *secondary_msg = NULL;
1210 argv = sync_pipe_add_arg(argv, &argc, "-k");
1211 argv = sync_pipe_add_arg(argv, &argc, opt);
1214 /* Run dumpcap in capture child mode */
1215 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1216 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1219 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1225 * Get the list of interfaces using dumpcap.
1227 * On success, *data points to a buffer containing the dumpcap output,
1228 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1229 * must be freed with g_free().
1231 * On failure, *data is NULL, *primary_msg points to an error message,
1232 * *secondary_msg either points to an additional error message or is
1233 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1234 * must be freed with g_free().
1237 sync_interface_list_open(gchar **data, gchar **primary_msg,
1238 gchar **secondary_msg, void (*update_cb)(void))
1243 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1245 argv = init_pipe_args(&argc);
1248 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1249 *secondary_msg = NULL;
1254 /* Ask for the interface list */
1255 argv = sync_pipe_add_arg(argv, &argc, "-D");
1258 /* Run dumpcap in capture child mode */
1259 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1260 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1262 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1266 * Get the capabilities of an interface using dumpcap.
1268 * On success, *data points to a buffer containing the dumpcap output,
1269 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1270 * must be freed with g_free().
1272 * On failure, *data is NULL, *primary_msg points to an error message,
1273 * *secondary_msg either points to an additional error message or is
1274 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1275 * must be freed with g_free().
1278 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1279 gchar **data, gchar **primary_msg,
1280 gchar **secondary_msg, void (*update_cb)(void))
1285 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1287 argv = init_pipe_args(&argc);
1290 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1291 *secondary_msg = NULL;
1296 /* Ask for the interface capabilities */
1297 argv = sync_pipe_add_arg(argv, &argc, "-i");
1298 argv = sync_pipe_add_arg(argv, &argc, ifname);
1299 argv = sync_pipe_add_arg(argv, &argc, "-L");
1301 argv = sync_pipe_add_arg(argv, &argc, "-I");
1304 /* Run dumpcap in capture child mode */
1305 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1306 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1308 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1312 * Start getting interface statistics using dumpcap. On success, read_fd
1313 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1314 * and zero is returned. On failure, *msg will point to an error message
1315 * that must be g_free()d, and -1 will be returned.
1318 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
1322 int message_read_fd, ret;
1324 gchar buffer[PIPE_BUF_SIZE+1];
1327 int primary_msg_len;
1328 char *primary_msg_text;
1329 int secondary_msg_len;
1330 /*char *secondary_msg_text;*/
1333 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1335 argv = init_pipe_args(&argc);
1338 *msg = g_strdup("We don't know where to find dumpcap.");
1342 /* Ask for the interface statistics */
1343 argv = sync_pipe_add_arg(argv, &argc, "-S");
1346 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1347 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1349 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1350 fork_child, msg, update_cb);
1355 * We were able to set up to read dumpcap's output. Do so.
1357 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1359 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1362 /* We got a read error from the sync pipe, or we got no data at
1363 all from the sync pipe, so we're not going to be getting any
1364 data or error message from the child process. Pick up its
1365 exit status, and complain.
1367 We don't have to worry about killing the child, if the sync pipe
1368 returned an error. Usually this error is caused as the child killed
1369 itself while going down. Even in the rare cases that this isn't the
1370 case, the child will get an error when writing to the broken pipe
1371 the next time, cleaning itself up then. */
1372 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1374 /* We got an EOF from the sync pipe. That means that it exited
1375 before giving us any data to read. If ret is -1, we report
1376 that as a bad exit (e.g., exiting due to a signal); otherwise,
1377 we report it as a premature exit. */
1381 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1383 /* We got an error from the sync pipe. If ret is -1, report
1384 both the sync pipe I/O error and the wait error. */
1386 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1389 *msg = combined_msg;
1396 /* we got a valid message block from the child, process it */
1401 * Error from dumpcap; there will be a primary message and a
1402 * secondary message.
1405 /* convert primary message */
1406 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1407 primary_msg_text = buffer+4;
1408 /* convert secondary message */
1409 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1410 &secondary_msg_len);
1411 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1412 /* the capture child will close the sync_pipe, nothing to do */
1415 * Pick up the child status.
1417 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1421 * Child process failed unexpectedly, or wait failed; msg is the
1426 * Child process failed, but returned the expected exit status.
1427 * Return the messages it gave us, and indicate failure.
1429 *msg = g_strdup(primary_msg_text);
1435 /* Close the message pipe. */
1436 ws_close(message_read_fd);
1441 * Pick up the child status.
1443 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1447 * Child process failed unexpectedly, or wait failed; msg is the
1452 * Child process returned an unknown status.
1454 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1463 /* Close down the stats process */
1465 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1469 * Don't bother waiting for the child. sync_pipe_close_command
1470 * does this for us on Windows.
1472 sync_pipe_kill(*fork_child);
1474 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1477 /* read a number of bytes from a pipe */
1478 /* (blocks until enough bytes read or an error occurs) */
1480 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1487 newly = read(pipe_fd, &bytes[offset], required);
1490 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1491 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1498 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1499 "read from pipe %d: error(%u): %s", pipe_fd, error,
1501 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1506 required -= (int)newly;
1514 static gboolean pipe_data_available(int pipe_fd) {
1515 #ifdef _WIN32 /* PeekNamedPipe */
1516 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1519 if (hPipe == INVALID_HANDLE_VALUE)
1522 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1525 if (bytes_avail > 0)
1530 struct timeval timeout;
1533 FD_SET(pipe_fd, &rfds);
1535 timeout.tv_usec = 0;
1537 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1544 /* Read a line from a pipe, similar to fgets */
1546 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1550 while(offset < max - 1) {
1552 if (! pipe_data_available(pipe_fd))
1554 newly = read(pipe_fd, &bytes[offset], 1);
1556 /* EOF - not necessarily an error */
1558 } else if (newly == -1) {
1560 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1561 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1563 } else if (bytes[offset] == '\n') {
1569 bytes[offset] = '\0';
1575 /* convert header values (indicator and 3-byte length) */
1577 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1579 g_assert(header_len == 4);
1581 /* convert header values */
1582 *indicator = header[0];
1583 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1586 /* read a message from the sending pipe in the standard format
1587 (1-byte message indicator, 3-byte message length (excluding length
1588 and indicator field), and the rest is the message) */
1590 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1597 /* read header (indicator and 3-byte length) */
1598 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1602 * Immediate EOF; if the capture child exits normally, this
1603 * is an "I'm done" indication, so don't report it as an
1606 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1607 "read %d got an EOF", pipe_fd);
1610 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1611 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1614 * Short read, but not an immediate EOF.
1616 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1622 /* convert header values */
1623 pipe_convert_header((guchar*)header, 4, indicator, &required);
1625 /* only indicator with no value? */
1627 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1628 "read %d indicator: %c empty value", pipe_fd, *indicator);
1632 /* does the data fit into the given buffer? */
1633 if(required > len) {
1634 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1635 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1636 pipe_fd, required, len,
1637 header[0], header[1], header[2], header[3]);
1639 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1640 memcpy(msg, header, sizeof(header));
1641 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1642 if (newly < 0) { /* error */
1643 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1644 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1646 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1652 /* read the actual block data */
1653 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1654 if(newly != required) {
1656 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1662 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1663 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1664 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1671 /* There's stuff to read from the sync pipe, meaning the child has sent
1672 us a message, or the sync pipe has closed, meaning the child has
1673 closed it (perhaps because it exited). */
1675 sync_pipe_input_cb(gint source, gpointer user_data)
1677 capture_session *cap_session = (capture_session *)user_data;
1679 char buffer[SP_MAX_MSG_LEN+1];
1685 char *secondary_msg;
1686 char *wait_msg, *combined_msg;
1689 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1692 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1694 If we got a read error or a bad message, nread is -1 and
1695 primary_msg is set to point to an error message. We don't
1696 have to worry about killing the child; usually this error
1697 is caused as the child killed itself while going down.
1698 Even in the rare cases that this isn't the case, the child
1699 will get an error when writing to the broken pipe the next time,
1700 cleaning itself up then.
1702 If we got an EOF, nread is 0 and primary_msg isn't set. This
1703 is an indication that the capture is finished. */
1704 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1706 /* We got an EOF from the sync pipe. That means that the capture
1707 child exited, and not in the middle of a message; we treat
1708 that as an indication that it's done, and only report an
1709 error if ret is -1, in which case wait_msg is the error
1712 primary_msg = wait_msg;
1714 /* We got an error from the sync pipe. If ret is -1, report
1715 both the sync pipe I/O error and the wait error. */
1717 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1718 g_free(primary_msg);
1720 primary_msg = combined_msg;
1724 /* No more child process. */
1725 cap_session->fork_child = -1;
1726 cap_session->fork_child_status = ret;
1729 ws_close(cap_session->signal_pipe_write_fd);
1731 capture_input_closed(cap_session, primary_msg);
1732 g_free(primary_msg);
1736 /* we got a valid message block from the child, process it */
1739 if(!capture_input_new_file(cap_session, buffer)) {
1740 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1742 /* We weren't able to open the new capture file; user has been
1743 alerted. Close the sync pipe. */
1746 /* The child has sent us a filename which we couldn't open.
1748 This could mean that the child is creating files faster
1749 than we can handle it. (XXX - why would that result in
1750 a failure to open the file?)
1752 That should only be the case for very fast file switches;
1753 We can't do much more than telling the child to stop.
1754 (This is the "emergency brake" if the user e.g. wants to
1755 switch files every second).
1757 This can also happen if the user specified "-", meaning
1758 "standard output", as the capture file. */
1759 sync_pipe_stop(cap_session);
1760 capture_input_closed(cap_session, NULL);
1764 case SP_PACKET_COUNT:
1765 npackets = atoi(buffer);
1766 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1767 capture_input_new_packets(cap_session, npackets);
1770 /* convert primary message */
1771 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1772 primary_msg = buffer+4;
1773 /* convert secondary message */
1774 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1775 secondary_msg = primary_msg + primary_len + 4;
1776 /* message output */
1777 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1778 /* the capture child will close the sync_pipe, nothing to do for now */
1779 /* (an error message doesn't mean we have to stop capturing) */
1781 case SP_BAD_FILTER: {
1785 ch = strtok(buffer, ":");
1786 indx = (int)strtol(ch, NULL, 10);
1787 ch = strtok(NULL, ":");
1788 capture_input_cfilter_error_message(cap_session, indx, ch);
1789 /* the capture child will close the sync_pipe, nothing to do for now */
1793 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1796 g_assert_not_reached();
1805 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1806 * unchanged, and the exit status of dumpcap is returned. On
1807 * failure (which includes "dumpcap exited due to being killed by
1808 * a signal or an exception"), *msgp points to an error message
1809 * for the failure, and -1 is returned. In the latter case, *msgp
1810 * must be freed with g_free().
1813 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1815 int fork_child_status;
1817 GTimeVal start_time;
1822 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1825 g_get_current_time(&start_time);
1827 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1828 g_assert(fork_child != -1);
1830 *msgp = NULL; /* assume no error */
1832 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1833 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1837 * The child exited; return its exit status. Do not treat this as
1840 ret = fork_child_status;
1841 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1842 /* Probably an exception code */
1843 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1844 win32strexception(fork_child_status));
1849 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1850 if (WIFEXITED(fork_child_status)) {
1852 * The child exited; return its exit status. Do not treat this as
1855 ret = WEXITSTATUS(fork_child_status);
1856 } else if (WIFSTOPPED(fork_child_status)) {
1857 /* It stopped, rather than exiting. "Should not happen." */
1858 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1859 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1861 } else if (WIFSIGNALED(fork_child_status)) {
1862 /* It died with a signal. */
1863 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1864 sync_pipe_signame(WTERMSIG(fork_child_status)),
1865 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1868 /* What? It had to either have exited, or stopped, or died with
1869 a signal; what happened here? */
1870 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1874 } else if (errno != ECHILD) {
1875 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1878 /* errno == ECHILD ; echld might have already reaped the child */
1879 ret = fetch_dumpcap_pid ? 0 : -1;
1883 g_get_current_time(&end_time);
1884 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1885 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1886 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1892 /* convert signal to corresponding name */
1894 sync_pipe_signame(int sig)
1897 static char sigmsg_buf[6+1+3+1];
1906 sigmsg = "Interrupted";
1914 sigmsg = "Illegal instruction";
1918 sigmsg = "Trace trap";
1926 sigmsg = "Arithmetic exception";
1934 sigmsg = "Bus error";
1938 sigmsg = "Segmentation violation";
1941 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1942 Linux is POSIX compliant. These are not POSIX-defined signals ---
1943 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1945 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1946 were omitted from POSIX.1 because their behavior is
1947 implementation dependent and could not be adequately catego-
1948 rized. Conforming implementations may deliver these sig-
1949 nals, but must document the circumstances under which they
1950 are delivered and note any restrictions concerning their
1953 So we only check for SIGSYS on those systems that happen to
1954 implement them (a system can be POSIX-compliant and implement
1955 them, it's just that POSIX doesn't *require* a POSIX-compliant
1956 system to implement them).
1961 sigmsg = "Bad system call";
1966 sigmsg = "Broken pipe";
1970 sigmsg = "Alarm clock";
1974 sigmsg = "Terminated";
1978 /* Returning a static buffer is ok in the context we use it here */
1979 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1980 sigmsg = sigmsg_buf;
1989 /* tell the child through the signal pipe that we want to quit the capture */
1991 signal_pipe_capquit_to_child(capture_session *cap_session)
1993 const char quit_msg[] = "QUIT";
1996 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1998 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1999 /* simply sending a "QUIT" string */
2000 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2001 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2003 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2004 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2010 /* user wants to stop the capture run */
2012 sync_pipe_stop(capture_session *cap_session)
2017 gboolean terminate = TRUE;
2020 if (cap_session->fork_child != -1) {
2022 /* send the SIGINT signal to close the capture child gracefully. */
2023 int sts = kill(cap_session->fork_child, SIGINT);
2025 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2026 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2029 #define STOP_SLEEP_TIME 500 /* ms */
2030 #define STOP_CHECK_TIME 50
2031 /* First, use the special signal pipe to try to close the capture child
2034 signal_pipe_capquit_to_child(cap_session);
2036 /* Next, wait for the process to exit on its own */
2037 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2038 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2039 childstatus != STILL_ACTIVE) {
2043 Sleep(STOP_CHECK_TIME);
2046 /* Force the issue. */
2048 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2049 "sync_pipe_stop: forcing child to exit");
2050 sync_pipe_kill(cap_session->fork_child);
2057 /* Wireshark has to exit, force the capture child to close */
2059 sync_pipe_kill(int fork_child)
2061 if (fork_child != -1) {
2063 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2065 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2066 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2069 /* Remark: This is not the preferred method of closing a process!
2070 * the clean way would be getting the process id of the child process,
2071 * then getting window handle hWnd of that process (using EnumChildWindows),
2072 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2074 * Unfortunately, I don't know how to get the process id from the
2075 * handle. OpenProcess will get an handle (not a window handle)
2076 * from the process ID; it will not get a window handle from the
2077 * process ID. (How could it? A process can have more than one
2078 * window. For that matter, a process might have *no* windows,
2079 * as a process running dumpcap, the normal child process program,
2082 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2083 * running in the same console; that's not necessarily the case for
2084 * us, as we might not be running in a console.
2085 * And this also will require to have the process id.
2087 TerminateProcess((HANDLE) (fork_child), 0);
2092 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
2093 fetch_dumpcap_pid = cb;
2096 #endif /* HAVE_LIBPCAP */