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 == '\\')
213 #define ARGV_NUMBER_LEN 24
215 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
217 sync_pipe_start(capture_options *capture_opts) {
218 char ssnap[ARGV_NUMBER_LEN];
219 char scount[ARGV_NUMBER_LEN];
220 char sfilesize[ARGV_NUMBER_LEN];
221 char sfile_duration[ARGV_NUMBER_LEN];
222 char sring_num_files[ARGV_NUMBER_LEN];
223 char sautostop_files[ARGV_NUMBER_LEN];
224 char sautostop_filesize[ARGV_NUMBER_LEN];
225 char sautostop_duration[ARGV_NUMBER_LEN];
227 char buffer_size[ARGV_NUMBER_LEN];
228 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
229 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
230 HANDLE signal_pipe_read; /* pipe used to send messages from parent to child (currently only stop) */
231 HANDLE signal_pipe_write; /* pipe used to send messages from parent to child (currently only stop) */
232 GString *args = g_string_sized_new(200);
234 SECURITY_ATTRIBUTES sa;
236 PROCESS_INFORMATION pi;
240 int sync_pipe[2]; /* pipe used to send messages from child to parent */
241 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
243 int sync_pipe_read_fd;
244 const char *progfile_dir;
250 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
251 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
253 capture_opts->fork_child = -1;
255 progfile_dir = get_progfile_dir();
256 if (progfile_dir == NULL) {
257 /* We don't know where to find dumpcap. */
258 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
262 /* Allocate the string pointer array with enough space for the
263 terminating NULL pointer. */
265 argv = g_malloc(sizeof (char *));
268 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
269 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
271 /* Make that the first argument in the argument list (argv[0]). */
272 argv = sync_pipe_add_arg(argv, &argc, exename);
274 argv = sync_pipe_add_arg(argv, &argc, "-i");
275 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
277 if (capture_opts->has_snaplen) {
278 argv = sync_pipe_add_arg(argv, &argc, "-s");
279 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
280 argv = sync_pipe_add_arg(argv, &argc, ssnap);
283 if (capture_opts->linktype != -1) {
284 argv = sync_pipe_add_arg(argv, &argc, "-y");
285 #ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
286 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
288 /* we can't get the type name, just treat it as a number */
289 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->linktype);
291 argv = sync_pipe_add_arg(argv, &argc, ssnap);
294 if(capture_opts->multi_files_on) {
295 if (capture_opts->has_autostop_filesize) {
296 argv = sync_pipe_add_arg(argv, &argc, "-b");
297 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
298 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
301 if (capture_opts->has_file_duration) {
302 argv = sync_pipe_add_arg(argv, &argc, "-b");
303 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
304 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
307 if (capture_opts->has_ring_num_files) {
308 argv = sync_pipe_add_arg(argv, &argc, "-b");
309 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
310 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
313 if (capture_opts->has_autostop_files) {
314 argv = sync_pipe_add_arg(argv, &argc, "-a");
315 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
316 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
319 if (capture_opts->has_autostop_filesize) {
320 argv = sync_pipe_add_arg(argv, &argc, "-a");
321 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
322 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
326 if (capture_opts->has_autostop_packets) {
327 argv = sync_pipe_add_arg(argv, &argc, "-c");
328 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
329 argv = sync_pipe_add_arg(argv, &argc, scount);
332 if (capture_opts->has_autostop_duration) {
333 argv = sync_pipe_add_arg(argv, &argc, "-a");
334 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
335 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
338 if (!capture_opts->promisc_mode)
339 argv = sync_pipe_add_arg(argv, &argc, "-p");
341 /* dumpcap should be running in capture child mode (hidden feature) */
343 argv = sync_pipe_add_arg(argv, &argc, "-Z");
347 argv = sync_pipe_add_arg(argv, &argc, "-B");
348 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
349 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
352 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
353 argv = sync_pipe_add_arg(argv, &argc, "-f");
354 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
357 if(capture_opts->save_file) {
358 argv = sync_pipe_add_arg(argv, &argc, "-w");
359 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
363 /* init SECURITY_ATTRIBUTES */
364 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
365 sa.bInheritHandle = TRUE;
366 sa.lpSecurityDescriptor = NULL;
368 /* Create a pipe for the child process */
369 /* (inrease this value if you have trouble while fast capture file switches) */
370 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
371 /* Couldn't create the pipe between parent and child. */
372 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
374 g_free( (gpointer) argv);
378 /* Create a pipe for the parent process */
379 if (! CreatePipe(&signal_pipe_read, &signal_pipe_write, &sa, 512)) {
380 /* Couldn't create the signal pipe between parent and child. */
381 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create signal pipe: %s",
383 CloseHandle(sync_pipe_read);
384 CloseHandle(sync_pipe_write);
385 g_free( (gpointer) argv);
389 /* init STARTUPINFO */
390 memset(&si, 0, sizeof(si));
393 si.dwFlags = STARTF_USESHOWWINDOW;
394 si.wShowWindow = SW_SHOW;
396 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
397 si.wShowWindow = SW_HIDE; /* this hides the console window */
398 si.hStdInput = signal_pipe_read;
399 si.hStdOutput = sync_pipe_write;
400 si.hStdError = sync_pipe_write;
401 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
404 /* convert args array into a single string */
405 /* XXX - could change sync_pipe_add_arg() instead */
406 /* there is a drawback here: the length is internally limited to 1024 bytes */
407 for(i=0; argv[i] != 0; i++) {
408 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
409 quoted_arg = protect_arg(argv[i]);
410 g_string_append(args, quoted_arg);
415 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
416 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
417 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
418 "Couldn't run %s in child process: error %u",
419 args->str, GetLastError());
420 CloseHandle(sync_pipe_read);
421 CloseHandle(sync_pipe_write);
422 g_free( (gpointer) argv);
425 capture_opts->fork_child = (int) pi.hProcess;
426 g_string_free(args, TRUE);
428 /* associate the operating system filehandle to a C run-time file handle */
429 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
430 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
432 /* associate the operating system filehandle to a C run-time file handle */
433 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe_write, _O_BINARY);
435 /* child owns the read side now, close our handle */
436 CloseHandle(signal_pipe_read);
438 if (pipe(sync_pipe) < 0) {
439 /* Couldn't create the pipe between parent and child. */
440 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Couldn't create sync pipe: %s",
446 if ((capture_opts->fork_child = fork()) == 0) {
448 * Child process - run dumpcap with the right arguments to make
449 * it just capture with the specified capture parameters
452 dup(sync_pipe[PIPE_WRITE]);
453 eth_close(sync_pipe[PIPE_READ]);
454 execv(exename, (gpointer)argv);
455 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
456 exename, strerror(errno));
457 sync_pipe_errmsg_to_parent(errmsg, "");
459 /* Exit with "_exit()", so that we don't close the connection
460 to the X server (and cause stuff buffered up by our parent but
461 not yet sent to be sent, as that stuff should only be sent by
466 sync_pipe_read_fd = sync_pipe[PIPE_READ];
471 /* Parent process - read messages from the child process over the
473 g_free( (gpointer) argv); /* free up arg array */
475 /* Close the write side of the pipe, so that only the child has it
476 open, and thus it completely closes, and thus returns to us
477 an EOF indication, if the child closes it (either deliberately
478 or by exiting abnormally). */
480 CloseHandle(sync_pipe_write);
482 eth_close(sync_pipe[PIPE_WRITE]);
485 if (capture_opts->fork_child == -1) {
486 /* We couldn't even create the child process. */
487 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
488 "Couldn't create child process: %s", strerror(errno));
489 eth_close(sync_pipe_read_fd);
491 eth_close(capture_opts->signal_pipe_write_fd);
496 /* we might wait for a moment till child is ready, so update screen now */
497 main_window_update();
499 /* We were able to set up to read the capture file;
500 arrange that our callback be called whenever it's possible
501 to read from the sync pipe, so that it's called when
502 the child process wants to tell us something. */
504 /* we have a running capture, now wait for the real capture filename */
505 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
506 &capture_opts->fork_child, sync_pipe_input_cb);
512 * Get an interface list using dumpcap. On success, msg points to
513 * a buffer containing the dumpcap output and returns 0. On failure, msg
514 * points to the error message returned by dumpcap, and returns dumpcap's
515 * exit value. In either case, msg must be freed with g_free().
517 /* XXX - This duplicates a lot of code in sync_pipe_start() and sync_interface_list_open() */
518 #define PIPE_BUF_SIZE 5120
520 sync_interface_list_open(gchar **msg) {
522 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
523 HANDLE sync_pipe_write; /* pipe used to send messages from parent to child */
524 GString *args = g_string_sized_new(200);
526 SECURITY_ATTRIBUTES sa;
528 PROCESS_INFORMATION pi;
531 int sync_pipe[2]; /* pipe used to send messages from child to parent */
532 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
534 int fork_child = -1, fork_child_status;
535 int sync_pipe_read_fd = -1;
536 const char *progfile_dir;
540 GString *msg_buf = NULL;
541 gchar buf[PIPE_BUF_SIZE+1];
544 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
547 /* We can't return anything */
549 g_string_free(args, TRUE);
554 progfile_dir = get_progfile_dir();
555 if (progfile_dir == NULL) {
556 /* We don't know where to find dumpcap. */
557 *msg = g_strdup("We don't know where to find dumpcap.");
558 return CANT_RUN_DUMPCAP;
561 /* Allocate the string pointer array with enough space for the
562 terminating NULL pointer. */
564 argv = g_malloc(sizeof (char *));
567 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
568 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
570 /* Make that the first argument in the argument list (argv[0]). */
571 argv = sync_pipe_add_arg(argv, &argc, exename);
573 /* Ask for the interface list */
574 argv = sync_pipe_add_arg(argv, &argc, "-I");
575 argv = sync_pipe_add_arg(argv, &argc, "l");
578 /* dumpcap should be running in capture child mode (hidden feature) */
580 argv = sync_pipe_add_arg(argv, &argc, "-Z");
585 /* init SECURITY_ATTRIBUTES */
586 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
587 sa.bInheritHandle = TRUE;
588 sa.lpSecurityDescriptor = NULL;
590 /* Create a pipe for the child process */
591 /* (inrease this value if you have trouble while fast capture file switches) */
592 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
593 /* Couldn't create the pipe between parent and child. */
594 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
595 g_free( (gpointer) argv);
596 return CANT_RUN_DUMPCAP;
599 /* init STARTUPINFO */
600 memset(&si, 0, sizeof(si));
603 si.dwFlags = STARTF_USESHOWWINDOW;
604 si.wShowWindow = SW_SHOW;
606 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
607 si.wShowWindow = SW_HIDE; /* this hides the console window */
609 si.hStdOutput = sync_pipe_write;
610 si.hStdError = sync_pipe_write;
611 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
614 /* convert args array into a single string */
615 /* XXX - could change sync_pipe_add_arg() instead */
616 /* there is a drawback here: the length is internally limited to 1024 bytes */
617 for(i=0; argv[i] != 0; i++) {
618 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
619 quoted_arg = protect_arg(argv[i]);
620 g_string_append(args, quoted_arg);
625 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
626 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
627 *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
628 args->str, GetLastError());
629 CloseHandle(sync_pipe_read);
630 CloseHandle(sync_pipe_write);
631 g_free( (gpointer) argv);
632 return CANT_RUN_DUMPCAP;
634 fork_child = (int) pi.hProcess;
635 g_string_free(args, TRUE);
637 /* associate the operating system filehandle to a C run-time file handle */
638 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
639 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
642 if (pipe(sync_pipe) < 0) {
643 /* Couldn't create the pipe between parent and child. */
644 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
646 return CANT_RUN_DUMPCAP;
649 if ((fork_child = fork()) == 0) {
651 * Child process - run dumpcap with the right arguments to make
652 * it just capture with the specified capture parameters
655 dup(sync_pipe[PIPE_WRITE]);
656 eth_close(sync_pipe[PIPE_READ]);
657 execv(exename, (gpointer)argv);
658 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
659 exename, strerror(errno));
660 return CANT_RUN_DUMPCAP;
663 sync_pipe_read_fd = sync_pipe[PIPE_READ];
668 /* Parent process - read messages from the child process over the
670 g_free( (gpointer) argv); /* free up arg array */
672 /* Close the write side of the pipe, so that only the child has it
673 open, and thus it completely closes, and thus returns to us
674 an EOF indication, if the child closes it (either deliberately
675 or by exiting abnormally). */
677 CloseHandle(sync_pipe_write);
679 eth_close(sync_pipe[PIPE_WRITE]);
682 if (fork_child == -1) {
683 /* We couldn't even create the child process. */
684 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
685 eth_close(sync_pipe_read_fd);
686 return CANT_RUN_DUMPCAP;
689 /* we might wait for a moment till child is ready, so update screen now */
690 main_window_update();
692 /* We were able to set up to read dumpcap's output. Do so and
693 return its exit value. */
694 msg_buf = g_string_new("");
695 while ((count = eth_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
697 g_string_append(msg_buf, buf);
700 eth_close(sync_pipe_read_fd);
702 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open: wait till child closed");
705 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
706 g_string_free(msg_buf, TRUE);
707 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
708 "(errno:%u)", errno);
709 return CANT_RUN_DUMPCAP;
712 if (wait(&fork_child_status) != -1) {
713 if (WIFEXITED(fork_child_status)) {
714 /* The child exited. */
715 fork_child_status = WEXITSTATUS(fork_child_status);
717 g_string_free(msg_buf, TRUE);
718 if (WIFSTOPPED(fork_child_status)) {
719 /* It stopped, rather than exiting. "Should not happen." */
720 *msg = g_strdup_printf("Child capture process stopped: %s",
721 sync_pipe_signame(WSTOPSIG(fork_child_status)));
722 } else if (WIFSIGNALED(fork_child_status)) {
723 /* It died with a signal. */
724 *msg = g_strdup_printf("Child capture process died: %s%s",
725 sync_pipe_signame(WTERMSIG(fork_child_status)),
726 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
728 /* What? It had to either have exited, or stopped, or died with
729 a signal; what happened here? */
730 *msg = g_strdup_printf("Child capture process died: wait status %#o",
733 return CANT_RUN_DUMPCAP;
736 g_string_free(msg_buf, TRUE);
737 *msg = g_strdup_printf("Child capture process stopped unexpectedly "
738 "(errno:%u)", errno);
739 return CANT_RUN_DUMPCAP;
744 g_string_free(msg_buf, FALSE);
745 return fork_child_status;
749 /* read a number of bytes from a pipe */
750 /* (blocks until enough bytes read or an error occurs) */
752 pipe_read_bytes(int pipe, char *bytes, int required) {
758 newly = read(pipe, &bytes[offset], required);
761 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
762 "read from pipe %d: EOF (capture closed?)", pipe);
767 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
768 "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
779 /* convert header values (indicator and 4-byte length) */
781 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
783 g_assert(header_len == 4);
785 /* convert header values */
786 *indicator = header[0];
787 *block_len = header[1]<<16 | header[2]<<8 | header[3];
790 /* read a message from the sending pipe in the standard format
791 (1-byte message indicator, 3-byte message length (excluding length
792 and indicator field), and the rest is the message) */
794 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
800 /* read header (indicator and 3-byte length) */
801 newly = pipe_read_bytes(pipe, header, 4);
803 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
804 "read %d failed to read header: %u", pipe, newly);
808 /* convert header values */
809 pipe_convert_header(header, 4, indicator, &required);
811 /* only indicator with no value? */
813 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
814 "read %d indicator: %c empty value", pipe, *indicator);
818 /* does the data fit into the given buffer? */
820 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
821 "read %d length error, required %d > len %d, indicator: %u",
822 pipe, required, len, *indicator);
824 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
825 memcpy(msg, header, sizeof(header));
826 newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
827 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
832 /* read the actual block data */
833 newly = pipe_read_bytes(pipe, msg, required);
834 if(newly != required) {
835 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
839 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
840 "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
846 /* There's stuff to read from the sync pipe, meaning the child has sent
847 us a message, or the sync pipe has closed, meaning the child has
848 closed it (perhaps because it exited). */
850 sync_pipe_input_cb(gint source, gpointer user_data)
852 capture_options *capture_opts = (capture_options *)user_data;
853 char buffer[SP_MAX_MSG_LEN+1];
859 char * secondary_msg;
862 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
865 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
866 "sync_pipe_input_cb: child has closed sync_pipe");
868 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
869 "sync_pipe_input_cb: error reading from sync pipe");
871 /* The child has closed the sync pipe, meaning it's not going to be
872 capturing any more packets. Pick up its exit status, and
873 complain if it did anything other than exit with status 0.
875 We don't have to worry about killing the child, if the sync pipe
876 returned an error. Usually this error is caused as the child killed itself
877 while going down. Even in the rare cases that this isn't the case,
878 the child will get an error when writing to the broken pipe the next time,
879 cleaning itself up then. */
880 sync_pipe_wait_for_child(capture_opts);
883 eth_close(capture_opts->signal_pipe_write_fd);
885 capture_input_closed(capture_opts);
889 /* we got a valid message block from the child, process it */
892 if(!capture_input_new_file(capture_opts, buffer)) {
893 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
895 /* We weren't able to open the new capture file; user has been
896 alerted. Close the sync pipe. */
899 /* the child has send us a filename which we couldn't open.
900 this probably means, the child is creating files faster than we can handle it.
901 this should only be the case for very fast file switches
902 we can't do much more than telling the child to stop
903 (this is the "emergency brake" if user e.g. wants to switch files every second) */
904 sync_pipe_stop(capture_opts);
907 case SP_PACKET_COUNT:
908 nread = atoi(buffer);
909 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
910 capture_input_new_packets(capture_opts, nread);
913 /* convert primary message */
914 pipe_convert_header(buffer, 4, &indicator, &primary_len);
915 primary_msg = buffer+4;
916 /* convert secondary message */
917 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
918 secondary_msg = primary_msg + primary_len + 4;
920 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
921 /* the capture child will close the sync_pipe, nothing to do for now */
922 /* (an error message doesn't mean we have to stop capturing) */
925 capture_input_cfilter_error_message(capture_opts, buffer);
926 /* the capture child will close the sync_pipe, nothing to do for now */
929 capture_input_drops(capture_opts, atoi(buffer));
932 g_assert_not_reached();
940 /* the child process is going down, wait until it's completely terminated */
942 sync_pipe_wait_for_child(capture_options *capture_opts)
947 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
948 g_assert(capture_opts->fork_child != -1);
951 if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
952 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
953 "Child capture process stopped unexpectedly (errno:%u)", errno);
956 if (wait(&wstatus) != -1) {
957 if (WIFEXITED(wstatus)) {
958 /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
959 /* the child will inform us about errors through the sync_pipe, which will popup */
960 /* an error message, so don't popup another one */
962 /* If there are situations where the child won't send us such an error message, */
963 /* this should be fixed in the child and not here! */
964 if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
965 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
966 "Child capture process exited: exit status %d",
967 WEXITSTATUS(wstatus));
969 } else if (WIFSTOPPED(wstatus)) {
970 /* It stopped, rather than exiting. "Should not happen." */
971 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
972 "Child capture process stopped: %s",
973 sync_pipe_signame(WSTOPSIG(wstatus)));
974 } else if (WIFSIGNALED(wstatus)) {
975 /* It died with a signal. */
976 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
977 "Child capture process died: %s%s",
978 sync_pipe_signame(WTERMSIG(wstatus)),
979 WCOREDUMP(wstatus) ? " - core dumped" : "");
981 /* What? It had to either have exited, or stopped, or died with
982 a signal; what happened here? */
983 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
984 "Child capture process died: wait status %#o", wstatus);
989 /* No more child process. */
990 capture_opts->fork_child = -1;
992 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
997 /* convert signal to corresponding name */
999 sync_pipe_signame(int sig)
1002 static char sigmsg_buf[6+1+3+1];
1011 sigmsg = "Interrupted";
1019 sigmsg = "Illegal instruction";
1023 sigmsg = "Trace trap";
1031 sigmsg = "Arithmetic exception";
1039 sigmsg = "Bus error";
1043 sigmsg = "Segmentation violation";
1046 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1047 Linux is POSIX compliant. These are not POSIX-defined signals ---
1048 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1050 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1051 were omitted from POSIX.1 because their behavior is
1052 implementation dependent and could not be adequately catego-
1053 rized. Conforming implementations may deliver these sig-
1054 nals, but must document the circumstances under which they
1055 are delivered and note any restrictions concerning their
1058 So we only check for SIGSYS on those systems that happen to
1059 implement them (a system can be POSIX-compliant and implement
1060 them, it's just that POSIX doesn't *require* a POSIX-compliant
1061 system to implement them).
1066 sigmsg = "Bad system call";
1071 sigmsg = "Broken pipe";
1075 sigmsg = "Alarm clock";
1079 sigmsg = "Terminated";
1083 /* Returning a static buffer is ok in the context we use it here */
1084 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1085 sigmsg = sigmsg_buf;
1094 /* tell the child through the signal pipe that we want to quit the capture */
1096 signal_pipe_capquit_to_child(capture_options *capture_opts)
1098 const char quit_msg[] = "QUIT";
1102 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1104 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1105 /* simply sending a "QUIT" string */
1106 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1107 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1109 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1110 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1116 /* user wants to stop the capture run */
1118 sync_pipe_stop(capture_options *capture_opts)
1120 if (capture_opts->fork_child != -1) {
1122 /* send the SIGUSR1 signal to close the capture child gracefully. */
1123 kill(capture_opts->fork_child, SIGUSR1);
1125 /* Win32 doesn't have the kill() system call, use the special signal pipe
1126 instead to close the capture child gracefully. */
1127 signal_pipe_capquit_to_child(capture_opts);
1133 /* Wireshark has to exit, force the capture child to close */
1135 sync_pipe_kill(int fork_child)
1137 if (fork_child != -1) {
1139 kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1141 /* Remark: This is not the preferred method of closing a process!
1142 * the clean way would be getting the process id of the child process,
1143 * then getting window handle hWnd of that process (using EnumChildWindows),
1144 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1146 * Unfortunately, I don't know how to get the process id from the
1147 * handle. OpenProcess will get an handle (not a window handle)
1148 * from the process ID; it will not get a window handle from the
1149 * process ID. (How could it? A process can have more than one
1150 * window. For that matter, a process might have *no* windows,
1151 * as a process running dumpcap, the normal child process program,
1154 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1155 * running in the same console; that's not necessarily the case for
1156 * us, as we might not be running in a console.
1157 * And this also will require to have the process id.
1159 TerminateProcess((HANDLE) (fork_child), 0);
1164 #endif /* HAVE_LIBPCAP */