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.
44 #include "epan/unicode-utils.h"
47 #ifdef HAVE_SYS_WAIT_H
48 # include <sys/wait.h>
51 #include "capture-pcap-util.h"
55 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
56 * macros) on UNIX systems that don't have them.
59 # define WIFEXITED(status) (((status) & 0177) == 0)
62 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
65 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
68 # define WEXITSTATUS(status) ((status) >> 8)
71 # define WTERMSIG(status) ((status) & 0177)
74 # define WCOREDUMP(status) ((status) & 0200)
77 # define WSTOPSIG(status) ((status) >> 8)
81 #include <epan/packet.h>
82 #include <epan/prefs.h>
86 #include <epan/filesystem.h>
89 #include "capture_sync.h"
90 #include "simple_dialog.h"
92 #include "sync_pipe.h"
95 #include "capture-wpcap.h"
98 #include "file_util.h"
102 #include <process.h> /* For spawning child process */
108 static const char *sync_pipe_signame(int);
112 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
113 static void sync_pipe_wait_for_child(capture_options *capture_opts);
117 /* Append an arg (realloc) to an argc/argv array */
118 /* (add a string pointer to a NULL-terminated array of string pointers) */
120 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
122 /* Grow the array; "*argc" currently contains the number of string
123 pointers, *not* counting the NULL pointer at the end, so we have
124 to add 2 in order to get the new size of the array, including the
125 new pointer and the terminating NULL pointer. */
126 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
128 /* Stuff the pointer into the penultimate element of the array, which
129 is the one at the index specified by "*argc". */
132 /* Now bump the count. */
135 /* We overwrite the NULL pointer; put it back right after the
145 /* Quote the argument element if necessary, so that it will get
146 * reconstructed correctly in the C runtime startup code. Note that
147 * the unquoting algorithm in the C runtime is really weird, and
148 * rather different than what Unix shells do. See stdargv.c in the C
149 * runtime sources (in the Platform SDK, in src/crt).
151 * Stolen from GLib's protect_argv(), an internal routine that quotes
152 * string in an argument list so that they arguments will be handled
153 * correctly in the command-line string passed to CreateProcess()
154 * if that string is constructed by gluing those strings together.
157 protect_arg (const gchar *argv)
160 const gchar *p = argv;
163 gboolean need_dblquotes = FALSE;
166 if (*p == ' ' || *p == '\t')
167 need_dblquotes = TRUE;
170 else if (*p == '\\') {
173 while (*pp && *pp == '\\')
182 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
191 else if (*p == '\\') {
194 while (*pp && *pp == '\\')
211 /* Initialize an argument list and add dumpcap to it. */
213 init_pipe_args(int *argc) {
215 const char *progfile_dir;
218 progfile_dir = get_progfile_dir();
219 if (progfile_dir == NULL) {
223 /* Allocate the string pointer array with enough space for the
224 terminating NULL pointer. */
226 argv = g_malloc(sizeof (char *));
229 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
230 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
232 /* Make that the first argument in the argument list (argv[0]). */
233 argv = sync_pipe_add_arg(argv, argc, exename);
238 #define ARGV_NUMBER_LEN 24
239 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
241 sync_pipe_start(capture_options *capture_opts) {
242 char ssnap[ARGV_NUMBER_LEN];
243 char scount[ARGV_NUMBER_LEN];
244 char sfilesize[ARGV_NUMBER_LEN];
245 char sfile_duration[ARGV_NUMBER_LEN];
246 char sring_num_files[ARGV_NUMBER_LEN];
247 char sautostop_files[ARGV_NUMBER_LEN];
248 char sautostop_filesize[ARGV_NUMBER_LEN];
249 char sautostop_duration[ARGV_NUMBER_LEN];
251 char buffer_size[ARGV_NUMBER_LEN];
252 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
253 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
254 HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
255 HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
256 GString *args = g_string_sized_new(200);
258 SECURITY_ATTRIBUTES sa;
260 PROCESS_INFORMATION pi;
264 int sync_pipe[2]; /* pipe used to send messages from child to parent */
265 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
267 int sync_pipe_read_fd;
272 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
273 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
275 capture_opts->fork_child = -1;
277 argv = init_pipe_args(&argc);
279 /* We don't know where to find dumpcap. */
280 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
284 argv = sync_pipe_add_arg(argv, &argc, "-i");
285 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
287 if (capture_opts->has_snaplen) {
288 argv = sync_pipe_add_arg(argv, &argc, "-s");
289 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
290 argv = sync_pipe_add_arg(argv, &argc, ssnap);
293 if (capture_opts->linktype != -1) {
294 argv = sync_pipe_add_arg(argv, &argc, "-y");
295 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
296 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
298 /* we can't get the type name, just treat it as a number */
299 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
301 argv = sync_pipe_add_arg(argv, &argc, ssnap);
304 if(capture_opts->multi_files_on) {
305 if (capture_opts->has_autostop_filesize) {
306 argv = sync_pipe_add_arg(argv, &argc, "-b");
307 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
308 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
311 if (capture_opts->has_file_duration) {
312 argv = sync_pipe_add_arg(argv, &argc, "-b");
313 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
314 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
317 if (capture_opts->has_ring_num_files) {
318 argv = sync_pipe_add_arg(argv, &argc, "-b");
319 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
320 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
323 if (capture_opts->has_autostop_files) {
324 argv = sync_pipe_add_arg(argv, &argc, "-a");
325 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
326 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
329 if (capture_opts->has_autostop_filesize) {
330 argv = sync_pipe_add_arg(argv, &argc, "-a");
331 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
332 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
336 if (capture_opts->has_autostop_packets) {
337 argv = sync_pipe_add_arg(argv, &argc, "-c");
338 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
339 argv = sync_pipe_add_arg(argv, &argc, scount);
342 if (capture_opts->has_autostop_duration) {
343 argv = sync_pipe_add_arg(argv, &argc, "-a");
344 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
345 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
348 if (!capture_opts->promisc_mode)
349 argv = sync_pipe_add_arg(argv, &argc, "-p");
351 /* dumpcap should be running in capture child mode (hidden feature) */
353 argv = sync_pipe_add_arg(argv, &argc, "-Z");
357 argv = sync_pipe_add_arg(argv, &argc, "-B");
358 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
359 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
362 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
363 argv = sync_pipe_add_arg(argv, &argc, "-f");
364 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
367 if(capture_opts->save_file) {
368 argv = sync_pipe_add_arg(argv, &argc, "-w");
369 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
373 /* init SECURITY_ATTRIBUTES */
374 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
375 sa.bInheritHandle = TRUE;
376 sa.lpSecurityDescriptor = NULL;
378 /* Create a pipe for the child process */
379 /* (inrease this value if you have trouble while fast capture file switches) */
380 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
381 /* Couldn't create the pipe between parent and child. */
382 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
384 g_free( (gpointer) argv[0]);
385 g_free( (gpointer) argv);
389 /* Create a pipe for the parent process */
390 if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
391 /* Couldn't create the signal pipe between parent and child. */
392 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
394 CloseHandle(sync_pipe_read);
395 CloseHandle(sync_pipe_write);
396 g_free( (gpointer) argv[0]);
397 g_free( (gpointer) argv);
401 /* init STARTUPINFO */
402 memset(&si, 0, sizeof(si));
405 si.dwFlags = STARTF_USESHOWWINDOW;
406 si.wShowWindow = SW_SHOW;
408 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
409 si.wShowWindow = SW_HIDE; /* this hides the console window */
410 si.hStdInput = signal_pipe_read;
411 si.hStdOutput = sync_pipe_write;
412 si.hStdError = sync_pipe_write;
413 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
416 /* convert args array into a single string */
417 /* XXX - could change sync_pipe_add_arg() instead */
418 /* there is a drawback here: the length is internally limited to 1024 bytes */
419 for(i=0; argv[i] != 0; i++) {
420 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
421 quoted_arg = protect_arg(argv[i]);
422 g_string_append(args, quoted_arg);
427 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
428 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
429 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
430 "Couldn't run %s in child process: error %u",
431 args->str, GetLastError());
432 CloseHandle(sync_pipe_read);
433 CloseHandle(sync_pipe_write);
434 g_free( (gpointer) argv[0]);
435 g_free( (gpointer) argv);
438 capture_opts->fork_child = (int) pi.hProcess;
439 g_string_free(args, TRUE);
441 /* associate the operating system filehandle to a C run-time file handle */
442 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
443 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
445 /* associate the operating system filehandle to a C run-time file handle */
446 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
448 /* child owns the read side now, close our handle */
449 CloseHandle(signal_pipe_read);
451 if (pipe(sync_pipe) < 0) {
452 /* Couldn't create the pipe between parent and child. */
453 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
455 g_free( (gpointer) argv[0]);
460 if ((capture_opts->fork_child = fork()) == 0) {
462 * Child process - run dumpcap with the right arguments to make
463 * it just capture with the specified capture parameters
466 dup(sync_pipe[PIPE_WRITE]);
467 eth_close(sync_pipe[PIPE_READ]);
468 execv(argv[0], (gpointer)argv);
469 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
470 argv[0], strerror(errno));
471 sync_pipe_errmsg_to_parent(errmsg, "");
473 /* Exit with "_exit()", so that we don't close the connection
474 to the X server (and cause stuff buffered up by our parent but
475 not yet sent to be sent, as that stuff should only be sent by
480 sync_pipe_read_fd = sync_pipe[PIPE_READ];
483 g_free( (gpointer) argv[0]); /* exename */
485 /* Parent process - read messages from the child process over the
487 g_free( (gpointer) argv); /* free up arg array */
489 /* Close the write side of the pipe, so that only the child has it
490 open, and thus it completely closes, and thus returns to us
491 an EOF indication, if the child closes it (either deliberately
492 or by exiting abnormally). */
494 CloseHandle(sync_pipe_write);
496 eth_close(sync_pipe[PIPE_WRITE]);
499 if (capture_opts->fork_child == -1) {
500 /* We couldn't even create the child process. */
501 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
502 "Couldn't create child process: %s", strerror(errno));
503 eth_close(sync_pipe_read_fd);
505 eth_close(capture_opts->signal_pipe_write_fd);
510 /* we might wait for a moment till child is ready, so update screen now */
511 main_window_update();
513 /* We were able to set up to read the capture file;
514 arrange that our callback be called whenever it's possible
515 to read from the sync pipe, so that it's called when
516 the child process wants to tell us something. */
518 /* we have a running capture, now wait for the real capture filename */
519 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
520 &capture_opts->fork_child, sync_pipe_input_cb);
526 * Run dumpcap with the supplied arguments. On success, msg points to
527 * a buffer containing the dumpcap output and returns 0. On failure, msg
528 * points to the error message returned by dumpcap, and returns dumpcap's
529 * exit value. In either case, msg must be freed with g_free().
531 /* XXX - This duplicates a lot of code in sync_pipe_start() */
532 #define PIPE_BUF_SIZE 5120
534 sync_pipe_run_command(const char** argv, gchar **msg) {
536 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
537 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
538 GString *args = g_string_sized_new(200);
540 SECURITY_ATTRIBUTES sa;
542 PROCESS_INFORMATION pi;
545 int sync_pipe[2]; /* pipe used to send messages from child to parent */
546 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
548 int fork_child = -1, fork_child_status;
549 int sync_pipe_read_fd = -1;
550 GString *msg_buf = NULL;
551 gchar buf[PIPE_BUF_SIZE+1];
554 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
557 /* We can't return anything */
559 g_string_free(args, TRUE);
565 /* init SECURITY_ATTRIBUTES */
566 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
567 sa.bInheritHandle = TRUE;
568 sa.lpSecurityDescriptor = NULL;
570 /* Create a pipe for the child process */
571 /* (inrease this value if you have trouble while fast capture file switches) */
572 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
573 /* Couldn't create the pipe between parent and child. */
574 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
575 g_free( (gpointer) argv[0]);
576 g_free( (gpointer) argv);
577 return CANT_RUN_DUMPCAP;
580 /* init STARTUPINFO */
581 memset(&si, 0, sizeof(si));
584 si.dwFlags = STARTF_USESHOWWINDOW;
585 si.wShowWindow = SW_SHOW;
587 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
588 si.wShowWindow = SW_HIDE; /* this hides the console window */
590 si.hStdOutput = sync_pipe_write;
591 si.hStdError = sync_pipe_write;
592 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
595 /* convert args array into a single string */
596 /* XXX - could change sync_pipe_add_arg() instead */
597 /* there is a drawback here: the length is internally limited to 1024 bytes */
598 for(i=0; argv[i] != 0; i++) {
599 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
600 quoted_arg = protect_arg(argv[i]);
601 g_string_append(args, quoted_arg);
606 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
607 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
608 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
609 args->str, GetLastError());
610 CloseHandle(sync_pipe_read);
611 CloseHandle(sync_pipe_write);
612 g_free( (gpointer) argv[0]);
613 g_free( (gpointer) argv);
614 return CANT_RUN_DUMPCAP;
616 fork_child = (int) pi.hProcess;
617 g_string_free(args, TRUE);
619 /* associate the operating system filehandle to a C run-time file handle */
620 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
621 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
624 if (pipe(sync_pipe) < 0) {
625 /* Couldn't create the pipe between parent and child. */
626 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
627 g_free( (gpointer) argv[0]);
629 return CANT_RUN_DUMPCAP;
632 if ((fork_child = fork()) == 0) {
634 * Child process - run dumpcap with the right arguments to make
635 * it just capture with the specified capture parameters
638 dup(sync_pipe[PIPE_WRITE]);
639 eth_close(sync_pipe[PIPE_READ]);
640 execv(argv[0], (gpointer)argv);
641 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
642 argv[0], strerror(errno));
643 return CANT_RUN_DUMPCAP;
646 sync_pipe_read_fd = sync_pipe[PIPE_READ];
649 g_free( (gpointer) argv[0]); /* exename */
651 /* Parent process - read messages from the child process over the
653 g_free( (gpointer) argv); /* free up arg array */
655 /* Close the write side of the pipe, so that only the child has it
656 open, and thus it completely closes, and thus returns to us
657 an EOF indication, if the child closes it (either deliberately
658 or by exiting abnormally). */
660 CloseHandle(sync_pipe_write);
662 eth_close(sync_pipe[PIPE_WRITE]);
665 if (fork_child == -1) {
666 /* We couldn't even create the child process. */
667 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
668 eth_close(sync_pipe_read_fd);
669 return CANT_RUN_DUMPCAP;
672 /* we might wait for a moment till child is ready, so update screen now */
673 main_window_update();
675 /* We were able to set up to read dumpcap's output. Do so and
676 return its exit value. */
677 msg_buf = g_string_new("");
678 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
680 g_string_append(msg_buf, buf);
683 eth_close(sync_pipe_read_fd);
685 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open: wait till child closed");
688 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
689 g_string_free(msg_buf, TRUE);
690 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
691 "(errno:%u)", errno);
692 return CANT_RUN_DUMPCAP;
695 if (wait(&fork_child_status) != -1) {
696 if (WIFEXITED(fork_child_status)) {
697 /* The child exited. */
698 fork_child_status = WEXITSTATUS(fork_child_status);
700 g_string_free(msg_buf, TRUE);
701 if (WIFSTOPPED(fork_child_status)) {
702 /* It stopped, rather than exiting. "Should not happen." */
703 *msg = g_strdup_printf("Child capture process stopped: %s",
704 sync_pipe_signame(WSTOPSIG(fork_child_status)));
705 } else if (WIFSIGNALED(fork_child_status)) {
706 /* It died with a signal. */
707 *msg = g_strdup_printf("Child capture process died: %s%s",
708 sync_pipe_signame(WTERMSIG(fork_child_status)),
709 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
711 /* What? It had to either have exited, or stopped, or died with
712 a signal; what happened here? */
713 *msg = g_strdup_printf("Child capture process died: wait status %#o",
716 return CANT_RUN_DUMPCAP;
719 g_string_free(msg_buf, TRUE);
720 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
721 "(errno:%u)", errno);
722 return CANT_RUN_DUMPCAP;
727 g_string_free(msg_buf, FALSE);
728 return fork_child_status;
732 * Get an interface list using dumpcap. On success, msg points to
733 * a buffer containing the dumpcap output and returns 0. On failure, msg
734 * points to the error message returned by dumpcap, and returns dumpcap's
735 * exit value. In either case, msg must be freed with g_free().
738 sync_interface_list_open(gchar **msg) {
743 /* We can't return anything */
747 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
749 argv = init_pipe_args(&argc);
752 *msg = g_strdup_printf("We don't know where to find dumpcap.");
753 return CANT_RUN_DUMPCAP;
756 /* Ask for the interface list */
757 argv = sync_pipe_add_arg(argv, &argc, "-D");
758 argv = sync_pipe_add_arg(argv, &argc, "-M");
760 /* dumpcap should be running in capture child mode (hidden feature) */
762 argv = sync_pipe_add_arg(argv, &argc, "-Z");
765 return sync_pipe_run_command(argv, msg);
769 * Get an linktype list using dumpcap. On success, msg points to
770 * a buffer containing the dumpcap output and returns 0. On failure, msg
771 * points to the error message returned by dumpcap, and returns dumpcap's
772 * exit value. In either case, msg must be freed with g_free().
775 sync_linktype_list_open(gchar *ifname, gchar **msg) {
780 /* We can't return anything */
784 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
786 argv = init_pipe_args(&argc);
789 *msg = g_strdup_printf("We don't know where to find dumpcap.");
790 return CANT_RUN_DUMPCAP;
793 /* Ask for the linktype list */
794 argv = sync_pipe_add_arg(argv, &argc, "-i");
795 argv = sync_pipe_add_arg(argv, &argc, ifname);
796 argv = sync_pipe_add_arg(argv, &argc, "-L");
797 argv = sync_pipe_add_arg(argv, &argc, "-M");
799 /* dumpcap should be running in capture child mode (hidden feature) */
801 argv = sync_pipe_add_arg(argv, &argc, "-Z");
804 return sync_pipe_run_command(argv, msg);
808 /* read a number of bytes from a pipe */
809 /* (blocks until enough bytes read or an error occurs) */
811 pipe_read_bytes(int pipe, char *bytes, int required) {
817 newly = read(pipe, &bytes[offset], required);
820 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
821 "read from pipe %d: EOF (capture closed?)", pipe);
826 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
827 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
838 /* convert header values (indicator and 4-byte length) */
840 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
842 g_assert(header_len == 4);
844 /* convert header values */
845 *indicator = header[0];
846 *block_len = header[1]<<16 | header[2]<<8 | header[3];
849 /* read a message from the sending pipe in the standard format
850 (1-byte message indicator, 3-byte message length (excluding length
851 and indicator field), and the rest is the message) */
853 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
859 /* read header (indicator and 3-byte length) */
860 newly = pipe_read_bytes(pipe, header, 4);
862 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
863 "read %d failed to read header: %u", pipe, newly);
867 /* convert header values */
868 pipe_convert_header(header, 4, indicator, &required);
870 /* only indicator with no value? */
872 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
873 "read %d indicator: %c empty value", pipe, *indicator);
877 /* does the data fit into the given buffer? */
879 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
880 "read %d length error, required %d > len %d, indicator: %u",
881 pipe, required, len, *indicator);
883 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
884 memcpy(msg, header, sizeof(header));
885 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
886 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
891 /* read the actual block data */
892 newly = pipe_read_bytes(pipe, msg, required);
893 if(newly != required) {
894 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
898 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
899 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
905 /* There's stuff to read from the sync pipe, meaning the child has sent
906 us a message, or the sync pipe has closed, meaning the child has
907 closed it (perhaps because it exited). */
909 sync_pipe_input_cb(gint source, gpointer user_data)
911 capture_options *capture_opts = (capture_options *)user_data;
912 char buffer[SP_MAX_MSG_LEN+1];
918 char * secondary_msg;
921 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
924 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
925 "sync_pipe_input_cb: child has closed sync_pipe");
927 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
928 "sync_pipe_input_cb: error reading from sync pipe");
930 /* The child has closed the sync pipe, meaning it's not going to be
931 capturing any more packets. Pick up its exit status, and
932 complain if it did anything other than exit with status 0.
934 We don't have to worry about killing the child, if the sync pipe
935 returned an error. Usually this error is caused as the child killed itself
936 while going down. Even in the rare cases that this isn't the case,
937 the child will get an error when writing to the broken pipe the next time,
938 cleaning itself up then. */
939 sync_pipe_wait_for_child(capture_opts);
942 eth_close(capture_opts->signal_pipe_write_fd);
944 capture_input_closed(capture_opts);
948 /* we got a valid message block from the child, process it */
951 if(!capture_input_new_file(capture_opts, buffer)) {
952 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
954 /* We weren't able to open the new capture file; user has been
955 alerted. Close the sync pipe. */
958 /* the child has send us a filename which we couldn't open.
959 this probably means, the child is creating files faster than we can handle it.
960 this should only be the case for very fast file switches
961 we can't do much more than telling the child to stop
962 (this is the "emergency brake" if user e.g. wants to switch files every second) */
963 sync_pipe_stop(capture_opts);
966 case SP_PACKET_COUNT:
967 nread = atoi(buffer);
968 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
969 capture_input_new_packets(capture_opts, nread);
972 /* convert primary message */
973 pipe_convert_header(buffer, 4, &indicator, &primary_len);
974 primary_msg = buffer+4;
975 /* convert secondary message */
976 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
977 secondary_msg = primary_msg + primary_len + 4;
979 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
980 /* the capture child will close the sync_pipe, nothing to do for now */
981 /* (an error message doesn't mean we have to stop capturing) */
984 capture_input_cfilter_error_message(capture_opts, buffer);
985 /* the capture child will close the sync_pipe, nothing to do for now */
988 capture_input_drops(capture_opts, atoi(buffer));
991 g_assert_not_reached();
999 /* the child process is going down, wait until it's completely terminated */
1001 sync_pipe_wait_for_child(capture_options *capture_opts)
1006 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1007 g_assert(capture_opts->fork_child != -1);
1010 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1011 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1012 "Child capture process stopped unexpectedly (errno:%u)", errno);
1015 if (wait(&wstatus) != -1) {
1016 if (WIFEXITED(wstatus)) {
1017 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1018 /* the child will inform us about errors through the sync_pipe, which will popup */
1019 /* an error message, so don't popup another one */
1021 /* If there are situations where the child won't send us such an error message, */
1022 /* this should be fixed in the child and not here! */
1023 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1024 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1025 "Child capture process exited: exit status %d",
1026 WEXITSTATUS(wstatus));
1028 } else if (WIFSTOPPED(wstatus)) {
1029 /* It stopped, rather than exiting. "Should not happen." */
1030 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1031 "Child capture process stopped: %s",
1032 sync_pipe_signame(WSTOPSIG(wstatus)));
1033 } else if (WIFSIGNALED(wstatus)) {
1034 /* It died with a signal. */
1035 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1036 "Child capture process died: %s%s",
1037 sync_pipe_signame(WTERMSIG(wstatus)),
1038 WCOREDUMP(wstatus) ? " - core dumped" : "");
1040 /* What? It had to either have exited, or stopped, or died with
1041 a signal; what happened here? */
1042 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1043 "Child capture process died: wait status %#o", wstatus);
1048 /* No more child process. */
1049 capture_opts->fork_child = -1;
1051 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1056 /* convert signal to corresponding name */
1058 sync_pipe_signame(int sig)
1061 static char sigmsg_buf[6+1+3+1];
1070 sigmsg = "Interrupted";
1078 sigmsg = "Illegal instruction";
1082 sigmsg = "Trace trap";
1090 sigmsg = "Arithmetic exception";
1098 sigmsg = "Bus error";
1102 sigmsg = "Segmentation violation";
1105 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1106 Linux is POSIX compliant. These are not POSIX-defined signals ---
1107 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1109 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1110 were omitted from POSIX.1 because their behavior is
1111 implementation dependent and could not be adequately catego-
1112 rized. Conforming implementations may deliver these sig-
1113 nals, but must document the circumstances under which they
1114 are delivered and note any restrictions concerning their
1117 So we only check for SIGSYS on those systems that happen to
1118 implement them (a system can be POSIX-compliant and implement
1119 them, it's just that POSIX doesn't *require* a POSIX-compliant
1120 system to implement them).
1125 sigmsg = "Bad system call";
1130 sigmsg = "Broken pipe";
1134 sigmsg = "Alarm clock";
1138 sigmsg = "Terminated";
1142 /* Returning a static buffer is ok in the context we use it here */
1143 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1144 sigmsg = sigmsg_buf;
1153 /* tell the child through the signal pipe that we want to quit the capture */
1155 signal_pipe_capquit_to_child(capture_options *capture_opts)
1157 const char quit_msg[] = "QUIT";
1161 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1163 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1164 /* simply sending a "QUIT" string */
1165 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1166 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1168 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1169 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1175 /* user wants to stop the capture run */
1177 sync_pipe_stop(capture_options *capture_opts)
1179 if (capture_opts->fork_child != -1) {
1181 /* send the SIGUSR1 signal to close the capture child gracefully. */
1182 kill(capture_opts->fork_child, SIGUSR1);
1184 /* Win32 doesn't have the kill() system call, use the special signal pipe
1185 instead to close the capture child gracefully. */
1186 signal_pipe_capquit_to_child(capture_opts);
1192 /* Wireshark has to exit, force the capture child to close */
1194 sync_pipe_kill(int fork_child)
1196 if (fork_child != -1) {
1198 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1200 /* Remark: This is not the preferred method of closing a process!
1201 * the clean way would be getting the process id of the child process,
1202 * then getting window handle hWnd of that process (using EnumChildWindows),
1203 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1205 * Unfortunately, I don't know how to get the process id from the
1206 * handle. OpenProcess will get an handle (not a window handle)
1207 * from the process ID; it will not get a window handle from the
1208 * process ID. (How could it? A process can have more than one
1209 * window. For that matter, a process might have *no* windows,
1210 * as a process running dumpcap, the normal child process program,
1213 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1214 * running in the same console; that's not necessarily the case for
1215 * us, as we might not be running in a console.
1216 * And this also will require to have the process id.
1218 TerminateProcess((HANDLE) (fork_child), 0);
1223 #endif /* HAVE_LIBPCAP */