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 void sync_pipe_wait_for_child(capture_options *capture_opts);
120 /* Append an arg (realloc) to an argc/argv array */
121 /* (add a string pointer to a NULL-terminated array of string pointers) */
123 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
125 /* Grow the array; "*argc" currently contains the number of string
126 pointers, *not* counting the NULL pointer at the end, so we have
127 to add 2 in order to get the new size of the array, including the
128 new pointer and the terminating NULL pointer. */
129 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
131 /* Stuff the pointer into the penultimate element of the array, which
132 is the one at the index specified by "*argc". */
135 /* Now bump the count. */
138 /* We overwrite the NULL pointer; put it back right after the
148 /* Quote the argument element if necessary, so that it will get
149 * reconstructed correctly in the C runtime startup code. Note that
150 * the unquoting algorithm in the C runtime is really weird, and
151 * rather different than what Unix shells do. See stdargv.c in the C
152 * runtime sources (in the Platform SDK, in src/crt).
154 * Stolen from GLib's protect_argv(), an internal routine that quotes
155 * string in an argument list so that they arguments will be handled
156 * correctly in the command-line string passed to CreateProcess()
157 * if that string is constructed by gluing those strings together.
160 protect_arg (const gchar *argv)
163 const gchar *p = argv;
166 gboolean need_dblquotes = FALSE;
169 if (*p == ' ' || *p == '\t')
170 need_dblquotes = TRUE;
173 else if (*p == '\\') {
176 while (*pp && *pp == '\\')
185 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
194 else if (*p == '\\') {
197 while (*pp && *pp == '\\')
214 /* Initialize an argument list and add dumpcap to it. */
216 init_pipe_args(int *argc) {
218 const char *progfile_dir;
221 progfile_dir = get_progfile_dir();
222 if (progfile_dir == NULL) {
226 /* Allocate the string pointer array with enough space for the
227 terminating NULL pointer. */
229 argv = g_malloc(sizeof (char *));
232 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
233 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
235 /* Make that the first argument in the argument list (argv[0]). */
236 argv = sync_pipe_add_arg(argv, argc, exename);
241 #define ARGV_NUMBER_LEN 24
242 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
244 sync_pipe_start(capture_options *capture_opts) {
245 char ssnap[ARGV_NUMBER_LEN];
246 char sdlt[ARGV_NUMBER_LEN];
247 char scount[ARGV_NUMBER_LEN];
248 char sfilesize[ARGV_NUMBER_LEN];
249 char sfile_duration[ARGV_NUMBER_LEN];
250 char sring_num_files[ARGV_NUMBER_LEN];
251 char sautostop_files[ARGV_NUMBER_LEN];
252 char sautostop_filesize[ARGV_NUMBER_LEN];
253 char sautostop_duration[ARGV_NUMBER_LEN];
254 #ifdef HAVE_PCAP_REMOTE
257 #ifdef HAVE_PCAP_SETSAMPLING
258 char ssampling[ARGV_NUMBER_LEN];
260 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
261 char buffer_size[ARGV_NUMBER_LEN];
264 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
265 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
266 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
267 GString *args = g_string_sized_new(200);
269 SECURITY_ATTRIBUTES sa;
271 PROCESS_INFORMATION pi;
273 char control_id[ARGV_NUMBER_LEN];
274 gchar *signal_pipe_name;
277 int sync_pipe[2]; /* pipe used to send messages from child to parent */
278 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
280 int sync_pipe_read_fd;
285 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
286 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
288 capture_opts->fork_child = -1;
290 argv = init_pipe_args(&argc);
292 /* We don't know where to find dumpcap. */
293 report_failure("We don't know where to find dumpcap.");
297 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
299 argv = sync_pipe_add_arg(argv, &argc, "-i");
300 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
302 if (capture_opts->has_snaplen) {
303 argv = sync_pipe_add_arg(argv, &argc, "-s");
304 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
305 argv = sync_pipe_add_arg(argv, &argc, ssnap);
308 if (capture_opts->linktype != -1) {
309 argv = sync_pipe_add_arg(argv, &argc, "-y");
310 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
311 argv = sync_pipe_add_arg(argv, &argc, sdlt);
314 if(capture_opts->multi_files_on) {
315 if (capture_opts->has_autostop_filesize) {
316 argv = sync_pipe_add_arg(argv, &argc, "-b");
317 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
318 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
321 if (capture_opts->has_file_duration) {
322 argv = sync_pipe_add_arg(argv, &argc, "-b");
323 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
324 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
327 if (capture_opts->has_ring_num_files) {
328 argv = sync_pipe_add_arg(argv, &argc, "-b");
329 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
330 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
333 if (capture_opts->has_autostop_files) {
334 argv = sync_pipe_add_arg(argv, &argc, "-a");
335 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
336 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
339 if (capture_opts->has_autostop_filesize) {
340 argv = sync_pipe_add_arg(argv, &argc, "-a");
341 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
342 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
346 if (capture_opts->has_autostop_packets) {
347 argv = sync_pipe_add_arg(argv, &argc, "-c");
348 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
349 argv = sync_pipe_add_arg(argv, &argc, scount);
352 if (capture_opts->has_autostop_duration) {
353 argv = sync_pipe_add_arg(argv, &argc, "-a");
354 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
355 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
358 if (!capture_opts->promisc_mode)
359 argv = sync_pipe_add_arg(argv, &argc, "-p");
360 #ifdef HAVE_PCAP_CREATE
361 if (capture_opts->monitor_mode)
362 argv = sync_pipe_add_arg(argv, &argc, "-I");
364 if (capture_opts->use_pcapng)
365 argv = sync_pipe_add_arg(argv, &argc, "-n");
366 #ifdef HAVE_PCAP_REMOTE
367 if (capture_opts->datatx_udp)
368 argv = sync_pipe_add_arg(argv, &argc, "-u");
370 if (!capture_opts->nocap_rpcap)
371 argv = sync_pipe_add_arg(argv, &argc, "-r");
373 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
375 argv = sync_pipe_add_arg(argv, &argc, "-A");
376 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
377 capture_opts->auth_password);
378 argv = sync_pipe_add_arg(argv, &argc, sauth);
381 #ifdef HAVE_PCAP_SETSAMPLING
382 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
384 argv = sync_pipe_add_arg(argv, &argc, "-m");
385 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
386 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
387 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
389 capture_opts->sampling_param);
390 argv = sync_pipe_add_arg(argv, &argc, ssampling);
394 /* dumpcap should be running in capture child mode (hidden feature) */
396 argv = sync_pipe_add_arg(argv, &argc, "-Z");
398 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
399 argv = sync_pipe_add_arg(argv, &argc, control_id);
401 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
405 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
406 argv = sync_pipe_add_arg(argv, &argc, "-B");
407 #ifdef HAVE_PCAP_REMOTE
408 if (capture_opts->src_type == CAPTURE_IFREMOTE)
409 /* No buffer size when using remote interfaces */
410 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
413 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
414 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
417 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
418 argv = sync_pipe_add_arg(argv, &argc, "-f");
419 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
422 if(capture_opts->save_file) {
423 argv = sync_pipe_add_arg(argv, &argc, "-w");
424 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
428 /* init SECURITY_ATTRIBUTES */
429 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
430 sa.bInheritHandle = TRUE;
431 sa.lpSecurityDescriptor = NULL;
433 /* Create a pipe for the child process */
434 /* (increase this value if you have trouble while fast capture file switches) */
435 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
436 /* Couldn't create the pipe between parent and child. */
437 report_failure("Couldn't create sync pipe: %s", strerror(errno));
438 g_free( (gpointer) argv[0]);
439 g_free( (gpointer) argv);
443 /* Create the signal pipe */
444 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
445 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
446 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
447 g_free(signal_pipe_name);
449 if (signal_pipe == INVALID_HANDLE_VALUE) {
450 /* Couldn't create the signal pipe between parent and child. */
451 report_failure("Couldn't create signal pipe: %s", strerror(errno));
452 g_free( (gpointer) argv[0]);
453 g_free( (gpointer) argv);
457 /* init STARTUPINFO */
458 memset(&si, 0, sizeof(si));
461 si.dwFlags = STARTF_USESHOWWINDOW;
462 si.wShowWindow = SW_SHOW;
464 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
465 si.wShowWindow = SW_HIDE; /* this hides the console window */
466 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
467 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
468 si.hStdError = sync_pipe_write;
469 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
472 /* convert args array into a single string */
473 /* XXX - could change sync_pipe_add_arg() instead */
474 /* there is a drawback here: the length is internally limited to 1024 bytes */
475 for(i=0; argv[i] != 0; i++) {
476 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
477 quoted_arg = protect_arg(argv[i]);
478 g_string_append(args, quoted_arg);
483 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
484 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
485 report_failure("Couldn't run %s in child process: error %u",
486 args->str, GetLastError());
487 CloseHandle(sync_pipe_read);
488 CloseHandle(sync_pipe_write);
489 g_free( (gpointer) argv[0]);
490 g_free( (gpointer) argv);
493 capture_opts->fork_child = (int) pi.hProcess;
494 g_string_free(args, TRUE);
496 /* associate the operating system filehandle to a C run-time file handle */
497 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
498 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
500 /* associate the operating system filehandle to a C run-time file handle */
501 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
504 if (pipe(sync_pipe) < 0) {
505 /* Couldn't create the pipe between parent and child. */
506 report_failure("Couldn't create sync pipe: %s", strerror(errno));
507 g_free( (gpointer) argv[0]);
512 if ((capture_opts->fork_child = fork()) == 0) {
514 * Child process - run dumpcap with the right arguments to make
515 * it just capture with the specified capture parameters
517 dup2(sync_pipe[PIPE_WRITE], 2);
518 ws_close(sync_pipe[PIPE_READ]);
519 execv(argv[0], (gpointer)argv);
520 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
521 argv[0], strerror(errno));
522 sync_pipe_errmsg_to_parent(2, errmsg, "");
524 /* Exit with "_exit()", so that we don't close the connection
525 to the X server (and cause stuff buffered up by our parent but
526 not yet sent to be sent, as that stuff should only be sent by
527 our parent). We've sent an error message to the parent, so
528 we exit with an exit status of 1 (any exit status other than
529 0 or 1 will cause an additional message to report that exit
530 status, over and above the error message we sent to the parent). */
534 sync_pipe_read_fd = sync_pipe[PIPE_READ];
537 g_free( (gpointer) argv[0]); /* exename */
539 /* Parent process - read messages from the child process over the
541 g_free( (gpointer) argv); /* free up arg array */
543 /* Close the write side of the pipe, so that only the child has it
544 open, and thus it completely closes, and thus returns to us
545 an EOF indication, if the child closes it (either deliberately
546 or by exiting abnormally). */
548 CloseHandle(sync_pipe_write);
550 ws_close(sync_pipe[PIPE_WRITE]);
553 if (capture_opts->fork_child == -1) {
554 /* We couldn't even create the child process. */
555 report_failure("Couldn't create child process: %s", strerror(errno));
556 ws_close(sync_pipe_read_fd);
558 ws_close(capture_opts->signal_pipe_write_fd);
563 /* we might wait for a moment till child is ready, so update screen now */
564 main_window_update();
566 /* We were able to set up to read the capture file;
567 arrange that our callback be called whenever it's possible
568 to read from the sync pipe, so that it's called when
569 the child process wants to tell us something. */
571 /* we have a running capture, now wait for the real capture filename */
572 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
573 &capture_opts->fork_child, sync_pipe_input_cb);
579 * Open a pipe to dumpcap with the supplied arguments. On success, *msg
580 * is unchanged and 0 is returned; read_fd and fork_child point to the
581 * pipe's file descriptor and child PID/handle, respectively. On failure,
582 * *msg points to an error message for the failure, and -1 is returned.
583 * In the latter case, *msg must be freed with g_free().
585 /* XXX - This duplicates a lot of code in sync_pipe_start() */
586 #define PIPE_BUF_SIZE 5120
588 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
590 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
591 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
592 GString *args = g_string_sized_new(200);
594 SECURITY_ATTRIBUTES sa;
596 PROCESS_INFORMATION pi;
600 int sync_pipe[2]; /* pipe used to send messages from child to parent */
601 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
606 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
609 /* We can't return anything */
611 g_string_free(args, TRUE);
617 /* init SECURITY_ATTRIBUTES */
618 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
619 sa.bInheritHandle = TRUE;
620 sa.lpSecurityDescriptor = NULL;
622 /* Create a pipe for the child process */
623 /* (increase this value if you have trouble while fast capture file switches) */
624 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
625 /* Couldn't create the pipe between parent and child. */
626 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
627 g_free( (gpointer) argv[0]);
628 g_free( (gpointer) argv);
632 /* init STARTUPINFO */
633 memset(&si, 0, sizeof(si));
636 si.dwFlags = STARTF_USESHOWWINDOW;
637 si.wShowWindow = SW_SHOW;
639 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
640 si.wShowWindow = SW_HIDE; /* this hides the console window */
642 si.hStdOutput = sync_pipe_write;
643 si.hStdError = sync_pipe_write;
644 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
647 /* convert args array into a single string */
648 /* XXX - could change sync_pipe_add_arg() instead */
649 /* there is a drawback here: the length is internally limited to 1024 bytes */
650 for(i=0; argv[i] != 0; i++) {
651 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
652 quoted_arg = protect_arg(argv[i]);
653 g_string_append(args, quoted_arg);
658 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
659 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
660 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
661 args->str, GetLastError());
662 CloseHandle(sync_pipe_read);
663 CloseHandle(sync_pipe_write);
664 g_free( (gpointer) argv[0]);
665 g_free( (gpointer) argv);
668 *fork_child = (int) pi.hProcess;
669 g_string_free(args, TRUE);
671 /* associate the operating system filehandle to a C run-time file handle */
672 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
673 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
676 if (pipe(sync_pipe) < 0) {
677 /* Couldn't create the pipe between parent and child. */
678 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
679 g_free( (gpointer) argv[0]);
684 if ((*fork_child = fork()) == 0) {
686 * Child process - run dumpcap with the right arguments to make
687 * it just capture with the specified capture parameters
689 dup2(sync_pipe[PIPE_WRITE], 1);
690 ws_close(sync_pipe[PIPE_READ]);
691 execv(argv[0], (gpointer)argv);
692 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
693 argv[0], strerror(errno));
694 sync_pipe_errmsg_to_parent(1, errmsg, "");
696 /* Exit with "_exit()", so that we don't close the connection
697 to the X server (and cause stuff buffered up by our parent but
698 not yet sent to be sent, as that stuff should only be sent by
699 our parent). We've sent an error message to the parent, so
700 we exit with an exit status of 1 (any exit status other than
701 0 or 1 will cause an additional message to report that exit
702 status, over and above the error message we sent to the parent). */
706 *read_fd = sync_pipe[PIPE_READ];
709 g_free( (gpointer) argv[0]); /* exename */
711 /* Parent process - read messages from the child process over the
713 g_free( (gpointer) argv); /* free up arg array */
715 /* Close the write side of the pipe, so that only the child has it
716 open, and thus it completely closes, and thus returns to us
717 an EOF indication, if the child closes it (either deliberately
718 or by exiting abnormally). */
720 CloseHandle(sync_pipe_write);
722 ws_close(sync_pipe[PIPE_WRITE]);
725 if (*fork_child == -1) {
726 /* We couldn't even create the child process. */
727 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
732 /* we might wait for a moment till child is ready, so update screen now */
733 main_window_update();
738 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
739 * returned. On failure, *msg points to an error message for the
740 * failure, and -1 is returned. In the latter case, *msg must be
741 * freed with g_free().
745 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
747 sync_pipe_close_command(int *read_fd, gchar **msg) {
749 int fork_child_status;
753 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
756 /* XXX - Should we signal the child somehow? */
757 sync_pipe_kill(*fork_child);
758 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
759 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
760 "(errno:%u)", errno);
764 if (wait(&fork_child_status) != -1) {
765 if (WIFEXITED(fork_child_status)) {
766 /* The child exited. */
767 fork_child_status = WEXITSTATUS(fork_child_status);
769 if (WIFSTOPPED(fork_child_status)) {
770 /* It stopped, rather than exiting. "Should not happen." */
771 *msg = g_strdup_printf("Child capture process stopped: %s",
772 sync_pipe_signame(WSTOPSIG(fork_child_status)));
773 } else if (WIFSIGNALED(fork_child_status)) {
774 /* It died with a signal. */
775 *msg = g_strdup_printf("Child capture process died: %s%s",
776 sync_pipe_signame(WTERMSIG(fork_child_status)),
777 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
779 /* What? It had to either have exited, or stopped, or died with
780 a signal; what happened here? */
781 *msg = g_strdup_printf("Child capture process died: wait status %#o",
787 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
788 "(errno:%u)", errno);
796 * Run dumpcap with the supplied arguments. On success, *msg points to
797 * a buffer containing the dumpcap output, and 0 is returned. On failure,
798 * *msg points to an error message, and -1 is returned. In either case,
799 * *msg must be freed with g_free().
801 * XXX - this doesn't check the exit status of dumpcap if it can be
802 * started and its return status could be fetched.
804 /* XXX - This duplicates a lot of code in sync_pipe_start() */
805 #define PIPE_BUF_SIZE 5120
807 sync_pipe_run_command(const char** argv, gchar **msg) {
808 int sync_pipe_read_fd, fork_child, ret;
809 gchar buf[PIPE_BUF_SIZE+1];
810 GString *msg_buf = NULL;
813 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
818 /* We were able to set up to read dumpcap's output. Do so. */
819 msg_buf = g_string_new("");
820 while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
822 g_string_append(msg_buf, buf);
826 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
828 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
832 g_string_free(msg_buf, TRUE);
837 g_string_free(msg_buf, FALSE);
842 * Get an interface list using dumpcap. On success, *msg points to
843 * a buffer containing the dumpcap output, and 0 is returned. On failure,
844 * *msg points to an error message, and -1 is returned. In either case,
845 * msg must be freed with g_free().
848 sync_interface_list_open(gchar **msg) {
853 /* We can't return anything */
857 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
859 argv = init_pipe_args(&argc);
862 *msg = g_strdup_printf("We don't know where to find dumpcap.");
866 /* Ask for the interface list */
867 argv = sync_pipe_add_arg(argv, &argc, "-D");
868 argv = sync_pipe_add_arg(argv, &argc, "-M");
871 /* dumpcap should be running in capture child mode (hidden feature) */
872 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
873 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
874 /* stderr in normal format and are then sent to whereever our stderr goes. */
875 /* Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
876 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
877 /* msgs to stderr in a special type/len/string format which would then */
878 /* currently be sent as is to stderr resulting in garbled output. */
879 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
880 /* special format error messages to stderr are captured and returned to caller */
881 /* (eg: so can be processed and displayed in a pop-up box). */
883 argv = sync_pipe_add_arg(argv, &argc, "-Z");
884 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
888 return sync_pipe_run_command(argv, msg);
892 * Get an linktype list using dumpcap. On success, *msg points to
893 * a buffer containing the dumpcap output, and 0 is returned. On failure,
894 * *msg points to an error message, and -1 is returned. In either case,
895 * *msg must be freed with g_free().
898 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
903 /* We can't return anything */
907 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
909 argv = init_pipe_args(&argc);
912 *msg = g_strdup_printf("We don't know where to find dumpcap.");
916 /* Ask for the linktype list */
917 argv = sync_pipe_add_arg(argv, &argc, "-i");
918 argv = sync_pipe_add_arg(argv, &argc, ifname);
919 argv = sync_pipe_add_arg(argv, &argc, "-L");
920 argv = sync_pipe_add_arg(argv, &argc, "-M");
923 /* dumpcap should be running in capture child mode (hidden feature) */
924 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
925 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
926 /* stderr in normal format and are then sent to whereever our stderr goes. */
927 /* Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
928 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
929 /* msgs to stderr in a special type/len/string format which would then */
930 /* currently be sent as is to stderr resulting in garbled output. */
931 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
932 /* special format error messages to stderr are captured and returned to caller */
933 /* (eg: so can be processed and displayed in a pop-up box). */
935 argv = sync_pipe_add_arg(argv, &argc, "-Z");
936 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
939 return sync_pipe_run_command(argv, msg);
943 * Start getting interface statistics using dumpcap. On success, read_fd
944 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
945 * and zero is returned. On failure, *msg will point to an error message
946 * that must be g_free()d, and -1 will be returned.
949 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
954 /* We can't return anything */
958 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
960 argv = init_pipe_args(&argc);
963 *msg = g_strdup_printf("We don't know where to find dumpcap.");
967 /* Ask for the interface statistics */
968 argv = sync_pipe_add_arg(argv, &argc, "-S");
969 argv = sync_pipe_add_arg(argv, &argc, "-M");
972 /* dumpcap should be running in capture child mode (hidden feature) */
973 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
974 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
975 /* stderr in normal format and are then sent to whereever our stderr goes. */
976 /* Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
977 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
978 /* msgs to stderr in a special type/len/string format which would then */
979 /* currently be sent as is to stderr resulting in garbled output. */
980 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
981 /* special format error messages to stderr are captured and returned to caller */
982 /* (eg: so can be processed and displayed in a pop-up box). */
984 argv = sync_pipe_add_arg(argv, &argc, "-Z");
985 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
988 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
991 /* Close down the stats process */
993 sync_interface_stats_close(int *read_fd, int *fork_child
999 return sync_pipe_close_command(read_fd, fork_child, msg);
1001 return sync_pipe_close_command(read_fd, msg);
1005 /* read a number of bytes from a pipe */
1006 /* (blocks until enough bytes read or an error occurs) */
1008 pipe_read_bytes(int pipe_fd, char *bytes, int required) {
1013 newly = read(pipe_fd, &bytes[offset], required);
1016 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1017 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1022 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1023 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1034 static gboolean pipe_data_available(int pipe_fd) {
1035 #ifdef _WIN32 /* PeekNamedPipe */
1036 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1039 if (hPipe == INVALID_HANDLE_VALUE)
1042 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1045 if (bytes_avail > 0)
1050 struct timeval timeout;
1053 FD_SET(pipe_fd, &rfds);
1055 timeout.tv_usec = 0;
1057 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1064 /* Read a line from a pipe, similar to fgets */
1066 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1070 while(offset < max - 1) {
1072 if (! pipe_data_available(pipe_fd))
1074 newly = read(pipe_fd, &bytes[offset], 1);
1076 /* EOF - not necessarily an error */
1078 } else if (newly < 0) {
1080 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1081 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1083 } else if (bytes[offset] == '\n') {
1089 bytes[offset] = '\0';
1095 /* convert header values (indicator and 4-byte length) */
1097 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1099 g_assert(header_len == 4);
1101 /* convert header values */
1102 *indicator = header[0];
1103 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1106 /* read a message from the sending pipe in the standard format
1107 (1-byte message indicator, 3-byte message length (excluding length
1108 and indicator field), and the rest is the message) */
1110 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg) {
1116 /* read header (indicator and 3-byte length) */
1117 newly = pipe_read_bytes(pipe_fd, header, 4);
1119 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1120 "read %d failed to read header: %u", pipe_fd, newly);
1124 /* convert header values */
1125 pipe_convert_header(header, 4, indicator, &required);
1127 /* only indicator with no value? */
1129 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1130 "read %d indicator: %c empty value", pipe_fd, *indicator);
1134 /* does the data fit into the given buffer? */
1135 if(required > len) {
1136 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1137 "read %d length error, required %d > len %d, indicator: %u",
1138 pipe_fd, required, len, *indicator);
1140 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1141 memcpy(msg, header, sizeof(header));
1142 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1143 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1148 /* read the actual block data */
1149 newly = pipe_read_bytes(pipe_fd, msg, required);
1150 if(newly != required) {
1151 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1155 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1156 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1157 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1163 /* There's stuff to read from the sync pipe, meaning the child has sent
1164 us a message, or the sync pipe has closed, meaning the child has
1165 closed it (perhaps because it exited). */
1167 sync_pipe_input_cb(gint source, gpointer user_data)
1169 capture_options *capture_opts = (capture_options *)user_data;
1170 char buffer[SP_MAX_MSG_LEN+1];
1176 char * secondary_msg;
1179 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1182 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1183 "sync_pipe_input_cb: child has closed sync_pipe");
1185 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1186 "sync_pipe_input_cb: error reading from sync pipe");
1188 /* The child has closed the sync pipe, meaning it's not going to be
1189 capturing any more packets. Pick up its exit status, and
1190 complain if it did anything other than exit with status 0.
1192 We don't have to worry about killing the child, if the sync pipe
1193 returned an error. Usually this error is caused as the child killed itself
1194 while going down. Even in the rare cases that this isn't the case,
1195 the child will get an error when writing to the broken pipe the next time,
1196 cleaning itself up then. */
1197 sync_pipe_wait_for_child(capture_opts);
1200 ws_close(capture_opts->signal_pipe_write_fd);
1202 capture_input_closed(capture_opts);
1206 /* we got a valid message block from the child, process it */
1209 if(!capture_input_new_file(capture_opts, buffer)) {
1210 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1212 /* We weren't able to open the new capture file; user has been
1213 alerted. Close the sync pipe. */
1216 /* the child has send us a filename which we couldn't open.
1217 this probably means, the child is creating files faster than we can handle it.
1218 this should only be the case for very fast file switches
1219 we can't do much more than telling the child to stop
1220 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1221 sync_pipe_stop(capture_opts);
1224 case SP_PACKET_COUNT:
1225 nread = atoi(buffer);
1226 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1227 capture_input_new_packets(capture_opts, nread);
1230 /* convert primary message */
1231 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1232 primary_msg = buffer+4;
1233 /* convert secondary message */
1234 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1235 secondary_msg = primary_msg + primary_len + 4;
1236 /* message output */
1237 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1238 /* the capture child will close the sync_pipe, nothing to do for now */
1239 /* (an error message doesn't mean we have to stop capturing) */
1242 capture_input_cfilter_error_message(capture_opts, buffer);
1243 /* the capture child will close the sync_pipe, nothing to do for now */
1246 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1249 g_assert_not_reached();
1257 /* the child process is going down, wait until it's completely terminated */
1259 sync_pipe_wait_for_child(capture_options *capture_opts)
1264 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1265 g_assert(capture_opts->fork_child != -1);
1268 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1269 report_failure("Child capture process stopped unexpectedly (errno:%u)",
1273 if (wait(&wstatus) != -1) {
1274 if (WIFEXITED(wstatus)) {
1275 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1276 /* the child will inform us about errors through the sync_pipe, which will popup */
1277 /* an error message, so don't popup another one */
1279 /* If there are situations where the child won't send us such an error message, */
1280 /* this should be fixed in the child and not here! */
1281 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1282 report_failure("Child capture process exited: exit status %d",
1283 WEXITSTATUS(wstatus));
1285 } else if (WIFSTOPPED(wstatus)) {
1286 /* It stopped, rather than exiting. "Should not happen." */
1287 report_failure("Child capture process stopped: %s",
1288 sync_pipe_signame(WSTOPSIG(wstatus)));
1289 } else if (WIFSIGNALED(wstatus)) {
1290 /* It died with a signal. */
1291 report_failure("Child capture process died: %s%s",
1292 sync_pipe_signame(WTERMSIG(wstatus)),
1293 WCOREDUMP(wstatus) ? " - core dumped" : "");
1295 /* What? It had to either have exited, or stopped, or died with
1296 a signal; what happened here? */
1297 report_failure("Child capture process died: wait status %#o", wstatus);
1302 /* No more child process. */
1303 capture_opts->fork_child = -1;
1305 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1310 /* convert signal to corresponding name */
1312 sync_pipe_signame(int sig)
1315 static char sigmsg_buf[6+1+3+1];
1324 sigmsg = "Interrupted";
1332 sigmsg = "Illegal instruction";
1336 sigmsg = "Trace trap";
1344 sigmsg = "Arithmetic exception";
1352 sigmsg = "Bus error";
1356 sigmsg = "Segmentation violation";
1359 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1360 Linux is POSIX compliant. These are not POSIX-defined signals ---
1361 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1363 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1364 were omitted from POSIX.1 because their behavior is
1365 implementation dependent and could not be adequately catego-
1366 rized. Conforming implementations may deliver these sig-
1367 nals, but must document the circumstances under which they
1368 are delivered and note any restrictions concerning their
1371 So we only check for SIGSYS on those systems that happen to
1372 implement them (a system can be POSIX-compliant and implement
1373 them, it's just that POSIX doesn't *require* a POSIX-compliant
1374 system to implement them).
1379 sigmsg = "Bad system call";
1384 sigmsg = "Broken pipe";
1388 sigmsg = "Alarm clock";
1392 sigmsg = "Terminated";
1396 /* Returning a static buffer is ok in the context we use it here */
1397 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1398 sigmsg = sigmsg_buf;
1407 /* tell the child through the signal pipe that we want to quit the capture */
1409 signal_pipe_capquit_to_child(capture_options *capture_opts)
1411 const char quit_msg[] = "QUIT";
1415 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1417 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1418 /* simply sending a "QUIT" string */
1419 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1420 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1422 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1423 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1429 /* user wants to stop the capture run */
1431 sync_pipe_stop(capture_options *capture_opts)
1436 gboolean terminate = TRUE;
1439 if (capture_opts->fork_child != -1) {
1441 /* send the SIGINT signal to close the capture child gracefully. */
1442 int sts = kill(capture_opts->fork_child, SIGINT);
1444 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1445 "Sending SIGINT to child failed: %s\n", strerror(errno));
1448 #define STOP_SLEEP_TIME 500 /* ms */
1449 #define STOP_CHECK_TIME 50
1450 /* First, use the special signal pipe to try to close the capture child
1453 signal_pipe_capquit_to_child(capture_opts);
1455 /* Next, wait for the process to exit on its own */
1456 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1457 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1458 childstatus != STILL_ACTIVE) {
1462 Sleep(STOP_CHECK_TIME);
1465 /* Force the issue. */
1467 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1468 "sync_pipe_stop: forcing child to exit");
1469 sync_pipe_kill(capture_opts->fork_child);
1476 /* Wireshark has to exit, force the capture child to close */
1478 sync_pipe_kill(int fork_child)
1480 if (fork_child != -1) {
1482 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1484 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1485 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1488 /* Remark: This is not the preferred method of closing a process!
1489 * the clean way would be getting the process id of the child process,
1490 * then getting window handle hWnd of that process (using EnumChildWindows),
1491 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1493 * Unfortunately, I don't know how to get the process id from the
1494 * handle. OpenProcess will get an handle (not a window handle)
1495 * from the process ID; it will not get a window handle from the
1496 * process ID. (How could it? A process can have more than one
1497 * window. For that matter, a process might have *no* windows,
1498 * as a process running dumpcap, the normal child process program,
1501 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1502 * running in the same console; that's not necessarily the case for
1503 * us, as we might not be running in a console.
1504 * And this also will require to have the process id.
1506 TerminateProcess((HANDLE) (fork_child), 0);
1511 #endif /* HAVE_LIBPCAP */