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 char buffer_size[ARGV_NUMBER_LEN];
339 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
340 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
341 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
342 GString *args = g_string_sized_new(200);
344 SECURITY_ATTRIBUTES sa;
346 PROCESS_INFORMATION pi;
347 char control_id[ARGV_NUMBER_LEN];
348 gchar *signal_pipe_name;
351 int sync_pipe[2]; /* pipe used to send messages from child to parent */
352 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
354 int sync_pipe_read_fd;
359 interface_options interface_opts;
361 if (capture_opts->ifaces->len > 1)
362 capture_opts->use_pcapng = TRUE;
363 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
364 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
366 capture_opts->fork_child = -1;
368 argv = init_pipe_args(&argc);
370 /* We don't know where to find dumpcap. */
371 report_failure("We don't know where to find dumpcap.");
375 if (capture_opts->ifaces->len > 1)
376 argv = sync_pipe_add_arg(argv, &argc, "-t");
378 if (capture_opts->use_pcapng)
379 argv = sync_pipe_add_arg(argv, &argc, "-n");
381 if (capture_opts->multi_files_on) {
382 if (capture_opts->has_autostop_filesize) {
383 argv = sync_pipe_add_arg(argv, &argc, "-b");
384 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
385 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
388 if (capture_opts->has_file_duration) {
389 argv = sync_pipe_add_arg(argv, &argc, "-b");
390 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
391 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
394 if (capture_opts->has_ring_num_files) {
395 argv = sync_pipe_add_arg(argv, &argc, "-b");
396 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
397 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
400 if (capture_opts->has_autostop_files) {
401 argv = sync_pipe_add_arg(argv, &argc, "-a");
402 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
403 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
406 if (capture_opts->has_autostop_filesize) {
407 argv = sync_pipe_add_arg(argv, &argc, "-a");
408 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
409 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
413 if (capture_opts->has_autostop_packets) {
414 argv = sync_pipe_add_arg(argv, &argc, "-c");
415 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
416 argv = sync_pipe_add_arg(argv, &argc, scount);
419 if (capture_opts->has_autostop_duration) {
420 argv = sync_pipe_add_arg(argv, &argc, "-a");
421 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
422 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
425 for (j = 0; j < capture_opts->ifaces->len; j++) {
426 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
428 argv = sync_pipe_add_arg(argv, &argc, "-i");
429 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
431 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
432 argv = sync_pipe_add_arg(argv, &argc, "-f");
433 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
436 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
437 argv = sync_pipe_add_arg(argv, &argc, "-s");
438 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
439 argv = sync_pipe_add_arg(argv, &argc, ssnap);
442 if (interface_opts.linktype != -1) {
443 argv = sync_pipe_add_arg(argv, &argc, "-y");
444 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
445 argv = sync_pipe_add_arg(argv, &argc, sdlt);
448 if (!interface_opts.promisc_mode) {
449 argv = sync_pipe_add_arg(argv, &argc, "-p");
452 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
453 if (interface_opts.buffer_size != 1) {
454 argv = sync_pipe_add_arg(argv, &argc, "-B");
455 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
456 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
460 if (interface_opts.monitor_mode) {
461 argv = sync_pipe_add_arg(argv, &argc, "-I");
464 #ifdef HAVE_PCAP_REMOTE
465 if (interface_opts.datatx_udp)
466 argv = sync_pipe_add_arg(argv, &argc, "-u");
468 if (!interface_opts.nocap_rpcap)
469 argv = sync_pipe_add_arg(argv, &argc, "-r");
471 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
472 argv = sync_pipe_add_arg(argv, &argc, "-A");
473 g_snprintf(sauth, sizeof(sauth), "%s:%s",
474 interface_opts.auth_username,
475 interface_opts.auth_password);
476 argv = sync_pipe_add_arg(argv, &argc, sauth);
480 #ifdef HAVE_PCAP_SETSAMPLING
481 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
482 argv = sync_pipe_add_arg(argv, &argc, "-m");
483 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
484 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
485 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
487 interface_opts.sampling_param);
488 argv = sync_pipe_add_arg(argv, &argc, ssampling);
493 /* dumpcap should be running in capture child mode (hidden feature) */
495 argv = sync_pipe_add_arg(argv, &argc, "-Z");
497 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
498 argv = sync_pipe_add_arg(argv, &argc, control_id);
500 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
504 if (capture_opts->save_file) {
505 argv = sync_pipe_add_arg(argv, &argc, "-w");
506 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
510 /* init SECURITY_ATTRIBUTES */
511 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
512 sa.bInheritHandle = TRUE;
513 sa.lpSecurityDescriptor = NULL;
515 /* Create a pipe for the child process */
516 /* (increase this value if you have trouble while fast capture file switches) */
517 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
518 /* Couldn't create the pipe between parent and child. */
519 report_failure("Couldn't create sync pipe: %s",
520 win32strerror(GetLastError()));
521 g_free( (gpointer) argv[0]);
522 g_free( (gpointer) argv);
526 /* Create the signal pipe */
527 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
528 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
529 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
530 g_free(signal_pipe_name);
532 if (signal_pipe == INVALID_HANDLE_VALUE) {
533 /* Couldn't create the signal pipe between parent and child. */
534 report_failure("Couldn't create signal pipe: %s",
535 win32strerror(GetLastError()));
536 g_free( (gpointer) argv[0]);
537 g_free( (gpointer) argv);
541 /* init STARTUPINFO */
542 memset(&si, 0, sizeof(si));
545 si.dwFlags = STARTF_USESHOWWINDOW;
546 si.wShowWindow = SW_SHOW;
548 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
549 si.wShowWindow = SW_HIDE; /* this hides the console window */
550 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
551 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
552 si.hStdError = sync_pipe_write;
553 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
556 /* convert args array into a single string */
557 /* XXX - could change sync_pipe_add_arg() instead */
558 /* there is a drawback here: the length is internally limited to 1024 bytes */
559 for(i=0; argv[i] != 0; i++) {
560 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
561 quoted_arg = protect_arg(argv[i]);
562 g_string_append(args, quoted_arg);
567 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
568 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
569 report_failure("Couldn't run %s in child process: %s",
570 args->str, win32strerror(GetLastError()));
571 CloseHandle(sync_pipe_read);
572 CloseHandle(sync_pipe_write);
573 g_free( (gpointer) argv[0]);
574 g_free( (gpointer) argv);
577 capture_opts->fork_child = (int) pi.hProcess;
578 g_string_free(args, TRUE);
580 /* associate the operating system filehandle to a C run-time file handle */
581 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
582 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
584 /* associate the operating system filehandle to a C run-time file handle */
585 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
588 if (pipe(sync_pipe) < 0) {
589 /* Couldn't create the pipe between parent and child. */
590 report_failure("Couldn't create sync pipe: %s", strerror(errno));
591 g_free( (gpointer) argv[0]);
596 if ((capture_opts->fork_child = fork()) == 0) {
598 * Child process - run dumpcap with the right arguments to make
599 * it just capture with the specified capture parameters
601 dup2(sync_pipe[PIPE_WRITE], 2);
602 ws_close(sync_pipe[PIPE_READ]);
603 for (i = 0; i < argc; i++) {
604 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
606 execv(argv[0], (gpointer)argv);
607 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
608 argv[0], strerror(errno));
609 sync_pipe_errmsg_to_parent(2, errmsg, "");
611 /* Exit with "_exit()", so that we don't close the connection
612 to the X server (and cause stuff buffered up by our parent but
613 not yet sent to be sent, as that stuff should only be sent by
614 our parent). We've sent an error message to the parent, so
615 we exit with an exit status of 1 (any exit status other than
616 0 or 1 will cause an additional message to report that exit
617 status, over and above the error message we sent to the parent). */
621 sync_pipe_read_fd = sync_pipe[PIPE_READ];
624 g_free( (gpointer) argv[0]); /* exename */
626 /* Parent process - read messages from the child process over the
628 g_free( (gpointer) argv); /* free up arg array */
630 /* Close the write side of the pipe, so that only the child has it
631 open, and thus it completely closes, and thus returns to us
632 an EOF indication, if the child closes it (either deliberately
633 or by exiting abnormally). */
635 CloseHandle(sync_pipe_write);
637 ws_close(sync_pipe[PIPE_WRITE]);
640 if (capture_opts->fork_child == -1) {
641 /* We couldn't even create the child process. */
642 report_failure("Couldn't create child process: %s", strerror(errno));
643 ws_close(sync_pipe_read_fd);
645 ws_close(capture_opts->signal_pipe_write_fd);
650 capture_opts->fork_child_status = 0;
652 /* we might wait for a moment till child is ready, so update screen now */
653 main_window_update();
655 /* We were able to set up to read the capture file;
656 arrange that our callback be called whenever it's possible
657 to read from the sync pipe, so that it's called when
658 the child process wants to tell us something. */
660 /* we have a running capture, now wait for the real capture filename */
661 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
662 &capture_opts->fork_child, sync_pipe_input_cb);
668 * Open two pipes to dumpcap with the supplied arguments, one for its
669 * standard output and one for its standard error.
671 * On success, *msg is unchanged and 0 is returned; data_read_fd,
672 * messsage_read_fd, and fork_child point to the standard output pipe's
673 * file descriptor, the standard error pipe's file descriptor, and
674 * the child's PID/handle, respectively.
676 * On failure, *msg points to an error message for the failure, and -1 is
677 * returned, in which case *msg must be freed with g_free().
679 /* XXX - This duplicates a lot of code in sync_pipe_start() */
680 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
681 #define PIPE_BUF_SIZE 5120
683 sync_pipe_open_command(const char** argv, int *data_read_fd,
684 int *message_read_fd, int *fork_child, gchar **msg)
686 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
688 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
689 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
690 GString *args = g_string_sized_new(200);
692 SECURITY_ATTRIBUTES sa;
694 PROCESS_INFORMATION pi;
698 int sync_pipe[2]; /* pipe used to send messages from child to parent */
699 int data_pipe[2]; /* pipe used to send data from child to parent */
704 *message_read_fd = -1;
705 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
708 /* We can't return anything */
710 g_string_free(args, TRUE);
716 /* init SECURITY_ATTRIBUTES */
717 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
718 sa.bInheritHandle = TRUE;
719 sa.lpSecurityDescriptor = NULL;
721 /* Create a pipe for the child process to send us messages */
722 /* (increase this value if you have trouble while fast capture file switches) */
723 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
724 /* Couldn't create the message pipe between parent and child. */
725 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
726 win32strerror(GetLastError()));
727 g_free( (gpointer) argv[0]);
728 g_free( (gpointer) argv);
732 /* Create a pipe for the child process to send us data */
733 /* (increase this value if you have trouble while fast capture file switches) */
734 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
735 /* Couldn't create the message pipe between parent and child. */
736 *msg = g_strdup_printf("Couldn't create data pipe: %s",
737 win32strerror(GetLastError()));
738 CloseHandle(sync_pipe[PIPE_READ]);
739 CloseHandle(sync_pipe[PIPE_WRITE]);
740 g_free( (gpointer) argv[0]);
741 g_free( (gpointer) argv);
745 /* init STARTUPINFO */
746 memset(&si, 0, sizeof(si));
749 si.dwFlags = STARTF_USESHOWWINDOW;
750 si.wShowWindow = SW_SHOW;
752 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
753 si.wShowWindow = SW_HIDE; /* this hides the console window */
755 si.hStdOutput = data_pipe[PIPE_WRITE];
756 si.hStdError = sync_pipe[PIPE_WRITE];
759 /* convert args array into a single string */
760 /* XXX - could change sync_pipe_add_arg() instead */
761 /* there is a drawback here: the length is internally limited to 1024 bytes */
762 for(i=0; argv[i] != 0; i++) {
763 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
764 quoted_arg = protect_arg(argv[i]);
765 g_string_append(args, quoted_arg);
770 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
771 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
772 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
773 args->str, win32strerror(GetLastError()));
774 CloseHandle(data_pipe[PIPE_READ]);
775 CloseHandle(data_pipe[PIPE_WRITE]);
776 CloseHandle(sync_pipe[PIPE_READ]);
777 CloseHandle(sync_pipe[PIPE_WRITE]);
778 g_free( (gpointer) argv[0]);
779 g_free( (gpointer) argv);
782 *fork_child = (int) pi.hProcess;
783 g_string_free(args, TRUE);
785 /* associate the operating system filehandles to C run-time file handles */
786 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
787 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
788 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
790 /* Create a pipe for the child process to send us messages */
791 if (pipe(sync_pipe) < 0) {
792 /* Couldn't create the message pipe between parent and child. */
793 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
794 g_free( (gpointer) argv[0]);
799 /* Create a pipe for the child process to send us data */
800 if (pipe(data_pipe) < 0) {
801 /* Couldn't create the data pipe between parent and child. */
802 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
803 ws_close(sync_pipe[PIPE_READ]);
804 ws_close(sync_pipe[PIPE_WRITE]);
805 g_free( (gpointer) argv[0]);
810 if ((*fork_child = fork()) == 0) {
812 * Child process - run dumpcap with the right arguments to make
813 * it just capture with the specified capture parameters
815 dup2(data_pipe[PIPE_WRITE], 1);
816 ws_close(data_pipe[PIPE_READ]);
817 ws_close(data_pipe[PIPE_WRITE]);
818 dup2(sync_pipe[PIPE_WRITE], 2);
819 ws_close(sync_pipe[PIPE_READ]);
820 ws_close(sync_pipe[PIPE_WRITE]);
821 execv(argv[0], (gpointer)argv);
822 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
823 argv[0], strerror(errno));
824 sync_pipe_errmsg_to_parent(2, errmsg, "");
826 /* Exit with "_exit()", so that we don't close the connection
827 to the X server (and cause stuff buffered up by our parent but
828 not yet sent to be sent, as that stuff should only be sent by
829 our parent). We've sent an error message to the parent, so
830 we exit with an exit status of 1 (any exit status other than
831 0 or 1 will cause an additional message to report that exit
832 status, over and above the error message we sent to the parent). */
836 *data_read_fd = data_pipe[PIPE_READ];
837 *message_read_fd = sync_pipe[PIPE_READ];
840 g_free( (gpointer) argv[0]); /* exename */
842 /* Parent process - read messages from the child process over the
844 g_free( (gpointer) argv); /* free up arg array */
846 /* Close the write sides of the pipes, so that only the child has them
847 open, and thus they completely close, and thus return to us
848 an EOF indication, if the child closes them (either deliberately
849 or by exiting abnormally). */
851 CloseHandle(data_pipe[PIPE_WRITE]);
852 CloseHandle(sync_pipe[PIPE_WRITE]);
854 ws_close(data_pipe[PIPE_WRITE]);
855 ws_close(sync_pipe[PIPE_WRITE]);
858 if (*fork_child == -1) {
859 /* We couldn't even create the child process. */
860 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
861 ws_close(*data_read_fd);
862 ws_close(*message_read_fd);
866 /* we might wait for a moment till child is ready, so update screen now */
867 main_window_update();
872 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
873 * returned. On failure, *msg points to an error message for the
874 * failure, and -1 is returned. In the latter case, *msg must be
875 * freed with g_free().
878 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
879 int *fork_child, gchar **msg)
881 ws_close(*data_read_fd);
882 if (message_read_fd != NULL)
883 ws_close(*message_read_fd);
886 /* XXX - Should we signal the child somehow? */
887 sync_pipe_kill(*fork_child);
890 return sync_pipe_wait_for_child(*fork_child, msg);
894 * Run dumpcap with the supplied arguments.
896 * On success, *data points to a buffer containing the dumpcap output,
897 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
898 * must be freed with g_free().
900 * On failure, *data is NULL, *primary_msg points to an error message,
901 * *secondary_msg either points to an additional error message or is
902 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
903 * must be freed with g_free().
905 /* XXX - This duplicates a lot of code in sync_pipe_start() */
906 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
907 #define PIPE_BUF_SIZE 5120
909 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
910 gchar **secondary_msg)
913 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
915 gchar buffer[PIPE_BUF_SIZE+1];
919 char *primary_msg_text;
920 int secondary_msg_len;
921 char *secondary_msg_text;
923 GString *data_buf = NULL;
926 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
930 *secondary_msg = NULL;
936 * We were able to set up to read dumpcap's output. Do so.
938 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
940 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
941 buffer, primary_msg);
943 /* We got a read error from the sync pipe, or we got no data at
944 all from the sync pipe, so we're not going to be getting any
945 data or error message from the child process. Pick up its
946 exit status, and complain.
948 We don't have to worry about killing the child, if the sync pipe
949 returned an error. Usually this error is caused as the child killed
950 itself while going down. Even in the rare cases that this isn't the
951 case, the child will get an error when writing to the broken pipe
952 the next time, cleaning itself up then. */
953 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
955 /* We got an EOF from the sync pipe. That means that it exited
956 before giving us any data to read. If ret is -1, we report
957 that as a bad exit (e.g., exiting due to a signal); otherwise,
958 we report it as a premature exit. */
960 *primary_msg = wait_msg;
962 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
964 /* We got an error from the sync pipe. If ret is -1, report
965 both the sync pipe I/O error and the wait error. */
967 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
968 g_free(*primary_msg);
970 *primary_msg = combined_msg;
973 *secondary_msg = NULL;
978 /* we got a valid message block from the child, process it */
983 * Error from dumpcap; there will be a primary message and a
987 /* convert primary message */
988 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
989 primary_msg_text = buffer+4;
990 /* convert secondary message */
991 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
993 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
994 /* the capture child will close the sync_pipe, nothing to do */
997 * Pick up the child status.
999 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1003 * Child process failed unexpectedly, or wait failed; msg is the
1007 *secondary_msg = NULL;
1010 * Child process failed, but returned the expected exit status.
1011 * Return the messages it gave us, and indicate failure.
1013 *primary_msg = g_strdup(primary_msg_text);
1014 *secondary_msg = g_strdup(secondary_msg_text);
1021 /* read the output from the command */
1022 data_buf = g_string_new("");
1023 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1024 buffer[count] = '\0';
1025 g_string_append(data_buf, buffer);
1029 * Pick up the child status.
1031 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1035 * Child process failed unexpectedly, or wait failed; msg is the
1039 *secondary_msg = NULL;
1040 g_string_free(data_buf, TRUE);
1044 * Child process succeeded.
1046 *primary_msg = NULL;
1047 *secondary_msg = NULL;
1048 *data = data_buf->str;
1049 g_string_free(data_buf, FALSE);
1055 * Pick up the child status.
1057 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1061 * Child process failed unexpectedly, or wait failed; msg is the
1065 *secondary_msg = NULL;
1068 * Child process returned an unknown status.
1070 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1072 *secondary_msg = NULL;
1082 * Get the list of interfaces using dumpcap.
1084 * On success, *data points to a buffer containing the dumpcap output,
1085 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1086 * must be freed with g_free().
1088 * On failure, *data is NULL, *primary_msg points to an error message,
1089 * *secondary_msg either points to an additional error message or is
1090 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1091 * must be freed with g_free().
1094 sync_interface_list_open(gchar **data, gchar **primary_msg,
1095 gchar **secondary_msg)
1100 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1102 argv = init_pipe_args(&argc);
1105 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1106 *secondary_msg = NULL;
1111 /* Ask for the interface list */
1112 argv = sync_pipe_add_arg(argv, &argc, "-D");
1115 /* Run dumpcap in capture child mode */
1116 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1117 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1119 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1123 * Get the capabilities of an interface using dumpcap.
1125 * On success, *data points to a buffer containing the dumpcap output,
1126 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1127 * must be freed with g_free().
1129 * On failure, *data is NULL, *primary_msg points to an error message,
1130 * *secondary_msg either points to an additional error message or is
1131 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1132 * must be freed with g_free().
1135 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1136 gchar **data, gchar **primary_msg,
1137 gchar **secondary_msg)
1142 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1144 argv = init_pipe_args(&argc);
1147 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1148 *secondary_msg = NULL;
1153 /* Ask for the interface capabilities */
1154 argv = sync_pipe_add_arg(argv, &argc, "-i");
1155 argv = sync_pipe_add_arg(argv, &argc, ifname);
1156 argv = sync_pipe_add_arg(argv, &argc, "-L");
1158 argv = sync_pipe_add_arg(argv, &argc, "-I");
1161 /* Run dumpcap in capture child mode */
1162 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1163 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1165 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1169 * Start getting interface statistics using dumpcap. On success, read_fd
1170 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1171 * and zero is returned. On failure, *msg will point to an error message
1172 * that must be g_free()d, and -1 will be returned.
1175 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1179 int message_read_fd, ret;
1181 gchar buffer[PIPE_BUF_SIZE+1];
1184 int primary_msg_len;
1185 char *primary_msg_text;
1186 int secondary_msg_len;
1187 char *secondary_msg_text;
1190 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1192 argv = init_pipe_args(&argc);
1195 *msg = g_strdup("We don't know where to find dumpcap.");
1199 /* Ask for the interface statistics */
1200 argv = sync_pipe_add_arg(argv, &argc, "-S");
1203 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1204 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1206 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1212 * We were able to set up to read dumpcap's output. Do so.
1214 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1216 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1219 /* We got a read error from the sync pipe, or we got no data at
1220 all from the sync pipe, so we're not going to be getting any
1221 data or error message from the child process. Pick up its
1222 exit status, and complain.
1224 We don't have to worry about killing the child, if the sync pipe
1225 returned an error. Usually this error is caused as the child killed
1226 itself while going down. Even in the rare cases that this isn't the
1227 case, the child will get an error when writing to the broken pipe
1228 the next time, cleaning itself up then. */
1229 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1231 /* We got an EOF from the sync pipe. That means that it exited
1232 before giving us any data to read. If ret is -1, we report
1233 that as a bad exit (e.g., exiting due to a signal); otherwise,
1234 we report it as a premature exit. */
1238 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1240 /* We got an error from the sync pipe. If ret is -1, report
1241 both the sync pipe I/O error and the wait error. */
1243 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1246 *msg = combined_msg;
1253 /* we got a valid message block from the child, process it */
1258 * Error from dumpcap; there will be a primary message and a
1259 * secondary message.
1262 /* convert primary message */
1263 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1264 primary_msg_text = buffer+4;
1265 /* convert secondary message */
1266 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1267 &secondary_msg_len);
1268 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1269 /* the capture child will close the sync_pipe, nothing to do */
1272 * Pick up the child status.
1274 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1278 * Child process failed unexpectedly, or wait failed; msg is the
1283 * Child process failed, but returned the expected exit status.
1284 * Return the messages it gave us, and indicate failure.
1286 *msg = g_strdup(primary_msg_text);
1292 /* Close the message pipe. */
1293 ws_close(message_read_fd);
1298 * Pick up the child status.
1300 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1304 * Child process failed unexpectedly, or wait failed; msg is the
1309 * Child process returned an unknown status.
1311 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1320 /* Close down the stats process */
1322 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1324 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1327 /* read a number of bytes from a pipe */
1328 /* (blocks until enough bytes read or an error occurs) */
1330 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1337 newly = read(pipe_fd, &bytes[offset], required);
1340 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1341 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1348 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1349 "read from pipe %d: error(%u): %s", pipe_fd, error,
1351 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1364 static gboolean pipe_data_available(int pipe_fd) {
1365 #ifdef _WIN32 /* PeekNamedPipe */
1366 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1369 if (hPipe == INVALID_HANDLE_VALUE)
1372 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1375 if (bytes_avail > 0)
1380 struct timeval timeout;
1383 FD_SET(pipe_fd, &rfds);
1385 timeout.tv_usec = 0;
1387 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1394 /* Read a line from a pipe, similar to fgets */
1396 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1400 while(offset < max - 1) {
1402 if (! pipe_data_available(pipe_fd))
1404 newly = read(pipe_fd, &bytes[offset], 1);
1406 /* EOF - not necessarily an error */
1408 } else if (newly < 0) {
1410 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1411 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1413 } else if (bytes[offset] == '\n') {
1419 bytes[offset] = '\0';
1425 /* convert header values (indicator and 3-byte length) */
1427 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1429 g_assert(header_len == 4);
1431 /* convert header values */
1432 *indicator = header[0];
1433 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1436 /* read a message from the sending pipe in the standard format
1437 (1-byte message indicator, 3-byte message length (excluding length
1438 and indicator field), and the rest is the message) */
1440 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1447 /* read header (indicator and 3-byte length) */
1448 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1452 * Immediate EOF; if the capture child exits normally, this
1453 * is an "I'm done" indication, so don't report it as an
1456 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1457 "read %d got an EOF", pipe_fd);
1460 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1461 "read %d failed to read header: %u", pipe_fd, newly);
1464 * Short read, but not an immediate EOF.
1466 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
1472 /* convert header values */
1473 pipe_convert_header(header, 4, indicator, &required);
1475 /* only indicator with no value? */
1477 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1478 "read %d indicator: %c empty value", pipe_fd, *indicator);
1482 /* does the data fit into the given buffer? */
1483 if(required > len) {
1484 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1485 "read %d length error, required %d > len %d, indicator: %u",
1486 pipe_fd, required, len, *indicator);
1488 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1489 memcpy(msg, header, sizeof(header));
1490 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1491 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1497 /* read the actual block data */
1498 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1499 if(newly != required) {
1501 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1507 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1508 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1509 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1516 /* There's stuff to read from the sync pipe, meaning the child has sent
1517 us a message, or the sync pipe has closed, meaning the child has
1518 closed it (perhaps because it exited). */
1520 sync_pipe_input_cb(gint source, gpointer user_data)
1522 capture_options *capture_opts = (capture_options *)user_data;
1524 char buffer[SP_MAX_MSG_LEN+1];
1530 char *secondary_msg;
1531 char *wait_msg, *combined_msg;
1533 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1536 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1538 If we got a read error or a bad message, nread is -1 and
1539 primary_msg is set to point to an error message. We don't
1540 have to worry about killing the child; usually this error
1541 is caused as the child killed itself while going down.
1542 Even in the rare cases that this isn't the case, the child
1543 will get an error when writing to the broken pipe the next time,
1544 cleaning itself up then.
1546 If we got an EOF, nread is 0 and primary_msg isn't set. This
1547 is an indication that the capture is finished. */
1548 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
1550 /* We got an EOF from the sync pipe. That means that the capture
1551 child exited, and not in the middle of a message; we treat
1552 that as an indication that it's done, and only report an
1553 error if ret is -1, in which case wait_msg is the error
1556 primary_msg = wait_msg;
1558 /* We got an error from the sync pipe. If ret is -1, report
1559 both the sync pipe I/O error and the wait error. */
1561 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1562 g_free(primary_msg);
1564 primary_msg = combined_msg;
1568 /* No more child process. */
1569 capture_opts->fork_child = -1;
1570 capture_opts->fork_child_status = ret;
1573 ws_close(capture_opts->signal_pipe_write_fd);
1575 capture_input_closed(capture_opts, primary_msg);
1576 g_free(primary_msg);
1580 /* we got a valid message block from the child, process it */
1583 if(!capture_input_new_file(capture_opts, buffer)) {
1584 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1586 /* We weren't able to open the new capture file; user has been
1587 alerted. Close the sync pipe. */
1590 /* the child has send us a filename which we couldn't open.
1591 this probably means, the child is creating files faster than we can handle it.
1592 this should only be the case for very fast file switches
1593 we can't do much more than telling the child to stop
1594 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1595 sync_pipe_stop(capture_opts);
1598 case SP_PACKET_COUNT:
1599 nread = atoi(buffer);
1600 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1601 capture_input_new_packets(capture_opts, nread);
1604 /* convert primary message */
1605 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1606 primary_msg = buffer+4;
1607 /* convert secondary message */
1608 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1609 secondary_msg = primary_msg + primary_len + 4;
1610 /* message output */
1611 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1612 /* the capture child will close the sync_pipe, nothing to do for now */
1613 /* (an error message doesn't mean we have to stop capturing) */
1616 capture_input_cfilter_error_message(capture_opts, buffer);
1617 /* the capture child will close the sync_pipe, nothing to do for now */
1620 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1623 g_assert_not_reached();
1631 /* the child process is going down, wait until it's completely terminated */
1633 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1635 int fork_child_status;
1638 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1639 g_assert(fork_child != -1);
1641 *msgp = NULL; /* assume no error */
1644 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1645 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1649 * The child exited; return its exit status. Do not treat this as
1652 ret = fork_child_status;
1653 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1654 /* Probably an exception code */
1655 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1656 win32strexception(fork_child_status));
1661 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1662 if (WIFEXITED(fork_child_status)) {
1664 * The child exited; return its exit status. Do not treat this as
1667 ret = WEXITSTATUS(fork_child_status);
1668 } else if (WIFSTOPPED(fork_child_status)) {
1669 /* It stopped, rather than exiting. "Should not happen." */
1670 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1671 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1673 } else if (WIFSIGNALED(fork_child_status)) {
1674 /* It died with a signal. */
1675 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1676 sync_pipe_signame(WTERMSIG(fork_child_status)),
1677 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1680 /* What? It had to either have exited, or stopped, or died with
1681 a signal; what happened here? */
1682 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1687 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1692 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1698 /* convert signal to corresponding name */
1700 sync_pipe_signame(int sig)
1703 static char sigmsg_buf[6+1+3+1];
1712 sigmsg = "Interrupted";
1720 sigmsg = "Illegal instruction";
1724 sigmsg = "Trace trap";
1732 sigmsg = "Arithmetic exception";
1740 sigmsg = "Bus error";
1744 sigmsg = "Segmentation violation";
1747 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1748 Linux is POSIX compliant. These are not POSIX-defined signals ---
1749 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1751 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1752 were omitted from POSIX.1 because their behavior is
1753 implementation dependent and could not be adequately catego-
1754 rized. Conforming implementations may deliver these sig-
1755 nals, but must document the circumstances under which they
1756 are delivered and note any restrictions concerning their
1759 So we only check for SIGSYS on those systems that happen to
1760 implement them (a system can be POSIX-compliant and implement
1761 them, it's just that POSIX doesn't *require* a POSIX-compliant
1762 system to implement them).
1767 sigmsg = "Bad system call";
1772 sigmsg = "Broken pipe";
1776 sigmsg = "Alarm clock";
1780 sigmsg = "Terminated";
1784 /* Returning a static buffer is ok in the context we use it here */
1785 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1786 sigmsg = sigmsg_buf;
1795 /* tell the child through the signal pipe that we want to quit the capture */
1797 signal_pipe_capquit_to_child(capture_options *capture_opts)
1799 const char quit_msg[] = "QUIT";
1803 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1805 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1806 /* simply sending a "QUIT" string */
1807 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1808 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1810 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1811 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1817 /* user wants to stop the capture run */
1819 sync_pipe_stop(capture_options *capture_opts)
1824 gboolean terminate = TRUE;
1827 if (capture_opts->fork_child != -1) {
1829 /* send the SIGINT signal to close the capture child gracefully. */
1830 int sts = kill(capture_opts->fork_child, SIGINT);
1832 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1833 "Sending SIGINT to child failed: %s\n", strerror(errno));
1836 #define STOP_SLEEP_TIME 500 /* ms */
1837 #define STOP_CHECK_TIME 50
1838 /* First, use the special signal pipe to try to close the capture child
1841 signal_pipe_capquit_to_child(capture_opts);
1843 /* Next, wait for the process to exit on its own */
1844 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1845 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1846 childstatus != STILL_ACTIVE) {
1850 Sleep(STOP_CHECK_TIME);
1853 /* Force the issue. */
1855 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1856 "sync_pipe_stop: forcing child to exit");
1857 sync_pipe_kill(capture_opts->fork_child);
1864 /* Wireshark has to exit, force the capture child to close */
1866 sync_pipe_kill(int fork_child)
1868 if (fork_child != -1) {
1870 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1872 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1873 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1876 /* Remark: This is not the preferred method of closing a process!
1877 * the clean way would be getting the process id of the child process,
1878 * then getting window handle hWnd of that process (using EnumChildWindows),
1879 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1881 * Unfortunately, I don't know how to get the process id from the
1882 * handle. OpenProcess will get an handle (not a window handle)
1883 * from the process ID; it will not get a window handle from the
1884 * process ID. (How could it? A process can have more than one
1885 * window. For that matter, a process might have *no* windows,
1886 * as a process running dumpcap, the normal child process program,
1889 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1890 * running in the same console; that's not necessarily the case for
1891 * us, as we might not be running in a console.
1892 * And this also will require to have the process id.
1894 TerminateProcess((HANDLE) (fork_child), 0);
1899 #endif /* HAVE_LIBPCAP */