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 argv = sync_pipe_add_arg(argv, &argc, "-i");
296 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
298 if (capture_opts->has_snaplen) {
299 argv = sync_pipe_add_arg(argv, &argc, "-s");
300 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
301 argv = sync_pipe_add_arg(argv, &argc, ssnap);
304 if (capture_opts->linktype != -1) {
305 argv = sync_pipe_add_arg(argv, &argc, "-y");
306 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
307 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
309 /* we can't get the type name, just treat it as a number */
310 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
312 argv = sync_pipe_add_arg(argv, &argc, sdlt);
315 if(capture_opts->multi_files_on) {
316 if (capture_opts->has_autostop_filesize) {
317 argv = sync_pipe_add_arg(argv, &argc, "-b");
318 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
319 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
322 if (capture_opts->has_file_duration) {
323 argv = sync_pipe_add_arg(argv, &argc, "-b");
324 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
325 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
328 if (capture_opts->has_ring_num_files) {
329 argv = sync_pipe_add_arg(argv, &argc, "-b");
330 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
331 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
334 if (capture_opts->has_autostop_files) {
335 argv = sync_pipe_add_arg(argv, &argc, "-a");
336 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
337 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
340 if (capture_opts->has_autostop_filesize) {
341 argv = sync_pipe_add_arg(argv, &argc, "-a");
342 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
343 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
347 if (capture_opts->has_autostop_packets) {
348 argv = sync_pipe_add_arg(argv, &argc, "-c");
349 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
350 argv = sync_pipe_add_arg(argv, &argc, scount);
353 if (capture_opts->has_autostop_duration) {
354 argv = sync_pipe_add_arg(argv, &argc, "-a");
355 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
356 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
359 if (!capture_opts->promisc_mode)
360 argv = sync_pipe_add_arg(argv, &argc, "-p");
361 #ifdef HAVE_PCAP_REMOTE
362 if (capture_opts->datatx_udp)
363 argv = sync_pipe_add_arg(argv, &argc, "-u");
365 if (!capture_opts->nocap_rpcap)
366 argv = sync_pipe_add_arg(argv, &argc, "-r");
368 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
370 argv = sync_pipe_add_arg(argv, &argc, "-A");
371 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
372 capture_opts->auth_password);
373 argv = sync_pipe_add_arg(argv, &argc, sauth);
376 #ifdef HAVE_PCAP_SETSAMPLING
377 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
379 argv = sync_pipe_add_arg(argv, &argc, "-m");
380 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
381 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
382 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
384 capture_opts->sampling_param);
385 argv = sync_pipe_add_arg(argv, &argc, ssampling);
389 /* dumpcap should be running in capture child mode (hidden feature) */
391 argv = sync_pipe_add_arg(argv, &argc, "-Z");
393 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
394 argv = sync_pipe_add_arg(argv, &argc, control_id);
396 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
401 argv = sync_pipe_add_arg(argv, &argc, "-B");
402 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
403 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
406 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
407 argv = sync_pipe_add_arg(argv, &argc, "-f");
408 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
411 if(capture_opts->save_file) {
412 argv = sync_pipe_add_arg(argv, &argc, "-w");
413 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
417 /* init SECURITY_ATTRIBUTES */
418 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
419 sa.bInheritHandle = TRUE;
420 sa.lpSecurityDescriptor = NULL;
422 /* Create a pipe for the child process */
423 /* (increase this value if you have trouble while fast capture file switches) */
424 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
425 /* Couldn't create the pipe between parent and child. */
426 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
428 g_free( (gpointer) argv[0]);
429 g_free( (gpointer) argv);
433 /* Create the signal pipe */
434 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
435 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
436 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
437 g_free(signal_pipe_name);
439 if (signal_pipe == INVALID_HANDLE_VALUE) {
440 /* Couldn't create the signal pipe between parent and child. */
441 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
443 g_free( (gpointer) argv[0]);
444 g_free( (gpointer) argv);
448 /* init STARTUPINFO */
449 memset(&si, 0, sizeof(si));
452 si.dwFlags = STARTF_USESHOWWINDOW;
453 si.wShowWindow = SW_SHOW;
455 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
456 si.wShowWindow = SW_HIDE; /* this hides the console window */
457 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
458 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
459 si.hStdError = sync_pipe_write;
460 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
463 /* convert args array into a single string */
464 /* XXX - could change sync_pipe_add_arg() instead */
465 /* there is a drawback here: the length is internally limited to 1024 bytes */
466 for(i=0; argv[i] != 0; i++) {
467 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
468 quoted_arg = protect_arg(argv[i]);
469 g_string_append(args, quoted_arg);
474 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
475 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
476 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
477 "Couldn't run %s in child process: error %u",
478 args->str, GetLastError());
479 CloseHandle(sync_pipe_read);
480 CloseHandle(sync_pipe_write);
481 g_free( (gpointer) argv[0]);
482 g_free( (gpointer) argv);
485 capture_opts->fork_child = (int) pi.hProcess;
486 g_string_free(args, TRUE);
488 /* associate the operating system filehandle to a C run-time file handle */
489 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
490 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
492 /* associate the operating system filehandle to a C run-time file handle */
493 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
496 if (pipe(sync_pipe) < 0) {
497 /* Couldn't create the pipe between parent and child. */
498 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
500 g_free( (gpointer) argv[0]);
505 if ((capture_opts->fork_child = fork()) == 0) {
507 * Child process - run dumpcap with the right arguments to make
508 * it just capture with the specified capture parameters
511 dup(sync_pipe[PIPE_WRITE]);
512 eth_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(1, 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
525 sync_pipe_read_fd = sync_pipe[PIPE_READ];
528 g_free( (gpointer) argv[0]); /* exename */
530 /* Parent process - read messages from the child process over the
532 g_free( (gpointer) argv); /* free up arg array */
534 /* Close the write side of the pipe, so that only the child has it
535 open, and thus it completely closes, and thus returns to us
536 an EOF indication, if the child closes it (either deliberately
537 or by exiting abnormally). */
539 CloseHandle(sync_pipe_write);
541 eth_close(sync_pipe[PIPE_WRITE]);
544 if (capture_opts->fork_child == -1) {
545 /* We couldn't even create the child process. */
546 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
547 "Couldn't create child process: %s", strerror(errno));
548 eth_close(sync_pipe_read_fd);
550 eth_close(capture_opts->signal_pipe_write_fd);
555 /* we might wait for a moment till child is ready, so update screen now */
556 main_window_update();
558 /* We were able to set up to read the capture file;
559 arrange that our callback be called whenever it's possible
560 to read from the sync pipe, so that it's called when
561 the child process wants to tell us something. */
563 /* we have a running capture, now wait for the real capture filename */
564 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
565 &capture_opts->fork_child, sync_pipe_input_cb);
571 * Open dumpcap with the supplied arguments. On success, msg points to
572 * a buffer containing the dumpcap output and returns 0. read_fd and
573 * fork_child point to the pipe's file descriptor and child PID/handle,
574 * respectively. On failure, msg points to the error message returned by
575 * dumpcap, and returns dumpcap's exit value. In either case, msg must be
576 * freed with g_free().
578 /* XXX - This duplicates a lot of code in sync_pipe_start() */
579 #define PIPE_BUF_SIZE 5120
581 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
583 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
584 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
585 GString *args = g_string_sized_new(200);
587 SECURITY_ATTRIBUTES sa;
589 PROCESS_INFORMATION pi;
592 int sync_pipe[2]; /* pipe used to send messages from child to parent */
593 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
598 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
601 /* We can't return anything */
603 g_string_free(args, TRUE);
609 /* init SECURITY_ATTRIBUTES */
610 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
611 sa.bInheritHandle = TRUE;
612 sa.lpSecurityDescriptor = NULL;
614 /* Create a pipe for the child process */
615 /* (inrease this value if you have trouble while fast capture file switches) */
616 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
617 /* Couldn't create the pipe between parent and child. */
618 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
619 g_free( (gpointer) argv[0]);
620 g_free( (gpointer) argv);
621 return CANT_RUN_DUMPCAP;
624 /* init STARTUPINFO */
625 memset(&si, 0, sizeof(si));
628 si.dwFlags = STARTF_USESHOWWINDOW;
629 si.wShowWindow = SW_SHOW;
631 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
632 si.wShowWindow = SW_HIDE; /* this hides the console window */
634 si.hStdOutput = sync_pipe_write;
635 si.hStdError = sync_pipe_write;
636 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
639 /* convert args array into a single string */
640 /* XXX - could change sync_pipe_add_arg() instead */
641 /* there is a drawback here: the length is internally limited to 1024 bytes */
642 for(i=0; argv[i] != 0; i++) {
643 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
644 quoted_arg = protect_arg(argv[i]);
645 g_string_append(args, quoted_arg);
650 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
651 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
652 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
653 args->str, GetLastError());
654 CloseHandle(sync_pipe_read);
655 CloseHandle(sync_pipe_write);
656 g_free( (gpointer) argv[0]);
657 g_free( (gpointer) argv);
658 return CANT_RUN_DUMPCAP;
660 *fork_child = (int) pi.hProcess;
661 g_string_free(args, TRUE);
663 /* associate the operating system filehandle to a C run-time file handle */
664 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
665 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
668 if (pipe(sync_pipe) < 0) {
669 /* Couldn't create the pipe between parent and child. */
670 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
671 g_free( (gpointer) argv[0]);
673 return CANT_RUN_DUMPCAP;
676 if ((*fork_child = fork()) == 0) {
678 * Child process - run dumpcap with the right arguments to make
679 * it just capture with the specified capture parameters
682 dup(sync_pipe[PIPE_WRITE]);
683 eth_close(sync_pipe[PIPE_READ]);
684 execv(argv[0], (gpointer)argv);
685 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
686 argv[0], strerror(errno));
687 return CANT_RUN_DUMPCAP;
690 *read_fd = sync_pipe[PIPE_READ];
693 g_free( (gpointer) argv[0]); /* exename */
695 /* Parent process - read messages from the child process over the
697 g_free( (gpointer) argv); /* free up arg array */
699 /* Close the write side of the pipe, so that only the child has it
700 open, and thus it completely closes, and thus returns to us
701 an EOF indication, if the child closes it (either deliberately
702 or by exiting abnormally). */
704 CloseHandle(sync_pipe_write);
706 eth_close(sync_pipe[PIPE_WRITE]);
709 if (*fork_child == -1) {
710 /* We couldn't even create the child process. */
711 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
713 return CANT_RUN_DUMPCAP;
716 /* we might wait for a moment till child is ready, so update screen now */
717 main_window_update();
723 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
725 sync_pipe_close_command(int *read_fd, gchar **msg) {
727 int fork_child_status;
731 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
734 /* XXX - Should we signal the child somehow? */
735 sync_pipe_kill(*fork_child);
736 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
737 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
738 "(errno:%u)", errno);
739 return CANT_RUN_DUMPCAP;
742 if (wait(&fork_child_status) != -1) {
743 if (WIFEXITED(fork_child_status)) {
744 /* The child exited. */
745 fork_child_status = WEXITSTATUS(fork_child_status);
747 if (WIFSTOPPED(fork_child_status)) {
748 /* It stopped, rather than exiting. "Should not happen." */
749 *msg = g_strdup_printf("Child capture process stopped: %s",
750 sync_pipe_signame(WSTOPSIG(fork_child_status)));
751 } else if (WIFSIGNALED(fork_child_status)) {
752 /* It died with a signal. */
753 *msg = g_strdup_printf("Child capture process died: %s%s",
754 sync_pipe_signame(WTERMSIG(fork_child_status)),
755 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
757 /* What? It had to either have exited, or stopped, or died with
758 a signal; what happened here? */
759 *msg = g_strdup_printf("Child capture process died: wait status %#o",
762 return CANT_RUN_DUMPCAP;
765 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
766 "(errno:%u)", errno);
767 return CANT_RUN_DUMPCAP;
774 * Run dumpcap with the supplied arguments. On success, msg points to
775 * a buffer containing the dumpcap output and returns 0. On failure, msg
776 * points to the error message returned by dumpcap, and returns dumpcap's
777 * exit value. In either case, msg must be freed with g_free().
779 /* XXX - This duplicates a lot of code in sync_pipe_start() */
780 #define PIPE_BUF_SIZE 5120
782 sync_pipe_run_command(const char** argv, gchar **msg) {
783 int sync_pipe_read_fd, fork_child, ret;
784 gchar buf[PIPE_BUF_SIZE+1];
785 GString *msg_buf = NULL;
788 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
793 /* We were able to set up to read dumpcap's output. Do so and
794 return its exit value. */
795 msg_buf = g_string_new("");
796 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
798 g_string_append(msg_buf, buf);
802 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
804 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
808 g_string_free(msg_buf, TRUE);
813 g_string_free(msg_buf, FALSE);
818 * Get an interface list using dumpcap. On success, msg points to
819 * a buffer containing the dumpcap output and returns 0. On failure, msg
820 * points to the error message returned by dumpcap, and returns dumpcap's
821 * exit value. In either case, msg must be freed with g_free().
824 sync_interface_list_open(gchar **msg) {
829 /* We can't return anything */
833 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
835 argv = init_pipe_args(&argc);
838 *msg = g_strdup_printf("We don't know where to find dumpcap.");
839 return CANT_RUN_DUMPCAP;
842 /* Ask for the interface list */
843 argv = sync_pipe_add_arg(argv, &argc, "-D");
844 argv = sync_pipe_add_arg(argv, &argc, "-M");
846 /* dumpcap should be running in capture child mode (hidden feature) */
848 argv = sync_pipe_add_arg(argv, &argc, "-Z");
849 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
852 return sync_pipe_run_command(argv, msg);
856 * Get an linktype list using dumpcap. On success, msg points to
857 * a buffer containing the dumpcap output and returns 0. On failure, msg
858 * points to the error message returned by dumpcap, and returns dumpcap's
859 * exit value. In either case, msg must be freed with g_free().
862 sync_linktype_list_open(gchar *ifname, gchar **msg) {
867 /* We can't return anything */
871 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
873 argv = init_pipe_args(&argc);
876 *msg = g_strdup_printf("We don't know where to find dumpcap.");
877 return CANT_RUN_DUMPCAP;
880 /* Ask for the linktype list */
881 argv = sync_pipe_add_arg(argv, &argc, "-i");
882 argv = sync_pipe_add_arg(argv, &argc, ifname);
883 argv = sync_pipe_add_arg(argv, &argc, "-L");
884 argv = sync_pipe_add_arg(argv, &argc, "-M");
886 /* dumpcap should be running in capture child mode (hidden feature) */
888 argv = sync_pipe_add_arg(argv, &argc, "-Z");
889 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
892 return sync_pipe_run_command(argv, msg);
896 * Start getting interface statistics using dumpcap. On success, read_fd
897 * contains the file descriptor for the pipe's stdout, msg is unchanged,
898 * and zero is returned. On failure, msg will point to an error message
899 * that must be g_free()d and a nonzero error value will be returned.
902 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
907 /* We can't return anything */
911 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
913 argv = init_pipe_args(&argc);
916 *msg = g_strdup_printf("We don't know where to find dumpcap.");
917 return CANT_RUN_DUMPCAP;
920 /* Ask for the linktype list */
921 argv = sync_pipe_add_arg(argv, &argc, "-S");
922 argv = sync_pipe_add_arg(argv, &argc, "-M");
924 /* dumpcap should be running in capture child mode (hidden feature) */
926 argv = sync_pipe_add_arg(argv, &argc, "-Z");
927 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
930 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
933 /* Close down the stats process */
935 sync_interface_stats_close(int *read_fd, int *fork_child
941 return sync_pipe_close_command(read_fd, fork_child, msg);
943 return sync_pipe_close_command(read_fd, msg);
947 /* read a number of bytes from a pipe */
948 /* (blocks until enough bytes read or an error occurs) */
950 pipe_read_bytes(int pipe, char *bytes, int required) {
955 newly = read(pipe, &bytes[offset], required);
958 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
959 "read from pipe %d: EOF (capture closed?)", pipe);
964 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
965 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
976 static gboolean pipe_data_available(int pipe) {
977 #ifdef _WIN32 /* PeekNamedPipe */
978 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
981 if (hPipe == INVALID_HANDLE_VALUE)
984 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
992 struct timeval timeout;
999 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
1006 /* Read a line from a pipe, similar to fgets */
1008 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
1012 while(offset < max - 1) {
1014 if (! pipe_data_available(pipe))
1016 newly = read(pipe, &bytes[offset], 1);
1018 /* EOF - not necessarily an error */
1020 } else if (newly < 0) {
1022 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1023 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1025 } else if (bytes[offset] == '\n') {
1031 bytes[offset] = '\0';
1037 /* convert header values (indicator and 4-byte length) */
1039 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1041 g_assert(header_len == 4);
1043 /* convert header values */
1044 *indicator = header[0];
1045 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1048 /* read a message from the sending pipe in the standard format
1049 (1-byte message indicator, 3-byte message length (excluding length
1050 and indicator field), and the rest is the message) */
1052 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1058 /* read header (indicator and 3-byte length) */
1059 newly = pipe_read_bytes(pipe, header, 4);
1061 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1062 "read %d failed to read header: %u", pipe, newly);
1066 /* convert header values */
1067 pipe_convert_header(header, 4, indicator, &required);
1069 /* only indicator with no value? */
1071 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1072 "read %d indicator: %c empty value", pipe, *indicator);
1076 /* does the data fit into the given buffer? */
1077 if(required > len) {
1078 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1079 "read %d length error, required %d > len %d, indicator: %u",
1080 pipe, required, len, *indicator);
1082 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1083 memcpy(msg, header, sizeof(header));
1084 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1085 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1090 /* read the actual block data */
1091 newly = pipe_read_bytes(pipe, msg, required);
1092 if(newly != required) {
1093 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1097 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1098 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1104 /* There's stuff to read from the sync pipe, meaning the child has sent
1105 us a message, or the sync pipe has closed, meaning the child has
1106 closed it (perhaps because it exited). */
1108 sync_pipe_input_cb(gint source, gpointer user_data)
1110 capture_options *capture_opts = (capture_options *)user_data;
1111 char buffer[SP_MAX_MSG_LEN+1];
1117 char * secondary_msg;
1120 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1123 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1124 "sync_pipe_input_cb: child has closed sync_pipe");
1126 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1127 "sync_pipe_input_cb: error reading from sync pipe");
1129 /* The child has closed the sync pipe, meaning it's not going to be
1130 capturing any more packets. Pick up its exit status, and
1131 complain if it did anything other than exit with status 0.
1133 We don't have to worry about killing the child, if the sync pipe
1134 returned an error. Usually this error is caused as the child killed itself
1135 while going down. Even in the rare cases that this isn't the case,
1136 the child will get an error when writing to the broken pipe the next time,
1137 cleaning itself up then. */
1138 sync_pipe_wait_for_child(capture_opts);
1141 eth_close(capture_opts->signal_pipe_write_fd);
1143 capture_input_closed(capture_opts);
1147 /* we got a valid message block from the child, process it */
1150 if(!capture_input_new_file(capture_opts, buffer)) {
1151 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1153 /* We weren't able to open the new capture file; user has been
1154 alerted. Close the sync pipe. */
1157 /* the child has send us a filename which we couldn't open.
1158 this probably means, the child is creating files faster than we can handle it.
1159 this should only be the case for very fast file switches
1160 we can't do much more than telling the child to stop
1161 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1162 sync_pipe_stop(capture_opts);
1165 case SP_PACKET_COUNT:
1166 nread = atoi(buffer);
1167 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1168 capture_input_new_packets(capture_opts, nread);
1171 /* convert primary message */
1172 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1173 primary_msg = buffer+4;
1174 /* convert secondary message */
1175 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1176 secondary_msg = primary_msg + primary_len + 4;
1177 /* message output */
1178 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1179 /* the capture child will close the sync_pipe, nothing to do for now */
1180 /* (an error message doesn't mean we have to stop capturing) */
1183 capture_input_cfilter_error_message(capture_opts, buffer);
1184 /* the capture child will close the sync_pipe, nothing to do for now */
1187 capture_input_drops(capture_opts, atoi(buffer));
1190 g_assert_not_reached();
1198 /* the child process is going down, wait until it's completely terminated */
1200 sync_pipe_wait_for_child(capture_options *capture_opts)
1205 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1206 g_assert(capture_opts->fork_child != -1);
1209 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1210 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1211 "Child capture process stopped unexpectedly (errno:%u)", errno);
1214 if (wait(&wstatus) != -1) {
1215 if (WIFEXITED(wstatus)) {
1216 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1217 /* the child will inform us about errors through the sync_pipe, which will popup */
1218 /* an error message, so don't popup another one */
1220 /* If there are situations where the child won't send us such an error message, */
1221 /* this should be fixed in the child and not here! */
1222 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1223 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1224 "Child capture process exited: exit status %d",
1225 WEXITSTATUS(wstatus));
1227 } else if (WIFSTOPPED(wstatus)) {
1228 /* It stopped, rather than exiting. "Should not happen." */
1229 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1230 "Child capture process stopped: %s",
1231 sync_pipe_signame(WSTOPSIG(wstatus)));
1232 } else if (WIFSIGNALED(wstatus)) {
1233 /* It died with a signal. */
1234 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1235 "Child capture process died: %s%s",
1236 sync_pipe_signame(WTERMSIG(wstatus)),
1237 WCOREDUMP(wstatus) ? " - core dumped" : "");
1239 /* What? It had to either have exited, or stopped, or died with
1240 a signal; what happened here? */
1241 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1242 "Child capture process died: wait status %#o", wstatus);
1247 /* No more child process. */
1248 capture_opts->fork_child = -1;
1250 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1255 /* convert signal to corresponding name */
1257 sync_pipe_signame(int sig)
1260 static char sigmsg_buf[6+1+3+1];
1269 sigmsg = "Interrupted";
1277 sigmsg = "Illegal instruction";
1281 sigmsg = "Trace trap";
1289 sigmsg = "Arithmetic exception";
1297 sigmsg = "Bus error";
1301 sigmsg = "Segmentation violation";
1304 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1305 Linux is POSIX compliant. These are not POSIX-defined signals ---
1306 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1308 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1309 were omitted from POSIX.1 because their behavior is
1310 implementation dependent and could not be adequately catego-
1311 rized. Conforming implementations may deliver these sig-
1312 nals, but must document the circumstances under which they
1313 are delivered and note any restrictions concerning their
1316 So we only check for SIGSYS on those systems that happen to
1317 implement them (a system can be POSIX-compliant and implement
1318 them, it's just that POSIX doesn't *require* a POSIX-compliant
1319 system to implement them).
1324 sigmsg = "Bad system call";
1329 sigmsg = "Broken pipe";
1333 sigmsg = "Alarm clock";
1337 sigmsg = "Terminated";
1341 /* Returning a static buffer is ok in the context we use it here */
1342 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1343 sigmsg = sigmsg_buf;
1352 /* tell the child through the signal pipe that we want to quit the capture */
1354 signal_pipe_capquit_to_child(capture_options *capture_opts)
1356 const char quit_msg[] = "QUIT";
1360 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1362 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1363 /* simply sending a "QUIT" string */
1364 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1365 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1367 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1368 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1374 /* user wants to stop the capture run */
1376 sync_pipe_stop(capture_options *capture_opts)
1381 gboolean terminate = TRUE;
1384 if (capture_opts->fork_child != -1) {
1386 /* send the SIGUSR1 signal to close the capture child gracefully. */
1387 kill(capture_opts->fork_child, SIGUSR1);
1389 #define STOP_SLEEP_TIME 500 /* ms */
1390 #define STOP_CHECK_TIME 50
1391 /* First, use the special signal pipe to try to close the capture child
1394 signal_pipe_capquit_to_child(capture_opts);
1396 /* Next, wait for the process to exit on its own */
1397 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1398 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1399 childstatus != STILL_ACTIVE) {
1403 Sleep(STOP_CHECK_TIME);
1406 /* Force the issue. */
1408 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1409 "sync_pipe_stop: forcing child to exit");
1410 sync_pipe_kill(capture_opts->fork_child);
1417 /* Wireshark has to exit, force the capture child to close */
1419 sync_pipe_kill(int fork_child)
1421 if (fork_child != -1) {
1423 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1425 /* Remark: This is not the preferred method of closing a process!
1426 * the clean way would be getting the process id of the child process,
1427 * then getting window handle hWnd of that process (using EnumChildWindows),
1428 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1430 * Unfortunately, I don't know how to get the process id from the
1431 * handle. OpenProcess will get an handle (not a window handle)
1432 * from the process ID; it will not get a window handle from the
1433 * process ID. (How could it? A process can have more than one
1434 * window. For that matter, a process might have *no* windows,
1435 * as a process running dumpcap, the normal child process program,
1438 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1439 * running in the same console; that's not necessarily the case for
1440 * us, as we might not be running in a console.
1441 * And this also will require to have the process id.
1443 TerminateProcess((HANDLE) (fork_child), 0);
1448 #endif /* HAVE_LIBPCAP */