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 scount[ARGV_NUMBER_LEN];
247 char sfilesize[ARGV_NUMBER_LEN];
248 char sfile_duration[ARGV_NUMBER_LEN];
249 char sring_num_files[ARGV_NUMBER_LEN];
250 char sautostop_files[ARGV_NUMBER_LEN];
251 char sautostop_filesize[ARGV_NUMBER_LEN];
252 char sautostop_duration[ARGV_NUMBER_LEN];
254 char buffer_size[ARGV_NUMBER_LEN];
255 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
256 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
257 HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
258 HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
259 GString *args = g_string_sized_new(200);
261 SECURITY_ATTRIBUTES sa;
263 PROCESS_INFORMATION pi;
267 int sync_pipe[2]; /* pipe used to send messages from child to parent */
268 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
270 int sync_pipe_read_fd;
275 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
276 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
278 capture_opts->fork_child = -1;
280 argv = init_pipe_args(&argc);
282 /* We don't know where to find dumpcap. */
283 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
287 argv = sync_pipe_add_arg(argv, &argc, "-i");
288 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
290 if (capture_opts->has_snaplen) {
291 argv = sync_pipe_add_arg(argv, &argc, "-s");
292 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
293 argv = sync_pipe_add_arg(argv, &argc, ssnap);
296 if (capture_opts->linktype != -1) {
297 argv = sync_pipe_add_arg(argv, &argc, "-y");
298 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
299 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
301 /* we can't get the type name, just treat it as a number */
302 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
304 argv = sync_pipe_add_arg(argv, &argc, ssnap);
307 if(capture_opts->multi_files_on) {
308 if (capture_opts->has_autostop_filesize) {
309 argv = sync_pipe_add_arg(argv, &argc, "-b");
310 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
311 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
314 if (capture_opts->has_file_duration) {
315 argv = sync_pipe_add_arg(argv, &argc, "-b");
316 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
317 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
320 if (capture_opts->has_ring_num_files) {
321 argv = sync_pipe_add_arg(argv, &argc, "-b");
322 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
323 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
326 if (capture_opts->has_autostop_files) {
327 argv = sync_pipe_add_arg(argv, &argc, "-a");
328 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
329 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
332 if (capture_opts->has_autostop_filesize) {
333 argv = sync_pipe_add_arg(argv, &argc, "-a");
334 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
335 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
339 if (capture_opts->has_autostop_packets) {
340 argv = sync_pipe_add_arg(argv, &argc, "-c");
341 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
342 argv = sync_pipe_add_arg(argv, &argc, scount);
345 if (capture_opts->has_autostop_duration) {
346 argv = sync_pipe_add_arg(argv, &argc, "-a");
347 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
348 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
351 if (!capture_opts->promisc_mode)
352 argv = sync_pipe_add_arg(argv, &argc, "-p");
354 /* dumpcap should be running in capture child mode (hidden feature) */
356 argv = sync_pipe_add_arg(argv, &argc, "-Z");
357 argv = sync_pipe_add_arg(argv, &argc, "1");
361 argv = sync_pipe_add_arg(argv, &argc, "-B");
362 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
363 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
366 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
367 argv = sync_pipe_add_arg(argv, &argc, "-f");
368 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
371 if(capture_opts->save_file) {
372 argv = sync_pipe_add_arg(argv, &argc, "-w");
373 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
377 /* init SECURITY_ATTRIBUTES */
378 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
379 sa.bInheritHandle = TRUE;
380 sa.lpSecurityDescriptor = NULL;
382 /* Create a pipe for the child process */
383 /* (inrease this value if you have trouble while fast capture file switches) */
384 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
385 /* Couldn't create the pipe between parent and child. */
386 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
388 g_free( (gpointer) argv[0]);
389 g_free( (gpointer) argv);
393 /* Create a pipe for the parent process */
394 if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
395 /* Couldn't create the signal pipe between parent and child. */
396 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
398 CloseHandle(sync_pipe_read);
399 CloseHandle(sync_pipe_write);
400 g_free( (gpointer) argv[0]);
401 g_free( (gpointer) argv);
405 /* init STARTUPINFO */
406 memset(&si, 0, sizeof(si));
409 si.dwFlags = STARTF_USESHOWWINDOW;
410 si.wShowWindow = SW_SHOW;
412 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
413 si.wShowWindow = SW_HIDE; /* this hides the console window */
414 si.hStdInput = signal_pipe_read;
415 si.hStdOutput = sync_pipe_write;
416 si.hStdError = sync_pipe_write;
417 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
420 /* convert args array into a single string */
421 /* XXX - could change sync_pipe_add_arg() instead */
422 /* there is a drawback here: the length is internally limited to 1024 bytes */
423 for(i=0; argv[i] != 0; i++) {
424 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
425 quoted_arg = protect_arg(argv[i]);
426 g_string_append(args, quoted_arg);
431 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
432 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
433 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
434 "Couldn't run %s in child process: error %u",
435 args->str, GetLastError());
436 CloseHandle(sync_pipe_read);
437 CloseHandle(sync_pipe_write);
438 g_free( (gpointer) argv[0]);
439 g_free( (gpointer) argv);
442 capture_opts->fork_child = (int) pi.hProcess;
443 g_string_free(args, TRUE);
445 /* associate the operating system filehandle to a C run-time file handle */
446 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
447 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
449 /* associate the operating system filehandle to a C run-time file handle */
450 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
452 /* child owns the read side now, close our handle */
453 CloseHandle(signal_pipe_read);
455 if (pipe(sync_pipe) < 0) {
456 /* Couldn't create the pipe between parent and child. */
457 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
459 g_free( (gpointer) argv[0]);
464 if ((capture_opts->fork_child = fork()) == 0) {
466 * Child process - run dumpcap with the right arguments to make
467 * it just capture with the specified capture parameters
470 dup(sync_pipe[PIPE_WRITE]);
471 eth_close(sync_pipe[PIPE_READ]);
472 execv(argv[0], (gpointer)argv);
473 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
474 argv[0], strerror(errno));
475 sync_pipe_errmsg_to_parent(1, errmsg, "");
477 /* Exit with "_exit()", so that we don't close the connection
478 to the X server (and cause stuff buffered up by our parent but
479 not yet sent to be sent, as that stuff should only be sent by
484 sync_pipe_read_fd = sync_pipe[PIPE_READ];
487 g_free( (gpointer) argv[0]); /* exename */
489 /* Parent process - read messages from the child process over the
491 g_free( (gpointer) argv); /* free up arg array */
493 /* Close the write side of the pipe, so that only the child has it
494 open, and thus it completely closes, and thus returns to us
495 an EOF indication, if the child closes it (either deliberately
496 or by exiting abnormally). */
498 CloseHandle(sync_pipe_write);
500 eth_close(sync_pipe[PIPE_WRITE]);
503 if (capture_opts->fork_child == -1) {
504 /* We couldn't even create the child process. */
505 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
506 "Couldn't create child process: %s", strerror(errno));
507 eth_close(sync_pipe_read_fd);
509 eth_close(capture_opts->signal_pipe_write_fd);
514 /* we might wait for a moment till child is ready, so update screen now */
515 main_window_update();
517 /* We were able to set up to read the capture file;
518 arrange that our callback be called whenever it's possible
519 to read from the sync pipe, so that it's called when
520 the child process wants to tell us something. */
522 /* we have a running capture, now wait for the real capture filename */
523 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
524 &capture_opts->fork_child, sync_pipe_input_cb);
530 * Open dumpcap with the supplied arguments. On success, msg points to
531 * a buffer containing the dumpcap output and returns 0. read_fd and
532 * fork_child point to the pipe's file descriptor and child PID/handle,
533 * respectively. On failure, msg points to the error message returned by
534 * dumpcap, and returns dumpcap's exit value. In either case, msg must be
535 * freed with g_free().
537 /* XXX - This duplicates a lot of code in sync_pipe_start() */
538 #define PIPE_BUF_SIZE 5120
540 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
542 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
543 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
544 GString *args = g_string_sized_new(200);
546 SECURITY_ATTRIBUTES sa;
548 PROCESS_INFORMATION pi;
551 int sync_pipe[2]; /* pipe used to send messages from child to parent */
552 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
557 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
560 /* We can't return anything */
562 g_string_free(args, TRUE);
568 /* init SECURITY_ATTRIBUTES */
569 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
570 sa.bInheritHandle = TRUE;
571 sa.lpSecurityDescriptor = NULL;
573 /* Create a pipe for the child process */
574 /* (inrease this value if you have trouble while fast capture file switches) */
575 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
576 /* Couldn't create the pipe between parent and child. */
577 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
578 g_free( (gpointer) argv[0]);
579 g_free( (gpointer) argv);
580 return CANT_RUN_DUMPCAP;
583 /* init STARTUPINFO */
584 memset(&si, 0, sizeof(si));
587 si.dwFlags = STARTF_USESHOWWINDOW;
588 si.wShowWindow = SW_SHOW;
590 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
591 si.wShowWindow = SW_HIDE; /* this hides the console window */
593 si.hStdOutput = sync_pipe_write;
594 si.hStdError = sync_pipe_write;
595 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
598 /* convert args array into a single string */
599 /* XXX - could change sync_pipe_add_arg() instead */
600 /* there is a drawback here: the length is internally limited to 1024 bytes */
601 for(i=0; argv[i] != 0; i++) {
602 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
603 quoted_arg = protect_arg(argv[i]);
604 g_string_append(args, quoted_arg);
609 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
610 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
611 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
612 args->str, GetLastError());
613 CloseHandle(sync_pipe_read);
614 CloseHandle(sync_pipe_write);
615 g_free( (gpointer) argv[0]);
616 g_free( (gpointer) argv);
617 return CANT_RUN_DUMPCAP;
619 *fork_child = (int) pi.hProcess;
620 g_string_free(args, TRUE);
622 /* associate the operating system filehandle to a C run-time file handle */
623 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
624 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
627 if (pipe(sync_pipe) < 0) {
628 /* Couldn't create the pipe between parent and child. */
629 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
630 g_free( (gpointer) argv[0]);
632 return CANT_RUN_DUMPCAP;
635 if ((*fork_child = fork()) == 0) {
637 * Child process - run dumpcap with the right arguments to make
638 * it just capture with the specified capture parameters
641 dup(sync_pipe[PIPE_WRITE]);
642 eth_close(sync_pipe[PIPE_READ]);
643 execv(argv[0], (gpointer)argv);
644 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
645 argv[0], strerror(errno));
646 return CANT_RUN_DUMPCAP;
649 *read_fd = sync_pipe[PIPE_READ];
652 g_free( (gpointer) argv[0]); /* exename */
654 /* Parent process - read messages from the child process over the
656 g_free( (gpointer) argv); /* free up arg array */
658 /* Close the write side of the pipe, so that only the child has it
659 open, and thus it completely closes, and thus returns to us
660 an EOF indication, if the child closes it (either deliberately
661 or by exiting abnormally). */
663 CloseHandle(sync_pipe_write);
665 eth_close(sync_pipe[PIPE_WRITE]);
668 if (*fork_child == -1) {
669 /* We couldn't even create the child process. */
670 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
672 return CANT_RUN_DUMPCAP;
675 /* we might wait for a moment till child is ready, so update screen now */
676 main_window_update();
682 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
684 sync_pipe_close_command(int *read_fd, gchar **msg) {
686 int fork_child_status;
690 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open: wait till child closed");
693 /* XXX - Should we signal the child somehow? */
694 sync_pipe_kill(*fork_child);
695 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
696 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
697 "(errno:%u)", errno);
698 return CANT_RUN_DUMPCAP;
701 if (wait(&fork_child_status) != -1) {
702 if (WIFEXITED(fork_child_status)) {
703 /* The child exited. */
704 fork_child_status = WEXITSTATUS(fork_child_status);
706 if (WIFSTOPPED(fork_child_status)) {
707 /* It stopped, rather than exiting. "Should not happen." */
708 *msg = g_strdup_printf("Child capture process stopped: %s",
709 sync_pipe_signame(WSTOPSIG(fork_child_status)));
710 } else if (WIFSIGNALED(fork_child_status)) {
711 /* It died with a signal. */
712 *msg = g_strdup_printf("Child capture process died: %s%s",
713 sync_pipe_signame(WTERMSIG(fork_child_status)),
714 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
716 /* What? It had to either have exited, or stopped, or died with
717 a signal; what happened here? */
718 *msg = g_strdup_printf("Child capture process died: wait status %#o",
721 return CANT_RUN_DUMPCAP;
724 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
725 "(errno:%u)", errno);
726 return CANT_RUN_DUMPCAP;
733 * Run dumpcap with the supplied arguments. On success, msg points to
734 * a buffer containing the dumpcap output and returns 0. On failure, msg
735 * points to the error message returned by dumpcap, and returns dumpcap's
736 * exit value. In either case, msg must be freed with g_free().
738 /* XXX - This duplicates a lot of code in sync_pipe_start() */
739 #define PIPE_BUF_SIZE 5120
741 sync_pipe_run_command(const char** argv, gchar **msg) {
742 int sync_pipe_read_fd, fork_child, ret;
743 gchar buf[PIPE_BUF_SIZE+1];
744 GString *msg_buf = NULL;
747 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
752 /* We were able to set up to read dumpcap's output. Do so and
753 return its exit value. */
754 msg_buf = g_string_new("");
755 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
757 g_string_append(msg_buf, buf);
761 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
763 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
767 g_string_free(msg_buf, TRUE);
772 g_string_free(msg_buf, FALSE);
777 * Get an interface list using dumpcap. On success, msg points to
778 * a buffer containing the dumpcap output and returns 0. On failure, msg
779 * points to the error message returned by dumpcap, and returns dumpcap's
780 * exit value. In either case, msg must be freed with g_free().
783 sync_interface_list_open(gchar **msg) {
788 /* We can't return anything */
792 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
794 argv = init_pipe_args(&argc);
797 *msg = g_strdup_printf("We don't know where to find dumpcap.");
798 return CANT_RUN_DUMPCAP;
801 /* Ask for the interface list */
802 argv = sync_pipe_add_arg(argv, &argc, "-D");
803 argv = sync_pipe_add_arg(argv, &argc, "-M");
805 /* dumpcap should be running in capture child mode (hidden feature) */
807 argv = sync_pipe_add_arg(argv, &argc, "-Z");
808 argv = sync_pipe_add_arg(argv, &argc, "1");
811 return sync_pipe_run_command(argv, msg);
815 * Get an linktype list using dumpcap. On success, msg points to
816 * a buffer containing the dumpcap output and returns 0. On failure, msg
817 * points to the error message returned by dumpcap, and returns dumpcap's
818 * exit value. In either case, msg must be freed with g_free().
821 sync_linktype_list_open(gchar *ifname, gchar **msg) {
826 /* We can't return anything */
830 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
832 argv = init_pipe_args(&argc);
835 *msg = g_strdup_printf("We don't know where to find dumpcap.");
836 return CANT_RUN_DUMPCAP;
839 /* Ask for the linktype list */
840 argv = sync_pipe_add_arg(argv, &argc, "-i");
841 argv = sync_pipe_add_arg(argv, &argc, ifname);
842 argv = sync_pipe_add_arg(argv, &argc, "-L");
843 argv = sync_pipe_add_arg(argv, &argc, "-M");
845 /* dumpcap should be running in capture child mode (hidden feature) */
847 argv = sync_pipe_add_arg(argv, &argc, "-Z");
848 argv = sync_pipe_add_arg(argv, &argc, "1");
851 return sync_pipe_run_command(argv, msg);
855 * Start getting interface statistics using dumpcap. On success, read_fd
856 * contains the file descriptor for the pipe's stdout, msg is unchanged,
857 * and zero is returned. On failure, msg will point to an error message
858 * that must be g_free()d and a nonzero error value will be returned.
861 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
866 /* We can't return anything */
870 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
872 argv = init_pipe_args(&argc);
875 *msg = g_strdup_printf("We don't know where to find dumpcap.");
876 return CANT_RUN_DUMPCAP;
879 /* Ask for the linktype list */
880 argv = sync_pipe_add_arg(argv, &argc, "-S");
881 argv = sync_pipe_add_arg(argv, &argc, "-M");
883 /* dumpcap should be running in capture child mode (hidden feature) */
885 argv = sync_pipe_add_arg(argv, &argc, "-Z");
886 argv = sync_pipe_add_arg(argv, &argc, "1");
889 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
892 /* Close down the stats process */
894 sync_interface_stats_close(int *read_fd, int *fork_child
900 return sync_pipe_close_command(read_fd, fork_child, msg);
902 return sync_pipe_close_command(read_fd, msg);
906 /* read a number of bytes from a pipe */
907 /* (blocks until enough bytes read or an error occurs) */
909 pipe_read_bytes(int pipe, char *bytes, int required) {
914 newly = read(pipe, &bytes[offset], required);
917 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
918 "read from pipe %d: EOF (capture closed?)", pipe);
923 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
924 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
935 static gboolean pipe_data_available(int pipe) {
936 #ifdef _WIN32 /* PeekNamedPipe */
937 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
940 if (hPipe == INVALID_HANDLE_VALUE)
943 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
951 struct timeval timeout;
958 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
965 /* Read a line from a pipe, similar to fgets */
967 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
971 while(offset < max - 1) {
973 if (! pipe_data_available(pipe))
975 newly = read(pipe, &bytes[offset], 1);
977 /* EOF - not necessarily an error */
979 } else if (newly < 0) {
981 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
982 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
984 } else if (bytes[offset] == '\n') {
990 bytes[offset] = '\0';
996 /* convert header values (indicator and 4-byte length) */
998 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1000 g_assert(header_len == 4);
1002 /* convert header values */
1003 *indicator = header[0];
1004 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1007 /* read a message from the sending pipe in the standard format
1008 (1-byte message indicator, 3-byte message length (excluding length
1009 and indicator field), and the rest is the message) */
1011 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1017 /* read header (indicator and 3-byte length) */
1018 newly = pipe_read_bytes(pipe, header, 4);
1020 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1021 "read %d failed to read header: %u", pipe, newly);
1025 /* convert header values */
1026 pipe_convert_header(header, 4, indicator, &required);
1028 /* only indicator with no value? */
1030 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1031 "read %d indicator: %c empty value", pipe, *indicator);
1035 /* does the data fit into the given buffer? */
1036 if(required > len) {
1037 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1038 "read %d length error, required %d > len %d, indicator: %u",
1039 pipe, required, len, *indicator);
1041 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1042 memcpy(msg, header, sizeof(header));
1043 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1044 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1049 /* read the actual block data */
1050 newly = pipe_read_bytes(pipe, msg, required);
1051 if(newly != required) {
1052 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1056 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1057 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1063 /* There's stuff to read from the sync pipe, meaning the child has sent
1064 us a message, or the sync pipe has closed, meaning the child has
1065 closed it (perhaps because it exited). */
1067 sync_pipe_input_cb(gint source, gpointer user_data)
1069 capture_options *capture_opts = (capture_options *)user_data;
1070 char buffer[SP_MAX_MSG_LEN+1];
1076 char * secondary_msg;
1079 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1082 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1083 "sync_pipe_input_cb: child has closed sync_pipe");
1085 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1086 "sync_pipe_input_cb: error reading from sync pipe");
1088 /* The child has closed the sync pipe, meaning it's not going to be
1089 capturing any more packets. Pick up its exit status, and
1090 complain if it did anything other than exit with status 0.
1092 We don't have to worry about killing the child, if the sync pipe
1093 returned an error. Usually this error is caused as the child killed itself
1094 while going down. Even in the rare cases that this isn't the case,
1095 the child will get an error when writing to the broken pipe the next time,
1096 cleaning itself up then. */
1097 sync_pipe_wait_for_child(capture_opts);
1100 eth_close(capture_opts->signal_pipe_write_fd);
1102 capture_input_closed(capture_opts);
1106 /* we got a valid message block from the child, process it */
1109 if(!capture_input_new_file(capture_opts, buffer)) {
1110 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1112 /* We weren't able to open the new capture file; user has been
1113 alerted. Close the sync pipe. */
1116 /* the child has send us a filename which we couldn't open.
1117 this probably means, the child is creating files faster than we can handle it.
1118 this should only be the case for very fast file switches
1119 we can't do much more than telling the child to stop
1120 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1121 sync_pipe_stop(capture_opts);
1124 case SP_PACKET_COUNT:
1125 nread = atoi(buffer);
1126 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1127 capture_input_new_packets(capture_opts, nread);
1130 /* convert primary message */
1131 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1132 primary_msg = buffer+4;
1133 /* convert secondary message */
1134 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1135 secondary_msg = primary_msg + primary_len + 4;
1136 /* message output */
1137 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1138 /* the capture child will close the sync_pipe, nothing to do for now */
1139 /* (an error message doesn't mean we have to stop capturing) */
1142 capture_input_cfilter_error_message(capture_opts, buffer);
1143 /* the capture child will close the sync_pipe, nothing to do for now */
1146 capture_input_drops(capture_opts, atoi(buffer));
1149 g_assert_not_reached();
1157 /* the child process is going down, wait until it's completely terminated */
1159 sync_pipe_wait_for_child(capture_options *capture_opts)
1164 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1165 g_assert(capture_opts->fork_child != -1);
1168 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1169 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1170 "Child capture process stopped unexpectedly (errno:%u)", errno);
1173 if (wait(&wstatus) != -1) {
1174 if (WIFEXITED(wstatus)) {
1175 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1176 /* the child will inform us about errors through the sync_pipe, which will popup */
1177 /* an error message, so don't popup another one */
1179 /* If there are situations where the child won't send us such an error message, */
1180 /* this should be fixed in the child and not here! */
1181 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1182 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1183 "Child capture process exited: exit status %d",
1184 WEXITSTATUS(wstatus));
1186 } else if (WIFSTOPPED(wstatus)) {
1187 /* It stopped, rather than exiting. "Should not happen." */
1188 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1189 "Child capture process stopped: %s",
1190 sync_pipe_signame(WSTOPSIG(wstatus)));
1191 } else if (WIFSIGNALED(wstatus)) {
1192 /* It died with a signal. */
1193 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1194 "Child capture process died: %s%s",
1195 sync_pipe_signame(WTERMSIG(wstatus)),
1196 WCOREDUMP(wstatus) ? " - core dumped" : "");
1198 /* What? It had to either have exited, or stopped, or died with
1199 a signal; what happened here? */
1200 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1201 "Child capture process died: wait status %#o", wstatus);
1206 /* No more child process. */
1207 capture_opts->fork_child = -1;
1209 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1214 /* convert signal to corresponding name */
1216 sync_pipe_signame(int sig)
1219 static char sigmsg_buf[6+1+3+1];
1228 sigmsg = "Interrupted";
1236 sigmsg = "Illegal instruction";
1240 sigmsg = "Trace trap";
1248 sigmsg = "Arithmetic exception";
1256 sigmsg = "Bus error";
1260 sigmsg = "Segmentation violation";
1263 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1264 Linux is POSIX compliant. These are not POSIX-defined signals ---
1265 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1267 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1268 were omitted from POSIX.1 because their behavior is
1269 implementation dependent and could not be adequately catego-
1270 rized. Conforming implementations may deliver these sig-
1271 nals, but must document the circumstances under which they
1272 are delivered and note any restrictions concerning their
1275 So we only check for SIGSYS on those systems that happen to
1276 implement them (a system can be POSIX-compliant and implement
1277 them, it's just that POSIX doesn't *require* a POSIX-compliant
1278 system to implement them).
1283 sigmsg = "Bad system call";
1288 sigmsg = "Broken pipe";
1292 sigmsg = "Alarm clock";
1296 sigmsg = "Terminated";
1300 /* Returning a static buffer is ok in the context we use it here */
1301 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1302 sigmsg = sigmsg_buf;
1311 /* tell the child through the signal pipe that we want to quit the capture */
1313 signal_pipe_capquit_to_child(capture_options *capture_opts)
1315 const char quit_msg[] = "QUIT";
1319 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1321 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1322 /* simply sending a "QUIT" string */
1323 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1324 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1326 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1327 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1333 /* user wants to stop the capture run */
1335 sync_pipe_stop(capture_options *capture_opts)
1337 if (capture_opts->fork_child != -1) {
1339 /* send the SIGUSR1 signal to close the capture child gracefully. */
1340 kill(capture_opts->fork_child, SIGUSR1);
1342 /* Win32 doesn't have the kill() system call, use the special signal pipe
1343 instead to close the capture child gracefully. */
1344 signal_pipe_capquit_to_child(capture_opts);
1350 /* Wireshark has to exit, force the capture child to close */
1352 sync_pipe_kill(int fork_child)
1354 if (fork_child != -1) {
1356 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1358 /* Remark: This is not the preferred method of closing a process!
1359 * the clean way would be getting the process id of the child process,
1360 * then getting window handle hWnd of that process (using EnumChildWindows),
1361 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1363 * Unfortunately, I don't know how to get the process id from the
1364 * handle. OpenProcess will get an handle (not a window handle)
1365 * from the process ID; it will not get a window handle from the
1366 * process ID. (How could it? A process can have more than one
1367 * window. For that matter, a process might have *no* windows,
1368 * as a process running dumpcap, the normal child process program,
1371 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1372 * running in the same console; that's not necessarily the case for
1373 * us, as we might not be running in a console.
1374 * And this also will require to have the process id.
1376 TerminateProcess((HANDLE) (fork_child), 0);
1381 #endif /* HAVE_LIBPCAP */