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];
337 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
338 char buffer_size[ARGV_NUMBER_LEN];
341 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
342 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
343 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
344 GString *args = g_string_sized_new(200);
346 SECURITY_ATTRIBUTES sa;
348 PROCESS_INFORMATION pi;
350 char control_id[ARGV_NUMBER_LEN];
351 gchar *signal_pipe_name;
354 int sync_pipe[2]; /* pipe used to send messages from child to parent */
355 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
357 int sync_pipe_read_fd;
362 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
363 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
365 capture_opts->fork_child = -1;
367 argv = init_pipe_args(&argc);
369 /* We don't know where to find dumpcap. */
370 report_failure("We don't know where to find dumpcap.");
374 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
376 argv = sync_pipe_add_arg(argv, &argc, "-i");
377 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
379 if (capture_opts->has_snaplen) {
380 argv = sync_pipe_add_arg(argv, &argc, "-s");
381 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
382 argv = sync_pipe_add_arg(argv, &argc, ssnap);
385 if (capture_opts->linktype != -1) {
386 argv = sync_pipe_add_arg(argv, &argc, "-y");
387 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
388 argv = sync_pipe_add_arg(argv, &argc, sdlt);
391 if(capture_opts->multi_files_on) {
392 if (capture_opts->has_autostop_filesize) {
393 argv = sync_pipe_add_arg(argv, &argc, "-b");
394 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
395 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
398 if (capture_opts->has_file_duration) {
399 argv = sync_pipe_add_arg(argv, &argc, "-b");
400 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
401 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
404 if (capture_opts->has_ring_num_files) {
405 argv = sync_pipe_add_arg(argv, &argc, "-b");
406 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
407 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
410 if (capture_opts->has_autostop_files) {
411 argv = sync_pipe_add_arg(argv, &argc, "-a");
412 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
413 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
416 if (capture_opts->has_autostop_filesize) {
417 argv = sync_pipe_add_arg(argv, &argc, "-a");
418 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
419 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
423 if (capture_opts->has_autostop_packets) {
424 argv = sync_pipe_add_arg(argv, &argc, "-c");
425 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
426 argv = sync_pipe_add_arg(argv, &argc, scount);
429 if (capture_opts->has_autostop_duration) {
430 argv = sync_pipe_add_arg(argv, &argc, "-a");
431 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
432 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
435 if (!capture_opts->promisc_mode)
436 argv = sync_pipe_add_arg(argv, &argc, "-p");
437 #ifdef HAVE_PCAP_CREATE
438 if (capture_opts->monitor_mode)
439 argv = sync_pipe_add_arg(argv, &argc, "-I");
441 if (capture_opts->use_pcapng)
442 argv = sync_pipe_add_arg(argv, &argc, "-n");
443 #ifdef HAVE_PCAP_REMOTE
444 if (capture_opts->datatx_udp)
445 argv = sync_pipe_add_arg(argv, &argc, "-u");
447 if (!capture_opts->nocap_rpcap)
448 argv = sync_pipe_add_arg(argv, &argc, "-r");
450 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
452 argv = sync_pipe_add_arg(argv, &argc, "-A");
453 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
454 capture_opts->auth_password);
455 argv = sync_pipe_add_arg(argv, &argc, sauth);
458 #ifdef HAVE_PCAP_SETSAMPLING
459 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
461 argv = sync_pipe_add_arg(argv, &argc, "-m");
462 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
463 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
464 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
466 capture_opts->sampling_param);
467 argv = sync_pipe_add_arg(argv, &argc, ssampling);
471 /* dumpcap should be running in capture child mode (hidden feature) */
473 argv = sync_pipe_add_arg(argv, &argc, "-Z");
475 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
476 argv = sync_pipe_add_arg(argv, &argc, control_id);
478 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
482 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
483 argv = sync_pipe_add_arg(argv, &argc, "-B");
484 #ifdef HAVE_PCAP_REMOTE
485 if (capture_opts->src_type == CAPTURE_IFREMOTE)
486 /* No buffer size when using remote interfaces */
487 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
490 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
491 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
494 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
495 argv = sync_pipe_add_arg(argv, &argc, "-f");
496 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
499 if(capture_opts->save_file) {
500 argv = sync_pipe_add_arg(argv, &argc, "-w");
501 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
505 /* init SECURITY_ATTRIBUTES */
506 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
507 sa.bInheritHandle = TRUE;
508 sa.lpSecurityDescriptor = NULL;
510 /* Create a pipe for the child process */
511 /* (increase this value if you have trouble while fast capture file switches) */
512 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
513 /* Couldn't create the pipe between parent and child. */
514 report_failure("Couldn't create sync pipe: %s",
515 win32strerror(GetLastError()));
516 g_free( (gpointer) argv[0]);
517 g_free( (gpointer) argv);
521 /* Create the signal pipe */
522 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
523 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
524 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
525 g_free(signal_pipe_name);
527 if (signal_pipe == INVALID_HANDLE_VALUE) {
528 /* Couldn't create the signal pipe between parent and child. */
529 report_failure("Couldn't create signal pipe: %s",
530 win32strerror(GetLastError()));
531 g_free( (gpointer) argv[0]);
532 g_free( (gpointer) argv);
536 /* init STARTUPINFO */
537 memset(&si, 0, sizeof(si));
540 si.dwFlags = STARTF_USESHOWWINDOW;
541 si.wShowWindow = SW_SHOW;
543 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
544 si.wShowWindow = SW_HIDE; /* this hides the console window */
545 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
546 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
547 si.hStdError = sync_pipe_write;
548 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
551 /* convert args array into a single string */
552 /* XXX - could change sync_pipe_add_arg() instead */
553 /* there is a drawback here: the length is internally limited to 1024 bytes */
554 for(i=0; argv[i] != 0; i++) {
555 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
556 quoted_arg = protect_arg(argv[i]);
557 g_string_append(args, quoted_arg);
562 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
563 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
564 report_failure("Couldn't run %s in child process: %s",
565 args->str, win32strerror(GetLastError()));
566 CloseHandle(sync_pipe_read);
567 CloseHandle(sync_pipe_write);
568 g_free( (gpointer) argv[0]);
569 g_free( (gpointer) argv);
572 capture_opts->fork_child = (int) pi.hProcess;
573 g_string_free(args, TRUE);
575 /* associate the operating system filehandle to a C run-time file handle */
576 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
577 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
579 /* associate the operating system filehandle to a C run-time file handle */
580 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
583 if (pipe(sync_pipe) < 0) {
584 /* Couldn't create the pipe between parent and child. */
585 report_failure("Couldn't create sync pipe: %s", strerror(errno));
586 g_free( (gpointer) argv[0]);
591 if ((capture_opts->fork_child = fork()) == 0) {
593 * Child process - run dumpcap with the right arguments to make
594 * it just capture with the specified capture parameters
596 dup2(sync_pipe[PIPE_WRITE], 2);
597 ws_close(sync_pipe[PIPE_READ]);
598 execv(argv[0], (gpointer)argv);
599 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
600 argv[0], strerror(errno));
601 sync_pipe_errmsg_to_parent(2, errmsg, "");
603 /* Exit with "_exit()", so that we don't close the connection
604 to the X server (and cause stuff buffered up by our parent but
605 not yet sent to be sent, as that stuff should only be sent by
606 our parent). We've sent an error message to the parent, so
607 we exit with an exit status of 1 (any exit status other than
608 0 or 1 will cause an additional message to report that exit
609 status, over and above the error message we sent to the parent). */
613 sync_pipe_read_fd = sync_pipe[PIPE_READ];
616 g_free( (gpointer) argv[0]); /* exename */
618 /* Parent process - read messages from the child process over the
620 g_free( (gpointer) argv); /* free up arg array */
622 /* Close the write side of the pipe, so that only the child has it
623 open, and thus it completely closes, and thus returns to us
624 an EOF indication, if the child closes it (either deliberately
625 or by exiting abnormally). */
627 CloseHandle(sync_pipe_write);
629 ws_close(sync_pipe[PIPE_WRITE]);
632 if (capture_opts->fork_child == -1) {
633 /* We couldn't even create the child process. */
634 report_failure("Couldn't create child process: %s", strerror(errno));
635 ws_close(sync_pipe_read_fd);
637 ws_close(capture_opts->signal_pipe_write_fd);
642 capture_opts->fork_child_status = 0;
644 /* we might wait for a moment till child is ready, so update screen now */
645 main_window_update();
647 /* We were able to set up to read the capture file;
648 arrange that our callback be called whenever it's possible
649 to read from the sync pipe, so that it's called when
650 the child process wants to tell us something. */
652 /* we have a running capture, now wait for the real capture filename */
653 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
654 &capture_opts->fork_child, sync_pipe_input_cb);
660 * Open two pipes to dumpcap with the supplied arguments, one for its
661 * standard output and one for its standard error.
663 * On success, *msg is unchanged and 0 is returned; data_read_fd,
664 * messsage_read_fd, and fork_child point to the standard output pipe's
665 * file descriptor, the standard error pipe's file descriptor, and
666 * the child's PID/handle, respectively.
668 * On failure, *msg points to an error message for the failure, and -1 is
669 * returned, in which case *msg must be freed with g_free().
671 /* XXX - This duplicates a lot of code in sync_pipe_start() */
672 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
673 #define PIPE_BUF_SIZE 5120
675 sync_pipe_open_command(const char** argv, int *data_read_fd,
676 int *message_read_fd, int *fork_child, gchar **msg)
678 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
680 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
681 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
682 GString *args = g_string_sized_new(200);
684 SECURITY_ATTRIBUTES sa;
686 PROCESS_INFORMATION pi;
690 int sync_pipe[2]; /* pipe used to send messages from child to parent */
691 int data_pipe[2]; /* pipe used to send data from child to parent */
696 *message_read_fd = -1;
697 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
700 /* We can't return anything */
702 g_string_free(args, TRUE);
708 /* init SECURITY_ATTRIBUTES */
709 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
710 sa.bInheritHandle = TRUE;
711 sa.lpSecurityDescriptor = NULL;
713 /* Create a pipe for the child process to send us messages */
714 /* (increase this value if you have trouble while fast capture file switches) */
715 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
716 /* Couldn't create the message pipe between parent and child. */
717 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
718 win32strerror(GetLastError()));
719 g_free( (gpointer) argv[0]);
720 g_free( (gpointer) argv);
724 /* Create a pipe for the child process to send us data */
725 /* (increase this value if you have trouble while fast capture file switches) */
726 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
727 /* Couldn't create the message pipe between parent and child. */
728 *msg = g_strdup_printf("Couldn't create data pipe: %s",
729 win32strerror(GetLastError()));
730 CloseHandle(sync_pipe[PIPE_READ]);
731 CloseHandle(sync_pipe[PIPE_WRITE]);
732 g_free( (gpointer) argv[0]);
733 g_free( (gpointer) argv);
737 /* init STARTUPINFO */
738 memset(&si, 0, sizeof(si));
741 si.dwFlags = STARTF_USESHOWWINDOW;
742 si.wShowWindow = SW_SHOW;
744 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
745 si.wShowWindow = SW_HIDE; /* this hides the console window */
747 si.hStdOutput = data_pipe[PIPE_WRITE];
748 si.hStdError = sync_pipe[PIPE_WRITE];
751 /* convert args array into a single string */
752 /* XXX - could change sync_pipe_add_arg() instead */
753 /* there is a drawback here: the length is internally limited to 1024 bytes */
754 for(i=0; argv[i] != 0; i++) {
755 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
756 quoted_arg = protect_arg(argv[i]);
757 g_string_append(args, quoted_arg);
762 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
763 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
764 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
765 args->str, win32strerror(GetLastError()));
766 CloseHandle(data_pipe[PIPE_READ]);
767 CloseHandle(data_pipe[PIPE_WRITE]);
768 CloseHandle(sync_pipe[PIPE_READ]);
769 CloseHandle(sync_pipe[PIPE_WRITE]);
770 g_free( (gpointer) argv[0]);
771 g_free( (gpointer) argv);
774 *fork_child = (int) pi.hProcess;
775 g_string_free(args, TRUE);
777 /* associate the operating system filehandles to C run-time file handles */
778 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
779 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
780 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
782 /* Create a pipe for the child process to send us messages */
783 if (pipe(sync_pipe) < 0) {
784 /* Couldn't create the message pipe between parent and child. */
785 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
786 g_free( (gpointer) argv[0]);
791 /* Create a pipe for the child process to send us data */
792 if (pipe(data_pipe) < 0) {
793 /* Couldn't create the data pipe between parent and child. */
794 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
795 ws_close(sync_pipe[PIPE_READ]);
796 ws_close(sync_pipe[PIPE_WRITE]);
797 g_free( (gpointer) argv[0]);
802 if ((*fork_child = fork()) == 0) {
804 * Child process - run dumpcap with the right arguments to make
805 * it just capture with the specified capture parameters
807 dup2(data_pipe[PIPE_WRITE], 1);
808 ws_close(data_pipe[PIPE_READ]);
809 ws_close(data_pipe[PIPE_WRITE]);
810 dup2(sync_pipe[PIPE_WRITE], 2);
811 ws_close(sync_pipe[PIPE_READ]);
812 ws_close(sync_pipe[PIPE_WRITE]);
813 execv(argv[0], (gpointer)argv);
814 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
815 argv[0], strerror(errno));
816 sync_pipe_errmsg_to_parent(2, errmsg, "");
818 /* Exit with "_exit()", so that we don't close the connection
819 to the X server (and cause stuff buffered up by our parent but
820 not yet sent to be sent, as that stuff should only be sent by
821 our parent). We've sent an error message to the parent, so
822 we exit with an exit status of 1 (any exit status other than
823 0 or 1 will cause an additional message to report that exit
824 status, over and above the error message we sent to the parent). */
828 *data_read_fd = data_pipe[PIPE_READ];
829 *message_read_fd = sync_pipe[PIPE_READ];
832 g_free( (gpointer) argv[0]); /* exename */
834 /* Parent process - read messages from the child process over the
836 g_free( (gpointer) argv); /* free up arg array */
838 /* Close the write sides of the pipes, so that only the child has them
839 open, and thus they completely close, and thus return to us
840 an EOF indication, if the child closes them (either deliberately
841 or by exiting abnormally). */
843 CloseHandle(data_pipe[PIPE_WRITE]);
844 CloseHandle(sync_pipe[PIPE_WRITE]);
846 ws_close(data_pipe[PIPE_WRITE]);
847 ws_close(sync_pipe[PIPE_WRITE]);
850 if (*fork_child == -1) {
851 /* We couldn't even create the child process. */
852 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
853 ws_close(*data_read_fd);
854 ws_close(*message_read_fd);
858 /* we might wait for a moment till child is ready, so update screen now */
859 main_window_update();
864 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
865 * returned. On failure, *msg points to an error message for the
866 * failure, and -1 is returned. In the latter case, *msg must be
867 * freed with g_free().
870 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
871 int *fork_child, gchar **msg)
873 ws_close(*data_read_fd);
874 if (message_read_fd != NULL)
875 ws_close(*message_read_fd);
878 /* XXX - Should we signal the child somehow? */
879 sync_pipe_kill(*fork_child);
882 return sync_pipe_wait_for_child(*fork_child, msg);
886 * Run dumpcap with the supplied arguments.
888 * On success, *data points to a buffer containing the dumpcap output,
889 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
890 * must be freed with g_free().
892 * On failure, *data is NULL, *primary_msg points to an error message,
893 * *secondary_msg either points to an additional error message or is
894 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
895 * must be freed with g_free().
897 /* XXX - This duplicates a lot of code in sync_pipe_start() */
898 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
899 #define PIPE_BUF_SIZE 5120
901 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
902 gchar **secondary_msg)
905 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
907 gchar buffer[PIPE_BUF_SIZE+1];
911 char *primary_msg_text;
912 int secondary_msg_len;
913 char *secondary_msg_text;
915 GString *data_buf = NULL;
918 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
922 *secondary_msg = NULL;
928 * We were able to set up to read dumpcap's output. Do so.
930 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
932 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
933 buffer, primary_msg);
935 /* We got a read error from the sync pipe, or we got no data at
936 all from the sync pipe, so we're not going to be getting any
937 data or error message from the child process. Pick up its
938 exit status, and complain.
940 We don't have to worry about killing the child, if the sync pipe
941 returned an error. Usually this error is caused as the child killed
942 itself while going down. Even in the rare cases that this isn't the
943 case, the child will get an error when writing to the broken pipe
944 the next time, cleaning itself up then. */
945 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
947 /* We got an EOF from the sync pipe. That means that it exited
948 before giving us any data to read. If ret is -1, we report
949 that as a bad exit (e.g., exiting due to a signal); otherwise,
950 we report it as a premature exit. */
952 *primary_msg = wait_msg;
954 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
956 /* We got an error from the sync pipe. If ret is -1, report
957 both the sync pipe I/O error and the wait error. */
959 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
960 g_free(*primary_msg);
962 *primary_msg = combined_msg;
965 *secondary_msg = NULL;
970 /* we got a valid message block from the child, process it */
975 * Error from dumpcap; there will be a primary message and a
979 /* convert primary message */
980 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
981 primary_msg_text = buffer+4;
982 /* convert secondary message */
983 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
985 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
986 /* the capture child will close the sync_pipe, nothing to do */
989 * Pick up the child status.
991 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
995 * Child process failed unexpectedly, or wait failed; msg is the
999 *secondary_msg = NULL;
1002 * Child process failed, but returned the expected exit status.
1003 * Return the messages it gave us, and indicate failure.
1005 *primary_msg = g_strdup(primary_msg_text);
1006 *secondary_msg = g_strdup(secondary_msg_text);
1013 /* read the output from the command */
1014 data_buf = g_string_new("");
1015 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1016 buffer[count] = '\0';
1017 g_string_append(data_buf, buffer);
1021 * Pick up the child status.
1023 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1027 * Child process failed unexpectedly, or wait failed; msg is the
1031 *secondary_msg = NULL;
1032 g_string_free(data_buf, TRUE);
1036 * Child process succeeded.
1038 *primary_msg = NULL;
1039 *secondary_msg = NULL;
1040 *data = data_buf->str;
1041 g_string_free(data_buf, FALSE);
1047 * Pick up the child status.
1049 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1053 * Child process failed unexpectedly, or wait failed; msg is the
1057 *secondary_msg = NULL;
1060 * Child process returned an unknown status.
1062 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1064 *secondary_msg = NULL;
1074 * Get the list of interfaces using dumpcap.
1076 * On success, *data points to a buffer containing the dumpcap output,
1077 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1078 * must be freed with g_free().
1080 * On failure, *data is NULL, *primary_msg points to an error message,
1081 * *secondary_msg either points to an additional error message or is
1082 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1083 * must be freed with g_free().
1086 sync_interface_list_open(gchar **data, gchar **primary_msg,
1087 gchar **secondary_msg)
1092 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1094 argv = init_pipe_args(&argc);
1097 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1098 *secondary_msg = NULL;
1103 /* Ask for the interface list */
1104 argv = sync_pipe_add_arg(argv, &argc, "-D");
1107 /* Run dumpcap in capture child mode */
1108 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1109 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1111 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1115 * Get the capabilities of an interface using dumpcap.
1117 * On success, *data points to a buffer containing the dumpcap output,
1118 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1119 * must be freed with g_free().
1121 * On failure, *data is NULL, *primary_msg points to an error message,
1122 * *secondary_msg either points to an additional error message or is
1123 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1124 * must be freed with g_free().
1127 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1128 gchar **data, gchar **primary_msg,
1129 gchar **secondary_msg)
1134 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1136 argv = init_pipe_args(&argc);
1139 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1140 *secondary_msg = NULL;
1145 /* Ask for the interface capabilities */
1146 argv = sync_pipe_add_arg(argv, &argc, "-i");
1147 argv = sync_pipe_add_arg(argv, &argc, ifname);
1148 argv = sync_pipe_add_arg(argv, &argc, "-L");
1150 argv = sync_pipe_add_arg(argv, &argc, "-I");
1153 /* Run dumpcap in capture child mode */
1154 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1155 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1157 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1161 * Start getting interface statistics using dumpcap. On success, read_fd
1162 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1163 * and zero is returned. On failure, *msg will point to an error message
1164 * that must be g_free()d, and -1 will be returned.
1167 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1171 int message_read_fd, ret;
1173 gchar buffer[PIPE_BUF_SIZE+1];
1176 int primary_msg_len;
1177 char *primary_msg_text;
1178 int secondary_msg_len;
1179 char *secondary_msg_text;
1182 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1184 argv = init_pipe_args(&argc);
1187 *msg = g_strdup("We don't know where to find dumpcap.");
1191 /* Ask for the interface statistics */
1192 argv = sync_pipe_add_arg(argv, &argc, "-S");
1195 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1196 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1198 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1204 * We were able to set up to read dumpcap's output. Do so.
1206 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1208 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1211 /* We got a read error from the sync pipe, or we got no data at
1212 all from the sync pipe, so we're not going to be getting any
1213 data or error message from the child process. Pick up its
1214 exit status, and complain.
1216 We don't have to worry about killing the child, if the sync pipe
1217 returned an error. Usually this error is caused as the child killed
1218 itself while going down. Even in the rare cases that this isn't the
1219 case, the child will get an error when writing to the broken pipe
1220 the next time, cleaning itself up then. */
1221 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1223 /* We got an EOF from the sync pipe. That means that it exited
1224 before giving us any data to read. If ret is -1, we report
1225 that as a bad exit (e.g., exiting due to a signal); otherwise,
1226 we report it as a premature exit. */
1230 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1232 /* We got an error from the sync pipe. If ret is -1, report
1233 both the sync pipe I/O error and the wait error. */
1235 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1238 *msg = combined_msg;
1245 /* we got a valid message block from the child, process it */
1250 * Error from dumpcap; there will be a primary message and a
1251 * secondary message.
1254 /* convert primary message */
1255 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1256 primary_msg_text = buffer+4;
1257 /* convert secondary message */
1258 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1259 &secondary_msg_len);
1260 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1261 /* the capture child will close the sync_pipe, nothing to do */
1264 * Pick up the child status.
1266 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1270 * Child process failed unexpectedly, or wait failed; msg is the
1275 * Child process failed, but returned the expected exit status.
1276 * Return the messages it gave us, and indicate failure.
1278 *msg = g_strdup(primary_msg_text);
1284 /* Close the message pipe. */
1285 ws_close(message_read_fd);
1290 * Pick up the child status.
1292 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1296 * Child process failed unexpectedly, or wait failed; msg is the
1301 * Child process returned an unknown status.
1303 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1312 /* Close down the stats process */
1314 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1316 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1319 /* read a number of bytes from a pipe */
1320 /* (blocks until enough bytes read or an error occurs) */
1322 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1329 newly = read(pipe_fd, &bytes[offset], required);
1332 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1333 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1340 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1341 "read from pipe %d: error(%u): %s", pipe_fd, error,
1343 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1356 static gboolean pipe_data_available(int pipe_fd) {
1357 #ifdef _WIN32 /* PeekNamedPipe */
1358 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1361 if (hPipe == INVALID_HANDLE_VALUE)
1364 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1367 if (bytes_avail > 0)
1372 struct timeval timeout;
1375 FD_SET(pipe_fd, &rfds);
1377 timeout.tv_usec = 0;
1379 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1386 /* Read a line from a pipe, similar to fgets */
1388 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1392 while(offset < max - 1) {
1394 if (! pipe_data_available(pipe_fd))
1396 newly = read(pipe_fd, &bytes[offset], 1);
1398 /* EOF - not necessarily an error */
1400 } else if (newly < 0) {
1402 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1403 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1405 } else if (bytes[offset] == '\n') {
1411 bytes[offset] = '\0';
1417 /* convert header values (indicator and 3-byte length) */
1419 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1421 g_assert(header_len == 4);
1423 /* convert header values */
1424 *indicator = header[0];
1425 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1428 /* read a message from the sending pipe in the standard format
1429 (1-byte message indicator, 3-byte message length (excluding length
1430 and indicator field), and the rest is the message) */
1432 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1439 /* read header (indicator and 3-byte length) */
1440 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1444 * Immediate EOF; if the capture child exits normally, this
1445 * is an "I'm done" indication, so don't report it as an
1448 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1449 "read %d got an EOF", pipe_fd);
1452 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1453 "read %d failed to read header: %u", pipe_fd, newly);
1456 * Short read, but not an immediate EOF.
1458 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
1464 /* convert header values */
1465 pipe_convert_header(header, 4, indicator, &required);
1467 /* only indicator with no value? */
1469 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1470 "read %d indicator: %c empty value", pipe_fd, *indicator);
1474 /* does the data fit into the given buffer? */
1475 if(required > len) {
1476 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1477 "read %d length error, required %d > len %d, indicator: %u",
1478 pipe_fd, required, len, *indicator);
1480 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1481 memcpy(msg, header, sizeof(header));
1482 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1483 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1489 /* read the actual block data */
1490 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1491 if(newly != required) {
1493 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1499 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1500 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1501 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1508 /* There's stuff to read from the sync pipe, meaning the child has sent
1509 us a message, or the sync pipe has closed, meaning the child has
1510 closed it (perhaps because it exited). */
1512 sync_pipe_input_cb(gint source, gpointer user_data)
1514 capture_options *capture_opts = (capture_options *)user_data;
1516 char buffer[SP_MAX_MSG_LEN+1];
1522 char *secondary_msg;
1523 char *wait_msg, *combined_msg;
1525 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1528 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1530 If we got a read error or a bad message, nread is -1 and
1531 primary_msg is set to point to an error message. We don't
1532 have to worry about killing the child; usually this error
1533 is caused as the child killed itself while going down.
1534 Even in the rare cases that this isn't the case, the child
1535 will get an error when writing to the broken pipe the next time,
1536 cleaning itself up then.
1538 If we got an EOF, nread is 0 and primary_msg isn't set. This
1539 is an indication that the capture is finished. */
1540 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
1542 /* We got an EOF from the sync pipe. That means that the capture
1543 child exited, and not in the middle of a message; we treat
1544 that as an indication that it's done, and only report an
1545 error if ret is -1, in which case wait_msg is the error
1548 primary_msg = wait_msg;
1550 /* We got an error from the sync pipe. If ret is -1, report
1551 both the sync pipe I/O error and the wait error. */
1553 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1554 g_free(primary_msg);
1556 primary_msg = combined_msg;
1560 /* No more child process. */
1561 capture_opts->fork_child = -1;
1562 capture_opts->fork_child_status = ret;
1565 ws_close(capture_opts->signal_pipe_write_fd);
1567 capture_input_closed(capture_opts, primary_msg);
1568 g_free(primary_msg);
1572 /* we got a valid message block from the child, process it */
1575 if(!capture_input_new_file(capture_opts, buffer)) {
1576 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1578 /* We weren't able to open the new capture file; user has been
1579 alerted. Close the sync pipe. */
1582 /* the child has send us a filename which we couldn't open.
1583 this probably means, the child is creating files faster than we can handle it.
1584 this should only be the case for very fast file switches
1585 we can't do much more than telling the child to stop
1586 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1587 sync_pipe_stop(capture_opts);
1590 case SP_PACKET_COUNT:
1591 nread = atoi(buffer);
1592 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1593 capture_input_new_packets(capture_opts, nread);
1596 /* convert primary message */
1597 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1598 primary_msg = buffer+4;
1599 /* convert secondary message */
1600 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1601 secondary_msg = primary_msg + primary_len + 4;
1602 /* message output */
1603 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1604 /* the capture child will close the sync_pipe, nothing to do for now */
1605 /* (an error message doesn't mean we have to stop capturing) */
1608 capture_input_cfilter_error_message(capture_opts, buffer);
1609 /* the capture child will close the sync_pipe, nothing to do for now */
1612 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1615 g_assert_not_reached();
1623 /* the child process is going down, wait until it's completely terminated */
1625 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1627 int fork_child_status;
1630 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1631 g_assert(fork_child != -1);
1633 *msgp = NULL; /* assume no error */
1636 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1637 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1641 * The child exited; return its exit status. Do not treat this as
1644 ret = fork_child_status;
1645 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1646 /* Probably an exception code */
1647 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1648 win32strexception(fork_child_status));
1653 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1654 if (WIFEXITED(fork_child_status)) {
1656 * The child exited; return its exit status. Do not treat this as
1659 ret = WEXITSTATUS(fork_child_status);
1660 } else if (WIFSTOPPED(fork_child_status)) {
1661 /* It stopped, rather than exiting. "Should not happen." */
1662 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1663 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1665 } else if (WIFSIGNALED(fork_child_status)) {
1666 /* It died with a signal. */
1667 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1668 sync_pipe_signame(WTERMSIG(fork_child_status)),
1669 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1672 /* What? It had to either have exited, or stopped, or died with
1673 a signal; what happened here? */
1674 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1679 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1684 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1690 /* convert signal to corresponding name */
1692 sync_pipe_signame(int sig)
1695 static char sigmsg_buf[6+1+3+1];
1704 sigmsg = "Interrupted";
1712 sigmsg = "Illegal instruction";
1716 sigmsg = "Trace trap";
1724 sigmsg = "Arithmetic exception";
1732 sigmsg = "Bus error";
1736 sigmsg = "Segmentation violation";
1739 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1740 Linux is POSIX compliant. These are not POSIX-defined signals ---
1741 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1743 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1744 were omitted from POSIX.1 because their behavior is
1745 implementation dependent and could not be adequately catego-
1746 rized. Conforming implementations may deliver these sig-
1747 nals, but must document the circumstances under which they
1748 are delivered and note any restrictions concerning their
1751 So we only check for SIGSYS on those systems that happen to
1752 implement them (a system can be POSIX-compliant and implement
1753 them, it's just that POSIX doesn't *require* a POSIX-compliant
1754 system to implement them).
1759 sigmsg = "Bad system call";
1764 sigmsg = "Broken pipe";
1768 sigmsg = "Alarm clock";
1772 sigmsg = "Terminated";
1776 /* Returning a static buffer is ok in the context we use it here */
1777 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1778 sigmsg = sigmsg_buf;
1787 /* tell the child through the signal pipe that we want to quit the capture */
1789 signal_pipe_capquit_to_child(capture_options *capture_opts)
1791 const char quit_msg[] = "QUIT";
1795 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1797 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1798 /* simply sending a "QUIT" string */
1799 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1800 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1802 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1803 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1809 /* user wants to stop the capture run */
1811 sync_pipe_stop(capture_options *capture_opts)
1816 gboolean terminate = TRUE;
1819 if (capture_opts->fork_child != -1) {
1821 /* send the SIGINT signal to close the capture child gracefully. */
1822 int sts = kill(capture_opts->fork_child, SIGINT);
1824 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1825 "Sending SIGINT to child failed: %s\n", strerror(errno));
1828 #define STOP_SLEEP_TIME 500 /* ms */
1829 #define STOP_CHECK_TIME 50
1830 /* First, use the special signal pipe to try to close the capture child
1833 signal_pipe_capquit_to_child(capture_opts);
1835 /* Next, wait for the process to exit on its own */
1836 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1837 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1838 childstatus != STILL_ACTIVE) {
1842 Sleep(STOP_CHECK_TIME);
1845 /* Force the issue. */
1847 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1848 "sync_pipe_stop: forcing child to exit");
1849 sync_pipe_kill(capture_opts->fork_child);
1856 /* Wireshark has to exit, force the capture child to close */
1858 sync_pipe_kill(int fork_child)
1860 if (fork_child != -1) {
1862 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1864 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1865 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1868 /* Remark: This is not the preferred method of closing a process!
1869 * the clean way would be getting the process id of the child process,
1870 * then getting window handle hWnd of that process (using EnumChildWindows),
1871 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1873 * Unfortunately, I don't know how to get the process id from the
1874 * handle. OpenProcess will get an handle (not a window handle)
1875 * from the process ID; it will not get a window handle from the
1876 * process ID. (How could it? A process can have more than one
1877 * window. For that matter, a process might have *no* windows,
1878 * as a process running dumpcap, the normal child process program,
1881 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1882 * running in the same console; that's not necessarily the case for
1883 * us, as we might not be running in a console.
1884 * And this also will require to have the process id.
1886 TerminateProcess((HANDLE) (fork_child), 0);
1891 #endif /* HAVE_LIBPCAP */