2 * Synchronisation between Wireshark capture parent and child instances
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
47 #include <wsutil/unicode-utils.h>
50 #ifdef HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
54 #include "capture-pcap-util.h"
58 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
59 * macros) on UNIX systems that don't have them.
62 # define WIFEXITED(status) (((status) & 0177) == 0)
65 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
68 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
71 # define WEXITSTATUS(status) ((status) >> 8)
74 # define WTERMSIG(status) ((status) & 0177)
77 # define WCOREDUMP(status) ((status) & 0200)
80 # define WSTOPSIG(status) ((status) >> 8)
84 #include <epan/packet.h>
85 #include <epan/prefs.h>
89 #include <epan/filesystem.h>
90 #include <epan/report_err.h>
93 #include "capture_sync.h"
95 #include "sync_pipe.h"
98 #include "capture-wpcap.h"
101 #include <wsutil/file_util.h>
105 #include <process.h> /* For spawning child process */
111 static const char *sync_pipe_signame(int);
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
117 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
118 static int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
123 /* Append an arg (realloc) to an argc/argv array */
124 /* (add a string pointer to a NULL-terminated array of string pointers) */
126 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
128 /* Grow the array; "*argc" currently contains the number of string
129 pointers, *not* counting the NULL pointer at the end, so we have
130 to add 2 in order to get the new size of the array, including the
131 new pointer and the terminating NULL pointer. */
132 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
134 /* Stuff the pointer into the penultimate element of the array, which
135 is the one at the index specified by "*argc". */
138 /* Now bump the count. */
141 /* We overwrite the NULL pointer; put it back right after the
151 /* Quote the argument element if necessary, so that it will get
152 * reconstructed correctly in the C runtime startup code. Note that
153 * the unquoting algorithm in the C runtime is really weird, and
154 * rather different than what Unix shells do. See stdargv.c in the C
155 * runtime sources (in the Platform SDK, in src/crt).
157 * Stolen from GLib's protect_argv(), an internal routine that quotes
158 * string in an argument list so that they arguments will be handled
159 * correctly in the command-line string passed to CreateProcess()
160 * if that string is constructed by gluing those strings together.
163 protect_arg (const gchar *argv)
166 const gchar *p = argv;
169 gboolean need_dblquotes = FALSE;
172 if (*p == ' ' || *p == '\t')
173 need_dblquotes = TRUE;
176 else if (*p == '\\') {
179 while (*pp && *pp == '\\')
188 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
197 else if (*p == '\\') {
200 while (*pp && *pp == '\\')
217 * Generate a string for a Win32 error.
219 #define ERRBUF_SIZE 1024
221 win32strerror(DWORD error)
223 static char errbuf[ERRBUF_SIZE+1];
227 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
231 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
232 * message. Get rid of it.
234 errlen = strlen(errbuf);
236 errbuf[errlen - 1] = '\0';
237 errbuf[errlen - 2] = '\0';
239 p = strchr(errbuf, '\0');
240 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
245 * Generate a string for a Win32 exception code.
248 win32strexception(DWORD exception)
250 static char errbuf[ERRBUF_SIZE+1];
251 static const struct exception_msg {
255 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
256 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
257 { EXCEPTION_BREAKPOINT, "Breakpoint" },
258 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
259 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
260 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
261 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
262 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
263 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
264 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
265 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
266 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
267 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
268 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
269 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
270 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
271 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
272 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
273 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
274 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
275 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
276 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
279 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
282 for (i = 0; i < N_EXCEPTIONS; i++) {
283 if (exceptions[i].code == exception)
284 return exceptions[i].msg;
286 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
291 /* Initialize an argument list and add dumpcap to it. */
293 init_pipe_args(int *argc) {
295 const char *progfile_dir;
298 progfile_dir = get_progfile_dir();
299 if (progfile_dir == NULL) {
303 /* Allocate the string pointer array with enough space for the
304 terminating NULL pointer. */
306 argv = g_malloc(sizeof (char *));
309 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
310 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
312 /* Make that the first argument in the argument list (argv[0]). */
313 argv = sync_pipe_add_arg(argv, argc, exename);
318 #define ARGV_NUMBER_LEN 24
319 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
321 sync_pipe_start(capture_options *capture_opts) {
322 char ssnap[ARGV_NUMBER_LEN];
323 char sdlt[ARGV_NUMBER_LEN];
324 char scount[ARGV_NUMBER_LEN];
325 char sfilesize[ARGV_NUMBER_LEN];
326 char sfile_duration[ARGV_NUMBER_LEN];
327 char sring_num_files[ARGV_NUMBER_LEN];
328 char sautostop_files[ARGV_NUMBER_LEN];
329 char sautostop_filesize[ARGV_NUMBER_LEN];
330 char sautostop_duration[ARGV_NUMBER_LEN];
331 #ifdef HAVE_PCAP_REMOTE
334 #ifdef HAVE_PCAP_SETSAMPLING
335 char ssampling[ARGV_NUMBER_LEN];
338 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
339 char buffer_size[ARGV_NUMBER_LEN];
343 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
344 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
345 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
346 GString *args = g_string_sized_new(200);
348 SECURITY_ATTRIBUTES sa;
350 PROCESS_INFORMATION pi;
351 char control_id[ARGV_NUMBER_LEN];
352 gchar *signal_pipe_name;
355 int sync_pipe[2]; /* pipe used to send messages from child to parent */
356 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
358 int sync_pipe_read_fd;
363 interface_options interface_opts;
366 if (capture_opts->ifaces->len > 1)
367 capture_opts->use_pcapng = TRUE;
368 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
369 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
371 capture_opts->fork_child = -1;
373 argv = init_pipe_args(&argc);
375 /* We don't know where to find dumpcap. */
376 report_failure("We don't know where to find dumpcap.");
380 if (capture_opts->ifaces->len > 1)
381 argv = sync_pipe_add_arg(argv, &argc, "-t");
383 if (capture_opts->use_pcapng)
384 argv = sync_pipe_add_arg(argv, &argc, "-n");
386 argv = sync_pipe_add_arg(argv, &argc, "-P");
388 if (capture_opts->multi_files_on) {
389 if (capture_opts->has_autostop_filesize) {
390 argv = sync_pipe_add_arg(argv, &argc, "-b");
391 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
392 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
395 if (capture_opts->has_file_duration) {
396 argv = sync_pipe_add_arg(argv, &argc, "-b");
397 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
398 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
401 if (capture_opts->has_ring_num_files) {
402 argv = sync_pipe_add_arg(argv, &argc, "-b");
403 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
404 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
407 if (capture_opts->has_autostop_files) {
408 argv = sync_pipe_add_arg(argv, &argc, "-a");
409 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
410 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
413 if (capture_opts->has_autostop_filesize) {
414 argv = sync_pipe_add_arg(argv, &argc, "-a");
415 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
416 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
420 if (capture_opts->has_autostop_packets) {
421 argv = sync_pipe_add_arg(argv, &argc, "-c");
422 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
423 argv = sync_pipe_add_arg(argv, &argc, scount);
426 if (capture_opts->has_autostop_duration) {
427 argv = sync_pipe_add_arg(argv, &argc, "-a");
428 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
429 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
431 if (capture_opts->ifaces->len == 0) {
433 interface_opts.name = g_strdup(capture_opts->iface);
434 if (capture_opts->iface_descr) {
435 interface_opts.descr = g_strdup(capture_opts->iface_descr);
437 interface_opts.descr = NULL;
439 interface_opts.cfilter = g_strdup(capture_opts->cfilter);
440 interface_opts.snaplen = capture_opts->snaplen;
441 interface_opts.linktype = capture_opts->linktype;
442 interface_opts.promisc_mode = capture_opts->promisc_mode;
443 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
444 interface_opts.buffer_size = capture_opts->buffer_size;
446 interface_opts.monitor_mode = capture_opts->monitor_mode;
447 #ifdef HAVE_PCAP_REMOTE
448 interface_opts.src_type = capture_opts->src_type;
449 if (capture_opts->remote_host) {
450 interface_opts.remote_host = g_strdup(capture_opts->remote_host);
452 interface_opts.remote_host = NULL;
454 if (capture_opts->remote_port) {
455 interface_opts.remote_port = g_strdup(capture_opts->remote_port);
457 interface_opts.remote_port = NULL;
459 interface_opts.auth_type = capture_opts->auth_type;
460 if (capture_opts->auth_username) {
461 interface_opts.auth_username = g_strdup(capture_opts->auth_username);
463 interface_opts.auth_username = NULL;
465 if (capture_opts->auth_password) {
466 interface_opts.auth_password = g_strdup(capture_opts->auth_password);
468 interface_opts.auth_password = NULL;
470 interface_opts.datatx_udp = capture_opts->datatx_udp;
471 interface_opts.nocap_rpcap = capture_opts->nocap_rpcap;
472 interface_opts.nocap_local = capture_opts->nocap_local;
474 #ifdef HAVE_PCAP_SETSAMPLING
475 interface_opts.sampling_method = capture_opts->sampling_method;
476 interface_opts.sampling_param = capture_opts->sampling_param;
478 g_array_append_val(capture_opts->ifaces, interface_opts);
483 for (j = 0; j < capture_opts->ifaces->len; j++) {
484 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
486 argv = sync_pipe_add_arg(argv, &argc, "-i");
487 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
489 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
490 argv = sync_pipe_add_arg(argv, &argc, "-f");
491 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
494 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
495 argv = sync_pipe_add_arg(argv, &argc, "-s");
496 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
497 argv = sync_pipe_add_arg(argv, &argc, ssnap);
500 if (interface_opts.linktype != -1) {
501 argv = sync_pipe_add_arg(argv, &argc, "-y");
502 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s", linktype_val_to_name(interface_opts.linktype));
503 argv = sync_pipe_add_arg(argv, &argc, sdlt);
506 if (!interface_opts.promisc_mode) {
507 argv = sync_pipe_add_arg(argv, &argc, "-p");
510 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
511 if (interface_opts.buffer_size != 1) {
512 argv = sync_pipe_add_arg(argv, &argc, "-B");
513 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
514 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
518 if (interface_opts.monitor_mode) {
519 argv = sync_pipe_add_arg(argv, &argc, "-I");
522 #ifdef HAVE_PCAP_REMOTE
523 if (interface_opts.datatx_udp)
524 argv = sync_pipe_add_arg(argv, &argc, "-u");
526 if (!interface_opts.nocap_rpcap)
527 argv = sync_pipe_add_arg(argv, &argc, "-r");
529 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
530 argv = sync_pipe_add_arg(argv, &argc, "-A");
531 g_snprintf(sauth, sizeof(sauth), "%s:%s",
532 interface_opts.auth_username,
533 interface_opts.auth_password);
534 argv = sync_pipe_add_arg(argv, &argc, sauth);
538 #ifdef HAVE_PCAP_SETSAMPLING
539 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
540 argv = sync_pipe_add_arg(argv, &argc, "-m");
541 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
542 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
543 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
545 interface_opts.sampling_param);
546 argv = sync_pipe_add_arg(argv, &argc, ssampling);
551 capture_opts->ifaces = g_array_remove_index(capture_opts->ifaces, 0);
554 /* dumpcap should be running in capture child mode (hidden feature) */
556 argv = sync_pipe_add_arg(argv, &argc, "-Z");
558 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
559 argv = sync_pipe_add_arg(argv, &argc, control_id);
561 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
565 if (capture_opts->save_file) {
566 argv = sync_pipe_add_arg(argv, &argc, "-w");
567 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
569 for (i = 0; i < argc; i++) {
570 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
574 /* init SECURITY_ATTRIBUTES */
575 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
576 sa.bInheritHandle = TRUE;
577 sa.lpSecurityDescriptor = NULL;
579 /* Create a pipe for the child process */
580 /* (increase this value if you have trouble while fast capture file switches) */
581 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
582 /* Couldn't create the pipe between parent and child. */
583 report_failure("Couldn't create sync pipe: %s",
584 win32strerror(GetLastError()));
585 g_free( (gpointer) argv[0]);
586 g_free( (gpointer) argv);
590 /* Create the signal pipe */
591 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
592 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
593 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
594 g_free(signal_pipe_name);
596 if (signal_pipe == INVALID_HANDLE_VALUE) {
597 /* Couldn't create the signal pipe between parent and child. */
598 report_failure("Couldn't create signal pipe: %s",
599 win32strerror(GetLastError()));
600 g_free( (gpointer) argv[0]);
601 g_free( (gpointer) argv);
605 /* init STARTUPINFO */
606 memset(&si, 0, sizeof(si));
609 si.dwFlags = STARTF_USESHOWWINDOW;
610 si.wShowWindow = SW_SHOW;
612 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
613 si.wShowWindow = SW_HIDE; /* this hides the console window */
614 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
615 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
616 si.hStdError = sync_pipe_write;
617 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
620 /* convert args array into a single string */
621 /* XXX - could change sync_pipe_add_arg() instead */
622 /* there is a drawback here: the length is internally limited to 1024 bytes */
623 for(i=0; argv[i] != 0; i++) {
624 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
625 quoted_arg = protect_arg(argv[i]);
626 g_string_append(args, quoted_arg);
631 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
632 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
633 report_failure("Couldn't run %s in child process: %s",
634 args->str, win32strerror(GetLastError()));
635 CloseHandle(sync_pipe_read);
636 CloseHandle(sync_pipe_write);
637 g_free( (gpointer) argv[0]);
638 g_free( (gpointer) argv);
641 capture_opts->fork_child = (int) pi.hProcess;
642 g_string_free(args, TRUE);
644 /* associate the operating system filehandle to a C run-time file handle */
645 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
646 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
648 /* associate the operating system filehandle to a C run-time file handle */
649 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
652 if (pipe(sync_pipe) < 0) {
653 /* Couldn't create the pipe between parent and child. */
654 report_failure("Couldn't create sync pipe: %s", strerror(errno));
655 g_free( (gpointer) argv[0]);
660 if ((capture_opts->fork_child = fork()) == 0) {
662 * Child process - run dumpcap with the right arguments to make
663 * it just capture with the specified capture parameters
665 dup2(sync_pipe[PIPE_WRITE], 2);
666 ws_close(sync_pipe[PIPE_READ]);
667 execv(argv[0], (gpointer)argv);
668 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
669 argv[0], strerror(errno));
670 sync_pipe_errmsg_to_parent(2, errmsg, "");
672 /* Exit with "_exit()", so that we don't close the connection
673 to the X server (and cause stuff buffered up by our parent but
674 not yet sent to be sent, as that stuff should only be sent by
675 our parent). We've sent an error message to the parent, so
676 we exit with an exit status of 1 (any exit status other than
677 0 or 1 will cause an additional message to report that exit
678 status, over and above the error message we sent to the parent). */
682 sync_pipe_read_fd = sync_pipe[PIPE_READ];
685 g_free( (gpointer) argv[0]); /* exename */
687 /* Parent process - read messages from the child process over the
689 g_free( (gpointer) argv); /* free up arg array */
691 /* Close the write side of the pipe, so that only the child has it
692 open, and thus it completely closes, and thus returns to us
693 an EOF indication, if the child closes it (either deliberately
694 or by exiting abnormally). */
696 CloseHandle(sync_pipe_write);
698 ws_close(sync_pipe[PIPE_WRITE]);
701 if (capture_opts->fork_child == -1) {
702 /* We couldn't even create the child process. */
703 report_failure("Couldn't create child process: %s", strerror(errno));
704 ws_close(sync_pipe_read_fd);
706 ws_close(capture_opts->signal_pipe_write_fd);
711 capture_opts->fork_child_status = 0;
713 /* we might wait for a moment till child is ready, so update screen now */
714 main_window_update();
716 /* We were able to set up to read the capture file;
717 arrange that our callback be called whenever it's possible
718 to read from the sync pipe, so that it's called when
719 the child process wants to tell us something. */
721 /* we have a running capture, now wait for the real capture filename */
722 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
723 &capture_opts->fork_child, sync_pipe_input_cb);
729 * Open two pipes to dumpcap with the supplied arguments, one for its
730 * standard output and one for its standard error.
732 * On success, *msg is unchanged and 0 is returned; data_read_fd,
733 * messsage_read_fd, and fork_child point to the standard output pipe's
734 * file descriptor, the standard error pipe's file descriptor, and
735 * the child's PID/handle, respectively.
737 * On failure, *msg points to an error message for the failure, and -1 is
738 * returned, in which case *msg must be freed with g_free().
740 /* XXX - This duplicates a lot of code in sync_pipe_start() */
741 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
742 #define PIPE_BUF_SIZE 5120
744 sync_pipe_open_command(const char** argv, int *data_read_fd,
745 int *message_read_fd, int *fork_child, gchar **msg)
747 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
749 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
750 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
751 GString *args = g_string_sized_new(200);
753 SECURITY_ATTRIBUTES sa;
755 PROCESS_INFORMATION pi;
759 int sync_pipe[2]; /* pipe used to send messages from child to parent */
760 int data_pipe[2]; /* pipe used to send data from child to parent */
765 *message_read_fd = -1;
766 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
769 /* We can't return anything */
771 g_string_free(args, TRUE);
777 /* init SECURITY_ATTRIBUTES */
778 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
779 sa.bInheritHandle = TRUE;
780 sa.lpSecurityDescriptor = NULL;
782 /* Create a pipe for the child process to send us messages */
783 /* (increase this value if you have trouble while fast capture file switches) */
784 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
785 /* Couldn't create the message pipe between parent and child. */
786 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
787 win32strerror(GetLastError()));
788 g_free( (gpointer) argv[0]);
789 g_free( (gpointer) argv);
793 /* Create a pipe for the child process to send us data */
794 /* (increase this value if you have trouble while fast capture file switches) */
795 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
796 /* Couldn't create the message pipe between parent and child. */
797 *msg = g_strdup_printf("Couldn't create data pipe: %s",
798 win32strerror(GetLastError()));
799 CloseHandle(sync_pipe[PIPE_READ]);
800 CloseHandle(sync_pipe[PIPE_WRITE]);
801 g_free( (gpointer) argv[0]);
802 g_free( (gpointer) argv);
806 /* init STARTUPINFO */
807 memset(&si, 0, sizeof(si));
810 si.dwFlags = STARTF_USESHOWWINDOW;
811 si.wShowWindow = SW_SHOW;
813 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
814 si.wShowWindow = SW_HIDE; /* this hides the console window */
816 si.hStdOutput = data_pipe[PIPE_WRITE];
817 si.hStdError = sync_pipe[PIPE_WRITE];
820 /* convert args array into a single string */
821 /* XXX - could change sync_pipe_add_arg() instead */
822 /* there is a drawback here: the length is internally limited to 1024 bytes */
823 for(i=0; argv[i] != 0; i++) {
824 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
825 quoted_arg = protect_arg(argv[i]);
826 g_string_append(args, quoted_arg);
831 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
832 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
833 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
834 args->str, win32strerror(GetLastError()));
835 CloseHandle(data_pipe[PIPE_READ]);
836 CloseHandle(data_pipe[PIPE_WRITE]);
837 CloseHandle(sync_pipe[PIPE_READ]);
838 CloseHandle(sync_pipe[PIPE_WRITE]);
839 g_free( (gpointer) argv[0]);
840 g_free( (gpointer) argv);
843 *fork_child = (int) pi.hProcess;
844 g_string_free(args, TRUE);
846 /* associate the operating system filehandles to C run-time file handles */
847 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
848 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
849 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
851 /* Create a pipe for the child process to send us messages */
852 if (pipe(sync_pipe) < 0) {
853 /* Couldn't create the message pipe between parent and child. */
854 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
855 g_free( (gpointer) argv[0]);
860 /* Create a pipe for the child process to send us data */
861 if (pipe(data_pipe) < 0) {
862 /* Couldn't create the data pipe between parent and child. */
863 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
864 ws_close(sync_pipe[PIPE_READ]);
865 ws_close(sync_pipe[PIPE_WRITE]);
866 g_free( (gpointer) argv[0]);
871 if ((*fork_child = fork()) == 0) {
873 * Child process - run dumpcap with the right arguments to make
874 * it just capture with the specified capture parameters
876 dup2(data_pipe[PIPE_WRITE], 1);
877 ws_close(data_pipe[PIPE_READ]);
878 ws_close(data_pipe[PIPE_WRITE]);
879 dup2(sync_pipe[PIPE_WRITE], 2);
880 ws_close(sync_pipe[PIPE_READ]);
881 ws_close(sync_pipe[PIPE_WRITE]);
882 execv(argv[0], (gpointer)argv);
883 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
884 argv[0], strerror(errno));
885 sync_pipe_errmsg_to_parent(2, errmsg, "");
887 /* Exit with "_exit()", so that we don't close the connection
888 to the X server (and cause stuff buffered up by our parent but
889 not yet sent to be sent, as that stuff should only be sent by
890 our parent). We've sent an error message to the parent, so
891 we exit with an exit status of 1 (any exit status other than
892 0 or 1 will cause an additional message to report that exit
893 status, over and above the error message we sent to the parent). */
897 *data_read_fd = data_pipe[PIPE_READ];
898 *message_read_fd = sync_pipe[PIPE_READ];
901 g_free( (gpointer) argv[0]); /* exename */
903 /* Parent process - read messages from the child process over the
905 g_free( (gpointer) argv); /* free up arg array */
907 /* Close the write sides of the pipes, so that only the child has them
908 open, and thus they completely close, and thus return to us
909 an EOF indication, if the child closes them (either deliberately
910 or by exiting abnormally). */
912 CloseHandle(data_pipe[PIPE_WRITE]);
913 CloseHandle(sync_pipe[PIPE_WRITE]);
915 ws_close(data_pipe[PIPE_WRITE]);
916 ws_close(sync_pipe[PIPE_WRITE]);
919 if (*fork_child == -1) {
920 /* We couldn't even create the child process. */
921 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
922 ws_close(*data_read_fd);
923 ws_close(*message_read_fd);
927 /* we might wait for a moment till child is ready, so update screen now */
928 main_window_update();
933 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
934 * returned. On failure, *msg points to an error message for the
935 * failure, and -1 is returned. In the latter case, *msg must be
936 * freed with g_free().
939 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
940 int *fork_child, gchar **msg)
942 ws_close(*data_read_fd);
943 if (message_read_fd != NULL)
944 ws_close(*message_read_fd);
947 /* XXX - Should we signal the child somehow? */
948 sync_pipe_kill(*fork_child);
951 return sync_pipe_wait_for_child(*fork_child, msg);
955 * Run dumpcap with the supplied arguments.
957 * On success, *data points to a buffer containing the dumpcap output,
958 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
959 * must be freed with g_free().
961 * On failure, *data is NULL, *primary_msg points to an error message,
962 * *secondary_msg either points to an additional error message or is
963 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
964 * must be freed with g_free().
966 /* XXX - This duplicates a lot of code in sync_pipe_start() */
967 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
968 #define PIPE_BUF_SIZE 5120
970 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
971 gchar **secondary_msg)
974 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
976 gchar buffer[PIPE_BUF_SIZE+1];
980 char *primary_msg_text;
981 int secondary_msg_len;
982 char *secondary_msg_text;
984 GString *data_buf = NULL;
987 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
991 *secondary_msg = NULL;
997 * We were able to set up to read dumpcap's output. Do so.
999 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1001 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1002 buffer, primary_msg);
1004 /* We got a read error from the sync pipe, or we got no data at
1005 all from the sync pipe, so we're not going to be getting any
1006 data or error message from the child process. Pick up its
1007 exit status, and complain.
1009 We don't have to worry about killing the child, if the sync pipe
1010 returned an error. Usually this error is caused as the child killed
1011 itself while going down. Even in the rare cases that this isn't the
1012 case, the child will get an error when writing to the broken pipe
1013 the next time, cleaning itself up then. */
1014 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1016 /* We got an EOF from the sync pipe. That means that it exited
1017 before giving us any data to read. If ret is -1, we report
1018 that as a bad exit (e.g., exiting due to a signal); otherwise,
1019 we report it as a premature exit. */
1021 *primary_msg = wait_msg;
1023 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1025 /* We got an error from the sync pipe. If ret is -1, report
1026 both the sync pipe I/O error and the wait error. */
1028 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1029 g_free(*primary_msg);
1031 *primary_msg = combined_msg;
1034 *secondary_msg = NULL;
1039 /* we got a valid message block from the child, process it */
1044 * Error from dumpcap; there will be a primary message and a
1045 * secondary message.
1048 /* convert primary message */
1049 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1050 primary_msg_text = buffer+4;
1051 /* convert secondary message */
1052 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1053 &secondary_msg_len);
1054 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1055 /* the capture child will close the sync_pipe, nothing to do */
1058 * Pick up the child status.
1060 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1064 * Child process failed unexpectedly, or wait failed; msg is the
1068 *secondary_msg = NULL;
1071 * Child process failed, but returned the expected exit status.
1072 * Return the messages it gave us, and indicate failure.
1074 *primary_msg = g_strdup(primary_msg_text);
1075 *secondary_msg = g_strdup(secondary_msg_text);
1082 /* read the output from the command */
1083 data_buf = g_string_new("");
1084 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1085 buffer[count] = '\0';
1086 g_string_append(data_buf, buffer);
1090 * Pick up the child status.
1092 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1096 * Child process failed unexpectedly, or wait failed; msg is the
1100 *secondary_msg = NULL;
1101 g_string_free(data_buf, TRUE);
1105 * Child process succeeded.
1107 *primary_msg = NULL;
1108 *secondary_msg = NULL;
1109 *data = data_buf->str;
1110 g_string_free(data_buf, FALSE);
1116 * Pick up the child status.
1118 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1122 * Child process failed unexpectedly, or wait failed; msg is the
1126 *secondary_msg = NULL;
1129 * Child process returned an unknown status.
1131 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1133 *secondary_msg = NULL;
1143 * Get the list of interfaces using dumpcap.
1145 * On success, *data points to a buffer containing the dumpcap output,
1146 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1147 * must be freed with g_free().
1149 * On failure, *data is NULL, *primary_msg points to an error message,
1150 * *secondary_msg either points to an additional error message or is
1151 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1152 * must be freed with g_free().
1155 sync_interface_list_open(gchar **data, gchar **primary_msg,
1156 gchar **secondary_msg)
1161 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1163 argv = init_pipe_args(&argc);
1166 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1167 *secondary_msg = NULL;
1172 /* Ask for the interface list */
1173 argv = sync_pipe_add_arg(argv, &argc, "-D");
1176 /* Run dumpcap in capture child mode */
1177 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1178 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1180 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1184 * Get the capabilities of an interface using dumpcap.
1186 * On success, *data points to a buffer containing the dumpcap output,
1187 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1188 * must be freed with g_free().
1190 * On failure, *data is NULL, *primary_msg points to an error message,
1191 * *secondary_msg either points to an additional error message or is
1192 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1193 * must be freed with g_free().
1196 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1197 gchar **data, gchar **primary_msg,
1198 gchar **secondary_msg)
1203 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1205 argv = init_pipe_args(&argc);
1208 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1209 *secondary_msg = NULL;
1214 /* Ask for the interface capabilities */
1215 argv = sync_pipe_add_arg(argv, &argc, "-i");
1216 argv = sync_pipe_add_arg(argv, &argc, ifname);
1217 argv = sync_pipe_add_arg(argv, &argc, "-L");
1219 argv = sync_pipe_add_arg(argv, &argc, "-I");
1222 /* Run dumpcap in capture child mode */
1223 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1224 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1226 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1230 * Start getting interface statistics using dumpcap. On success, read_fd
1231 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1232 * and zero is returned. On failure, *msg will point to an error message
1233 * that must be g_free()d, and -1 will be returned.
1236 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1240 int message_read_fd, ret;
1242 gchar buffer[PIPE_BUF_SIZE+1];
1245 int primary_msg_len;
1246 char *primary_msg_text;
1247 int secondary_msg_len;
1248 /*char *secondary_msg_text;*/
1251 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1253 argv = init_pipe_args(&argc);
1256 *msg = g_strdup("We don't know where to find dumpcap.");
1260 /* Ask for the interface statistics */
1261 argv = sync_pipe_add_arg(argv, &argc, "-S");
1264 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1265 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1267 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1273 * We were able to set up to read dumpcap's output. Do so.
1275 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1277 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1280 /* We got a read error from the sync pipe, or we got no data at
1281 all from the sync pipe, so we're not going to be getting any
1282 data or error message from the child process. Pick up its
1283 exit status, and complain.
1285 We don't have to worry about killing the child, if the sync pipe
1286 returned an error. Usually this error is caused as the child killed
1287 itself while going down. Even in the rare cases that this isn't the
1288 case, the child will get an error when writing to the broken pipe
1289 the next time, cleaning itself up then. */
1290 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1292 /* We got an EOF from the sync pipe. That means that it exited
1293 before giving us any data to read. If ret is -1, we report
1294 that as a bad exit (e.g., exiting due to a signal); otherwise,
1295 we report it as a premature exit. */
1299 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1301 /* We got an error from the sync pipe. If ret is -1, report
1302 both the sync pipe I/O error and the wait error. */
1304 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1307 *msg = combined_msg;
1314 /* we got a valid message block from the child, process it */
1319 * Error from dumpcap; there will be a primary message and a
1320 * secondary message.
1323 /* convert primary message */
1324 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1325 primary_msg_text = buffer+4;
1326 /* convert secondary message */
1327 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1328 &secondary_msg_len);
1329 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1330 /* the capture child will close the sync_pipe, nothing to do */
1333 * Pick up the child status.
1335 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1339 * Child process failed unexpectedly, or wait failed; msg is the
1344 * Child process failed, but returned the expected exit status.
1345 * Return the messages it gave us, and indicate failure.
1347 *msg = g_strdup(primary_msg_text);
1353 /* Close the message pipe. */
1354 ws_close(message_read_fd);
1359 * Pick up the child status.
1361 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1365 * Child process failed unexpectedly, or wait failed; msg is the
1370 * Child process returned an unknown status.
1372 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1381 /* Close down the stats process */
1383 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1385 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1388 /* read a number of bytes from a pipe */
1389 /* (blocks until enough bytes read or an error occurs) */
1391 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1398 newly = read(pipe_fd, &bytes[offset], required);
1401 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1402 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1409 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1410 "read from pipe %d: error(%u): %s", pipe_fd, error,
1412 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1425 static gboolean pipe_data_available(int pipe_fd) {
1426 #ifdef _WIN32 /* PeekNamedPipe */
1427 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1430 if (hPipe == INVALID_HANDLE_VALUE)
1433 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1436 if (bytes_avail > 0)
1441 struct timeval timeout;
1444 FD_SET(pipe_fd, &rfds);
1446 timeout.tv_usec = 0;
1448 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1455 /* Read a line from a pipe, similar to fgets */
1457 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1461 while(offset < max - 1) {
1463 if (! pipe_data_available(pipe_fd))
1465 newly = read(pipe_fd, &bytes[offset], 1);
1467 /* EOF - not necessarily an error */
1469 } else if (newly < 0) {
1471 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1472 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1474 } else if (bytes[offset] == '\n') {
1480 bytes[offset] = '\0';
1486 /* convert header values (indicator and 3-byte length) */
1488 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1490 g_assert(header_len == 4);
1492 /* convert header values */
1493 *indicator = header[0];
1494 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1497 /* read a message from the sending pipe in the standard format
1498 (1-byte message indicator, 3-byte message length (excluding length
1499 and indicator field), and the rest is the message) */
1501 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1508 /* read header (indicator and 3-byte length) */
1509 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1513 * Immediate EOF; if the capture child exits normally, this
1514 * is an "I'm done" indication, so don't report it as an
1517 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1518 "read %d got an EOF", pipe_fd);
1521 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1522 "read %d failed to read header: %u", pipe_fd, newly);
1525 * Short read, but not an immediate EOF.
1527 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %d bytes",
1533 /* convert header values */
1534 pipe_convert_header(header, 4, indicator, &required);
1536 /* only indicator with no value? */
1538 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1539 "read %d indicator: %c empty value", pipe_fd, *indicator);
1543 /* does the data fit into the given buffer? */
1544 if(required > len) {
1545 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1546 "read %d length error, required %d > len %d, indicator: %u",
1547 pipe_fd, required, len, *indicator);
1549 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1550 memcpy(msg, header, sizeof(header));
1551 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1552 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1558 /* read the actual block data */
1559 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1560 if(newly != required) {
1562 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1568 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1569 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1570 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1577 /* There's stuff to read from the sync pipe, meaning the child has sent
1578 us a message, or the sync pipe has closed, meaning the child has
1579 closed it (perhaps because it exited). */
1581 sync_pipe_input_cb(gint source, gpointer user_data)
1583 capture_options *capture_opts = (capture_options *)user_data;
1585 char buffer[SP_MAX_MSG_LEN+1];
1591 char *secondary_msg;
1592 char *wait_msg, *combined_msg;
1594 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1597 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1599 If we got a read error or a bad message, nread is -1 and
1600 primary_msg is set to point to an error message. We don't
1601 have to worry about killing the child; usually this error
1602 is caused as the child killed itself while going down.
1603 Even in the rare cases that this isn't the case, the child
1604 will get an error when writing to the broken pipe the next time,
1605 cleaning itself up then.
1607 If we got an EOF, nread is 0 and primary_msg isn't set. This
1608 is an indication that the capture is finished. */
1609 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &wait_msg);
1611 /* We got an EOF from the sync pipe. That means that the capture
1612 child exited, and not in the middle of a message; we treat
1613 that as an indication that it's done, and only report an
1614 error if ret is -1, in which case wait_msg is the error
1617 primary_msg = wait_msg;
1619 /* We got an error from the sync pipe. If ret is -1, report
1620 both the sync pipe I/O error and the wait error. */
1622 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1623 g_free(primary_msg);
1625 primary_msg = combined_msg;
1629 /* No more child process. */
1630 capture_opts->fork_child = -1;
1631 capture_opts->fork_child_status = ret;
1634 ws_close(capture_opts->signal_pipe_write_fd);
1636 capture_input_closed(capture_opts, primary_msg);
1637 g_free(primary_msg);
1641 /* we got a valid message block from the child, process it */
1644 if(!capture_input_new_file(capture_opts, buffer)) {
1645 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1647 /* We weren't able to open the new capture file; user has been
1648 alerted. Close the sync pipe. */
1651 /* the child has send us a filename which we couldn't open.
1652 this probably means, the child is creating files faster than we can handle it.
1653 this should only be the case for very fast file switches
1654 we can't do much more than telling the child to stop
1655 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1656 sync_pipe_stop(capture_opts);
1659 case SP_PACKET_COUNT:
1660 nread = atoi(buffer);
1661 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1662 capture_input_new_packets(capture_opts, nread);
1665 /* convert primary message */
1666 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1667 primary_msg = buffer+4;
1668 /* convert secondary message */
1669 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1670 secondary_msg = primary_msg + primary_len + 4;
1671 /* message output */
1672 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1673 /* the capture child will close the sync_pipe, nothing to do for now */
1674 /* (an error message doesn't mean we have to stop capturing) */
1677 capture_input_cfilter_error_message(capture_opts, buffer);
1678 /* the capture child will close the sync_pipe, nothing to do for now */
1681 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1684 g_assert_not_reached();
1692 /* the child process is going down, wait until it's completely terminated */
1694 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1696 int fork_child_status;
1699 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1700 g_assert(fork_child != -1);
1702 *msgp = NULL; /* assume no error */
1705 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1706 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1710 * The child exited; return its exit status. Do not treat this as
1713 ret = fork_child_status;
1714 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1715 /* Probably an exception code */
1716 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1717 win32strexception(fork_child_status));
1722 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1723 if (WIFEXITED(fork_child_status)) {
1725 * The child exited; return its exit status. Do not treat this as
1728 ret = WEXITSTATUS(fork_child_status);
1729 } else if (WIFSTOPPED(fork_child_status)) {
1730 /* It stopped, rather than exiting. "Should not happen." */
1731 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1732 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1734 } else if (WIFSIGNALED(fork_child_status)) {
1735 /* It died with a signal. */
1736 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1737 sync_pipe_signame(WTERMSIG(fork_child_status)),
1738 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1741 /* What? It had to either have exited, or stopped, or died with
1742 a signal; what happened here? */
1743 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1748 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1753 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1759 /* convert signal to corresponding name */
1761 sync_pipe_signame(int sig)
1764 static char sigmsg_buf[6+1+3+1];
1773 sigmsg = "Interrupted";
1781 sigmsg = "Illegal instruction";
1785 sigmsg = "Trace trap";
1793 sigmsg = "Arithmetic exception";
1801 sigmsg = "Bus error";
1805 sigmsg = "Segmentation violation";
1808 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1809 Linux is POSIX compliant. These are not POSIX-defined signals ---
1810 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1812 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1813 were omitted from POSIX.1 because their behavior is
1814 implementation dependent and could not be adequately catego-
1815 rized. Conforming implementations may deliver these sig-
1816 nals, but must document the circumstances under which they
1817 are delivered and note any restrictions concerning their
1820 So we only check for SIGSYS on those systems that happen to
1821 implement them (a system can be POSIX-compliant and implement
1822 them, it's just that POSIX doesn't *require* a POSIX-compliant
1823 system to implement them).
1828 sigmsg = "Bad system call";
1833 sigmsg = "Broken pipe";
1837 sigmsg = "Alarm clock";
1841 sigmsg = "Terminated";
1845 /* Returning a static buffer is ok in the context we use it here */
1846 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1847 sigmsg = sigmsg_buf;
1856 /* tell the child through the signal pipe that we want to quit the capture */
1858 signal_pipe_capquit_to_child(capture_options *capture_opts)
1860 const char quit_msg[] = "QUIT";
1864 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1866 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1867 /* simply sending a "QUIT" string */
1868 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1869 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1871 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1872 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1878 /* user wants to stop the capture run */
1880 sync_pipe_stop(capture_options *capture_opts)
1885 gboolean terminate = TRUE;
1888 if (capture_opts->fork_child != -1) {
1890 /* send the SIGINT signal to close the capture child gracefully. */
1891 int sts = kill(capture_opts->fork_child, SIGINT);
1893 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1894 "Sending SIGINT to child failed: %s\n", strerror(errno));
1897 #define STOP_SLEEP_TIME 500 /* ms */
1898 #define STOP_CHECK_TIME 50
1899 /* First, use the special signal pipe to try to close the capture child
1902 signal_pipe_capquit_to_child(capture_opts);
1904 /* Next, wait for the process to exit on its own */
1905 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1906 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1907 childstatus != STILL_ACTIVE) {
1911 Sleep(STOP_CHECK_TIME);
1914 /* Force the issue. */
1916 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1917 "sync_pipe_stop: forcing child to exit");
1918 sync_pipe_kill(capture_opts->fork_child);
1925 /* Wireshark has to exit, force the capture child to close */
1927 sync_pipe_kill(int fork_child)
1929 if (fork_child != -1) {
1931 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1933 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1934 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1937 /* Remark: This is not the preferred method of closing a process!
1938 * the clean way would be getting the process id of the child process,
1939 * then getting window handle hWnd of that process (using EnumChildWindows),
1940 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1942 * Unfortunately, I don't know how to get the process id from the
1943 * handle. OpenProcess will get an handle (not a window handle)
1944 * from the process ID; it will not get a window handle from the
1945 * process ID. (How could it? A process can have more than one
1946 * window. For that matter, a process might have *no* windows,
1947 * as a process running dumpcap, the normal child process program,
1950 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1951 * running in the same console; that's not necessarily the case for
1952 * us, as we might not be running in a console.
1953 * And this also will require to have the process id.
1955 TerminateProcess((HANDLE) (fork_child), 0);
1960 #endif /* HAVE_LIBPCAP */