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;
366 if (capture_opts->ifaces->len > 1)
367 capture_opts->use_pcapng = TRUE;
368 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
369 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
371 capture_opts->fork_child = -1;
373 argv = init_pipe_args(&argc);
375 /* We don't know where to find dumpcap. */
376 report_failure("We don't know where to find dumpcap.");
380 if (capture_opts->ifaces->len > 1)
381 argv = sync_pipe_add_arg(argv, &argc, "-t");
383 if (capture_opts->use_pcapng)
384 argv = sync_pipe_add_arg(argv, &argc, "-n");
386 if (capture_opts->multi_files_on) {
387 if (capture_opts->has_autostop_filesize) {
388 argv = sync_pipe_add_arg(argv, &argc, "-b");
389 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
390 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
393 if (capture_opts->has_file_duration) {
394 argv = sync_pipe_add_arg(argv, &argc, "-b");
395 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
396 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
399 if (capture_opts->has_ring_num_files) {
400 argv = sync_pipe_add_arg(argv, &argc, "-b");
401 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
402 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
405 if (capture_opts->has_autostop_files) {
406 argv = sync_pipe_add_arg(argv, &argc, "-a");
407 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
408 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
411 if (capture_opts->has_autostop_filesize) {
412 argv = sync_pipe_add_arg(argv, &argc, "-a");
413 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
414 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
418 if (capture_opts->has_autostop_packets) {
419 argv = sync_pipe_add_arg(argv, &argc, "-c");
420 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
421 argv = sync_pipe_add_arg(argv, &argc, scount);
424 if (capture_opts->has_autostop_duration) {
425 argv = sync_pipe_add_arg(argv, &argc, "-a");
426 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
427 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
429 if (capture_opts->ifaces->len == 0) {
431 interface_opts.name = g_strdup(capture_opts->iface);
432 if (capture_opts->iface_descr) {
433 interface_opts.descr = g_strdup(capture_opts->iface_descr);
435 interface_opts.descr = NULL;
437 interface_opts.cfilter = g_strdup(capture_opts->cfilter);
438 interface_opts.snaplen = capture_opts->snaplen;
439 interface_opts.linktype = capture_opts->linktype;
440 interface_opts.promisc_mode = capture_opts->promisc_mode;
441 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
442 interface_opts.buffer_size = capture_opts->buffer_size;
444 interface_opts.monitor_mode = capture_opts->monitor_mode;
445 #ifdef HAVE_PCAP_REMOTE
446 interface_opts.src_type = capture_opts->src_type;
447 if (capture_opts->remote_host) {
448 interface_opts.remote_host = g_strdup(capture_opts->remote_host);
450 interface_opts.remote_host = NULL;
452 if (capture_opts->remote_port) {
453 interface_opts.remote_port = g_strdup(capture_opts->remote_port);
455 interface_opts.remote_port = NULL;
457 interface_opts.auth_type = capture_opts->auth_type;
458 if (capture_opts->auth_username) {
459 interface_opts.auth_username = g_strdup(capture_opts->auth_username);
461 interface_opts.auth_username = NULL;
463 if (capture_opts->auth_password) {
464 interface_opts.auth_password = g_strdup(capture_opts->auth_password);
466 interface_opts.auth_password = NULL;
468 interface_opts.datatx_udp = capture_opts->datatx_udp;
469 interface_opts.nocap_rpcap = capture_opts->nocap_rpcap;
470 interface_opts.nocap_local = capture_opts->nocap_local;
472 #ifdef HAVE_PCAP_SETSAMPLING
473 interface_opts.sampling_method = capture_opts->sampling_method;
474 interface_opts.sampling_param = capture_opts->sampling_param;
476 g_array_append_val(capture_opts->ifaces, interface_opts);
481 for (j = 0; j < capture_opts->ifaces->len; j++) {
482 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
484 argv = sync_pipe_add_arg(argv, &argc, "-i");
485 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
487 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
488 argv = sync_pipe_add_arg(argv, &argc, "-f");
489 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
492 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
493 argv = sync_pipe_add_arg(argv, &argc, "-s");
494 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
495 argv = sync_pipe_add_arg(argv, &argc, ssnap);
498 if (interface_opts.linktype != -1) {
499 argv = sync_pipe_add_arg(argv, &argc, "-y");
500 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
501 argv = sync_pipe_add_arg(argv, &argc, sdlt);
504 if (!interface_opts.promisc_mode) {
505 argv = sync_pipe_add_arg(argv, &argc, "-p");
508 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
509 if (interface_opts.buffer_size != 1) {
510 argv = sync_pipe_add_arg(argv, &argc, "-B");
511 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
512 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
516 if (interface_opts.monitor_mode) {
517 argv = sync_pipe_add_arg(argv, &argc, "-I");
520 #ifdef HAVE_PCAP_REMOTE
521 if (interface_opts.datatx_udp)
522 argv = sync_pipe_add_arg(argv, &argc, "-u");
524 if (!interface_opts.nocap_rpcap)
525 argv = sync_pipe_add_arg(argv, &argc, "-r");
527 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
528 argv = sync_pipe_add_arg(argv, &argc, "-A");
529 g_snprintf(sauth, sizeof(sauth), "%s:%s",
530 interface_opts.auth_username,
531 interface_opts.auth_password);
532 argv = sync_pipe_add_arg(argv, &argc, sauth);
536 #ifdef HAVE_PCAP_SETSAMPLING
537 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
538 argv = sync_pipe_add_arg(argv, &argc, "-m");
539 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
540 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
541 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
543 interface_opts.sampling_param);
544 argv = sync_pipe_add_arg(argv, &argc, ssampling);
549 capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
552 /* dumpcap should be running in capture child mode (hidden feature) */
554 argv = sync_pipe_add_arg(argv, &argc, "-Z");
556 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
557 argv = sync_pipe_add_arg(argv, &argc, control_id);
559 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
563 if (capture_opts->save_file) {
564 argv = sync_pipe_add_arg(argv, &argc, "-w");
565 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
567 for (i = 0; i < argc; i++) {
568 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
572 /* init SECURITY_ATTRIBUTES */
573 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
574 sa.bInheritHandle = TRUE;
575 sa.lpSecurityDescriptor = NULL;
577 /* Create a pipe for the child process */
578 /* (increase this value if you have trouble while fast capture file switches) */
579 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
580 /* Couldn't create the pipe between parent and child. */
581 report_failure("Couldn't create sync pipe: %s",
582 win32strerror(GetLastError()));
583 g_free( (gpointer) argv[0]);
584 g_free( (gpointer) argv);
588 /* Create the signal pipe */
589 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
590 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
591 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
592 g_free(signal_pipe_name);
594 if (signal_pipe == INVALID_HANDLE_VALUE) {
595 /* Couldn't create the signal pipe between parent and child. */
596 report_failure("Couldn't create signal pipe: %s",
597 win32strerror(GetLastError()));
598 g_free( (gpointer) argv[0]);
599 g_free( (gpointer) argv);
603 /* init STARTUPINFO */
604 memset(&si, 0, sizeof(si));
607 si.dwFlags = STARTF_USESHOWWINDOW;
608 si.wShowWindow = SW_SHOW;
610 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
611 si.wShowWindow = SW_HIDE; /* this hides the console window */
612 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
613 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
614 si.hStdError = sync_pipe_write;
615 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
618 /* convert args array into a single string */
619 /* XXX - could change sync_pipe_add_arg() instead */
620 /* there is a drawback here: the length is internally limited to 1024 bytes */
621 for(i=0; argv[i] != 0; i++) {
622 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
623 quoted_arg = protect_arg(argv[i]);
624 g_string_append(args, quoted_arg);
629 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
630 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
631 report_failure("Couldn't run %s in child process: %s",
632 args->str, win32strerror(GetLastError()));
633 CloseHandle(sync_pipe_read);
634 CloseHandle(sync_pipe_write);
635 g_free( (gpointer) argv[0]);
636 g_free( (gpointer) argv);
639 capture_opts->fork_child = (int) pi.hProcess;
640 g_string_free(args, TRUE);
642 /* associate the operating system filehandle to a C run-time file handle */
643 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
644 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
646 /* associate the operating system filehandle to a C run-time file handle */
647 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
650 if (pipe(sync_pipe) < 0) {
651 /* Couldn't create the pipe between parent and child. */
652 report_failure("Couldn't create sync pipe: %s", strerror(errno));
653 g_free( (gpointer) argv[0]);
658 if ((capture_opts->fork_child = fork()) == 0) {
660 * Child process - run dumpcap with the right arguments to make
661 * it just capture with the specified capture parameters
663 dup2(sync_pipe[PIPE_WRITE], 2);
664 ws_close(sync_pipe[PIPE_READ]);
665 execv(argv[0], (gpointer)argv);
666 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
667 argv[0], strerror(errno));
668 sync_pipe_errmsg_to_parent(2, errmsg, "");
670 /* Exit with "_exit()", so that we don't close the connection
671 to the X server (and cause stuff buffered up by our parent but
672 not yet sent to be sent, as that stuff should only be sent by
673 our parent). We've sent an error message to the parent, so
674 we exit with an exit status of 1 (any exit status other than
675 0 or 1 will cause an additional message to report that exit
676 status, over and above the error message we sent to the parent). */
680 sync_pipe_read_fd = sync_pipe[PIPE_READ];
683 g_free( (gpointer) argv[0]); /* exename */
685 /* Parent process - read messages from the child process over the
687 g_free( (gpointer) argv); /* free up arg array */
689 /* Close the write side of the pipe, so that only the child has it
690 open, and thus it completely closes, and thus returns to us
691 an EOF indication, if the child closes it (either deliberately
692 or by exiting abnormally). */
694 CloseHandle(sync_pipe_write);
696 ws_close(sync_pipe[PIPE_WRITE]);
699 if (capture_opts->fork_child == -1) {
700 /* We couldn't even create the child process. */
701 report_failure("Couldn't create child process: %s", strerror(errno));
702 ws_close(sync_pipe_read_fd);
704 ws_close(capture_opts->signal_pipe_write_fd);
709 capture_opts->fork_child_status = 0;
711 /* we might wait for a moment till child is ready, so update screen now */
712 main_window_update();
714 /* We were able to set up to read the capture file;
715 arrange that our callback be called whenever it's possible
716 to read from the sync pipe, so that it's called when
717 the child process wants to tell us something. */
719 /* we have a running capture, now wait for the real capture filename */
720 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
721 &capture_opts->fork_child, sync_pipe_input_cb);
727 * Open two pipes to dumpcap with the supplied arguments, one for its
728 * standard output and one for its standard error.
730 * On success, *msg is unchanged and 0 is returned; data_read_fd,
731 * messsage_read_fd, and fork_child point to the standard output pipe's
732 * file descriptor, the standard error pipe's file descriptor, and
733 * the child's PID/handle, respectively.
735 * On failure, *msg points to an error message for the failure, and -1 is
736 * returned, in which case *msg must be freed with g_free().
738 /* XXX - This duplicates a lot of code in sync_pipe_start() */
739 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
740 #define PIPE_BUF_SIZE 5120
742 sync_pipe_open_command(const char** argv, int *data_read_fd,
743 int *message_read_fd, int *fork_child, gchar **msg)
745 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
747 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
748 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
749 GString *args = g_string_sized_new(200);
751 SECURITY_ATTRIBUTES sa;
753 PROCESS_INFORMATION pi;
757 int sync_pipe[2]; /* pipe used to send messages from child to parent */
758 int data_pipe[2]; /* pipe used to send data from child to parent */
763 *message_read_fd = -1;
764 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
767 /* We can't return anything */
769 g_string_free(args, TRUE);
775 /* init SECURITY_ATTRIBUTES */
776 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
777 sa.bInheritHandle = TRUE;
778 sa.lpSecurityDescriptor = NULL;
780 /* Create a pipe for the child process to send us messages */
781 /* (increase this value if you have trouble while fast capture file switches) */
782 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
783 /* Couldn't create the message pipe between parent and child. */
784 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
785 win32strerror(GetLastError()));
786 g_free( (gpointer) argv[0]);
787 g_free( (gpointer) argv);
791 /* Create a pipe for the child process to send us data */
792 /* (increase this value if you have trouble while fast capture file switches) */
793 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
794 /* Couldn't create the message pipe between parent and child. */
795 *msg = g_strdup_printf("Couldn't create data pipe: %s",
796 win32strerror(GetLastError()));
797 CloseHandle(sync_pipe[PIPE_READ]);
798 CloseHandle(sync_pipe[PIPE_WRITE]);
799 g_free( (gpointer) argv[0]);
800 g_free( (gpointer) argv);
804 /* init STARTUPINFO */
805 memset(&si, 0, sizeof(si));
808 si.dwFlags = STARTF_USESHOWWINDOW;
809 si.wShowWindow = SW_SHOW;
811 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
812 si.wShowWindow = SW_HIDE; /* this hides the console window */
814 si.hStdOutput = data_pipe[PIPE_WRITE];
815 si.hStdError = sync_pipe[PIPE_WRITE];
818 /* convert args array into a single string */
819 /* XXX - could change sync_pipe_add_arg() instead */
820 /* there is a drawback here: the length is internally limited to 1024 bytes */
821 for(i=0; argv[i] != 0; i++) {
822 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
823 quoted_arg = protect_arg(argv[i]);
824 g_string_append(args, quoted_arg);
829 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
830 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
831 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
832 args->str, win32strerror(GetLastError()));
833 CloseHandle(data_pipe[PIPE_READ]);
834 CloseHandle(data_pipe[PIPE_WRITE]);
835 CloseHandle(sync_pipe[PIPE_READ]);
836 CloseHandle(sync_pipe[PIPE_WRITE]);
837 g_free( (gpointer) argv[0]);
838 g_free( (gpointer) argv);
841 *fork_child = (int) pi.hProcess;
842 g_string_free(args, TRUE);
844 /* associate the operating system filehandles to C run-time file handles */
845 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
846 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
847 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
849 /* Create a pipe for the child process to send us messages */
850 if (pipe(sync_pipe) < 0) {
851 /* Couldn't create the message pipe between parent and child. */
852 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
853 g_free( (gpointer) argv[0]);
858 /* Create a pipe for the child process to send us data */
859 if (pipe(data_pipe) < 0) {
860 /* Couldn't create the data pipe between parent and child. */
861 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
862 ws_close(sync_pipe[PIPE_READ]);
863 ws_close(sync_pipe[PIPE_WRITE]);
864 g_free( (gpointer) argv[0]);
869 if ((*fork_child = fork()) == 0) {
871 * Child process - run dumpcap with the right arguments to make
872 * it just capture with the specified capture parameters
874 dup2(data_pipe[PIPE_WRITE], 1);
875 ws_close(data_pipe[PIPE_READ]);
876 ws_close(data_pipe[PIPE_WRITE]);
877 dup2(sync_pipe[PIPE_WRITE], 2);
878 ws_close(sync_pipe[PIPE_READ]);
879 ws_close(sync_pipe[PIPE_WRITE]);
880 execv(argv[0], (gpointer)argv);
881 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
882 argv[0], strerror(errno));
883 sync_pipe_errmsg_to_parent(2, errmsg, "");
885 /* Exit with "_exit()", so that we don't close the connection
886 to the X server (and cause stuff buffered up by our parent but
887 not yet sent to be sent, as that stuff should only be sent by
888 our parent). We've sent an error message to the parent, so
889 we exit with an exit status of 1 (any exit status other than
890 0 or 1 will cause an additional message to report that exit
891 status, over and above the error message we sent to the parent). */
895 *data_read_fd = data_pipe[PIPE_READ];
896 *message_read_fd = sync_pipe[PIPE_READ];
899 g_free( (gpointer) argv[0]); /* exename */
901 /* Parent process - read messages from the child process over the
903 g_free( (gpointer) argv); /* free up arg array */
905 /* Close the write sides of the pipes, so that only the child has them
906 open, and thus they completely close, and thus return to us
907 an EOF indication, if the child closes them (either deliberately
908 or by exiting abnormally). */
910 CloseHandle(data_pipe[PIPE_WRITE]);
911 CloseHandle(sync_pipe[PIPE_WRITE]);
913 ws_close(data_pipe[PIPE_WRITE]);
914 ws_close(sync_pipe[PIPE_WRITE]);
917 if (*fork_child == -1) {
918 /* We couldn't even create the child process. */
919 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
920 ws_close(*data_read_fd);
921 ws_close(*message_read_fd);
925 /* we might wait for a moment till child is ready, so update screen now */
926 main_window_update();
931 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
932 * returned. On failure, *msg points to an error message for the
933 * failure, and -1 is returned. In the latter case, *msg must be
934 * freed with g_free().
937 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
938 int *fork_child, gchar **msg)
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, msg);
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(const char** argv, gchar **data, gchar **primary_msg,
969 gchar **secondary_msg)
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,
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(buffer, 4, &indicator, &primary_msg_len);
1048 primary_msg_text = buffer+4;
1049 /* convert secondary message */
1050 pipe_convert_header(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;
1141 * Get the list of interfaces using dumpcap.
1143 * On success, *data points to a buffer containing the dumpcap output,
1144 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1145 * must be freed with g_free().
1147 * On failure, *data is NULL, *primary_msg points to an error message,
1148 * *secondary_msg either points to an additional error message or is
1149 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1150 * must be freed with g_free().
1153 sync_interface_list_open(gchar **data, gchar **primary_msg,
1154 gchar **secondary_msg)
1159 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1161 argv = init_pipe_args(&argc);
1164 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1165 *secondary_msg = NULL;
1170 /* Ask for the interface list */
1171 argv = sync_pipe_add_arg(argv, &argc, "-D");
1174 /* Run dumpcap in capture child mode */
1175 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1176 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1178 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1182 * Get the capabilities of an interface using dumpcap.
1184 * On success, *data points to a buffer containing the dumpcap output,
1185 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1186 * must be freed with g_free().
1188 * On failure, *data is NULL, *primary_msg points to an error message,
1189 * *secondary_msg either points to an additional error message or is
1190 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1191 * must be freed with g_free().
1194 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1195 gchar **data, gchar **primary_msg,
1196 gchar **secondary_msg)
1201 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1203 argv = init_pipe_args(&argc);
1206 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1207 *secondary_msg = NULL;
1212 /* Ask for the interface capabilities */
1213 argv = sync_pipe_add_arg(argv, &argc, "-i");
1214 argv = sync_pipe_add_arg(argv, &argc, ifname);
1215 argv = sync_pipe_add_arg(argv, &argc, "-L");
1217 argv = sync_pipe_add_arg(argv, &argc, "-I");
1220 /* Run dumpcap in capture child mode */
1221 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1222 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1224 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1228 * Start getting interface statistics using dumpcap. On success, read_fd
1229 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1230 * and zero is returned. On failure, *msg will point to an error message
1231 * that must be g_free()d, and -1 will be returned.
1234 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1238 int message_read_fd, ret;
1240 gchar buffer[PIPE_BUF_SIZE+1];
1243 int primary_msg_len;
1244 char *primary_msg_text;
1245 int secondary_msg_len;
1246 char *secondary_msg_text;
1249 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1251 argv = init_pipe_args(&argc);
1254 *msg = g_strdup("We don't know where to find dumpcap.");
1258 /* Ask for the interface statistics */
1259 argv = sync_pipe_add_arg(argv, &argc, "-S");
1262 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1263 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1265 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1271 * We were able to set up to read dumpcap's output. Do so.
1273 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1275 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1278 /* We got a read error from the sync pipe, or we got no data at
1279 all from the sync pipe, so we're not going to be getting any
1280 data or error message from the child process. Pick up its
1281 exit status, and complain.
1283 We don't have to worry about killing the child, if the sync pipe
1284 returned an error. Usually this error is caused as the child killed
1285 itself while going down. Even in the rare cases that this isn't the
1286 case, the child will get an error when writing to the broken pipe
1287 the next time, cleaning itself up then. */
1288 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1290 /* We got an EOF from the sync pipe. That means that it exited
1291 before giving us any data to read. If ret is -1, we report
1292 that as a bad exit (e.g., exiting due to a signal); otherwise,
1293 we report it as a premature exit. */
1297 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1299 /* We got an error from the sync pipe. If ret is -1, report
1300 both the sync pipe I/O error and the wait error. */
1302 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1305 *msg = combined_msg;
1312 /* we got a valid message block from the child, process it */
1317 * Error from dumpcap; there will be a primary message and a
1318 * secondary message.
1321 /* convert primary message */
1322 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1323 primary_msg_text = buffer+4;
1324 /* convert secondary message */
1325 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1326 &secondary_msg_len);
1327 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1328 /* the capture child will close the sync_pipe, nothing to do */
1331 * Pick up the child status.
1333 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1337 * Child process failed unexpectedly, or wait failed; msg is the
1342 * Child process failed, but returned the expected exit status.
1343 * Return the messages it gave us, and indicate failure.
1345 *msg = g_strdup(primary_msg_text);
1351 /* Close the message pipe. */
1352 ws_close(message_read_fd);
1357 * Pick up the child status.
1359 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1363 * Child process failed unexpectedly, or wait failed; msg is the
1368 * Child process returned an unknown status.
1370 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1379 /* Close down the stats process */
1381 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1383 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1386 /* read a number of bytes from a pipe */
1387 /* (blocks until enough bytes read or an error occurs) */
1389 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1396 newly = read(pipe_fd, &bytes[offset], required);
1399 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1400 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1407 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1408 "read from pipe %d: error(%u): %s", pipe_fd, error,
1410 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1423 static gboolean pipe_data_available(int pipe_fd) {
1424 #ifdef _WIN32 /* PeekNamedPipe */
1425 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1428 if (hPipe == INVALID_HANDLE_VALUE)
1431 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1434 if (bytes_avail > 0)
1439 struct timeval timeout;
1442 FD_SET(pipe_fd, &rfds);
1444 timeout.tv_usec = 0;
1446 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1453 /* Read a line from a pipe, similar to fgets */
1455 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1459 while(offset < max - 1) {
1461 if (! pipe_data_available(pipe_fd))
1463 newly = read(pipe_fd, &bytes[offset], 1);
1465 /* EOF - not necessarily an error */
1467 } else if (newly < 0) {
1469 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1470 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1472 } else if (bytes[offset] == '\n') {
1478 bytes[offset] = '\0';
1484 /* convert header values (indicator and 3-byte length) */
1486 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1488 g_assert(header_len == 4);
1490 /* convert header values */
1491 *indicator = header[0];
1492 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1495 /* read a message from the sending pipe in the standard format
1496 (1-byte message indicator, 3-byte message length (excluding length
1497 and indicator field), and the rest is the message) */
1499 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1506 /* read header (indicator and 3-byte length) */
1507 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1511 * Immediate EOF; if the capture child exits normally, this
1512 * is an "I'm done" indication, so don't report it as an
1515 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1516 "read %d got an EOF", pipe_fd);
1519 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1520 "read %d failed to read header: %u", pipe_fd, newly);
1523 * Short read, but not an immediate EOF.
1525 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
1531 /* convert header values */
1532 pipe_convert_header(header, 4, indicator, &required);
1534 /* only indicator with no value? */
1536 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1537 "read %d indicator: %c empty value", pipe_fd, *indicator);
1541 /* does the data fit into the given buffer? */
1542 if(required > len) {
1543 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1544 "read %d length error, required %d > len %d, indicator: %u",
1545 pipe_fd, required, len, *indicator);
1547 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1548 memcpy(msg, header, sizeof(header));
1549 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1550 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1556 /* read the actual block data */
1557 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1558 if(newly != required) {
1560 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1566 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1567 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1568 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1575 /* There's stuff to read from the sync pipe, meaning the child has sent
1576 us a message, or the sync pipe has closed, meaning the child has
1577 closed it (perhaps because it exited). */
1579 sync_pipe_input_cb(gint source, gpointer user_data)
1581 capture_options *capture_opts = (capture_options *)user_data;
1583 char buffer[SP_MAX_MSG_LEN+1];
1589 char *secondary_msg;
1590 char *wait_msg, *combined_msg;
1592 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1595 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1597 If we got a read error or a bad message, nread is -1 and
1598 primary_msg is set to point to an error message. We don't
1599 have to worry about killing the child; usually this error
1600 is caused as the child killed itself while going down.
1601 Even in the rare cases that this isn't the case, the child
1602 will get an error when writing to the broken pipe the next time,
1603 cleaning itself up then.
1605 If we got an EOF, nread is 0 and primary_msg isn't set. This
1606 is an indication that the capture is finished. */
1607 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
1609 /* We got an EOF from the sync pipe. That means that the capture
1610 child exited, and not in the middle of a message; we treat
1611 that as an indication that it's done, and only report an
1612 error if ret is -1, in which case wait_msg is the error
1615 primary_msg = wait_msg;
1617 /* We got an error from the sync pipe. If ret is -1, report
1618 both the sync pipe I/O error and the wait error. */
1620 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1621 g_free(primary_msg);
1623 primary_msg = combined_msg;
1627 /* No more child process. */
1628 capture_opts->fork_child = -1;
1629 capture_opts->fork_child_status = ret;
1632 ws_close(capture_opts->signal_pipe_write_fd);
1634 capture_input_closed(capture_opts, primary_msg);
1635 g_free(primary_msg);
1639 /* we got a valid message block from the child, process it */
1642 if(!capture_input_new_file(capture_opts, buffer)) {
1643 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1645 /* We weren't able to open the new capture file; user has been
1646 alerted. Close the sync pipe. */
1649 /* the child has send us a filename which we couldn't open.
1650 this probably means, the child is creating files faster than we can handle it.
1651 this should only be the case for very fast file switches
1652 we can't do much more than telling the child to stop
1653 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1654 sync_pipe_stop(capture_opts);
1657 case SP_PACKET_COUNT:
1658 nread = atoi(buffer);
1659 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1660 capture_input_new_packets(capture_opts, nread);
1663 /* convert primary message */
1664 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1665 primary_msg = buffer+4;
1666 /* convert secondary message */
1667 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1668 secondary_msg = primary_msg + primary_len + 4;
1669 /* message output */
1670 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1671 /* the capture child will close the sync_pipe, nothing to do for now */
1672 /* (an error message doesn't mean we have to stop capturing) */
1675 capture_input_cfilter_error_message(capture_opts, buffer);
1676 /* the capture child will close the sync_pipe, nothing to do for now */
1679 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1682 g_assert_not_reached();
1690 /* the child process is going down, wait until it's completely terminated */
1692 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1694 int fork_child_status;
1697 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1698 g_assert(fork_child != -1);
1700 *msgp = NULL; /* assume no error */
1703 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1704 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1708 * The child exited; return its exit status. Do not treat this as
1711 ret = fork_child_status;
1712 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1713 /* Probably an exception code */
1714 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1715 win32strexception(fork_child_status));
1720 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1721 if (WIFEXITED(fork_child_status)) {
1723 * The child exited; return its exit status. Do not treat this as
1726 ret = WEXITSTATUS(fork_child_status);
1727 } else if (WIFSTOPPED(fork_child_status)) {
1728 /* It stopped, rather than exiting. "Should not happen." */
1729 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1730 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1732 } else if (WIFSIGNALED(fork_child_status)) {
1733 /* It died with a signal. */
1734 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1735 sync_pipe_signame(WTERMSIG(fork_child_status)),
1736 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1739 /* What? It had to either have exited, or stopped, or died with
1740 a signal; what happened here? */
1741 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1746 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1751 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1757 /* convert signal to corresponding name */
1759 sync_pipe_signame(int sig)
1762 static char sigmsg_buf[6+1+3+1];
1771 sigmsg = "Interrupted";
1779 sigmsg = "Illegal instruction";
1783 sigmsg = "Trace trap";
1791 sigmsg = "Arithmetic exception";
1799 sigmsg = "Bus error";
1803 sigmsg = "Segmentation violation";
1806 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1807 Linux is POSIX compliant. These are not POSIX-defined signals ---
1808 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1810 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1811 were omitted from POSIX.1 because their behavior is
1812 implementation dependent and could not be adequately catego-
1813 rized. Conforming implementations may deliver these sig-
1814 nals, but must document the circumstances under which they
1815 are delivered and note any restrictions concerning their
1818 So we only check for SIGSYS on those systems that happen to
1819 implement them (a system can be POSIX-compliant and implement
1820 them, it's just that POSIX doesn't *require* a POSIX-compliant
1821 system to implement them).
1826 sigmsg = "Bad system call";
1831 sigmsg = "Broken pipe";
1835 sigmsg = "Alarm clock";
1839 sigmsg = "Terminated";
1843 /* Returning a static buffer is ok in the context we use it here */
1844 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1845 sigmsg = sigmsg_buf;
1854 /* tell the child through the signal pipe that we want to quit the capture */
1856 signal_pipe_capquit_to_child(capture_options *capture_opts)
1858 const char quit_msg[] = "QUIT";
1862 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1864 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1865 /* simply sending a "QUIT" string */
1866 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1867 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1869 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1870 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1876 /* user wants to stop the capture run */
1878 sync_pipe_stop(capture_options *capture_opts)
1883 gboolean terminate = TRUE;
1886 if (capture_opts->fork_child != -1) {
1888 /* send the SIGINT signal to close the capture child gracefully. */
1889 int sts = kill(capture_opts->fork_child, SIGINT);
1891 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1892 "Sending SIGINT to child failed: %s\n", strerror(errno));
1895 #define STOP_SLEEP_TIME 500 /* ms */
1896 #define STOP_CHECK_TIME 50
1897 /* First, use the special signal pipe to try to close the capture child
1900 signal_pipe_capquit_to_child(capture_opts);
1902 /* Next, wait for the process to exit on its own */
1903 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1904 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1905 childstatus != STILL_ACTIVE) {
1909 Sleep(STOP_CHECK_TIME);
1912 /* Force the issue. */
1914 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1915 "sync_pipe_stop: forcing child to exit");
1916 sync_pipe_kill(capture_opts->fork_child);
1923 /* Wireshark has to exit, force the capture child to close */
1925 sync_pipe_kill(int fork_child)
1927 if (fork_child != -1) {
1929 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1931 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1932 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1935 /* Remark: This is not the preferred method of closing a process!
1936 * the clean way would be getting the process id of the child process,
1937 * then getting window handle hWnd of that process (using EnumChildWindows),
1938 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1940 * Unfortunately, I don't know how to get the process id from the
1941 * handle. OpenProcess will get an handle (not a window handle)
1942 * from the process ID; it will not get a window handle from the
1943 * process ID. (How could it? A process can have more than one
1944 * window. For that matter, a process might have *no* windows,
1945 * as a process running dumpcap, the normal child process program,
1948 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1949 * running in the same console; that's not necessarily the case for
1950 * us, as we might not be running in a console.
1951 * And this also will require to have the process id.
1953 TerminateProcess((HANDLE) (fork_child), 0);
1958 #endif /* HAVE_LIBPCAP */