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
510 dup2(sync_pipe[PIPE_WRITE], 2);
511 eth_close(sync_pipe[PIPE_READ]);
512 execv(argv[0], (gpointer)argv);
513 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
514 argv[0], strerror(errno));
515 sync_pipe_errmsg_to_parent(2, errmsg, "");
517 /* Exit with "_exit()", so that we don't close the connection
518 to the X server (and cause stuff buffered up by our parent but
519 not yet sent to be sent, as that stuff should only be sent by
520 our parent). We've sent an error message to the parent, so
521 we exit with an exit status of 1 (any exit status other than
522 0 or 1 will cause an additional message to report that exit
523 status, over and above the error message we sent to the parent). */
527 sync_pipe_read_fd = sync_pipe[PIPE_READ];
530 g_free( (gpointer) argv[0]); /* exename */
532 /* Parent process - read messages from the child process over the
534 g_free( (gpointer) argv); /* free up arg array */
536 /* Close the write side of the pipe, so that only the child has it
537 open, and thus it completely closes, and thus returns to us
538 an EOF indication, if the child closes it (either deliberately
539 or by exiting abnormally). */
541 CloseHandle(sync_pipe_write);
543 eth_close(sync_pipe[PIPE_WRITE]);
546 if (capture_opts->fork_child == -1) {
547 /* We couldn't even create the child process. */
548 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
549 "Couldn't create child process: %s", strerror(errno));
550 eth_close(sync_pipe_read_fd);
552 eth_close(capture_opts->signal_pipe_write_fd);
557 /* we might wait for a moment till child is ready, so update screen now */
558 main_window_update();
560 /* We were able to set up to read the capture file;
561 arrange that our callback be called whenever it's possible
562 to read from the sync pipe, so that it's called when
563 the child process wants to tell us something. */
565 /* we have a running capture, now wait for the real capture filename */
566 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
567 &capture_opts->fork_child, sync_pipe_input_cb);
573 * Open dumpcap with the supplied arguments. On success, msg points to
574 * a buffer containing the dumpcap output and returns 0. read_fd and
575 * fork_child point to the pipe's file descriptor and child PID/handle,
576 * respectively. On failure, msg points to the error message returned by
577 * dumpcap, and returns dumpcap's exit value. In either case, msg must be
578 * freed with g_free().
580 /* XXX - This duplicates a lot of code in sync_pipe_start() */
581 #define PIPE_BUF_SIZE 5120
583 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
585 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
586 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
587 GString *args = g_string_sized_new(200);
589 SECURITY_ATTRIBUTES sa;
591 PROCESS_INFORMATION pi;
595 int sync_pipe[2]; /* pipe used to send messages from child to parent */
596 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
601 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
604 /* We can't return anything */
606 g_string_free(args, TRUE);
612 /* init SECURITY_ATTRIBUTES */
613 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
614 sa.bInheritHandle = TRUE;
615 sa.lpSecurityDescriptor = NULL;
617 /* Create a pipe for the child process */
618 /* (inrease this value if you have trouble while fast capture file switches) */
619 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
620 /* Couldn't create the pipe between parent and child. */
621 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
622 g_free( (gpointer) argv[0]);
623 g_free( (gpointer) argv);
624 return CANT_RUN_DUMPCAP;
627 /* init STARTUPINFO */
628 memset(&si, 0, sizeof(si));
631 si.dwFlags = STARTF_USESHOWWINDOW;
632 si.wShowWindow = SW_SHOW;
634 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
635 si.wShowWindow = SW_HIDE; /* this hides the console window */
637 si.hStdOutput = sync_pipe_write;
638 si.hStdError = sync_pipe_write;
639 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
642 /* convert args array into a single string */
643 /* XXX - could change sync_pipe_add_arg() instead */
644 /* there is a drawback here: the length is internally limited to 1024 bytes */
645 for(i=0; argv[i] != 0; i++) {
646 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
647 quoted_arg = protect_arg(argv[i]);
648 g_string_append(args, quoted_arg);
653 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
654 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
655 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
656 args->str, GetLastError());
657 CloseHandle(sync_pipe_read);
658 CloseHandle(sync_pipe_write);
659 g_free( (gpointer) argv[0]);
660 g_free( (gpointer) argv);
661 return CANT_RUN_DUMPCAP;
663 *fork_child = (int) pi.hProcess;
664 g_string_free(args, TRUE);
666 /* associate the operating system filehandle to a C run-time file handle */
667 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
668 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
671 if (pipe(sync_pipe) < 0) {
672 /* Couldn't create the pipe between parent and child. */
673 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
674 g_free( (gpointer) argv[0]);
676 return CANT_RUN_DUMPCAP;
679 if ((*fork_child = fork()) == 0) {
681 * Child process - run dumpcap with the right arguments to make
682 * it just capture with the specified capture parameters
684 dup2(sync_pipe[PIPE_WRITE], 1);
685 eth_close(sync_pipe[PIPE_READ]);
686 execv(argv[0], (gpointer)argv);
687 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
688 argv[0], strerror(errno));
689 sync_pipe_errmsg_to_parent(1, errmsg, "");
691 /* Exit with "_exit()", so that we don't close the connection
692 to the X server (and cause stuff buffered up by our parent but
693 not yet sent to be sent, as that stuff should only be sent by
694 our parent). We've sent an error message to the parent, so
695 we exit with an exit status of 1 (any exit status other than
696 0 or 1 will cause an additional message to report that exit
697 status, over and above the error message we sent to the parent). */
701 *read_fd = sync_pipe[PIPE_READ];
704 g_free( (gpointer) argv[0]); /* exename */
706 /* Parent process - read messages from the child process over the
708 g_free( (gpointer) argv); /* free up arg array */
710 /* Close the write side of the pipe, so that only the child has it
711 open, and thus it completely closes, and thus returns to us
712 an EOF indication, if the child closes it (either deliberately
713 or by exiting abnormally). */
715 CloseHandle(sync_pipe_write);
717 eth_close(sync_pipe[PIPE_WRITE]);
720 if (*fork_child == -1) {
721 /* We couldn't even create the child process. */
722 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
724 return CANT_RUN_DUMPCAP;
727 /* we might wait for a moment till child is ready, so update screen now */
728 main_window_update();
734 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
736 sync_pipe_close_command(int *read_fd, gchar **msg) {
738 int fork_child_status;
742 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
745 /* XXX - Should we signal the child somehow? */
746 sync_pipe_kill(*fork_child);
747 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
748 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
749 "(errno:%u)", errno);
750 return CANT_RUN_DUMPCAP;
753 if (wait(&fork_child_status) != -1) {
754 if (WIFEXITED(fork_child_status)) {
755 /* The child exited. */
756 fork_child_status = WEXITSTATUS(fork_child_status);
758 if (WIFSTOPPED(fork_child_status)) {
759 /* It stopped, rather than exiting. "Should not happen." */
760 *msg = g_strdup_printf("Child capture process stopped: %s",
761 sync_pipe_signame(WSTOPSIG(fork_child_status)));
762 } else if (WIFSIGNALED(fork_child_status)) {
763 /* It died with a signal. */
764 *msg = g_strdup_printf("Child capture process died: %s%s",
765 sync_pipe_signame(WTERMSIG(fork_child_status)),
766 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
768 /* What? It had to either have exited, or stopped, or died with
769 a signal; what happened here? */
770 *msg = g_strdup_printf("Child capture process died: wait status %#o",
773 return CANT_RUN_DUMPCAP;
776 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
777 "(errno:%u)", errno);
778 return CANT_RUN_DUMPCAP;
785 * Run dumpcap with the supplied arguments. On success, msg points to
786 * a buffer containing the dumpcap output and returns 0. On failure, msg
787 * points to the error message returned by dumpcap, and returns dumpcap's
788 * exit value. In either case, msg must be freed with g_free().
790 /* XXX - This duplicates a lot of code in sync_pipe_start() */
791 #define PIPE_BUF_SIZE 5120
793 sync_pipe_run_command(const char** argv, gchar **msg) {
794 int sync_pipe_read_fd, fork_child, ret;
795 gchar buf[PIPE_BUF_SIZE+1];
796 GString *msg_buf = NULL;
799 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
804 /* We were able to set up to read dumpcap's output. Do so and
805 return its exit value. */
806 msg_buf = g_string_new("");
807 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
809 g_string_append(msg_buf, buf);
813 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
815 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
819 g_string_free(msg_buf, TRUE);
824 g_string_free(msg_buf, FALSE);
829 * Get an interface list using dumpcap. On success, msg points to
830 * a buffer containing the dumpcap output and returns 0. On failure, msg
831 * points to the error message returned by dumpcap, and returns dumpcap's
832 * exit value. In either case, msg must be freed with g_free().
835 sync_interface_list_open(gchar **msg) {
840 /* We can't return anything */
844 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
846 argv = init_pipe_args(&argc);
849 *msg = g_strdup_printf("We don't know where to find dumpcap.");
850 return CANT_RUN_DUMPCAP;
853 /* Ask for the interface list */
854 argv = sync_pipe_add_arg(argv, &argc, "-D");
855 argv = sync_pipe_add_arg(argv, &argc, "-M");
857 /* dumpcap should be running in capture child mode (hidden feature) */
859 argv = sync_pipe_add_arg(argv, &argc, "-Z");
860 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
863 return sync_pipe_run_command(argv, msg);
867 * Get an linktype list using dumpcap. On success, msg points to
868 * a buffer containing the dumpcap output and returns 0. On failure, msg
869 * points to the error message returned by dumpcap, and returns dumpcap's
870 * exit value. In either case, msg must be freed with g_free().
873 sync_linktype_list_open(gchar *ifname, gchar **msg) {
878 /* We can't return anything */
882 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
884 argv = init_pipe_args(&argc);
887 *msg = g_strdup_printf("We don't know where to find dumpcap.");
888 return CANT_RUN_DUMPCAP;
891 /* Ask for the linktype list */
892 argv = sync_pipe_add_arg(argv, &argc, "-i");
893 argv = sync_pipe_add_arg(argv, &argc, ifname);
894 argv = sync_pipe_add_arg(argv, &argc, "-L");
895 argv = sync_pipe_add_arg(argv, &argc, "-M");
897 /* dumpcap should be running in capture child mode (hidden feature) */
899 argv = sync_pipe_add_arg(argv, &argc, "-Z");
900 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
903 return sync_pipe_run_command(argv, msg);
907 * Start getting interface statistics using dumpcap. On success, read_fd
908 * contains the file descriptor for the pipe's stdout, msg is unchanged,
909 * and zero is returned. On failure, msg will point to an error message
910 * that must be g_free()d and a nonzero error value will be returned.
913 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
918 /* We can't return anything */
922 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
924 argv = init_pipe_args(&argc);
927 *msg = g_strdup_printf("We don't know where to find dumpcap.");
928 return CANT_RUN_DUMPCAP;
931 /* Ask for the linktype list */
932 argv = sync_pipe_add_arg(argv, &argc, "-S");
933 argv = sync_pipe_add_arg(argv, &argc, "-M");
935 /* dumpcap should be running in capture child mode (hidden feature) */
937 argv = sync_pipe_add_arg(argv, &argc, "-Z");
938 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
941 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
944 /* Close down the stats process */
946 sync_interface_stats_close(int *read_fd, int *fork_child
952 return sync_pipe_close_command(read_fd, fork_child, msg);
954 return sync_pipe_close_command(read_fd, msg);
958 /* read a number of bytes from a pipe */
959 /* (blocks until enough bytes read or an error occurs) */
961 pipe_read_bytes(int pipe, char *bytes, int required) {
966 newly = read(pipe, &bytes[offset], required);
969 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
970 "read from pipe %d: EOF (capture closed?)", pipe);
975 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
976 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
987 static gboolean pipe_data_available(int pipe) {
988 #ifdef _WIN32 /* PeekNamedPipe */
989 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
992 if (hPipe == INVALID_HANDLE_VALUE)
995 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1003 struct timeval timeout;
1006 FD_SET(pipe, &rfds);
1008 timeout.tv_usec = 0;
1010 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
1017 /* Read a line from a pipe, similar to fgets */
1019 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
1023 while(offset < max - 1) {
1025 if (! pipe_data_available(pipe))
1027 newly = read(pipe, &bytes[offset], 1);
1029 /* EOF - not necessarily an error */
1031 } else if (newly < 0) {
1033 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1034 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1036 } else if (bytes[offset] == '\n') {
1042 bytes[offset] = '\0';
1048 /* convert header values (indicator and 4-byte length) */
1050 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1052 g_assert(header_len == 4);
1054 /* convert header values */
1055 *indicator = header[0];
1056 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1059 /* read a message from the sending pipe in the standard format
1060 (1-byte message indicator, 3-byte message length (excluding length
1061 and indicator field), and the rest is the message) */
1063 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1069 /* read header (indicator and 3-byte length) */
1070 newly = pipe_read_bytes(pipe, header, 4);
1072 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1073 "read %d failed to read header: %u", pipe, newly);
1077 /* convert header values */
1078 pipe_convert_header(header, 4, indicator, &required);
1080 /* only indicator with no value? */
1082 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1083 "read %d indicator: %c empty value", pipe, *indicator);
1087 /* does the data fit into the given buffer? */
1088 if(required > len) {
1089 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1090 "read %d length error, required %d > len %d, indicator: %u",
1091 pipe, required, len, *indicator);
1093 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1094 memcpy(msg, header, sizeof(header));
1095 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1096 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1101 /* read the actual block data */
1102 newly = pipe_read_bytes(pipe, msg, required);
1103 if(newly != required) {
1104 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1108 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1109 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1115 /* There's stuff to read from the sync pipe, meaning the child has sent
1116 us a message, or the sync pipe has closed, meaning the child has
1117 closed it (perhaps because it exited). */
1119 sync_pipe_input_cb(gint source, gpointer user_data)
1121 capture_options *capture_opts = (capture_options *)user_data;
1122 char buffer[SP_MAX_MSG_LEN+1];
1128 char * secondary_msg;
1131 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1134 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1135 "sync_pipe_input_cb: child has closed sync_pipe");
1137 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1138 "sync_pipe_input_cb: error reading from sync pipe");
1140 /* The child has closed the sync pipe, meaning it's not going to be
1141 capturing any more packets. Pick up its exit status, and
1142 complain if it did anything other than exit with status 0.
1144 We don't have to worry about killing the child, if the sync pipe
1145 returned an error. Usually this error is caused as the child killed itself
1146 while going down. Even in the rare cases that this isn't the case,
1147 the child will get an error when writing to the broken pipe the next time,
1148 cleaning itself up then. */
1149 sync_pipe_wait_for_child(capture_opts);
1152 eth_close(capture_opts->signal_pipe_write_fd);
1154 capture_input_closed(capture_opts);
1158 /* we got a valid message block from the child, process it */
1161 if(!capture_input_new_file(capture_opts, buffer)) {
1162 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1164 /* We weren't able to open the new capture file; user has been
1165 alerted. Close the sync pipe. */
1168 /* the child has send us a filename which we couldn't open.
1169 this probably means, the child is creating files faster than we can handle it.
1170 this should only be the case for very fast file switches
1171 we can't do much more than telling the child to stop
1172 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1173 sync_pipe_stop(capture_opts);
1176 case SP_PACKET_COUNT:
1177 nread = atoi(buffer);
1178 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1179 capture_input_new_packets(capture_opts, nread);
1182 /* convert primary message */
1183 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1184 primary_msg = buffer+4;
1185 /* convert secondary message */
1186 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1187 secondary_msg = primary_msg + primary_len + 4;
1188 /* message output */
1189 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1190 /* the capture child will close the sync_pipe, nothing to do for now */
1191 /* (an error message doesn't mean we have to stop capturing) */
1194 capture_input_cfilter_error_message(capture_opts, buffer);
1195 /* the capture child will close the sync_pipe, nothing to do for now */
1198 capture_input_drops(capture_opts, atoi(buffer));
1201 g_assert_not_reached();
1209 /* the child process is going down, wait until it's completely terminated */
1211 sync_pipe_wait_for_child(capture_options *capture_opts)
1216 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1217 g_assert(capture_opts->fork_child != -1);
1220 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1221 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1222 "Child capture process stopped unexpectedly (errno:%u)", errno);
1225 if (wait(&wstatus) != -1) {
1226 if (WIFEXITED(wstatus)) {
1227 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1228 /* the child will inform us about errors through the sync_pipe, which will popup */
1229 /* an error message, so don't popup another one */
1231 /* If there are situations where the child won't send us such an error message, */
1232 /* this should be fixed in the child and not here! */
1233 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1234 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1235 "Child capture process exited: exit status %d",
1236 WEXITSTATUS(wstatus));
1238 } else if (WIFSTOPPED(wstatus)) {
1239 /* It stopped, rather than exiting. "Should not happen." */
1240 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1241 "Child capture process stopped: %s",
1242 sync_pipe_signame(WSTOPSIG(wstatus)));
1243 } else if (WIFSIGNALED(wstatus)) {
1244 /* It died with a signal. */
1245 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1246 "Child capture process died: %s%s",
1247 sync_pipe_signame(WTERMSIG(wstatus)),
1248 WCOREDUMP(wstatus) ? " - core dumped" : "");
1250 /* What? It had to either have exited, or stopped, or died with
1251 a signal; what happened here? */
1252 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1253 "Child capture process died: wait status %#o", wstatus);
1258 /* No more child process. */
1259 capture_opts->fork_child = -1;
1261 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1266 /* convert signal to corresponding name */
1268 sync_pipe_signame(int sig)
1271 static char sigmsg_buf[6+1+3+1];
1280 sigmsg = "Interrupted";
1288 sigmsg = "Illegal instruction";
1292 sigmsg = "Trace trap";
1300 sigmsg = "Arithmetic exception";
1308 sigmsg = "Bus error";
1312 sigmsg = "Segmentation violation";
1315 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1316 Linux is POSIX compliant. These are not POSIX-defined signals ---
1317 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1319 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1320 were omitted from POSIX.1 because their behavior is
1321 implementation dependent and could not be adequately catego-
1322 rized. Conforming implementations may deliver these sig-
1323 nals, but must document the circumstances under which they
1324 are delivered and note any restrictions concerning their
1327 So we only check for SIGSYS on those systems that happen to
1328 implement them (a system can be POSIX-compliant and implement
1329 them, it's just that POSIX doesn't *require* a POSIX-compliant
1330 system to implement them).
1335 sigmsg = "Bad system call";
1340 sigmsg = "Broken pipe";
1344 sigmsg = "Alarm clock";
1348 sigmsg = "Terminated";
1352 /* Returning a static buffer is ok in the context we use it here */
1353 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1354 sigmsg = sigmsg_buf;
1363 /* tell the child through the signal pipe that we want to quit the capture */
1365 signal_pipe_capquit_to_child(capture_options *capture_opts)
1367 const char quit_msg[] = "QUIT";
1371 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1373 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1374 /* simply sending a "QUIT" string */
1375 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1376 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1378 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1379 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1385 /* user wants to stop the capture run */
1387 sync_pipe_stop(capture_options *capture_opts)
1392 gboolean terminate = TRUE;
1395 if (capture_opts->fork_child != -1) {
1397 /* send the SIGUSR1 signal to close the capture child gracefully. */
1398 kill(capture_opts->fork_child, SIGUSR1);
1400 #define STOP_SLEEP_TIME 500 /* ms */
1401 #define STOP_CHECK_TIME 50
1402 /* First, use the special signal pipe to try to close the capture child
1405 signal_pipe_capquit_to_child(capture_opts);
1407 /* Next, wait for the process to exit on its own */
1408 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1409 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1410 childstatus != STILL_ACTIVE) {
1414 Sleep(STOP_CHECK_TIME);
1417 /* Force the issue. */
1419 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1420 "sync_pipe_stop: forcing child to exit");
1421 sync_pipe_kill(capture_opts->fork_child);
1428 /* Wireshark has to exit, force the capture child to close */
1430 sync_pipe_kill(int fork_child)
1432 if (fork_child != -1) {
1434 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1436 /* Remark: This is not the preferred method of closing a process!
1437 * the clean way would be getting the process id of the child process,
1438 * then getting window handle hWnd of that process (using EnumChildWindows),
1439 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1441 * Unfortunately, I don't know how to get the process id from the
1442 * handle. OpenProcess will get an handle (not a window handle)
1443 * from the process ID; it will not get a window handle from the
1444 * process ID. (How could it? A process can have more than one
1445 * window. For that matter, a process might have *no* windows,
1446 * as a process running dumpcap, the normal child process program,
1449 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1450 * running in the same console; that's not necessarily the case for
1451 * us, as we might not be running in a console.
1452 * And this also will require to have the process id.
1454 TerminateProcess((HANDLE) (fork_child), 0);
1459 #endif /* HAVE_LIBPCAP */