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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
47 #include <wsutil/unicode-utils.h>
50 #ifdef HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
54 #include "capture-pcap-util.h"
58 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
59 * macros) on UNIX systems that don't have them.
62 # define WIFEXITED(status) (((status) & 0177) == 0)
65 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
68 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
71 # define WEXITSTATUS(status) ((status) >> 8)
74 # define WTERMSIG(status) ((status) & 0177)
77 # define WCOREDUMP(status) ((status) & 0200)
80 # define WSTOPSIG(status) ((status) >> 8)
84 #include <epan/packet.h>
85 #include <epan/prefs.h>
89 #include <epan/filesystem.h>
90 #include <epan/report_err.h>
93 #include "capture_sync.h"
95 #include "sync_pipe.h"
98 #include "capture-wpcap.h"
101 #include <wsutil/file_util.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 int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
123 /* Append an arg (realloc) to an argc/argv array */
124 /* (add a string pointer to a NULL-terminated array of string pointers) */
126 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
128 /* Grow the array; "*argc" currently contains the number of string
129 pointers, *not* counting the NULL pointer at the end, so we have
130 to add 2 in order to get the new size of the array, including the
131 new pointer and the terminating NULL pointer. */
132 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
134 /* Stuff the pointer into the penultimate element of the array, which
135 is the one at the index specified by "*argc". */
138 /* Now bump the count. */
141 /* We overwrite the NULL pointer; put it back right after the
151 /* Quote the argument element if necessary, so that it will get
152 * reconstructed correctly in the C runtime startup code. Note that
153 * the unquoting algorithm in the C runtime is really weird, and
154 * rather different than what Unix shells do. See stdargv.c in the C
155 * runtime sources (in the Platform SDK, in src/crt).
157 * Stolen from GLib's protect_argv(), an internal routine that quotes
158 * string in an argument list so that they arguments will be handled
159 * correctly in the command-line string passed to CreateProcess()
160 * if that string is constructed by gluing those strings together.
163 protect_arg (const gchar *argv)
166 const gchar *p = argv;
169 gboolean need_dblquotes = FALSE;
172 if (*p == ' ' || *p == '\t')
173 need_dblquotes = TRUE;
176 else if (*p == '\\') {
179 while (*pp && *pp == '\\')
188 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
197 else if (*p == '\\') {
200 while (*pp && *pp == '\\')
217 * Generate a string for a Win32 error.
219 #define ERRBUF_SIZE 1024
221 win32strerror(DWORD error)
223 static char errbuf[ERRBUF_SIZE+1];
227 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
231 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
232 * message. Get rid of it.
234 errlen = strlen(errbuf);
236 errbuf[errlen - 1] = '\0';
237 errbuf[errlen - 2] = '\0';
239 p = strchr(errbuf, '\0');
240 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
245 * Generate a string for a Win32 exception code.
248 win32strexception(DWORD exception)
250 static char errbuf[ERRBUF_SIZE+1];
251 static const struct exception_msg {
255 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
256 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
257 { EXCEPTION_BREAKPOINT, "Breakpoint" },
258 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
259 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
260 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
261 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
262 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
263 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
264 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
265 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
266 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
267 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
268 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
269 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
270 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
271 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
272 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
273 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
274 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
275 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
276 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
279 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
282 for (i = 0; i < N_EXCEPTIONS; i++) {
283 if (exceptions[i].code == exception)
284 return exceptions[i].msg;
286 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
291 /* Initialize an argument list and add dumpcap to it. */
293 init_pipe_args(int *argc) {
295 const char *progfile_dir;
298 progfile_dir = get_progfile_dir();
299 if (progfile_dir == NULL) {
303 /* Allocate the string pointer array with enough space for the
304 terminating NULL pointer. */
306 argv = g_malloc(sizeof (char *));
309 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
310 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
312 /* Make that the first argument in the argument list (argv[0]). */
313 argv = sync_pipe_add_arg(argv, argc, exename);
318 #define ARGV_NUMBER_LEN 24
319 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
321 sync_pipe_start(capture_options *capture_opts) {
322 char ssnap[ARGV_NUMBER_LEN];
323 char sdlt[ARGV_NUMBER_LEN];
324 char scount[ARGV_NUMBER_LEN];
325 char sfilesize[ARGV_NUMBER_LEN];
326 char sfile_duration[ARGV_NUMBER_LEN];
327 char sring_num_files[ARGV_NUMBER_LEN];
328 char sautostop_files[ARGV_NUMBER_LEN];
329 char sautostop_filesize[ARGV_NUMBER_LEN];
330 char sautostop_duration[ARGV_NUMBER_LEN];
331 #ifdef HAVE_PCAP_REMOTE
334 #ifdef HAVE_PCAP_SETSAMPLING
335 char ssampling[ARGV_NUMBER_LEN];
338 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
339 char buffer_size[ARGV_NUMBER_LEN];
343 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
344 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
345 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
346 GString *args = g_string_sized_new(200);
348 SECURITY_ATTRIBUTES sa;
350 PROCESS_INFORMATION pi;
351 char control_id[ARGV_NUMBER_LEN];
352 gchar *signal_pipe_name;
355 int sync_pipe[2]; /* pipe used to send messages from child to parent */
356 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
358 int sync_pipe_read_fd;
363 interface_options interface_opts;
365 if (capture_opts->ifaces->len > 1)
366 capture_opts->use_pcapng = TRUE;
367 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
368 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
370 capture_opts->fork_child = -1;
372 argv = init_pipe_args(&argc);
374 /* We don't know where to find dumpcap. */
375 report_failure("We don't know where to find dumpcap.");
379 if (capture_opts->ifaces->len > 1)
380 argv = sync_pipe_add_arg(argv, &argc, "-t");
382 if (capture_opts->use_pcapng)
383 argv = sync_pipe_add_arg(argv, &argc, "-n");
385 if (capture_opts->multi_files_on) {
386 if (capture_opts->has_autostop_filesize) {
387 argv = sync_pipe_add_arg(argv, &argc, "-b");
388 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
389 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
392 if (capture_opts->has_file_duration) {
393 argv = sync_pipe_add_arg(argv, &argc, "-b");
394 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
395 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
398 if (capture_opts->has_ring_num_files) {
399 argv = sync_pipe_add_arg(argv, &argc, "-b");
400 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
401 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
404 if (capture_opts->has_autostop_files) {
405 argv = sync_pipe_add_arg(argv, &argc, "-a");
406 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
407 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
410 if (capture_opts->has_autostop_filesize) {
411 argv = sync_pipe_add_arg(argv, &argc, "-a");
412 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
413 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
417 if (capture_opts->has_autostop_packets) {
418 argv = sync_pipe_add_arg(argv, &argc, "-c");
419 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
420 argv = sync_pipe_add_arg(argv, &argc, scount);
423 if (capture_opts->has_autostop_duration) {
424 argv = sync_pipe_add_arg(argv, &argc, "-a");
425 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
426 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
428 if (capture_opts->ifaces->len == 0) {
429 interface_opts.name = g_strdup(capture_opts->iface);
430 if (capture_opts->iface_descr) {
431 interface_opts.descr = g_strdup(capture_opts->iface_descr);
433 interface_opts.descr = NULL;
435 interface_opts.cfilter = g_strdup(capture_opts->cfilter);
436 interface_opts.snaplen = capture_opts->snaplen;
437 interface_opts.linktype = capture_opts->linktype;
438 interface_opts.promisc_mode = capture_opts->promisc_mode;
439 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
440 interface_opts.buffer_size = capture_opts->buffer_size;
442 interface_opts.monitor_mode = capture_opts->monitor_mode;
443 #ifdef HAVE_PCAP_REMOTE
444 interface_opts.src_type = capture_opts->src_type;
445 if (capture_opts->remote_host) {
446 interface_opts.remote_host = g_strdup(capture_opts->remote_host);
448 interface_opts.remote_host = NULL;
450 if (capture_opts->remote_port) {
451 interface_opts.remote_port = g_strdup(capture_opts->remote_port);
453 interface_opts.remote_port = NULL;
455 interface_opts.auth_type = capture_opts->auth_type;
456 if (capture_opts->auth_username) {
457 interface_opts.auth_username = g_strdup(capture_opts->auth_username);
459 interface_opts.auth_username = NULL;
461 if (capture_opts->auth_password) {
462 interface_opts.auth_password = g_strdup(capture_opts->auth_password);
464 interface_opts.auth_password = NULL;
466 interface_opts.datatx_udp = capture_opts->datatx_udp;
467 interface_opts.nocap_rpcap = capture_opts->nocap_rpcap;
468 interface_opts.nocap_local = capture_opts->nocap_local;
470 #ifdef HAVE_PCAP_SETSAMPLING
471 interface_opts.sampling_method = capture_opts->sampling_method;
472 interface_opts.sampling_param = capture_opts->sampling_param;
474 g_array_append_val(capture_opts->ifaces, interface_opts);
477 for (j = 0; j < capture_opts->ifaces->len; j++) {
478 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
480 argv = sync_pipe_add_arg(argv, &argc, "-i");
481 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
483 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
484 argv = sync_pipe_add_arg(argv, &argc, "-f");
485 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
488 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
489 argv = sync_pipe_add_arg(argv, &argc, "-s");
490 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
491 argv = sync_pipe_add_arg(argv, &argc, ssnap);
494 if (interface_opts.linktype != -1) {
495 argv = sync_pipe_add_arg(argv, &argc, "-y");
496 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
497 argv = sync_pipe_add_arg(argv, &argc, sdlt);
500 if (!interface_opts.promisc_mode) {
501 argv = sync_pipe_add_arg(argv, &argc, "-p");
504 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
505 if (interface_opts.buffer_size != 1) {
506 argv = sync_pipe_add_arg(argv, &argc, "-B");
507 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
508 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
512 if (interface_opts.monitor_mode) {
513 argv = sync_pipe_add_arg(argv, &argc, "-I");
516 #ifdef HAVE_PCAP_REMOTE
517 if (interface_opts.datatx_udp)
518 argv = sync_pipe_add_arg(argv, &argc, "-u");
520 if (!interface_opts.nocap_rpcap)
521 argv = sync_pipe_add_arg(argv, &argc, "-r");
523 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
524 argv = sync_pipe_add_arg(argv, &argc, "-A");
525 g_snprintf(sauth, sizeof(sauth), "%s:%s",
526 interface_opts.auth_username,
527 interface_opts.auth_password);
528 argv = sync_pipe_add_arg(argv, &argc, sauth);
532 #ifdef HAVE_PCAP_SETSAMPLING
533 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
534 argv = sync_pipe_add_arg(argv, &argc, "-m");
535 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
536 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
537 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
539 interface_opts.sampling_param);
540 argv = sync_pipe_add_arg(argv, &argc, ssampling);
545 /* dumpcap should be running in capture child mode (hidden feature) */
547 argv = sync_pipe_add_arg(argv, &argc, "-Z");
549 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
550 argv = sync_pipe_add_arg(argv, &argc, control_id);
552 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
556 if (capture_opts->save_file) {
557 argv = sync_pipe_add_arg(argv, &argc, "-w");
558 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
560 for (i = 0; i < argc; i++) {
561 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
565 /* init SECURITY_ATTRIBUTES */
566 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
567 sa.bInheritHandle = TRUE;
568 sa.lpSecurityDescriptor = NULL;
570 /* Create a pipe for the child process */
571 /* (increase this value if you have trouble while fast capture file switches) */
572 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
573 /* Couldn't create the pipe between parent and child. */
574 report_failure("Couldn't create sync pipe: %s",
575 win32strerror(GetLastError()));
576 g_free( (gpointer) argv[0]);
577 g_free( (gpointer) argv);
581 /* Create the signal pipe */
582 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
583 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
584 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
585 g_free(signal_pipe_name);
587 if (signal_pipe == INVALID_HANDLE_VALUE) {
588 /* Couldn't create the signal pipe between parent and child. */
589 report_failure("Couldn't create signal pipe: %s",
590 win32strerror(GetLastError()));
591 g_free( (gpointer) argv[0]);
592 g_free( (gpointer) argv);
596 /* init STARTUPINFO */
597 memset(&si, 0, sizeof(si));
600 si.dwFlags = STARTF_USESHOWWINDOW;
601 si.wShowWindow = SW_SHOW;
603 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
604 si.wShowWindow = SW_HIDE; /* this hides the console window */
605 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
606 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
607 si.hStdError = sync_pipe_write;
608 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
611 /* convert args array into a single string */
612 /* XXX - could change sync_pipe_add_arg() instead */
613 /* there is a drawback here: the length is internally limited to 1024 bytes */
614 for(i=0; argv[i] != 0; i++) {
615 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
616 quoted_arg = protect_arg(argv[i]);
617 g_string_append(args, quoted_arg);
622 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
623 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
624 report_failure("Couldn't run %s in child process: %s",
625 args->str, win32strerror(GetLastError()));
626 CloseHandle(sync_pipe_read);
627 CloseHandle(sync_pipe_write);
628 g_free( (gpointer) argv[0]);
629 g_free( (gpointer) argv);
632 capture_opts->fork_child = (int) pi.hProcess;
633 g_string_free(args, TRUE);
635 /* associate the operating system filehandle to a C run-time file handle */
636 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
637 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
639 /* associate the operating system filehandle to a C run-time file handle */
640 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
643 if (pipe(sync_pipe) < 0) {
644 /* Couldn't create the pipe between parent and child. */
645 report_failure("Couldn't create sync pipe: %s", strerror(errno));
646 g_free( (gpointer) argv[0]);
651 if ((capture_opts->fork_child = fork()) == 0) {
653 * Child process - run dumpcap with the right arguments to make
654 * it just capture with the specified capture parameters
656 dup2(sync_pipe[PIPE_WRITE], 2);
657 ws_close(sync_pipe[PIPE_READ]);
658 execv(argv[0], (gpointer)argv);
659 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
660 argv[0], strerror(errno));
661 sync_pipe_errmsg_to_parent(2, errmsg, "");
663 /* Exit with "_exit()", so that we don't close the connection
664 to the X server (and cause stuff buffered up by our parent but
665 not yet sent to be sent, as that stuff should only be sent by
666 our parent). We've sent an error message to the parent, so
667 we exit with an exit status of 1 (any exit status other than
668 0 or 1 will cause an additional message to report that exit
669 status, over and above the error message we sent to the parent). */
673 sync_pipe_read_fd = sync_pipe[PIPE_READ];
676 g_free( (gpointer) argv[0]); /* exename */
678 /* Parent process - read messages from the child process over the
680 g_free( (gpointer) argv); /* free up arg array */
682 /* Close the write side of the pipe, so that only the child has it
683 open, and thus it completely closes, and thus returns to us
684 an EOF indication, if the child closes it (either deliberately
685 or by exiting abnormally). */
687 CloseHandle(sync_pipe_write);
689 ws_close(sync_pipe[PIPE_WRITE]);
692 if (capture_opts->fork_child == -1) {
693 /* We couldn't even create the child process. */
694 report_failure("Couldn't create child process: %s", strerror(errno));
695 ws_close(sync_pipe_read_fd);
697 ws_close(capture_opts->signal_pipe_write_fd);
702 capture_opts->fork_child_status = 0;
704 /* we might wait for a moment till child is ready, so update screen now */
705 main_window_update();
707 /* We were able to set up to read the capture file;
708 arrange that our callback be called whenever it's possible
709 to read from the sync pipe, so that it's called when
710 the child process wants to tell us something. */
712 /* we have a running capture, now wait for the real capture filename */
713 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
714 &capture_opts->fork_child, sync_pipe_input_cb);
720 * Open two pipes to dumpcap with the supplied arguments, one for its
721 * standard output and one for its standard error.
723 * On success, *msg is unchanged and 0 is returned; data_read_fd,
724 * messsage_read_fd, and fork_child point to the standard output pipe's
725 * file descriptor, the standard error pipe's file descriptor, and
726 * the child's PID/handle, respectively.
728 * On failure, *msg points to an error message for the failure, and -1 is
729 * returned, in which case *msg must be freed with g_free().
731 /* XXX - This duplicates a lot of code in sync_pipe_start() */
732 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
733 #define PIPE_BUF_SIZE 5120
735 sync_pipe_open_command(const char** argv, int *data_read_fd,
736 int *message_read_fd, int *fork_child, gchar **msg)
738 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
740 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
741 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
742 GString *args = g_string_sized_new(200);
744 SECURITY_ATTRIBUTES sa;
746 PROCESS_INFORMATION pi;
750 int sync_pipe[2]; /* pipe used to send messages from child to parent */
751 int data_pipe[2]; /* pipe used to send data from child to parent */
756 *message_read_fd = -1;
757 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
760 /* We can't return anything */
762 g_string_free(args, TRUE);
768 /* init SECURITY_ATTRIBUTES */
769 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
770 sa.bInheritHandle = TRUE;
771 sa.lpSecurityDescriptor = NULL;
773 /* Create a pipe for the child process to send us messages */
774 /* (increase this value if you have trouble while fast capture file switches) */
775 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
776 /* Couldn't create the message pipe between parent and child. */
777 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
778 win32strerror(GetLastError()));
779 g_free( (gpointer) argv[0]);
780 g_free( (gpointer) argv);
784 /* Create a pipe for the child process to send us data */
785 /* (increase this value if you have trouble while fast capture file switches) */
786 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
787 /* Couldn't create the message pipe between parent and child. */
788 *msg = g_strdup_printf("Couldn't create data pipe: %s",
789 win32strerror(GetLastError()));
790 CloseHandle(sync_pipe[PIPE_READ]);
791 CloseHandle(sync_pipe[PIPE_WRITE]);
792 g_free( (gpointer) argv[0]);
793 g_free( (gpointer) argv);
797 /* init STARTUPINFO */
798 memset(&si, 0, sizeof(si));
801 si.dwFlags = STARTF_USESHOWWINDOW;
802 si.wShowWindow = SW_SHOW;
804 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
805 si.wShowWindow = SW_HIDE; /* this hides the console window */
807 si.hStdOutput = data_pipe[PIPE_WRITE];
808 si.hStdError = sync_pipe[PIPE_WRITE];
811 /* convert args array into a single string */
812 /* XXX - could change sync_pipe_add_arg() instead */
813 /* there is a drawback here: the length is internally limited to 1024 bytes */
814 for(i=0; argv[i] != 0; i++) {
815 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
816 quoted_arg = protect_arg(argv[i]);
817 g_string_append(args, quoted_arg);
822 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
823 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
824 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
825 args->str, win32strerror(GetLastError()));
826 CloseHandle(data_pipe[PIPE_READ]);
827 CloseHandle(data_pipe[PIPE_WRITE]);
828 CloseHandle(sync_pipe[PIPE_READ]);
829 CloseHandle(sync_pipe[PIPE_WRITE]);
830 g_free( (gpointer) argv[0]);
831 g_free( (gpointer) argv);
834 *fork_child = (int) pi.hProcess;
835 g_string_free(args, TRUE);
837 /* associate the operating system filehandles to C run-time file handles */
838 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
839 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
840 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
842 /* Create a pipe for the child process to send us messages */
843 if (pipe(sync_pipe) < 0) {
844 /* Couldn't create the message pipe between parent and child. */
845 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
846 g_free( (gpointer) argv[0]);
851 /* Create a pipe for the child process to send us data */
852 if (pipe(data_pipe) < 0) {
853 /* Couldn't create the data pipe between parent and child. */
854 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
855 ws_close(sync_pipe[PIPE_READ]);
856 ws_close(sync_pipe[PIPE_WRITE]);
857 g_free( (gpointer) argv[0]);
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], (gpointer)argv);
874 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
875 argv[0], 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 *data_read_fd = data_pipe[PIPE_READ];
889 *message_read_fd = sync_pipe[PIPE_READ];
892 g_free( (gpointer) argv[0]); /* exename */
894 /* Parent process - read messages from the child process over the
896 g_free( (gpointer) argv); /* free up arg array */
898 /* Close the write sides of the pipes, so that only the child has them
899 open, and thus they completely close, and thus return to us
900 an EOF indication, if the child closes them (either deliberately
901 or by exiting abnormally). */
903 CloseHandle(data_pipe[PIPE_WRITE]);
904 CloseHandle(sync_pipe[PIPE_WRITE]);
906 ws_close(data_pipe[PIPE_WRITE]);
907 ws_close(sync_pipe[PIPE_WRITE]);
910 if (*fork_child == -1) {
911 /* We couldn't even create the child process. */
912 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
913 ws_close(*data_read_fd);
914 ws_close(*message_read_fd);
918 /* we might wait for a moment till child is ready, so update screen now */
919 main_window_update();
924 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
925 * returned. On failure, *msg points to an error message for the
926 * failure, and -1 is returned. In the latter case, *msg must be
927 * freed with g_free().
930 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
931 int *fork_child, gchar **msg)
933 ws_close(*data_read_fd);
934 if (message_read_fd != NULL)
935 ws_close(*message_read_fd);
938 /* XXX - Should we signal the child somehow? */
939 sync_pipe_kill(*fork_child);
942 return sync_pipe_wait_for_child(*fork_child, msg);
946 * Run dumpcap with the supplied arguments.
948 * On success, *data points to a buffer containing the dumpcap output,
949 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
950 * must be freed with g_free().
952 * On failure, *data is NULL, *primary_msg points to an error message,
953 * *secondary_msg either points to an additional error message or is
954 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
955 * must be freed with g_free().
957 /* XXX - This duplicates a lot of code in sync_pipe_start() */
958 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
959 #define PIPE_BUF_SIZE 5120
961 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
962 gchar **secondary_msg)
965 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
967 gchar buffer[PIPE_BUF_SIZE+1];
971 char *primary_msg_text;
972 int secondary_msg_len;
973 char *secondary_msg_text;
975 GString *data_buf = NULL;
978 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
982 *secondary_msg = NULL;
988 * We were able to set up to read dumpcap's output. Do so.
990 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
992 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
993 buffer, primary_msg);
995 /* We got a read error from the sync pipe, or we got no data at
996 all from the sync pipe, so we're not going to be getting any
997 data or error message from the child process. Pick up its
998 exit status, and complain.
1000 We don't have to worry about killing the child, if the sync pipe
1001 returned an error. Usually this error is caused as the child killed
1002 itself while going down. Even in the rare cases that this isn't the
1003 case, the child will get an error when writing to the broken pipe
1004 the next time, cleaning itself up then. */
1005 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1007 /* We got an EOF from the sync pipe. That means that it exited
1008 before giving us any data to read. If ret is -1, we report
1009 that as a bad exit (e.g., exiting due to a signal); otherwise,
1010 we report it as a premature exit. */
1012 *primary_msg = wait_msg;
1014 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1016 /* We got an error from the sync pipe. If ret is -1, report
1017 both the sync pipe I/O error and the wait error. */
1019 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1020 g_free(*primary_msg);
1022 *primary_msg = combined_msg;
1025 *secondary_msg = NULL;
1030 /* we got a valid message block from the child, process it */
1035 * Error from dumpcap; there will be a primary message and a
1036 * secondary message.
1039 /* convert primary message */
1040 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1041 primary_msg_text = buffer+4;
1042 /* convert secondary message */
1043 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1044 &secondary_msg_len);
1045 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1046 /* the capture child will close the sync_pipe, nothing to do */
1049 * Pick up the child status.
1051 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1055 * Child process failed unexpectedly, or wait failed; msg is the
1059 *secondary_msg = NULL;
1062 * Child process failed, but returned the expected exit status.
1063 * Return the messages it gave us, and indicate failure.
1065 *primary_msg = g_strdup(primary_msg_text);
1066 *secondary_msg = g_strdup(secondary_msg_text);
1073 /* read the output from the command */
1074 data_buf = g_string_new("");
1075 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1076 buffer[count] = '\0';
1077 g_string_append(data_buf, buffer);
1081 * Pick up the child status.
1083 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1087 * Child process failed unexpectedly, or wait failed; msg is the
1091 *secondary_msg = NULL;
1092 g_string_free(data_buf, TRUE);
1096 * Child process succeeded.
1098 *primary_msg = NULL;
1099 *secondary_msg = NULL;
1100 *data = data_buf->str;
1101 g_string_free(data_buf, FALSE);
1107 * Pick up the child status.
1109 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1113 * Child process failed unexpectedly, or wait failed; msg is the
1117 *secondary_msg = NULL;
1120 * Child process returned an unknown status.
1122 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1124 *secondary_msg = NULL;
1134 * Get the list of interfaces using dumpcap.
1136 * On success, *data points to a buffer containing the dumpcap output,
1137 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1138 * must be freed with g_free().
1140 * On failure, *data is NULL, *primary_msg points to an error message,
1141 * *secondary_msg either points to an additional error message or is
1142 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1143 * must be freed with g_free().
1146 sync_interface_list_open(gchar **data, gchar **primary_msg,
1147 gchar **secondary_msg)
1152 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1154 argv = init_pipe_args(&argc);
1157 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1158 *secondary_msg = NULL;
1163 /* Ask for the interface list */
1164 argv = sync_pipe_add_arg(argv, &argc, "-D");
1167 /* Run dumpcap in capture child mode */
1168 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1169 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1171 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1175 * Get the capabilities of an interface using dumpcap.
1177 * On success, *data points to a buffer containing the dumpcap output,
1178 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1179 * must be freed with g_free().
1181 * On failure, *data is NULL, *primary_msg points to an error message,
1182 * *secondary_msg either points to an additional error message or is
1183 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1184 * must be freed with g_free().
1187 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1188 gchar **data, gchar **primary_msg,
1189 gchar **secondary_msg)
1194 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1196 argv = init_pipe_args(&argc);
1199 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1200 *secondary_msg = NULL;
1205 /* Ask for the interface capabilities */
1206 argv = sync_pipe_add_arg(argv, &argc, "-i");
1207 argv = sync_pipe_add_arg(argv, &argc, ifname);
1208 argv = sync_pipe_add_arg(argv, &argc, "-L");
1210 argv = sync_pipe_add_arg(argv, &argc, "-I");
1213 /* Run dumpcap in capture child mode */
1214 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1215 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1217 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1221 * Start getting interface statistics using dumpcap. On success, read_fd
1222 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1223 * and zero is returned. On failure, *msg will point to an error message
1224 * that must be g_free()d, and -1 will be returned.
1227 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1231 int message_read_fd, ret;
1233 gchar buffer[PIPE_BUF_SIZE+1];
1236 int primary_msg_len;
1237 char *primary_msg_text;
1238 int secondary_msg_len;
1239 char *secondary_msg_text;
1242 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1244 argv = init_pipe_args(&argc);
1247 *msg = g_strdup("We don't know where to find dumpcap.");
1251 /* Ask for the interface statistics */
1252 argv = sync_pipe_add_arg(argv, &argc, "-S");
1255 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1256 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1258 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1264 * We were able to set up to read dumpcap's output. Do so.
1266 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1268 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1271 /* We got a read error from the sync pipe, or we got no data at
1272 all from the sync pipe, so we're not going to be getting any
1273 data or error message from the child process. Pick up its
1274 exit status, and complain.
1276 We don't have to worry about killing the child, if the sync pipe
1277 returned an error. Usually this error is caused as the child killed
1278 itself while going down. Even in the rare cases that this isn't the
1279 case, the child will get an error when writing to the broken pipe
1280 the next time, cleaning itself up then. */
1281 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1283 /* We got an EOF from the sync pipe. That means that it exited
1284 before giving us any data to read. If ret is -1, we report
1285 that as a bad exit (e.g., exiting due to a signal); otherwise,
1286 we report it as a premature exit. */
1290 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1292 /* We got an error from the sync pipe. If ret is -1, report
1293 both the sync pipe I/O error and the wait error. */
1295 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1298 *msg = combined_msg;
1305 /* we got a valid message block from the child, process it */
1310 * Error from dumpcap; there will be a primary message and a
1311 * secondary message.
1314 /* convert primary message */
1315 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1316 primary_msg_text = buffer+4;
1317 /* convert secondary message */
1318 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1319 &secondary_msg_len);
1320 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1321 /* the capture child will close the sync_pipe, nothing to do */
1324 * Pick up the child status.
1326 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1330 * Child process failed unexpectedly, or wait failed; msg is the
1335 * Child process failed, but returned the expected exit status.
1336 * Return the messages it gave us, and indicate failure.
1338 *msg = g_strdup(primary_msg_text);
1344 /* Close the message pipe. */
1345 ws_close(message_read_fd);
1350 * Pick up the child status.
1352 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1356 * Child process failed unexpectedly, or wait failed; msg is the
1361 * Child process returned an unknown status.
1363 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1372 /* Close down the stats process */
1374 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1376 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1379 /* read a number of bytes from a pipe */
1380 /* (blocks until enough bytes read or an error occurs) */
1382 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1389 newly = read(pipe_fd, &bytes[offset], required);
1392 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1393 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1400 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1401 "read from pipe %d: error(%u): %s", pipe_fd, error,
1403 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1416 static gboolean pipe_data_available(int pipe_fd) {
1417 #ifdef _WIN32 /* PeekNamedPipe */
1418 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1421 if (hPipe == INVALID_HANDLE_VALUE)
1424 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1427 if (bytes_avail > 0)
1432 struct timeval timeout;
1435 FD_SET(pipe_fd, &rfds);
1437 timeout.tv_usec = 0;
1439 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1446 /* Read a line from a pipe, similar to fgets */
1448 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1452 while(offset < max - 1) {
1454 if (! pipe_data_available(pipe_fd))
1456 newly = read(pipe_fd, &bytes[offset], 1);
1458 /* EOF - not necessarily an error */
1460 } else if (newly < 0) {
1462 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1463 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1465 } else if (bytes[offset] == '\n') {
1471 bytes[offset] = '\0';
1477 /* convert header values (indicator and 3-byte length) */
1479 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1481 g_assert(header_len == 4);
1483 /* convert header values */
1484 *indicator = header[0];
1485 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1488 /* read a message from the sending pipe in the standard format
1489 (1-byte message indicator, 3-byte message length (excluding length
1490 and indicator field), and the rest is the message) */
1492 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1499 /* read header (indicator and 3-byte length) */
1500 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1504 * Immediate EOF; if the capture child exits normally, this
1505 * is an "I'm done" indication, so don't report it as an
1508 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1509 "read %d got an EOF", pipe_fd);
1512 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1513 "read %d failed to read header: %u", pipe_fd, newly);
1516 * Short read, but not an immediate EOF.
1518 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
1524 /* convert header values */
1525 pipe_convert_header(header, 4, indicator, &required);
1527 /* only indicator with no value? */
1529 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1530 "read %d indicator: %c empty value", pipe_fd, *indicator);
1534 /* does the data fit into the given buffer? */
1535 if(required > len) {
1536 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1537 "read %d length error, required %d > len %d, indicator: %u",
1538 pipe_fd, required, len, *indicator);
1540 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1541 memcpy(msg, header, sizeof(header));
1542 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1543 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1549 /* read the actual block data */
1550 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1551 if(newly != required) {
1553 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1559 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1560 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1561 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1568 /* There's stuff to read from the sync pipe, meaning the child has sent
1569 us a message, or the sync pipe has closed, meaning the child has
1570 closed it (perhaps because it exited). */
1572 sync_pipe_input_cb(gint source, gpointer user_data)
1574 capture_options *capture_opts = (capture_options *)user_data;
1576 char buffer[SP_MAX_MSG_LEN+1];
1582 char *secondary_msg;
1583 char *wait_msg, *combined_msg;
1585 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1588 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1590 If we got a read error or a bad message, nread is -1 and
1591 primary_msg is set to point to an error message. We don't
1592 have to worry about killing the child; usually this error
1593 is caused as the child killed itself while going down.
1594 Even in the rare cases that this isn't the case, the child
1595 will get an error when writing to the broken pipe the next time,
1596 cleaning itself up then.
1598 If we got an EOF, nread is 0 and primary_msg isn't set. This
1599 is an indication that the capture is finished. */
1600 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
1602 /* We got an EOF from the sync pipe. That means that the capture
1603 child exited, and not in the middle of a message; we treat
1604 that as an indication that it's done, and only report an
1605 error if ret is -1, in which case wait_msg is the error
1608 primary_msg = wait_msg;
1610 /* We got an error from the sync pipe. If ret is -1, report
1611 both the sync pipe I/O error and the wait error. */
1613 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1614 g_free(primary_msg);
1616 primary_msg = combined_msg;
1620 /* No more child process. */
1621 capture_opts->fork_child = -1;
1622 capture_opts->fork_child_status = ret;
1625 ws_close(capture_opts->signal_pipe_write_fd);
1627 capture_input_closed(capture_opts, primary_msg);
1628 g_free(primary_msg);
1632 /* we got a valid message block from the child, process it */
1635 if(!capture_input_new_file(capture_opts, buffer)) {
1636 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1638 /* We weren't able to open the new capture file; user has been
1639 alerted. Close the sync pipe. */
1642 /* the child has send us a filename which we couldn't open.
1643 this probably means, the child is creating files faster than we can handle it.
1644 this should only be the case for very fast file switches
1645 we can't do much more than telling the child to stop
1646 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1647 sync_pipe_stop(capture_opts);
1650 case SP_PACKET_COUNT:
1651 nread = atoi(buffer);
1652 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1653 capture_input_new_packets(capture_opts, nread);
1656 /* convert primary message */
1657 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1658 primary_msg = buffer+4;
1659 /* convert secondary message */
1660 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1661 secondary_msg = primary_msg + primary_len + 4;
1662 /* message output */
1663 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1664 /* the capture child will close the sync_pipe, nothing to do for now */
1665 /* (an error message doesn't mean we have to stop capturing) */
1668 capture_input_cfilter_error_message(capture_opts, buffer);
1669 /* the capture child will close the sync_pipe, nothing to do for now */
1672 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1675 g_assert_not_reached();
1683 /* the child process is going down, wait until it's completely terminated */
1685 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1687 int fork_child_status;
1690 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1691 g_assert(fork_child != -1);
1693 *msgp = NULL; /* assume no error */
1696 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1697 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1701 * The child exited; return its exit status. Do not treat this as
1704 ret = fork_child_status;
1705 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1706 /* Probably an exception code */
1707 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1708 win32strexception(fork_child_status));
1713 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1714 if (WIFEXITED(fork_child_status)) {
1716 * The child exited; return its exit status. Do not treat this as
1719 ret = WEXITSTATUS(fork_child_status);
1720 } else if (WIFSTOPPED(fork_child_status)) {
1721 /* It stopped, rather than exiting. "Should not happen." */
1722 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1723 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1725 } else if (WIFSIGNALED(fork_child_status)) {
1726 /* It died with a signal. */
1727 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1728 sync_pipe_signame(WTERMSIG(fork_child_status)),
1729 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1732 /* What? It had to either have exited, or stopped, or died with
1733 a signal; what happened here? */
1734 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1739 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1744 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1750 /* convert signal to corresponding name */
1752 sync_pipe_signame(int sig)
1755 static char sigmsg_buf[6+1+3+1];
1764 sigmsg = "Interrupted";
1772 sigmsg = "Illegal instruction";
1776 sigmsg = "Trace trap";
1784 sigmsg = "Arithmetic exception";
1792 sigmsg = "Bus error";
1796 sigmsg = "Segmentation violation";
1799 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1800 Linux is POSIX compliant. These are not POSIX-defined signals ---
1801 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1803 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1804 were omitted from POSIX.1 because their behavior is
1805 implementation dependent and could not be adequately catego-
1806 rized. Conforming implementations may deliver these sig-
1807 nals, but must document the circumstances under which they
1808 are delivered and note any restrictions concerning their
1811 So we only check for SIGSYS on those systems that happen to
1812 implement them (a system can be POSIX-compliant and implement
1813 them, it's just that POSIX doesn't *require* a POSIX-compliant
1814 system to implement them).
1819 sigmsg = "Bad system call";
1824 sigmsg = "Broken pipe";
1828 sigmsg = "Alarm clock";
1832 sigmsg = "Terminated";
1836 /* Returning a static buffer is ok in the context we use it here */
1837 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1838 sigmsg = sigmsg_buf;
1847 /* tell the child through the signal pipe that we want to quit the capture */
1849 signal_pipe_capquit_to_child(capture_options *capture_opts)
1851 const char quit_msg[] = "QUIT";
1855 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1857 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1858 /* simply sending a "QUIT" string */
1859 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1860 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1862 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1863 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1869 /* user wants to stop the capture run */
1871 sync_pipe_stop(capture_options *capture_opts)
1876 gboolean terminate = TRUE;
1879 if (capture_opts->fork_child != -1) {
1881 /* send the SIGINT signal to close the capture child gracefully. */
1882 int sts = kill(capture_opts->fork_child, SIGINT);
1884 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1885 "Sending SIGINT to child failed: %s\n", strerror(errno));
1888 #define STOP_SLEEP_TIME 500 /* ms */
1889 #define STOP_CHECK_TIME 50
1890 /* First, use the special signal pipe to try to close the capture child
1893 signal_pipe_capquit_to_child(capture_opts);
1895 /* Next, wait for the process to exit on its own */
1896 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1897 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1898 childstatus != STILL_ACTIVE) {
1902 Sleep(STOP_CHECK_TIME);
1905 /* Force the issue. */
1907 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1908 "sync_pipe_stop: forcing child to exit");
1909 sync_pipe_kill(capture_opts->fork_child);
1916 /* Wireshark has to exit, force the capture child to close */
1918 sync_pipe_kill(int fork_child)
1920 if (fork_child != -1) {
1922 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1924 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1925 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1928 /* Remark: This is not the preferred method of closing a process!
1929 * the clean way would be getting the process id of the child process,
1930 * then getting window handle hWnd of that process (using EnumChildWindows),
1931 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1933 * Unfortunately, I don't know how to get the process id from the
1934 * handle. OpenProcess will get an handle (not a window handle)
1935 * from the process ID; it will not get a window handle from the
1936 * process ID. (How could it? A process can have more than one
1937 * window. For that matter, a process might have *no* windows,
1938 * as a process running dumpcap, the normal child process program,
1941 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1942 * running in the same console; that's not necessarily the case for
1943 * us, as we might not be running in a console.
1944 * And this also will require to have the process id.
1946 TerminateProcess((HANDLE) (fork_child), 0);
1951 #endif /* HAVE_LIBPCAP */