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; /* named pipe used to send messages from parent to child (currently only stop) */
258 GString *args = g_string_sized_new(200);
260 SECURITY_ATTRIBUTES sa;
262 PROCESS_INFORMATION pi;
264 char control_id[ARGV_NUMBER_LEN];
265 gchar *signal_pipe_name;
268 int sync_pipe[2]; /* pipe used to send messages from child to parent */
269 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
271 int sync_pipe_read_fd;
276 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
277 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
279 capture_opts->fork_child = -1;
281 argv = init_pipe_args(&argc);
283 /* We don't know where to find dumpcap. */
284 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
288 argv = sync_pipe_add_arg(argv, &argc, "-i");
289 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
291 if (capture_opts->has_snaplen) {
292 argv = sync_pipe_add_arg(argv, &argc, "-s");
293 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
294 argv = sync_pipe_add_arg(argv, &argc, ssnap);
297 if (capture_opts->linktype != -1) {
298 argv = sync_pipe_add_arg(argv, &argc, "-y");
299 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
300 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
302 /* we can't get the type name, just treat it as a number */
303 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
305 argv = sync_pipe_add_arg(argv, &argc, ssnap);
308 if(capture_opts->multi_files_on) {
309 if (capture_opts->has_autostop_filesize) {
310 argv = sync_pipe_add_arg(argv, &argc, "-b");
311 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
312 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
315 if (capture_opts->has_file_duration) {
316 argv = sync_pipe_add_arg(argv, &argc, "-b");
317 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
318 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
321 if (capture_opts->has_ring_num_files) {
322 argv = sync_pipe_add_arg(argv, &argc, "-b");
323 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
324 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
327 if (capture_opts->has_autostop_files) {
328 argv = sync_pipe_add_arg(argv, &argc, "-a");
329 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
330 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
333 if (capture_opts->has_autostop_filesize) {
334 argv = sync_pipe_add_arg(argv, &argc, "-a");
335 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
336 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
340 if (capture_opts->has_autostop_packets) {
341 argv = sync_pipe_add_arg(argv, &argc, "-c");
342 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
343 argv = sync_pipe_add_arg(argv, &argc, scount);
346 if (capture_opts->has_autostop_duration) {
347 argv = sync_pipe_add_arg(argv, &argc, "-a");
348 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
349 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
352 if (!capture_opts->promisc_mode)
353 argv = sync_pipe_add_arg(argv, &argc, "-p");
355 /* dumpcap should be running in capture child mode (hidden feature) */
357 argv = sync_pipe_add_arg(argv, &argc, "-Z");
359 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
360 argv = sync_pipe_add_arg(argv, &argc, control_id);
362 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
367 argv = sync_pipe_add_arg(argv, &argc, "-B");
368 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
369 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
372 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
373 argv = sync_pipe_add_arg(argv, &argc, "-f");
374 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
377 if(capture_opts->save_file) {
378 argv = sync_pipe_add_arg(argv, &argc, "-w");
379 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
383 /* init SECURITY_ATTRIBUTES */
384 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
385 sa.bInheritHandle = TRUE;
386 sa.lpSecurityDescriptor = NULL;
388 /* Create a pipe for the child process */
389 /* (increase this value if you have trouble while fast capture file switches) */
390 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
391 /* Couldn't create the pipe between parent and child. */
392 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
394 g_free( (gpointer) argv[0]);
395 g_free( (gpointer) argv);
399 /* Create the signal pipe */
400 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
401 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
402 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
403 g_free(signal_pipe_name);
405 if (signal_pipe == INVALID_HANDLE_VALUE) {
406 /* Couldn't create the signal pipe between parent and child. */
407 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
409 g_free( (gpointer) argv[0]);
410 g_free( (gpointer) argv);
414 /* init STARTUPINFO */
415 memset(&si, 0, sizeof(si));
418 si.dwFlags = STARTF_USESHOWWINDOW;
419 si.wShowWindow = SW_SHOW;
421 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
422 si.wShowWindow = SW_HIDE; /* this hides the console window */
423 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
424 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
425 si.hStdError = sync_pipe_write;
426 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
429 /* convert args array into a single string */
430 /* XXX - could change sync_pipe_add_arg() instead */
431 /* there is a drawback here: the length is internally limited to 1024 bytes */
432 for(i=0; argv[i] != 0; i++) {
433 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
434 quoted_arg = protect_arg(argv[i]);
435 g_string_append(args, quoted_arg);
440 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
441 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
442 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
443 "Couldn't run %s in child process: error %u",
444 args->str, GetLastError());
445 CloseHandle(sync_pipe_read);
446 CloseHandle(sync_pipe_write);
447 g_free( (gpointer) argv[0]);
448 g_free( (gpointer) argv);
451 capture_opts->fork_child = (int) pi.hProcess;
452 g_string_free(args, TRUE);
454 /* associate the operating system filehandle to a C run-time file handle */
455 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
456 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
458 /* associate the operating system filehandle to a C run-time file handle */
459 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
462 if (pipe(sync_pipe) < 0) {
463 /* Couldn't create the pipe between parent and child. */
464 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
466 g_free( (gpointer) argv[0]);
471 if ((capture_opts->fork_child = fork()) == 0) {
473 * Child process - run dumpcap with the right arguments to make
474 * it just capture with the specified capture parameters
477 dup(sync_pipe[PIPE_WRITE]);
478 eth_close(sync_pipe[PIPE_READ]);
479 execv(argv[0], (gpointer)argv);
480 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
481 argv[0], strerror(errno));
482 sync_pipe_errmsg_to_parent(1, errmsg, "");
484 /* Exit with "_exit()", so that we don't close the connection
485 to the X server (and cause stuff buffered up by our parent but
486 not yet sent to be sent, as that stuff should only be sent by
491 sync_pipe_read_fd = sync_pipe[PIPE_READ];
494 g_free( (gpointer) argv[0]); /* exename */
496 /* Parent process - read messages from the child process over the
498 g_free( (gpointer) argv); /* free up arg array */
500 /* Close the write side of the pipe, so that only the child has it
501 open, and thus it completely closes, and thus returns to us
502 an EOF indication, if the child closes it (either deliberately
503 or by exiting abnormally). */
505 CloseHandle(sync_pipe_write);
507 eth_close(sync_pipe[PIPE_WRITE]);
510 if (capture_opts->fork_child == -1) {
511 /* We couldn't even create the child process. */
512 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
513 "Couldn't create child process: %s", strerror(errno));
514 eth_close(sync_pipe_read_fd);
516 eth_close(capture_opts->signal_pipe_write_fd);
521 /* we might wait for a moment till child is ready, so update screen now */
522 main_window_update();
524 /* We were able to set up to read the capture file;
525 arrange that our callback be called whenever it's possible
526 to read from the sync pipe, so that it's called when
527 the child process wants to tell us something. */
529 /* we have a running capture, now wait for the real capture filename */
530 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
531 &capture_opts->fork_child, sync_pipe_input_cb);
537 * Open dumpcap with the supplied arguments. On success, msg points to
538 * a buffer containing the dumpcap output and returns 0. read_fd and
539 * fork_child point to the pipe's file descriptor and child PID/handle,
540 * respectively. On failure, msg points to the error message returned by
541 * dumpcap, and returns dumpcap's exit value. In either case, msg must be
542 * freed with g_free().
544 /* XXX - This duplicates a lot of code in sync_pipe_start() */
545 #define PIPE_BUF_SIZE 5120
547 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
549 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
550 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
551 GString *args = g_string_sized_new(200);
553 SECURITY_ATTRIBUTES sa;
555 PROCESS_INFORMATION pi;
558 int sync_pipe[2]; /* pipe used to send messages from child to parent */
559 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
564 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
567 /* We can't return anything */
569 g_string_free(args, TRUE);
575 /* init SECURITY_ATTRIBUTES */
576 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
577 sa.bInheritHandle = TRUE;
578 sa.lpSecurityDescriptor = NULL;
580 /* Create a pipe for the child process */
581 /* (inrease this value if you have trouble while fast capture file switches) */
582 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
583 /* Couldn't create the pipe between parent and child. */
584 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
585 g_free( (gpointer) argv[0]);
586 g_free( (gpointer) argv);
587 return CANT_RUN_DUMPCAP;
590 /* init STARTUPINFO */
591 memset(&si, 0, sizeof(si));
594 si.dwFlags = STARTF_USESHOWWINDOW;
595 si.wShowWindow = SW_SHOW;
597 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
598 si.wShowWindow = SW_HIDE; /* this hides the console window */
600 si.hStdOutput = sync_pipe_write;
601 si.hStdError = sync_pipe_write;
602 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
605 /* convert args array into a single string */
606 /* XXX - could change sync_pipe_add_arg() instead */
607 /* there is a drawback here: the length is internally limited to 1024 bytes */
608 for(i=0; argv[i] != 0; i++) {
609 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
610 quoted_arg = protect_arg(argv[i]);
611 g_string_append(args, quoted_arg);
616 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
617 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
618 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
619 args->str, GetLastError());
620 CloseHandle(sync_pipe_read);
621 CloseHandle(sync_pipe_write);
622 g_free( (gpointer) argv[0]);
623 g_free( (gpointer) argv);
624 return CANT_RUN_DUMPCAP;
626 *fork_child = (int) pi.hProcess;
627 g_string_free(args, TRUE);
629 /* associate the operating system filehandle to a C run-time file handle */
630 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
631 *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
634 if (pipe(sync_pipe) < 0) {
635 /* Couldn't create the pipe between parent and child. */
636 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
637 g_free( (gpointer) argv[0]);
639 return CANT_RUN_DUMPCAP;
642 if ((*fork_child = fork()) == 0) {
644 * Child process - run dumpcap with the right arguments to make
645 * it just capture with the specified capture parameters
648 dup(sync_pipe[PIPE_WRITE]);
649 eth_close(sync_pipe[PIPE_READ]);
650 execv(argv[0], (gpointer)argv);
651 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
652 argv[0], strerror(errno));
653 return CANT_RUN_DUMPCAP;
656 *read_fd = sync_pipe[PIPE_READ];
659 g_free( (gpointer) argv[0]); /* exename */
661 /* Parent process - read messages from the child process over the
663 g_free( (gpointer) argv); /* free up arg array */
665 /* Close the write side of the pipe, so that only the child has it
666 open, and thus it completely closes, and thus returns to us
667 an EOF indication, if the child closes it (either deliberately
668 or by exiting abnormally). */
670 CloseHandle(sync_pipe_write);
672 eth_close(sync_pipe[PIPE_WRITE]);
675 if (*fork_child == -1) {
676 /* We couldn't even create the child process. */
677 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
679 return CANT_RUN_DUMPCAP;
682 /* we might wait for a moment till child is ready, so update screen now */
683 main_window_update();
689 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
691 sync_pipe_close_command(int *read_fd, gchar **msg) {
693 int fork_child_status;
697 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
700 /* XXX - Should we signal the child somehow? */
701 sync_pipe_kill(*fork_child);
702 if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
703 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
704 "(errno:%u)", errno);
705 return CANT_RUN_DUMPCAP;
708 if (wait(&fork_child_status) != -1) {
709 if (WIFEXITED(fork_child_status)) {
710 /* The child exited. */
711 fork_child_status = WEXITSTATUS(fork_child_status);
713 if (WIFSTOPPED(fork_child_status)) {
714 /* It stopped, rather than exiting. "Should not happen." */
715 *msg = g_strdup_printf("Child capture process stopped: %s",
716 sync_pipe_signame(WSTOPSIG(fork_child_status)));
717 } else if (WIFSIGNALED(fork_child_status)) {
718 /* It died with a signal. */
719 *msg = g_strdup_printf("Child capture process died: %s%s",
720 sync_pipe_signame(WTERMSIG(fork_child_status)),
721 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
723 /* What? It had to either have exited, or stopped, or died with
724 a signal; what happened here? */
725 *msg = g_strdup_printf("Child capture process died: wait status %#o",
728 return CANT_RUN_DUMPCAP;
731 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
732 "(errno:%u)", errno);
733 return CANT_RUN_DUMPCAP;
740 * Run dumpcap with the supplied arguments. On success, msg points to
741 * a buffer containing the dumpcap output and returns 0. On failure, msg
742 * points to the error message returned by dumpcap, and returns dumpcap's
743 * exit value. In either case, msg must be freed with g_free().
745 /* XXX - This duplicates a lot of code in sync_pipe_start() */
746 #define PIPE_BUF_SIZE 5120
748 sync_pipe_run_command(const char** argv, gchar **msg) {
749 int sync_pipe_read_fd, fork_child, ret;
750 gchar buf[PIPE_BUF_SIZE+1];
751 GString *msg_buf = NULL;
754 ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
759 /* We were able to set up to read dumpcap's output. Do so and
760 return its exit value. */
761 msg_buf = g_string_new("");
762 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
764 g_string_append(msg_buf, buf);
768 ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
770 ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
774 g_string_free(msg_buf, TRUE);
779 g_string_free(msg_buf, FALSE);
784 * Get an interface list using dumpcap. On success, msg points to
785 * a buffer containing the dumpcap output and returns 0. On failure, msg
786 * points to the error message returned by dumpcap, and returns dumpcap's
787 * exit value. In either case, msg must be freed with g_free().
790 sync_interface_list_open(gchar **msg) {
795 /* We can't return anything */
799 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
801 argv = init_pipe_args(&argc);
804 *msg = g_strdup_printf("We don't know where to find dumpcap.");
805 return CANT_RUN_DUMPCAP;
808 /* Ask for the interface list */
809 argv = sync_pipe_add_arg(argv, &argc, "-D");
810 argv = sync_pipe_add_arg(argv, &argc, "-M");
812 /* dumpcap should be running in capture child mode (hidden feature) */
814 argv = sync_pipe_add_arg(argv, &argc, "-Z");
815 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
818 return sync_pipe_run_command(argv, msg);
822 * Get an linktype list using dumpcap. On success, msg points to
823 * a buffer containing the dumpcap output and returns 0. On failure, msg
824 * points to the error message returned by dumpcap, and returns dumpcap's
825 * exit value. In either case, msg must be freed with g_free().
828 sync_linktype_list_open(gchar *ifname, gchar **msg) {
833 /* We can't return anything */
837 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
839 argv = init_pipe_args(&argc);
842 *msg = g_strdup_printf("We don't know where to find dumpcap.");
843 return CANT_RUN_DUMPCAP;
846 /* Ask for the linktype list */
847 argv = sync_pipe_add_arg(argv, &argc, "-i");
848 argv = sync_pipe_add_arg(argv, &argc, ifname);
849 argv = sync_pipe_add_arg(argv, &argc, "-L");
850 argv = sync_pipe_add_arg(argv, &argc, "-M");
852 /* dumpcap should be running in capture child mode (hidden feature) */
854 argv = sync_pipe_add_arg(argv, &argc, "-Z");
855 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
858 return sync_pipe_run_command(argv, msg);
862 * Start getting interface statistics using dumpcap. On success, read_fd
863 * contains the file descriptor for the pipe's stdout, msg is unchanged,
864 * and zero is returned. On failure, msg will point to an error message
865 * that must be g_free()d and a nonzero error value will be returned.
868 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
873 /* We can't return anything */
877 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
879 argv = init_pipe_args(&argc);
882 *msg = g_strdup_printf("We don't know where to find dumpcap.");
883 return CANT_RUN_DUMPCAP;
886 /* Ask for the linktype list */
887 argv = sync_pipe_add_arg(argv, &argc, "-S");
888 argv = sync_pipe_add_arg(argv, &argc, "-M");
890 /* dumpcap should be running in capture child mode (hidden feature) */
892 argv = sync_pipe_add_arg(argv, &argc, "-Z");
893 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
896 return sync_pipe_open_command(argv, read_fd, fork_child, msg);
899 /* Close down the stats process */
901 sync_interface_stats_close(int *read_fd, int *fork_child
907 return sync_pipe_close_command(read_fd, fork_child, msg);
909 return sync_pipe_close_command(read_fd, msg);
913 /* read a number of bytes from a pipe */
914 /* (blocks until enough bytes read or an error occurs) */
916 pipe_read_bytes(int pipe, char *bytes, int required) {
921 newly = read(pipe, &bytes[offset], required);
924 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
925 "read from pipe %d: EOF (capture closed?)", pipe);
930 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
931 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
942 static gboolean pipe_data_available(int pipe) {
943 #ifdef _WIN32 /* PeekNamedPipe */
944 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
947 if (hPipe == INVALID_HANDLE_VALUE)
950 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
958 struct timeval timeout;
965 if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
972 /* Read a line from a pipe, similar to fgets */
974 sync_pipe_gets_nonblock(int pipe, char *bytes, int max) {
978 while(offset < max - 1) {
980 if (! pipe_data_available(pipe))
982 newly = read(pipe, &bytes[offset], 1);
984 /* EOF - not necessarily an error */
986 } else if (newly < 0) {
988 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
989 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
991 } else if (bytes[offset] == '\n') {
997 bytes[offset] = '\0';
1003 /* convert header values (indicator and 4-byte length) */
1005 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1007 g_assert(header_len == 4);
1009 /* convert header values */
1010 *indicator = header[0];
1011 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1014 /* read a message from the sending pipe in the standard format
1015 (1-byte message indicator, 3-byte message length (excluding length
1016 and indicator field), and the rest is the message) */
1018 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1024 /* read header (indicator and 3-byte length) */
1025 newly = pipe_read_bytes(pipe, header, 4);
1027 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1028 "read %d failed to read header: %u", pipe, newly);
1032 /* convert header values */
1033 pipe_convert_header(header, 4, indicator, &required);
1035 /* only indicator with no value? */
1037 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1038 "read %d indicator: %c empty value", pipe, *indicator);
1042 /* does the data fit into the given buffer? */
1043 if(required > len) {
1044 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1045 "read %d length error, required %d > len %d, indicator: %u",
1046 pipe, required, len, *indicator);
1048 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1049 memcpy(msg, header, sizeof(header));
1050 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1051 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1056 /* read the actual block data */
1057 newly = pipe_read_bytes(pipe, msg, required);
1058 if(newly != required) {
1059 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1063 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1064 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1070 /* There's stuff to read from the sync pipe, meaning the child has sent
1071 us a message, or the sync pipe has closed, meaning the child has
1072 closed it (perhaps because it exited). */
1074 sync_pipe_input_cb(gint source, gpointer user_data)
1076 capture_options *capture_opts = (capture_options *)user_data;
1077 char buffer[SP_MAX_MSG_LEN+1];
1083 char * secondary_msg;
1086 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1089 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1090 "sync_pipe_input_cb: child has closed sync_pipe");
1092 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1093 "sync_pipe_input_cb: error reading from sync pipe");
1095 /* The child has closed the sync pipe, meaning it's not going to be
1096 capturing any more packets. Pick up its exit status, and
1097 complain if it did anything other than exit with status 0.
1099 We don't have to worry about killing the child, if the sync pipe
1100 returned an error. Usually this error is caused as the child killed itself
1101 while going down. Even in the rare cases that this isn't the case,
1102 the child will get an error when writing to the broken pipe the next time,
1103 cleaning itself up then. */
1104 sync_pipe_wait_for_child(capture_opts);
1107 eth_close(capture_opts->signal_pipe_write_fd);
1109 capture_input_closed(capture_opts);
1113 /* we got a valid message block from the child, process it */
1116 if(!capture_input_new_file(capture_opts, buffer)) {
1117 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1119 /* We weren't able to open the new capture file; user has been
1120 alerted. Close the sync pipe. */
1123 /* the child has send us a filename which we couldn't open.
1124 this probably means, the child is creating files faster than we can handle it.
1125 this should only be the case for very fast file switches
1126 we can't do much more than telling the child to stop
1127 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1128 sync_pipe_stop(capture_opts);
1131 case SP_PACKET_COUNT:
1132 nread = atoi(buffer);
1133 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1134 capture_input_new_packets(capture_opts, nread);
1137 /* convert primary message */
1138 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1139 primary_msg = buffer+4;
1140 /* convert secondary message */
1141 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1142 secondary_msg = primary_msg + primary_len + 4;
1143 /* message output */
1144 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1145 /* the capture child will close the sync_pipe, nothing to do for now */
1146 /* (an error message doesn't mean we have to stop capturing) */
1149 capture_input_cfilter_error_message(capture_opts, buffer);
1150 /* the capture child will close the sync_pipe, nothing to do for now */
1153 capture_input_drops(capture_opts, atoi(buffer));
1156 g_assert_not_reached();
1164 /* the child process is going down, wait until it's completely terminated */
1166 sync_pipe_wait_for_child(capture_options *capture_opts)
1171 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1172 g_assert(capture_opts->fork_child != -1);
1175 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1176 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1177 "Child capture process stopped unexpectedly (errno:%u)", errno);
1180 if (wait(&wstatus) != -1) {
1181 if (WIFEXITED(wstatus)) {
1182 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1183 /* the child will inform us about errors through the sync_pipe, which will popup */
1184 /* an error message, so don't popup another one */
1186 /* If there are situations where the child won't send us such an error message, */
1187 /* this should be fixed in the child and not here! */
1188 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1189 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1190 "Child capture process exited: exit status %d",
1191 WEXITSTATUS(wstatus));
1193 } else if (WIFSTOPPED(wstatus)) {
1194 /* It stopped, rather than exiting. "Should not happen." */
1195 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1196 "Child capture process stopped: %s",
1197 sync_pipe_signame(WSTOPSIG(wstatus)));
1198 } else if (WIFSIGNALED(wstatus)) {
1199 /* It died with a signal. */
1200 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1201 "Child capture process died: %s%s",
1202 sync_pipe_signame(WTERMSIG(wstatus)),
1203 WCOREDUMP(wstatus) ? " - core dumped" : "");
1205 /* What? It had to either have exited, or stopped, or died with
1206 a signal; what happened here? */
1207 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1208 "Child capture process died: wait status %#o", wstatus);
1213 /* No more child process. */
1214 capture_opts->fork_child = -1;
1216 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1221 /* convert signal to corresponding name */
1223 sync_pipe_signame(int sig)
1226 static char sigmsg_buf[6+1+3+1];
1235 sigmsg = "Interrupted";
1243 sigmsg = "Illegal instruction";
1247 sigmsg = "Trace trap";
1255 sigmsg = "Arithmetic exception";
1263 sigmsg = "Bus error";
1267 sigmsg = "Segmentation violation";
1270 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1271 Linux is POSIX compliant. These are not POSIX-defined signals ---
1272 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1274 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1275 were omitted from POSIX.1 because their behavior is
1276 implementation dependent and could not be adequately catego-
1277 rized. Conforming implementations may deliver these sig-
1278 nals, but must document the circumstances under which they
1279 are delivered and note any restrictions concerning their
1282 So we only check for SIGSYS on those systems that happen to
1283 implement them (a system can be POSIX-compliant and implement
1284 them, it's just that POSIX doesn't *require* a POSIX-compliant
1285 system to implement them).
1290 sigmsg = "Bad system call";
1295 sigmsg = "Broken pipe";
1299 sigmsg = "Alarm clock";
1303 sigmsg = "Terminated";
1307 /* Returning a static buffer is ok in the context we use it here */
1308 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1309 sigmsg = sigmsg_buf;
1318 /* tell the child through the signal pipe that we want to quit the capture */
1320 signal_pipe_capquit_to_child(capture_options *capture_opts)
1322 const char quit_msg[] = "QUIT";
1326 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1328 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1329 /* simply sending a "QUIT" string */
1330 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1331 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1333 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1334 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1340 /* user wants to stop the capture run */
1342 sync_pipe_stop(capture_options *capture_opts)
1344 if (capture_opts->fork_child != -1) {
1346 /* send the SIGUSR1 signal to close the capture child gracefully. */
1347 kill(capture_opts->fork_child, SIGUSR1);
1349 /* Win32 doesn't have the kill() system call, use the special signal pipe
1350 instead to close the capture child gracefully. */
1351 signal_pipe_capquit_to_child(capture_opts);
1357 /* Wireshark has to exit, force the capture child to close */
1359 sync_pipe_kill(int fork_child)
1361 if (fork_child != -1) {
1363 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1365 /* Remark: This is not the preferred method of closing a process!
1366 * the clean way would be getting the process id of the child process,
1367 * then getting window handle hWnd of that process (using EnumChildWindows),
1368 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1370 * Unfortunately, I don't know how to get the process id from the
1371 * handle. OpenProcess will get an handle (not a window handle)
1372 * from the process ID; it will not get a window handle from the
1373 * process ID. (How could it? A process can have more than one
1374 * window. For that matter, a process might have *no* windows,
1375 * as a process running dumpcap, the normal child process program,
1378 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1379 * running in the same console; that's not necessarily the case for
1380 * us, as we might not be running in a console.
1381 * And this also will require to have the process id.
1383 TerminateProcess((HANDLE) (fork_child), 0);
1388 #endif /* HAVE_LIBPCAP */