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];
261 char buffer_size[ARGV_NUMBER_LEN];
262 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
263 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
264 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
265 GString *args = g_string_sized_new(200);
267 SECURITY_ATTRIBUTES sa;
269 PROCESS_INFORMATION pi;
271 char control_id[ARGV_NUMBER_LEN];
272 gchar *signal_pipe_name;
275 int sync_pipe[2]; /* pipe used to send messages from child to parent */
276 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
278 int sync_pipe_read_fd;
283 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
284 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
286 capture_opts->fork_child = -1;
288 argv = init_pipe_args(&argc);
290 /* We don't know where to find dumpcap. */
291 report_failure("We don't know where to find dumpcap.");
295 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
297 argv = sync_pipe_add_arg(argv, &argc, "-i");
298 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
300 if (capture_opts->has_snaplen) {
301 argv = sync_pipe_add_arg(argv, &argc, "-s");
302 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
303 argv = sync_pipe_add_arg(argv, &argc, ssnap);
306 if (capture_opts->linktype != -1) {
307 argv = sync_pipe_add_arg(argv, &argc, "-y");
308 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
309 argv = sync_pipe_add_arg(argv, &argc, sdlt);
312 if(capture_opts->multi_files_on) {
313 if (capture_opts->has_autostop_filesize) {
314 argv = sync_pipe_add_arg(argv, &argc, "-b");
315 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
316 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
319 if (capture_opts->has_file_duration) {
320 argv = sync_pipe_add_arg(argv, &argc, "-b");
321 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
322 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
325 if (capture_opts->has_ring_num_files) {
326 argv = sync_pipe_add_arg(argv, &argc, "-b");
327 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
328 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
331 if (capture_opts->has_autostop_files) {
332 argv = sync_pipe_add_arg(argv, &argc, "-a");
333 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
334 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
337 if (capture_opts->has_autostop_filesize) {
338 argv = sync_pipe_add_arg(argv, &argc, "-a");
339 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
340 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
344 if (capture_opts->has_autostop_packets) {
345 argv = sync_pipe_add_arg(argv, &argc, "-c");
346 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
347 argv = sync_pipe_add_arg(argv, &argc, scount);
350 if (capture_opts->has_autostop_duration) {
351 argv = sync_pipe_add_arg(argv, &argc, "-a");
352 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
353 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
356 if (!capture_opts->promisc_mode)
357 argv = sync_pipe_add_arg(argv, &argc, "-p");
358 if (capture_opts->use_pcapng)
359 argv = sync_pipe_add_arg(argv, &argc, "-n");
360 #ifdef HAVE_PCAP_REMOTE
361 if (capture_opts->datatx_udp)
362 argv = sync_pipe_add_arg(argv, &argc, "-u");
364 if (!capture_opts->nocap_rpcap)
365 argv = sync_pipe_add_arg(argv, &argc, "-r");
367 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
369 argv = sync_pipe_add_arg(argv, &argc, "-A");
370 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
371 capture_opts->auth_password);
372 argv = sync_pipe_add_arg(argv, &argc, sauth);
375 #ifdef HAVE_PCAP_SETSAMPLING
376 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
378 argv = sync_pipe_add_arg(argv, &argc, "-m");
379 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
380 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
381 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
383 capture_opts->sampling_param);
384 argv = sync_pipe_add_arg(argv, &argc, ssampling);
388 /* dumpcap should be running in capture child mode (hidden feature) */
390 argv = sync_pipe_add_arg(argv, &argc, "-Z");
392 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
393 argv = sync_pipe_add_arg(argv, &argc, control_id);
395 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
400 argv = sync_pipe_add_arg(argv, &argc, "-B");
401 #ifdef HAVE_PCAP_REMOTE
402 if (capture_opts->src_type == CAPTURE_IFREMOTE)
403 /* No buffer size when using remote interfaces */
404 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
407 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
408 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
411 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
412 argv = sync_pipe_add_arg(argv, &argc, "-f");
413 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
416 if(capture_opts->save_file) {
417 argv = sync_pipe_add_arg(argv, &argc, "-w");
418 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
422 /* init SECURITY_ATTRIBUTES */
423 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
424 sa.bInheritHandle = TRUE;
425 sa.lpSecurityDescriptor = NULL;
427 /* Create a pipe for the child process */
428 /* (increase this value if you have trouble while fast capture file switches) */
429 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
430 /* Couldn't create the pipe between parent and child. */
431 report_failure("Couldn't create sync pipe: %s", strerror(errno));
432 g_free( (gpointer) argv[0]);
433 g_free( (gpointer) argv);
437 /* Create the signal pipe */
438 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
439 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
440 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
441 g_free(signal_pipe_name);
443 if (signal_pipe == INVALID_HANDLE_VALUE) {
444 /* Couldn't create the signal pipe between parent and child. */
445 report_failure("Couldn't create signal pipe: %s", strerror(errno));
446 g_free( (gpointer) argv[0]);
447 g_free( (gpointer) argv);
451 /* init STARTUPINFO */
452 memset(&si, 0, sizeof(si));
455 si.dwFlags = STARTF_USESHOWWINDOW;
456 si.wShowWindow = SW_SHOW;
458 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
459 si.wShowWindow = SW_HIDE; /* this hides the console window */
460 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
461 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
462 si.hStdError = sync_pipe_write;
463 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
466 /* convert args array into a single string */
467 /* XXX - could change sync_pipe_add_arg() instead */
468 /* there is a drawback here: the length is internally limited to 1024 bytes */
469 for(i=0; argv[i] != 0; i++) {
470 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
471 quoted_arg = protect_arg(argv[i]);
472 g_string_append(args, quoted_arg);
477 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
478 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
479 report_failure("Couldn't run %s in child process: error %u",
480 args->str, GetLastError());
481 CloseHandle(sync_pipe_read);
482 CloseHandle(sync_pipe_write);
483 g_free( (gpointer) argv[0]);
484 g_free( (gpointer) argv);
487 capture_opts->fork_child = (int) pi.hProcess;
488 g_string_free(args, TRUE);
490 /* associate the operating system filehandle to a C run-time file handle */
491 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
492 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
494 /* associate the operating system filehandle to a C run-time file handle */
495 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
498 if (pipe(sync_pipe) < 0) {
499 /* Couldn't create the pipe between parent and child. */
500 report_failure("Couldn't create sync pipe: %s", strerror(errno));
501 g_free( (gpointer) argv[0]);
506 if ((capture_opts->fork_child = fork()) == 0) {
508 * Child process - run dumpcap with the right arguments to make
509 * it just capture with the specified capture parameters
511 dup2(sync_pipe[PIPE_WRITE], 2);
512 ws_close(sync_pipe[PIPE_READ]);
513 execv(argv[0], (gpointer)argv);
514 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
515 argv[0], strerror(errno));
516 sync_pipe_errmsg_to_parent(2, errmsg, "");
518 /* Exit with "_exit()", so that we don't close the connection
519 to the X server (and cause stuff buffered up by our parent but
520 not yet sent to be sent, as that stuff should only be sent by
521 our parent). We've sent an error message to the parent, so
522 we exit with an exit status of 1 (any exit status other than
523 0 or 1 will cause an additional message to report that exit
524 status, over and above the error message we sent to the parent). */
528 sync_pipe_read_fd = sync_pipe[PIPE_READ];
531 g_free( (gpointer) argv[0]); /* exename */
533 /* Parent process - read messages from the child process over the
535 g_free( (gpointer) argv); /* free up arg array */
537 /* Close the write side of the pipe, so that only the child has it
538 open, and thus it completely closes, and thus returns to us
539 an EOF indication, if the child closes it (either deliberately
540 or by exiting abnormally). */
542 CloseHandle(sync_pipe_write);
544 ws_close(sync_pipe[PIPE_WRITE]);
547 if (capture_opts->fork_child == -1) {
548 /* We couldn't even create the child process. */
549 report_failure("Couldn't create child process: %s", strerror(errno));
550 ws_close(sync_pipe_read_fd);
552 ws_close(capture_opts->signal_pipe_write_fd);
557 /* we might wait for a moment till child is ready, so update screen now */
558 main_window_update();
560 /* We were able to set up to read the capture file;
561 arrange that our callback be called whenever it's possible
562 to read from the sync pipe, so that it's called when
563 the child process wants to tell us something. */
565 /* we have a running capture, now wait for the real capture filename */
566 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
567 &capture_opts->fork_child, sync_pipe_input_cb);
573 * Open a pipe to dumpcap with the supplied arguments. On success, *msg
574 * is unchanged and 0 is returned; read_fd and fork_child point to the
575 * pipe's file descriptor and child PID/handle, respectively. On failure,
576 * *msg points to an error message for the failure, and -1 is returned.
577 * In the latter case, *msg must be freed with g_free().
579 /* XXX - This duplicates a lot of code in sync_pipe_start() */
580 #define PIPE_BUF_SIZE 5120
582 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
584 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
585 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
586 GString *args = g_string_sized_new(200);
588 SECURITY_ATTRIBUTES sa;
590 PROCESS_INFORMATION pi;
594 int sync_pipe[2]; /* pipe used to send messages from child to parent */
595 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
600 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
603 /* We can't return anything */
605 g_string_free(args, TRUE);
611 /* init SECURITY_ATTRIBUTES */
612 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
613 sa.bInheritHandle = TRUE;
614 sa.lpSecurityDescriptor = NULL;
616 /* Create a pipe for the child process */
617 /* (increase this value if you have trouble while fast capture file switches) */
618 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
619 /* Couldn't create the pipe between parent and child. */
620 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
621 g_free( (gpointer) argv[0]);
622 g_free( (gpointer) argv);
626 /* init STARTUPINFO */
627 memset(&si, 0, sizeof(si));
630 si.dwFlags = STARTF_USESHOWWINDOW;
631 si.wShowWindow = SW_SHOW;
633 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
634 si.wShowWindow = SW_HIDE; /* this hides the console window */
636 si.hStdOutput = sync_pipe_write;
637 si.hStdError = sync_pipe_write;
638 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
641 /* convert args array into a single string */
642 /* XXX - could change sync_pipe_add_arg() instead */
643 /* there is a drawback here: the length is internally limited to 1024 bytes */
644 for(i=0; argv[i] != 0; i++) {
645 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
646 quoted_arg = protect_arg(argv[i]);
647 g_string_append(args, quoted_arg);
652 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
653 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
654 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
655 args->str, GetLastError());
656 CloseHandle(sync_pipe_read);
657 CloseHandle(sync_pipe_write);
658 g_free( (gpointer) argv[0]);
659 g_free( (gpointer) argv);
662 *fork_child = (int) pi.hProcess;
663 g_string_free(args, TRUE);
665 /* associate the operating system filehandle to a C run-time file handle */
666 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
667 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
670 if (pipe(sync_pipe) < 0) {
671 /* Couldn't create the pipe between parent and child. */
672 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
673 g_free( (gpointer) argv[0]);
678 if ((*fork_child = fork()) == 0) {
680 * Child process - run dumpcap with the right arguments to make
681 * it just capture with the specified capture parameters
683 dup2(sync_pipe[PIPE_WRITE], 1);
684 ws_close(sync_pipe[PIPE_READ]);
685 execv(argv[0], (gpointer)argv);
686 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
687 argv[0], strerror(errno));
688 sync_pipe_errmsg_to_parent(1, errmsg, "");
690 /* Exit with "_exit()", so that we don't close the connection
691 to the X server (and cause stuff buffered up by our parent but
692 not yet sent to be sent, as that stuff should only be sent by
693 our parent). We've sent an error message to the parent, so
694 we exit with an exit status of 1 (any exit status other than
695 0 or 1 will cause an additional message to report that exit
696 status, over and above the error message we sent to the parent). */
700 *read_fd = sync_pipe[PIPE_READ];
703 g_free( (gpointer) argv[0]); /* exename */
705 /* Parent process - read messages from the child process over the
707 g_free( (gpointer) argv); /* free up arg array */
709 /* Close the write side of the pipe, so that only the child has it
710 open, and thus it completely closes, and thus returns to us
711 an EOF indication, if the child closes it (either deliberately
712 or by exiting abnormally). */
714 CloseHandle(sync_pipe_write);
716 ws_close(sync_pipe[PIPE_WRITE]);
719 if (*fork_child == -1) {
720 /* We couldn't even create the child process. */
721 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
726 /* we might wait for a moment till child is ready, so update screen now */
727 main_window_update();
732 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
733 * returned. On failure, *msg points to an error message for the
734 * failure, and -1 is returned. In the latter case, *msg must be
735 * freed with g_free().
739 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
741 sync_pipe_close_command(int *read_fd, gchar **msg) {
743 int fork_child_status;
747 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
750 /* XXX - Should we signal the child somehow? */
751 sync_pipe_kill(*fork_child);
752 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
753 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
754 "(errno:%u)", errno);
758 if (wait(&fork_child_status) != -1) {
759 if (WIFEXITED(fork_child_status)) {
760 /* The child exited. */
761 fork_child_status = WEXITSTATUS(fork_child_status);
763 if (WIFSTOPPED(fork_child_status)) {
764 /* It stopped, rather than exiting. "Should not happen." */
765 *msg = g_strdup_printf("Child capture process stopped: %s",
766 sync_pipe_signame(WSTOPSIG(fork_child_status)));
767 } else if (WIFSIGNALED(fork_child_status)) {
768 /* It died with a signal. */
769 *msg = g_strdup_printf("Child capture process died: %s%s",
770 sync_pipe_signame(WTERMSIG(fork_child_status)),
771 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
773 /* What? It had to either have exited, or stopped, or died with
774 a signal; what happened here? */
775 *msg = g_strdup_printf("Child capture process died: wait status %#o",
781 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
782 "(errno:%u)", errno);
790 * Run dumpcap with the supplied arguments. On success, *msg points to
791 * a buffer containing the dumpcap output, and 0 is returned. On failure,
792 * *msg points to an error message, and -1 is returned. In either case,
793 * *msg must be freed with g_free().
795 * XXX - this doesn't check the exit status of dumpcap if it can be
796 * started and its return status could be fetched.
798 /* XXX - This duplicates a lot of code in sync_pipe_start() */
799 #define PIPE_BUF_SIZE 5120
801 sync_pipe_run_command(const char** argv, gchar **msg) {
802 int sync_pipe_read_fd, fork_child, ret;
803 gchar buf[PIPE_BUF_SIZE+1];
804 GString *msg_buf = NULL;
807 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
812 /* We were able to set up to read dumpcap's output. Do so. */
813 msg_buf = g_string_new("");
814 while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
816 g_string_append(msg_buf, buf);
820 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
822 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
826 g_string_free(msg_buf, TRUE);
831 g_string_free(msg_buf, FALSE);
836 * Get an interface list using dumpcap. On success, *msg points to
837 * a buffer containing the dumpcap output, and 0 is returned. On failure,
838 * *msg points to an error message, and -1 is returned. In either case,
839 * msg must be freed with g_free().
842 sync_interface_list_open(gchar **msg) {
847 /* We can't return anything */
851 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
853 argv = init_pipe_args(&argc);
856 *msg = g_strdup_printf("We don't know where to find dumpcap.");
860 /* Ask for the interface list */
861 argv = sync_pipe_add_arg(argv, &argc, "-D");
862 argv = sync_pipe_add_arg(argv, &argc, "-M");
865 /* dumpcap should be running in capture child mode (hidden feature) */
866 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
867 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
868 /* stderr in normal format and are then sent to whereever our stderr goes. */
869 /* Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
870 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
871 /* msgs to stderr in a special type/len/string format which would then */
872 /* currently be sent as is to stderr resulting in garbled output. */
873 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
874 /* special format error messages to stderr are captured and returned to caller */
875 /* (eg: so can be processed and displayed in a pop-up box). */
877 argv = sync_pipe_add_arg(argv, &argc, "-Z");
878 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
882 return sync_pipe_run_command(argv, msg);
886 * Get an linktype list using dumpcap. On success, *msg points to
887 * a buffer containing the dumpcap output, and 0 is returned. On failure,
888 * *msg points to an error message, and -1 is returned. In either case,
889 * *msg must be freed with g_free().
892 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
897 /* We can't return anything */
901 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
903 argv = init_pipe_args(&argc);
906 *msg = g_strdup_printf("We don't know where to find dumpcap.");
910 /* Ask for the linktype list */
911 argv = sync_pipe_add_arg(argv, &argc, "-i");
912 argv = sync_pipe_add_arg(argv, &argc, ifname);
913 argv = sync_pipe_add_arg(argv, &argc, "-L");
914 argv = sync_pipe_add_arg(argv, &argc, "-M");
917 /* dumpcap should be running in capture child mode (hidden feature) */
918 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
919 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
920 /* stderr in normal format and are then sent to whereever our stderr goes. */
921 /* Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
922 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
923 /* msgs to stderr in a special type/len/string format which would then */
924 /* currently be sent as is to stderr resulting in garbled output. */
925 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
926 /* special format error messages to stderr are captured and returned to caller */
927 /* (eg: so can be processed and displayed in a pop-up box). */
929 argv = sync_pipe_add_arg(argv, &argc, "-Z");
930 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
933 return sync_pipe_run_command(argv, msg);
937 * Start getting interface statistics using dumpcap. On success, read_fd
938 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
939 * and zero is returned. On failure, *msg will point to an error message
940 * that must be g_free()d, and -1 will be returned.
943 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
948 /* We can't return anything */
952 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
954 argv = init_pipe_args(&argc);
957 *msg = g_strdup_printf("We don't know where to find dumpcap.");
961 /* Ask for the interface statistics */
962 argv = sync_pipe_add_arg(argv, &argc, "-S");
963 argv = sync_pipe_add_arg(argv, &argc, "-M");
966 /* dumpcap should be running in capture child mode (hidden feature) */
967 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
968 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
969 /* stderr in normal format and are then sent to whereever our stderr goes. */
970 /* Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
971 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
972 /* msgs to stderr in a special type/len/string format which would then */
973 /* currently be sent as is to stderr resulting in garbled output. */
974 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
975 /* special format error messages to stderr are captured and returned to caller */
976 /* (eg: so can be processed and displayed in a pop-up box). */
978 argv = sync_pipe_add_arg(argv, &argc, "-Z");
979 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
982 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
985 /* Close down the stats process */
987 sync_interface_stats_close(int *read_fd, int *fork_child
993 return sync_pipe_close_command(read_fd, fork_child, msg);
995 return sync_pipe_close_command(read_fd, msg);
999 /* read a number of bytes from a pipe */
1000 /* (blocks until enough bytes read or an error occurs) */
1002 pipe_read_bytes(int pipe_fd, char *bytes, int required) {
1007 newly = read(pipe_fd, &bytes[offset], required);
1010 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1011 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1016 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1017 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1028 static gboolean pipe_data_available(int pipe_fd) {
1029 #ifdef _WIN32 /* PeekNamedPipe */
1030 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1033 if (hPipe == INVALID_HANDLE_VALUE)
1036 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1039 if (bytes_avail > 0)
1044 struct timeval timeout;
1047 FD_SET(pipe_fd, &rfds);
1049 timeout.tv_usec = 0;
1051 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1058 /* Read a line from a pipe, similar to fgets */
1060 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1064 while(offset < max - 1) {
1066 if (! pipe_data_available(pipe_fd))
1068 newly = read(pipe_fd, &bytes[offset], 1);
1070 /* EOF - not necessarily an error */
1072 } else if (newly < 0) {
1074 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1075 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1077 } else if (bytes[offset] == '\n') {
1083 bytes[offset] = '\0';
1089 /* convert header values (indicator and 4-byte length) */
1091 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1093 g_assert(header_len == 4);
1095 /* convert header values */
1096 *indicator = header[0];
1097 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1100 /* read a message from the sending pipe in the standard format
1101 (1-byte message indicator, 3-byte message length (excluding length
1102 and indicator field), and the rest is the message) */
1104 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg) {
1110 /* read header (indicator and 3-byte length) */
1111 newly = pipe_read_bytes(pipe_fd, header, 4);
1113 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1114 "read %d failed to read header: %u", pipe_fd, newly);
1118 /* convert header values */
1119 pipe_convert_header(header, 4, indicator, &required);
1121 /* only indicator with no value? */
1123 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1124 "read %d indicator: %c empty value", pipe_fd, *indicator);
1128 /* does the data fit into the given buffer? */
1129 if(required > len) {
1130 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1131 "read %d length error, required %d > len %d, indicator: %u",
1132 pipe_fd, required, len, *indicator);
1134 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1135 memcpy(msg, header, sizeof(header));
1136 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1137 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1142 /* read the actual block data */
1143 newly = pipe_read_bytes(pipe_fd, msg, required);
1144 if(newly != required) {
1145 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1149 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1150 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1151 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1157 /* There's stuff to read from the sync pipe, meaning the child has sent
1158 us a message, or the sync pipe has closed, meaning the child has
1159 closed it (perhaps because it exited). */
1161 sync_pipe_input_cb(gint source, gpointer user_data)
1163 capture_options *capture_opts = (capture_options *)user_data;
1164 char buffer[SP_MAX_MSG_LEN+1];
1170 char * secondary_msg;
1173 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1176 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1177 "sync_pipe_input_cb: child has closed sync_pipe");
1179 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1180 "sync_pipe_input_cb: error reading from sync pipe");
1182 /* The child has closed the sync pipe, meaning it's not going to be
1183 capturing any more packets. Pick up its exit status, and
1184 complain if it did anything other than exit with status 0.
1186 We don't have to worry about killing the child, if the sync pipe
1187 returned an error. Usually this error is caused as the child killed itself
1188 while going down. Even in the rare cases that this isn't the case,
1189 the child will get an error when writing to the broken pipe the next time,
1190 cleaning itself up then. */
1191 sync_pipe_wait_for_child(capture_opts);
1194 ws_close(capture_opts->signal_pipe_write_fd);
1196 capture_input_closed(capture_opts);
1200 /* we got a valid message block from the child, process it */
1203 if(!capture_input_new_file(capture_opts, buffer)) {
1204 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1206 /* We weren't able to open the new capture file; user has been
1207 alerted. Close the sync pipe. */
1210 /* the child has send us a filename which we couldn't open.
1211 this probably means, the child is creating files faster than we can handle it.
1212 this should only be the case for very fast file switches
1213 we can't do much more than telling the child to stop
1214 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1215 sync_pipe_stop(capture_opts);
1218 case SP_PACKET_COUNT:
1219 nread = atoi(buffer);
1220 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1221 capture_input_new_packets(capture_opts, nread);
1224 /* convert primary message */
1225 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1226 primary_msg = buffer+4;
1227 /* convert secondary message */
1228 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1229 secondary_msg = primary_msg + primary_len + 4;
1230 /* message output */
1231 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1232 /* the capture child will close the sync_pipe, nothing to do for now */
1233 /* (an error message doesn't mean we have to stop capturing) */
1236 capture_input_cfilter_error_message(capture_opts, buffer);
1237 /* the capture child will close the sync_pipe, nothing to do for now */
1240 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1243 g_assert_not_reached();
1251 /* the child process is going down, wait until it's completely terminated */
1253 sync_pipe_wait_for_child(capture_options *capture_opts)
1258 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1259 g_assert(capture_opts->fork_child != -1);
1262 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1263 report_failure("Child capture process stopped unexpectedly (errno:%u)",
1267 if (wait(&wstatus) != -1) {
1268 if (WIFEXITED(wstatus)) {
1269 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1270 /* the child will inform us about errors through the sync_pipe, which will popup */
1271 /* an error message, so don't popup another one */
1273 /* If there are situations where the child won't send us such an error message, */
1274 /* this should be fixed in the child and not here! */
1275 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1276 report_failure("Child capture process exited: exit status %d",
1277 WEXITSTATUS(wstatus));
1279 } else if (WIFSTOPPED(wstatus)) {
1280 /* It stopped, rather than exiting. "Should not happen." */
1281 report_failure("Child capture process stopped: %s",
1282 sync_pipe_signame(WSTOPSIG(wstatus)));
1283 } else if (WIFSIGNALED(wstatus)) {
1284 /* It died with a signal. */
1285 report_failure("Child capture process died: %s%s",
1286 sync_pipe_signame(WTERMSIG(wstatus)),
1287 WCOREDUMP(wstatus) ? " - core dumped" : "");
1289 /* What? It had to either have exited, or stopped, or died with
1290 a signal; what happened here? */
1291 report_failure("Child capture process died: wait status %#o", wstatus);
1296 /* No more child process. */
1297 capture_opts->fork_child = -1;
1299 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1304 /* convert signal to corresponding name */
1306 sync_pipe_signame(int sig)
1309 static char sigmsg_buf[6+1+3+1];
1318 sigmsg = "Interrupted";
1326 sigmsg = "Illegal instruction";
1330 sigmsg = "Trace trap";
1338 sigmsg = "Arithmetic exception";
1346 sigmsg = "Bus error";
1350 sigmsg = "Segmentation violation";
1353 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1354 Linux is POSIX compliant. These are not POSIX-defined signals ---
1355 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1357 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1358 were omitted from POSIX.1 because their behavior is
1359 implementation dependent and could not be adequately catego-
1360 rized. Conforming implementations may deliver these sig-
1361 nals, but must document the circumstances under which they
1362 are delivered and note any restrictions concerning their
1365 So we only check for SIGSYS on those systems that happen to
1366 implement them (a system can be POSIX-compliant and implement
1367 them, it's just that POSIX doesn't *require* a POSIX-compliant
1368 system to implement them).
1373 sigmsg = "Bad system call";
1378 sigmsg = "Broken pipe";
1382 sigmsg = "Alarm clock";
1386 sigmsg = "Terminated";
1390 /* Returning a static buffer is ok in the context we use it here */
1391 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1392 sigmsg = sigmsg_buf;
1401 /* tell the child through the signal pipe that we want to quit the capture */
1403 signal_pipe_capquit_to_child(capture_options *capture_opts)
1405 const char quit_msg[] = "QUIT";
1409 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1411 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1412 /* simply sending a "QUIT" string */
1413 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1414 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1416 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1417 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1423 /* user wants to stop the capture run */
1425 sync_pipe_stop(capture_options *capture_opts)
1430 gboolean terminate = TRUE;
1433 if (capture_opts->fork_child != -1) {
1435 /* send the SIGINT signal to close the capture child gracefully. */
1436 int sts = kill(capture_opts->fork_child, SIGINT);
1438 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1439 "Sending SIGINT to child failed: %s\n", strerror(errno));
1442 #define STOP_SLEEP_TIME 500 /* ms */
1443 #define STOP_CHECK_TIME 50
1444 /* First, use the special signal pipe to try to close the capture child
1447 signal_pipe_capquit_to_child(capture_opts);
1449 /* Next, wait for the process to exit on its own */
1450 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1451 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1452 childstatus != STILL_ACTIVE) {
1456 Sleep(STOP_CHECK_TIME);
1459 /* Force the issue. */
1461 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1462 "sync_pipe_stop: forcing child to exit");
1463 sync_pipe_kill(capture_opts->fork_child);
1470 /* Wireshark has to exit, force the capture child to close */
1472 sync_pipe_kill(int fork_child)
1474 if (fork_child != -1) {
1476 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1478 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1479 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1482 /* Remark: This is not the preferred method of closing a process!
1483 * the clean way would be getting the process id of the child process,
1484 * then getting window handle hWnd of that process (using EnumChildWindows),
1485 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1487 * Unfortunately, I don't know how to get the process id from the
1488 * handle. OpenProcess will get an handle (not a window handle)
1489 * from the process ID; it will not get a window handle from the
1490 * process ID. (How could it? A process can have more than one
1491 * window. For that matter, a process might have *no* windows,
1492 * as a process running dumpcap, the normal child process program,
1495 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1496 * running in the same console; that's not necessarily the case for
1497 * us, as we might not be running in a console.
1498 * And this also will require to have the process id.
1500 TerminateProcess((HANDLE) (fork_child), 0);
1505 #endif /* HAVE_LIBPCAP */