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 "epan/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>
92 #include "capture_sync.h"
93 #include "simple_dialog.h"
95 #include "sync_pipe.h"
98 #include "capture-wpcap.h"
101 #include "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 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "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 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
309 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
311 /* we can't get the type name, just treat it as a number */
312 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
314 argv = sync_pipe_add_arg(argv, &argc, sdlt);
317 if(capture_opts->multi_files_on) {
318 if (capture_opts->has_autostop_filesize) {
319 argv = sync_pipe_add_arg(argv, &argc, "-b");
320 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
321 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
324 if (capture_opts->has_file_duration) {
325 argv = sync_pipe_add_arg(argv, &argc, "-b");
326 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
327 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
330 if (capture_opts->has_ring_num_files) {
331 argv = sync_pipe_add_arg(argv, &argc, "-b");
332 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
333 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
336 if (capture_opts->has_autostop_files) {
337 argv = sync_pipe_add_arg(argv, &argc, "-a");
338 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
339 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
342 if (capture_opts->has_autostop_filesize) {
343 argv = sync_pipe_add_arg(argv, &argc, "-a");
344 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
345 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
349 if (capture_opts->has_autostop_packets) {
350 argv = sync_pipe_add_arg(argv, &argc, "-c");
351 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
352 argv = sync_pipe_add_arg(argv, &argc, scount);
355 if (capture_opts->has_autostop_duration) {
356 argv = sync_pipe_add_arg(argv, &argc, "-a");
357 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
358 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
361 if (!capture_opts->promisc_mode)
362 argv = sync_pipe_add_arg(argv, &argc, "-p");
363 #ifdef HAVE_PCAP_REMOTE
364 if (capture_opts->datatx_udp)
365 argv = sync_pipe_add_arg(argv, &argc, "-u");
367 if (!capture_opts->nocap_rpcap)
368 argv = sync_pipe_add_arg(argv, &argc, "-r");
370 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
372 argv = sync_pipe_add_arg(argv, &argc, "-A");
373 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
374 capture_opts->auth_password);
375 argv = sync_pipe_add_arg(argv, &argc, sauth);
378 #ifdef HAVE_PCAP_SETSAMPLING
379 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
381 argv = sync_pipe_add_arg(argv, &argc, "-m");
382 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
383 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
384 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
386 capture_opts->sampling_param);
387 argv = sync_pipe_add_arg(argv, &argc, ssampling);
391 /* dumpcap should be running in capture child mode (hidden feature) */
393 argv = sync_pipe_add_arg(argv, &argc, "-Z");
395 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
396 argv = sync_pipe_add_arg(argv, &argc, control_id);
398 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
403 argv = sync_pipe_add_arg(argv, &argc, "-B");
404 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
405 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
408 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
409 argv = sync_pipe_add_arg(argv, &argc, "-f");
410 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
413 if(capture_opts->save_file) {
414 argv = sync_pipe_add_arg(argv, &argc, "-w");
415 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
419 /* init SECURITY_ATTRIBUTES */
420 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
421 sa.bInheritHandle = TRUE;
422 sa.lpSecurityDescriptor = NULL;
424 /* Create a pipe for the child process */
425 /* (increase this value if you have trouble while fast capture file switches) */
426 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
427 /* Couldn't create the pipe between parent and child. */
428 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
430 g_free( (gpointer) argv[0]);
431 g_free( (gpointer) argv);
435 /* Create the signal pipe */
436 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
437 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
438 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
439 g_free(signal_pipe_name);
441 if (signal_pipe == INVALID_HANDLE_VALUE) {
442 /* Couldn't create the signal pipe between parent and child. */
443 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
445 g_free( (gpointer) argv[0]);
446 g_free( (gpointer) argv);
450 /* init STARTUPINFO */
451 memset(&si, 0, sizeof(si));
454 si.dwFlags = STARTF_USESHOWWINDOW;
455 si.wShowWindow = SW_SHOW;
457 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
458 si.wShowWindow = SW_HIDE; /* this hides the console window */
459 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
460 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
461 si.hStdError = sync_pipe_write;
462 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
465 /* convert args array into a single string */
466 /* XXX - could change sync_pipe_add_arg() instead */
467 /* there is a drawback here: the length is internally limited to 1024 bytes */
468 for(i=0; argv[i] != 0; i++) {
469 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
470 quoted_arg = protect_arg(argv[i]);
471 g_string_append(args, quoted_arg);
476 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
477 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
478 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
479 "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 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
502 g_free( (gpointer) argv[0]);
507 if ((capture_opts->fork_child = fork()) == 0) {
509 * Child process - run dumpcap with the right arguments to make
510 * it just capture with the specified capture parameters
512 dup2(sync_pipe[PIPE_WRITE], 2);
513 eth_close(sync_pipe[PIPE_READ]);
514 execv(argv[0], (gpointer)argv);
515 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
516 argv[0], strerror(errno));
517 sync_pipe_errmsg_to_parent(2, errmsg, "");
519 /* Exit with "_exit()", so that we don't close the connection
520 to the X server (and cause stuff buffered up by our parent but
521 not yet sent to be sent, as that stuff should only be sent by
522 our parent). We've sent an error message to the parent, so
523 we exit with an exit status of 1 (any exit status other than
524 0 or 1 will cause an additional message to report that exit
525 status, over and above the error message we sent to the parent). */
529 sync_pipe_read_fd = sync_pipe[PIPE_READ];
532 g_free( (gpointer) argv[0]); /* exename */
534 /* Parent process - read messages from the child process over the
536 g_free( (gpointer) argv); /* free up arg array */
538 /* Close the write side of the pipe, so that only the child has it
539 open, and thus it completely closes, and thus returns to us
540 an EOF indication, if the child closes it (either deliberately
541 or by exiting abnormally). */
543 CloseHandle(sync_pipe_write);
545 eth_close(sync_pipe[PIPE_WRITE]);
548 if (capture_opts->fork_child == -1) {
549 /* We couldn't even create the child process. */
550 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
551 "Couldn't create child process: %s", strerror(errno));
552 eth_close(sync_pipe_read_fd);
554 eth_close(capture_opts->signal_pipe_write_fd);
559 /* we might wait for a moment till child is ready, so update screen now */
560 main_window_update();
562 /* We were able to set up to read the capture file;
563 arrange that our callback be called whenever it's possible
564 to read from the sync pipe, so that it's called when
565 the child process wants to tell us something. */
567 /* we have a running capture, now wait for the real capture filename */
568 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
569 &capture_opts->fork_child, sync_pipe_input_cb);
575 * Open dumpcap with the supplied arguments. On success, msg points to
576 * a buffer containing the dumpcap output and returns 0. read_fd and
577 * fork_child point to the pipe's file descriptor and child PID/handle,
578 * respectively. On failure, msg points to the error message returned by
579 * dumpcap, and returns dumpcap's exit value. In either case, msg must be
580 * freed with g_free().
582 /* XXX - This duplicates a lot of code in sync_pipe_start() */
583 #define PIPE_BUF_SIZE 5120
585 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
587 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
588 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
589 GString *args = g_string_sized_new(200);
591 SECURITY_ATTRIBUTES sa;
593 PROCESS_INFORMATION pi;
597 int sync_pipe[2]; /* pipe used to send messages from child to parent */
598 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
603 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
606 /* We can't return anything */
608 g_string_free(args, TRUE);
614 /* init SECURITY_ATTRIBUTES */
615 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
616 sa.bInheritHandle = TRUE;
617 sa.lpSecurityDescriptor = NULL;
619 /* Create a pipe for the child process */
620 /* (inrease this value if you have trouble while fast capture file switches) */
621 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
622 /* Couldn't create the pipe between parent and child. */
623 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
624 g_free( (gpointer) argv[0]);
625 g_free( (gpointer) argv);
626 return CANT_RUN_DUMPCAP;
629 /* init STARTUPINFO */
630 memset(&si, 0, sizeof(si));
633 si.dwFlags = STARTF_USESHOWWINDOW;
634 si.wShowWindow = SW_SHOW;
636 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
637 si.wShowWindow = SW_HIDE; /* this hides the console window */
639 si.hStdOutput = sync_pipe_write;
640 si.hStdError = sync_pipe_write;
641 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
644 /* convert args array into a single string */
645 /* XXX - could change sync_pipe_add_arg() instead */
646 /* there is a drawback here: the length is internally limited to 1024 bytes */
647 for(i=0; argv[i] != 0; i++) {
648 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
649 quoted_arg = protect_arg(argv[i]);
650 g_string_append(args, quoted_arg);
655 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
656 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
657 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
658 args->str, GetLastError());
659 CloseHandle(sync_pipe_read);
660 CloseHandle(sync_pipe_write);
661 g_free( (gpointer) argv[0]);
662 g_free( (gpointer) argv);
663 return CANT_RUN_DUMPCAP;
665 *fork_child = (int) pi.hProcess;
666 g_string_free(args, TRUE);
668 /* associate the operating system filehandle to a C run-time file handle */
669 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
670 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
673 if (pipe(sync_pipe) < 0) {
674 /* Couldn't create the pipe between parent and child. */
675 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
676 g_free( (gpointer) argv[0]);
678 return CANT_RUN_DUMPCAP;
681 if ((*fork_child = fork()) == 0) {
683 * Child process - run dumpcap with the right arguments to make
684 * it just capture with the specified capture parameters
686 dup2(sync_pipe[PIPE_WRITE], 1);
687 eth_close(sync_pipe[PIPE_READ]);
688 execv(argv[0], (gpointer)argv);
689 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
690 argv[0], strerror(errno));
691 sync_pipe_errmsg_to_parent(1, errmsg, "");
693 /* Exit with "_exit()", so that we don't close the connection
694 to the X server (and cause stuff buffered up by our parent but
695 not yet sent to be sent, as that stuff should only be sent by
696 our parent). We've sent an error message to the parent, so
697 we exit with an exit status of 1 (any exit status other than
698 0 or 1 will cause an additional message to report that exit
699 status, over and above the error message we sent to the parent). */
703 *read_fd = sync_pipe[PIPE_READ];
706 g_free( (gpointer) argv[0]); /* exename */
708 /* Parent process - read messages from the child process over the
710 g_free( (gpointer) argv); /* free up arg array */
712 /* Close the write side of the pipe, so that only the child has it
713 open, and thus it completely closes, and thus returns to us
714 an EOF indication, if the child closes it (either deliberately
715 or by exiting abnormally). */
717 CloseHandle(sync_pipe_write);
719 eth_close(sync_pipe[PIPE_WRITE]);
722 if (*fork_child == -1) {
723 /* We couldn't even create the child process. */
724 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
726 return CANT_RUN_DUMPCAP;
729 /* we might wait for a moment till child is ready, so update screen now */
730 main_window_update();
736 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
738 sync_pipe_close_command(int *read_fd, gchar **msg) {
740 int fork_child_status;
744 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
747 /* XXX - Should we signal the child somehow? */
748 sync_pipe_kill(*fork_child);
749 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
750 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
751 "(errno:%u)", errno);
752 return CANT_RUN_DUMPCAP;
755 if (wait(&fork_child_status) != -1) {
756 if (WIFEXITED(fork_child_status)) {
757 /* The child exited. */
758 fork_child_status = WEXITSTATUS(fork_child_status);
760 if (WIFSTOPPED(fork_child_status)) {
761 /* It stopped, rather than exiting. "Should not happen." */
762 *msg = g_strdup_printf("Child capture process stopped: %s",
763 sync_pipe_signame(WSTOPSIG(fork_child_status)));
764 } else if (WIFSIGNALED(fork_child_status)) {
765 /* It died with a signal. */
766 *msg = g_strdup_printf("Child capture process died: %s%s",
767 sync_pipe_signame(WTERMSIG(fork_child_status)),
768 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
770 /* What? It had to either have exited, or stopped, or died with
771 a signal; what happened here? */
772 *msg = g_strdup_printf("Child capture process died: wait status %#o",
775 return CANT_RUN_DUMPCAP;
778 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
779 "(errno:%u)", errno);
780 return CANT_RUN_DUMPCAP;
787 * Run dumpcap with the supplied arguments. On success, msg points to
788 * a buffer containing the dumpcap output and returns 0. On failure, msg
789 * points to the error message returned by dumpcap, and returns dumpcap's
790 * exit value. In either case, msg must be freed with g_free().
792 /* XXX - This duplicates a lot of code in sync_pipe_start() */
793 #define PIPE_BUF_SIZE 5120
795 sync_pipe_run_command(const char** argv, gchar **msg) {
796 int sync_pipe_read_fd, fork_child, ret;
797 gchar buf[PIPE_BUF_SIZE+1];
798 GString *msg_buf = NULL;
801 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
806 /* We were able to set up to read dumpcap's output. Do so and
807 return its exit value. */
808 msg_buf = g_string_new("");
809 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
811 g_string_append(msg_buf, buf);
815 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
817 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
821 g_string_free(msg_buf, TRUE);
826 g_string_free(msg_buf, FALSE);
831 * Get an interface list using dumpcap. On success, msg points to
832 * a buffer containing the dumpcap output and returns 0. On failure, msg
833 * points to the error message returned by dumpcap, and returns dumpcap's
834 * exit value. In either case, msg must be freed with g_free().
837 sync_interface_list_open(gchar **msg) {
842 /* We can't return anything */
846 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
848 argv = init_pipe_args(&argc);
851 *msg = g_strdup_printf("We don't know where to find dumpcap.");
852 return CANT_RUN_DUMPCAP;
855 /* Ask for the interface list */
856 argv = sync_pipe_add_arg(argv, &argc, "-D");
857 argv = sync_pipe_add_arg(argv, &argc, "-M");
859 /* dumpcap should be running in capture child mode (hidden feature) */
861 argv = sync_pipe_add_arg(argv, &argc, "-Z");
862 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
865 return sync_pipe_run_command(argv, msg);
869 * Get an linktype list using dumpcap. On success, msg points to
870 * a buffer containing the dumpcap output and returns 0. On failure, msg
871 * points to the error message returned by dumpcap, and returns dumpcap's
872 * exit value. In either case, msg must be freed with g_free().
875 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
880 /* We can't return anything */
884 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
886 argv = init_pipe_args(&argc);
889 *msg = g_strdup_printf("We don't know where to find dumpcap.");
890 return CANT_RUN_DUMPCAP;
893 /* Ask for the linktype list */
894 argv = sync_pipe_add_arg(argv, &argc, "-i");
895 argv = sync_pipe_add_arg(argv, &argc, ifname);
896 argv = sync_pipe_add_arg(argv, &argc, "-L");
897 argv = sync_pipe_add_arg(argv, &argc, "-M");
899 /* dumpcap should be running in capture child mode (hidden feature) */
901 argv = sync_pipe_add_arg(argv, &argc, "-Z");
902 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
905 return sync_pipe_run_command(argv, msg);
909 * Start getting interface statistics using dumpcap. On success, read_fd
910 * contains the file descriptor for the pipe's stdout, msg is unchanged,
911 * and zero is returned. On failure, msg will point to an error message
912 * that must be g_free()d and a nonzero error value will be returned.
915 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
920 /* We can't return anything */
924 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
926 argv = init_pipe_args(&argc);
929 *msg = g_strdup_printf("We don't know where to find dumpcap.");
930 return CANT_RUN_DUMPCAP;
933 /* Ask for the linktype list */
934 argv = sync_pipe_add_arg(argv, &argc, "-S");
935 argv = sync_pipe_add_arg(argv, &argc, "-M");
937 /* dumpcap should be running in capture child mode (hidden feature) */
939 argv = sync_pipe_add_arg(argv, &argc, "-Z");
940 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
943 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
946 /* Close down the stats process */
948 sync_interface_stats_close(int *read_fd, int *fork_child
954 return sync_pipe_close_command(read_fd, fork_child, msg);
956 return sync_pipe_close_command(read_fd, msg);
960 /* read a number of bytes from a pipe */
961 /* (blocks until enough bytes read or an error occurs) */
963 pipe_read_bytes(int pipe, char *bytes, int required) {
968 newly = read(pipe, &bytes[offset], required);
971 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
972 "read from pipe %d: EOF (capture closed?)", pipe);
977 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
978 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
989 static gboolean pipe_data_available(int pipe) {
990 #ifdef _WIN32 /* PeekNamedPipe */
991 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
994 if (hPipe == INVALID_HANDLE_VALUE)
997 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1000 if (bytes_avail > 0)
1005 struct timeval timeout;
1008 FD_SET(pipe, &rfds);
1010 timeout.tv_usec = 0;
1012 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
1019 /* Read a line from a pipe, similar to fgets */
1021 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
1025 while(offset < max - 1) {
1027 if (! pipe_data_available(pipe))
1029 newly = read(pipe, &bytes[offset], 1);
1031 /* EOF - not necessarily an error */
1033 } else if (newly < 0) {
1035 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1036 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1038 } else if (bytes[offset] == '\n') {
1044 bytes[offset] = '\0';
1050 /* convert header values (indicator and 4-byte length) */
1052 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1054 g_assert(header_len == 4);
1056 /* convert header values */
1057 *indicator = header[0];
1058 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1061 /* read a message from the sending pipe in the standard format
1062 (1-byte message indicator, 3-byte message length (excluding length
1063 and indicator field), and the rest is the message) */
1065 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1071 /* read header (indicator and 3-byte length) */
1072 newly = pipe_read_bytes(pipe, header, 4);
1074 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1075 "read %d failed to read header: %u", pipe, newly);
1079 /* convert header values */
1080 pipe_convert_header(header, 4, indicator, &required);
1082 /* only indicator with no value? */
1084 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1085 "read %d indicator: %c empty value", pipe, *indicator);
1089 /* does the data fit into the given buffer? */
1090 if(required > len) {
1091 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1092 "read %d length error, required %d > len %d, indicator: %u",
1093 pipe, required, len, *indicator);
1095 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1096 memcpy(msg, header, sizeof(header));
1097 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1098 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1103 /* read the actual block data */
1104 newly = pipe_read_bytes(pipe, msg, required);
1105 if(newly != required) {
1106 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1110 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1111 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1112 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1118 /* There's stuff to read from the sync pipe, meaning the child has sent
1119 us a message, or the sync pipe has closed, meaning the child has
1120 closed it (perhaps because it exited). */
1122 sync_pipe_input_cb(gint source, gpointer user_data)
1124 capture_options *capture_opts = (capture_options *)user_data;
1125 char buffer[SP_MAX_MSG_LEN+1];
1131 char * secondary_msg;
1134 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1137 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1138 "sync_pipe_input_cb: child has closed sync_pipe");
1140 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1141 "sync_pipe_input_cb: error reading from sync pipe");
1143 /* The child has closed the sync pipe, meaning it's not going to be
1144 capturing any more packets. Pick up its exit status, and
1145 complain if it did anything other than exit with status 0.
1147 We don't have to worry about killing the child, if the sync pipe
1148 returned an error. Usually this error is caused as the child killed itself
1149 while going down. Even in the rare cases that this isn't the case,
1150 the child will get an error when writing to the broken pipe the next time,
1151 cleaning itself up then. */
1152 sync_pipe_wait_for_child(capture_opts);
1155 eth_close(capture_opts->signal_pipe_write_fd);
1157 capture_input_closed(capture_opts);
1161 /* we got a valid message block from the child, process it */
1164 if(!capture_input_new_file(capture_opts, buffer)) {
1165 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1167 /* We weren't able to open the new capture file; user has been
1168 alerted. Close the sync pipe. */
1171 /* the child has send us a filename which we couldn't open.
1172 this probably means, the child is creating files faster than we can handle it.
1173 this should only be the case for very fast file switches
1174 we can't do much more than telling the child to stop
1175 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1176 sync_pipe_stop(capture_opts);
1179 case SP_PACKET_COUNT:
1180 nread = atoi(buffer);
1181 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1182 capture_input_new_packets(capture_opts, nread);
1185 /* convert primary message */
1186 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1187 primary_msg = buffer+4;
1188 /* convert secondary message */
1189 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1190 secondary_msg = primary_msg + primary_len + 4;
1191 /* message output */
1192 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1193 /* the capture child will close the sync_pipe, nothing to do for now */
1194 /* (an error message doesn't mean we have to stop capturing) */
1197 capture_input_cfilter_error_message(capture_opts, buffer);
1198 /* the capture child will close the sync_pipe, nothing to do for now */
1201 capture_input_drops(capture_opts, atoi(buffer));
1204 g_assert_not_reached();
1212 /* the child process is going down, wait until it's completely terminated */
1214 sync_pipe_wait_for_child(capture_options *capture_opts)
1219 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1220 g_assert(capture_opts->fork_child != -1);
1223 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1224 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1225 "Child capture process stopped unexpectedly (errno:%u)", errno);
1228 if (wait(&wstatus) != -1) {
1229 if (WIFEXITED(wstatus)) {
1230 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1231 /* the child will inform us about errors through the sync_pipe, which will popup */
1232 /* an error message, so don't popup another one */
1234 /* If there are situations where the child won't send us such an error message, */
1235 /* this should be fixed in the child and not here! */
1236 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1237 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1238 "Child capture process exited: exit status %d",
1239 WEXITSTATUS(wstatus));
1241 } else if (WIFSTOPPED(wstatus)) {
1242 /* It stopped, rather than exiting. "Should not happen." */
1243 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1244 "Child capture process stopped: %s",
1245 sync_pipe_signame(WSTOPSIG(wstatus)));
1246 } else if (WIFSIGNALED(wstatus)) {
1247 /* It died with a signal. */
1248 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1249 "Child capture process died: %s%s",
1250 sync_pipe_signame(WTERMSIG(wstatus)),
1251 WCOREDUMP(wstatus) ? " - core dumped" : "");
1253 /* What? It had to either have exited, or stopped, or died with
1254 a signal; what happened here? */
1255 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1256 "Child capture process died: wait status %#o", wstatus);
1261 /* No more child process. */
1262 capture_opts->fork_child = -1;
1264 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1269 /* convert signal to corresponding name */
1271 sync_pipe_signame(int sig)
1274 static char sigmsg_buf[6+1+3+1];
1283 sigmsg = "Interrupted";
1291 sigmsg = "Illegal instruction";
1295 sigmsg = "Trace trap";
1303 sigmsg = "Arithmetic exception";
1311 sigmsg = "Bus error";
1315 sigmsg = "Segmentation violation";
1318 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1319 Linux is POSIX compliant. These are not POSIX-defined signals ---
1320 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1322 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1323 were omitted from POSIX.1 because their behavior is
1324 implementation dependent and could not be adequately catego-
1325 rized. Conforming implementations may deliver these sig-
1326 nals, but must document the circumstances under which they
1327 are delivered and note any restrictions concerning their
1330 So we only check for SIGSYS on those systems that happen to
1331 implement them (a system can be POSIX-compliant and implement
1332 them, it's just that POSIX doesn't *require* a POSIX-compliant
1333 system to implement them).
1338 sigmsg = "Bad system call";
1343 sigmsg = "Broken pipe";
1347 sigmsg = "Alarm clock";
1351 sigmsg = "Terminated";
1355 /* Returning a static buffer is ok in the context we use it here */
1356 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1357 sigmsg = sigmsg_buf;
1366 /* tell the child through the signal pipe that we want to quit the capture */
1368 signal_pipe_capquit_to_child(capture_options *capture_opts)
1370 const char quit_msg[] = "QUIT";
1374 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1376 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1377 /* simply sending a "QUIT" string */
1378 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1379 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1381 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1382 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1388 /* user wants to stop the capture run */
1390 sync_pipe_stop(capture_options *capture_opts)
1395 gboolean terminate = TRUE;
1398 if (capture_opts->fork_child != -1) {
1400 /* send the SIGUSR1 signal to close the capture child gracefully. */
1401 kill(capture_opts->fork_child, SIGUSR1);
1403 #define STOP_SLEEP_TIME 500 /* ms */
1404 #define STOP_CHECK_TIME 50
1405 /* First, use the special signal pipe to try to close the capture child
1408 signal_pipe_capquit_to_child(capture_opts);
1410 /* Next, wait for the process to exit on its own */
1411 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1412 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1413 childstatus != STILL_ACTIVE) {
1417 Sleep(STOP_CHECK_TIME);
1420 /* Force the issue. */
1422 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1423 "sync_pipe_stop: forcing child to exit");
1424 sync_pipe_kill(capture_opts->fork_child);
1431 /* Wireshark has to exit, force the capture child to close */
1433 sync_pipe_kill(int fork_child)
1435 if (fork_child != -1) {
1437 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1439 /* Remark: This is not the preferred method of closing a process!
1440 * the clean way would be getting the process id of the child process,
1441 * then getting window handle hWnd of that process (using EnumChildWindows),
1442 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1444 * Unfortunately, I don't know how to get the process id from the
1445 * handle. OpenProcess will get an handle (not a window handle)
1446 * from the process ID; it will not get a window handle from the
1447 * process ID. (How could it? A process can have more than one
1448 * window. For that matter, a process might have *no* windows,
1449 * as a process running dumpcap, the normal child process program,
1452 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1453 * running in the same console; that's not necessarily the case for
1454 * us, as we might not be running in a console.
1455 * And this also will require to have the process id.
1457 TerminateProcess((HANDLE) (fork_child), 0);
1462 #endif /* HAVE_LIBPCAP */