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");
860 /* dumpcap should be running in capture child mode (hidden feature) */
861 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
862 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
863 /* stderr in normal format and are then sent to whereever our stderr goes. */
864 /* Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
865 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
866 /* msgs to stderr in a special type/len/string format which would then */
867 /* currently be sent as is to stderr resulting in garbled output. */
868 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
869 /* special format error messages to stderr are captured and returned to caller */
870 /* (eg: so can be processed and displayed in a pop-up box). */
872 argv = sync_pipe_add_arg(argv, &argc, "-Z");
873 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
877 return sync_pipe_run_command(argv, msg);
881 * Get an linktype list using dumpcap. On success, msg points to
882 * a buffer containing the dumpcap output and returns 0. On failure, msg
883 * points to the error message returned by dumpcap, and returns dumpcap's
884 * exit value. In either case, msg must be freed with g_free().
887 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
892 /* We can't return anything */
896 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
898 argv = init_pipe_args(&argc);
901 *msg = g_strdup_printf("We don't know where to find dumpcap.");
902 return CANT_RUN_DUMPCAP;
905 /* Ask for the linktype list */
906 argv = sync_pipe_add_arg(argv, &argc, "-i");
907 argv = sync_pipe_add_arg(argv, &argc, ifname);
908 argv = sync_pipe_add_arg(argv, &argc, "-L");
909 argv = sync_pipe_add_arg(argv, &argc, "-M");
912 /* dumpcap should be running in capture child mode (hidden feature) */
913 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
914 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
915 /* stderr in normal format and are then sent to whereever our stderr goes. */
916 /* Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
917 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
918 /* msgs to stderr in a special type/len/string format which would then */
919 /* currently be sent as is to stderr resulting in garbled output. */
920 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
921 /* special format error messages to stderr are captured and returned to caller */
922 /* (eg: so can be processed and displayed in a pop-up box). */
924 argv = sync_pipe_add_arg(argv, &argc, "-Z");
925 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
928 return sync_pipe_run_command(argv, msg);
932 * Start getting interface statistics using dumpcap. On success, read_fd
933 * contains the file descriptor for the pipe's stdout, msg is unchanged,
934 * and zero is returned. On failure, msg will point to an error message
935 * that must be g_free()d and a nonzero error value will be returned.
938 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
943 /* We can't return anything */
947 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
949 argv = init_pipe_args(&argc);
952 *msg = g_strdup_printf("We don't know where to find dumpcap.");
953 return CANT_RUN_DUMPCAP;
956 /* Ask for the interface statistics */
957 argv = sync_pipe_add_arg(argv, &argc, "-S");
958 argv = sync_pipe_add_arg(argv, &argc, "-M");
961 /* dumpcap should be running in capture child mode (hidden feature) */
962 /* XXX: Actually: don't run dumpcap in capture_child_mode. */
963 /* Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to */
964 /* stderr in normal format and are then sent to whereever our stderr goes. */
965 /* Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
966 /* dumpcap err msgs. That is: dumpcap in capture_child mode outputs err */
967 /* msgs to stderr in a special type/len/string format which would then */
968 /* currently be sent as is to stderr resulting in garbled output. */
969 /* ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z' */
970 /* special format error messages to stderr are captured and returned to caller */
971 /* (eg: so can be processed and displayed in a pop-up box). */
973 argv = sync_pipe_add_arg(argv, &argc, "-Z");
974 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
977 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
980 /* Close down the stats process */
982 sync_interface_stats_close(int *read_fd, int *fork_child
988 return sync_pipe_close_command(read_fd, fork_child, msg);
990 return sync_pipe_close_command(read_fd, msg);
994 /* read a number of bytes from a pipe */
995 /* (blocks until enough bytes read or an error occurs) */
997 pipe_read_bytes(int pipe, char *bytes, int required) {
1002 newly = read(pipe, &bytes[offset], required);
1005 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1006 "read from pipe %d: EOF (capture closed?)", pipe);
1011 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1012 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1023 static gboolean pipe_data_available(int pipe) {
1024 #ifdef _WIN32 /* PeekNamedPipe */
1025 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
1028 if (hPipe == INVALID_HANDLE_VALUE)
1031 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1034 if (bytes_avail > 0)
1039 struct timeval timeout;
1042 FD_SET(pipe, &rfds);
1044 timeout.tv_usec = 0;
1046 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
1053 /* Read a line from a pipe, similar to fgets */
1055 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
1059 while(offset < max - 1) {
1061 if (! pipe_data_available(pipe))
1063 newly = read(pipe, &bytes[offset], 1);
1065 /* EOF - not necessarily an error */
1067 } else if (newly < 0) {
1069 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1070 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1072 } else if (bytes[offset] == '\n') {
1078 bytes[offset] = '\0';
1084 /* convert header values (indicator and 4-byte length) */
1086 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1088 g_assert(header_len == 4);
1090 /* convert header values */
1091 *indicator = header[0];
1092 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1095 /* read a message from the sending pipe in the standard format
1096 (1-byte message indicator, 3-byte message length (excluding length
1097 and indicator field), and the rest is the message) */
1099 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1105 /* read header (indicator and 3-byte length) */
1106 newly = pipe_read_bytes(pipe, header, 4);
1108 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1109 "read %d failed to read header: %u", pipe, newly);
1113 /* convert header values */
1114 pipe_convert_header(header, 4, indicator, &required);
1116 /* only indicator with no value? */
1118 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1119 "read %d indicator: %c empty value", pipe, *indicator);
1123 /* does the data fit into the given buffer? */
1124 if(required > len) {
1125 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1126 "read %d length error, required %d > len %d, indicator: %u",
1127 pipe, required, len, *indicator);
1129 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1130 memcpy(msg, header, sizeof(header));
1131 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1132 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1137 /* read the actual block data */
1138 newly = pipe_read_bytes(pipe, msg, required);
1139 if(newly != required) {
1140 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1144 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1145 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1146 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1152 /* There's stuff to read from the sync pipe, meaning the child has sent
1153 us a message, or the sync pipe has closed, meaning the child has
1154 closed it (perhaps because it exited). */
1156 sync_pipe_input_cb(gint source, gpointer user_data)
1158 capture_options *capture_opts = (capture_options *)user_data;
1159 char buffer[SP_MAX_MSG_LEN+1];
1165 char * secondary_msg;
1168 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1171 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1172 "sync_pipe_input_cb: child has closed sync_pipe");
1174 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1175 "sync_pipe_input_cb: error reading from sync pipe");
1177 /* The child has closed the sync pipe, meaning it's not going to be
1178 capturing any more packets. Pick up its exit status, and
1179 complain if it did anything other than exit with status 0.
1181 We don't have to worry about killing the child, if the sync pipe
1182 returned an error. Usually this error is caused as the child killed itself
1183 while going down. Even in the rare cases that this isn't the case,
1184 the child will get an error when writing to the broken pipe the next time,
1185 cleaning itself up then. */
1186 sync_pipe_wait_for_child(capture_opts);
1189 eth_close(capture_opts->signal_pipe_write_fd);
1191 capture_input_closed(capture_opts);
1195 /* we got a valid message block from the child, process it */
1198 if(!capture_input_new_file(capture_opts, buffer)) {
1199 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1201 /* We weren't able to open the new capture file; user has been
1202 alerted. Close the sync pipe. */
1205 /* the child has send us a filename which we couldn't open.
1206 this probably means, the child is creating files faster than we can handle it.
1207 this should only be the case for very fast file switches
1208 we can't do much more than telling the child to stop
1209 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1210 sync_pipe_stop(capture_opts);
1213 case SP_PACKET_COUNT:
1214 nread = atoi(buffer);
1215 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1216 capture_input_new_packets(capture_opts, nread);
1219 /* convert primary message */
1220 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1221 primary_msg = buffer+4;
1222 /* convert secondary message */
1223 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1224 secondary_msg = primary_msg + primary_len + 4;
1225 /* message output */
1226 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1227 /* the capture child will close the sync_pipe, nothing to do for now */
1228 /* (an error message doesn't mean we have to stop capturing) */
1231 capture_input_cfilter_error_message(capture_opts, buffer);
1232 /* the capture child will close the sync_pipe, nothing to do for now */
1235 capture_input_drops(capture_opts, atoi(buffer));
1238 g_assert_not_reached();
1246 /* the child process is going down, wait until it's completely terminated */
1248 sync_pipe_wait_for_child(capture_options *capture_opts)
1253 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1254 g_assert(capture_opts->fork_child != -1);
1257 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1259 "Child capture process stopped unexpectedly (errno:%u)", errno);
1262 if (wait(&wstatus) != -1) {
1263 if (WIFEXITED(wstatus)) {
1264 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1265 /* the child will inform us about errors through the sync_pipe, which will popup */
1266 /* an error message, so don't popup another one */
1268 /* If there are situations where the child won't send us such an error message, */
1269 /* this should be fixed in the child and not here! */
1270 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1271 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1272 "Child capture process exited: exit status %d",
1273 WEXITSTATUS(wstatus));
1275 } else if (WIFSTOPPED(wstatus)) {
1276 /* It stopped, rather than exiting. "Should not happen." */
1277 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1278 "Child capture process stopped: %s",
1279 sync_pipe_signame(WSTOPSIG(wstatus)));
1280 } else if (WIFSIGNALED(wstatus)) {
1281 /* It died with a signal. */
1282 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1283 "Child capture process died: %s%s",
1284 sync_pipe_signame(WTERMSIG(wstatus)),
1285 WCOREDUMP(wstatus) ? " - core dumped" : "");
1287 /* What? It had to either have exited, or stopped, or died with
1288 a signal; what happened here? */
1289 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1290 "Child capture process died: wait status %#o", wstatus);
1295 /* No more child process. */
1296 capture_opts->fork_child = -1;
1298 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1303 /* convert signal to corresponding name */
1305 sync_pipe_signame(int sig)
1308 static char sigmsg_buf[6+1+3+1];
1317 sigmsg = "Interrupted";
1325 sigmsg = "Illegal instruction";
1329 sigmsg = "Trace trap";
1337 sigmsg = "Arithmetic exception";
1345 sigmsg = "Bus error";
1349 sigmsg = "Segmentation violation";
1352 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1353 Linux is POSIX compliant. These are not POSIX-defined signals ---
1354 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1356 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1357 were omitted from POSIX.1 because their behavior is
1358 implementation dependent and could not be adequately catego-
1359 rized. Conforming implementations may deliver these sig-
1360 nals, but must document the circumstances under which they
1361 are delivered and note any restrictions concerning their
1364 So we only check for SIGSYS on those systems that happen to
1365 implement them (a system can be POSIX-compliant and implement
1366 them, it's just that POSIX doesn't *require* a POSIX-compliant
1367 system to implement them).
1372 sigmsg = "Bad system call";
1377 sigmsg = "Broken pipe";
1381 sigmsg = "Alarm clock";
1385 sigmsg = "Terminated";
1389 /* Returning a static buffer is ok in the context we use it here */
1390 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1391 sigmsg = sigmsg_buf;
1400 /* tell the child through the signal pipe that we want to quit the capture */
1402 signal_pipe_capquit_to_child(capture_options *capture_opts)
1404 const char quit_msg[] = "QUIT";
1408 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1410 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1411 /* simply sending a "QUIT" string */
1412 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1413 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1415 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1416 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1422 /* user wants to stop the capture run */
1424 sync_pipe_stop(capture_options *capture_opts)
1429 gboolean terminate = TRUE;
1432 if (capture_opts->fork_child != -1) {
1434 /* send the SIGUSR1 signal to close the capture child gracefully. */
1435 int sts = kill(capture_opts->fork_child, SIGUSR1);
1437 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1438 "Sending SIGUSR1 to child failed: %s\n", strerror(errno));
1441 #define STOP_SLEEP_TIME 500 /* ms */
1442 #define STOP_CHECK_TIME 50
1443 /* First, use the special signal pipe to try to close the capture child
1446 signal_pipe_capquit_to_child(capture_opts);
1448 /* Next, wait for the process to exit on its own */
1449 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1450 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1451 childstatus != STILL_ACTIVE) {
1455 Sleep(STOP_CHECK_TIME);
1458 /* Force the issue. */
1460 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1461 "sync_pipe_stop: forcing child to exit");
1462 sync_pipe_kill(capture_opts->fork_child);
1469 /* Wireshark has to exit, force the capture child to close */
1471 sync_pipe_kill(int fork_child)
1473 if (fork_child != -1) {
1475 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1477 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1478 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1481 /* Remark: This is not the preferred method of closing a process!
1482 * the clean way would be getting the process id of the child process,
1483 * then getting window handle hWnd of that process (using EnumChildWindows),
1484 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1486 * Unfortunately, I don't know how to get the process id from the
1487 * handle. OpenProcess will get an handle (not a window handle)
1488 * from the process ID; it will not get a window handle from the
1489 * process ID. (How could it? A process can have more than one
1490 * window. For that matter, a process might have *no* windows,
1491 * as a process running dumpcap, the normal child process program,
1494 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1495 * running in the same console; that's not necessarily the case for
1496 * us, as we might not be running in a console.
1497 * And this also will require to have the process id.
1499 TerminateProcess((HANDLE) (fork_child), 0);
1504 #endif /* HAVE_LIBPCAP */