2 * Synchronisation between Wireshark capture parent and child instances
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include <wsutil/strtoi.h>
37 #include <wsutil/unicode-utils.h>
38 #include <wsutil/win32-utils.h>
41 #ifdef HAVE_SYS_WAIT_H
42 # include <sys/wait.h>
45 #include "caputils/capture-pcap-util.h"
49 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
50 * macros) on UNIX systems that don't have them.
53 # define WIFEXITED(status) (((status) & 0177) == 0)
56 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
59 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
62 # define WEXITSTATUS(status) ((status) >> 8)
65 # define WTERMSIG(status) ((status) & 0177)
68 # define WCOREDUMP(status) ((status) & 0200)
71 # define WSTOPSIG(status) ((status) >> 8)
75 #include <epan/packet.h>
76 #include <epan/prefs.h>
81 #include "ui/capture.h"
82 #include <capchild/capture_sync.h>
84 #include "sync_pipe.h"
87 #include "caputils/capture-wpcap.h"
90 #include "ui/ui_util.h"
92 #include <wsutil/filesystem.h>
93 #include <wsutil/file_util.h>
94 #include <wsutil/report_err.h>
101 #include <process.h> /* For spawning child process */
107 static void create_dummy_signal_pipe();
108 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
109 static gchar *dummy_control_id;
111 static const char *sync_pipe_signame(int);
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static int sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp);
117 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
118 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
121 static void (*fetch_dumpcap_pid)(ws_process_id) = NULL;
125 capture_session_init(capture_session *cap_session, struct _capture_file *cf)
127 cap_session->cf = cf;
128 cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
130 cap_session->signal_pipe_write_fd = -1;
132 cap_session->state = CAPTURE_STOPPED;
134 cap_session->owner = getuid();
135 cap_session->group = getgid();
137 cap_session->count = 0;
138 cap_session->session_started = FALSE;
141 /* Append an arg (realloc) to an argc/argv array */
142 /* (add a string pointer to a NULL-terminated array of string pointers) */
144 sync_pipe_add_arg(char **args, int *argc, const char *arg)
146 /* Grow the array; "*argc" currently contains the number of string
147 pointers, *not* counting the NULL pointer at the end, so we have
148 to add 2 in order to get the new size of the array, including the
149 new pointer and the terminating NULL pointer. */
150 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
152 /* Stuff the pointer into the penultimate element of the array, which
153 is the one at the index specified by "*argc". */
154 args[*argc] = g_strdup(arg);
155 /* Now bump the count. */
158 /* We overwrite the NULL pointer; put it back right after the
165 /* Initialize an argument list and add dumpcap to it. */
167 init_pipe_args(int *argc) {
169 const char *progfile_dir;
172 progfile_dir = get_progfile_dir();
173 if (progfile_dir == NULL) {
177 /* Allocate the string pointer array with enough space for the
178 terminating NULL pointer. */
180 argv = (char **)g_malloc(sizeof (char *));
183 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
185 exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
187 exename = g_strdup_printf("%s/dumpcap", progfile_dir);
190 /* Make that the first argument in the argument list (argv[0]). */
191 argv = sync_pipe_add_arg(argv, argc, exename);
193 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
199 #define ARGV_NUMBER_LEN 24
200 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
202 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void (*update_cb)(void))
204 char ssnap[ARGV_NUMBER_LEN];
205 char scount[ARGV_NUMBER_LEN];
206 char sfilesize[ARGV_NUMBER_LEN];
207 char sfile_duration[ARGV_NUMBER_LEN];
208 char sring_num_files[ARGV_NUMBER_LEN];
209 char sautostop_files[ARGV_NUMBER_LEN];
210 char sautostop_filesize[ARGV_NUMBER_LEN];
211 char sautostop_duration[ARGV_NUMBER_LEN];
212 #ifdef HAVE_PCAP_REMOTE
215 #ifdef HAVE_PCAP_SETSAMPLING
216 char ssampling[ARGV_NUMBER_LEN];
219 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
220 char buffer_size[ARGV_NUMBER_LEN];
224 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
225 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
226 int signal_pipe_write_fd;
227 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
228 GString *args = g_string_sized_new(200);
230 gunichar2 *wcommandline;
231 SECURITY_ATTRIBUTES sa;
233 PROCESS_INFORMATION pi;
234 char control_id[ARGV_NUMBER_LEN];
235 gchar *signal_pipe_name;
238 int sync_pipe[2]; /* pipe used to send messages from child to parent */
239 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
241 int sync_pipe_read_fd;
246 interface_options interface_opts;
248 if (capture_opts->ifaces->len > 1)
249 capture_opts->use_pcapng = TRUE;
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 cap_session->fork_child = WS_INVALID_PID;
256 if (!extcap_init_interfaces(capture_opts)) {
257 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
263 argv = init_pipe_args(&argc);
265 /* We don't know where to find dumpcap. */
266 report_failure("We don't know where to find dumpcap.");
270 if (capture_opts->ifaces->len > 1)
271 argv = sync_pipe_add_arg(argv, &argc, "-t");
273 if (capture_opts->use_pcapng)
274 argv = sync_pipe_add_arg(argv, &argc, "-n");
276 argv = sync_pipe_add_arg(argv, &argc, "-P");
278 if (capture_opts->capture_comment) {
279 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
280 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
283 if (capture_opts->multi_files_on) {
284 if (capture_opts->has_autostop_filesize) {
285 argv = sync_pipe_add_arg(argv, &argc, "-b");
286 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
287 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
290 if (capture_opts->has_file_duration) {
291 argv = sync_pipe_add_arg(argv, &argc, "-b");
292 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
293 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
296 if (capture_opts->has_ring_num_files) {
297 argv = sync_pipe_add_arg(argv, &argc, "-b");
298 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
299 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
302 if (capture_opts->has_autostop_files) {
303 argv = sync_pipe_add_arg(argv, &argc, "-a");
304 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
305 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
308 if (capture_opts->has_autostop_filesize) {
309 argv = sync_pipe_add_arg(argv, &argc, "-a");
310 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
311 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
315 if (capture_opts->has_autostop_packets) {
316 argv = sync_pipe_add_arg(argv, &argc, "-c");
317 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
318 argv = sync_pipe_add_arg(argv, &argc, scount);
321 if (capture_opts->has_autostop_duration) {
322 argv = sync_pipe_add_arg(argv, &argc, "-a");
323 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
324 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
327 if (capture_opts->group_read_access) {
328 argv = sync_pipe_add_arg(argv, &argc, "-g");
331 for (j = 0; j < capture_opts->ifaces->len; j++) {
332 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
334 argv = sync_pipe_add_arg(argv, &argc, "-i");
336 if (interface_opts.extcap_fifo != NULL)
337 argv = sync_pipe_add_arg(argv, &argc, interface_opts.extcap_fifo);
340 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
342 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
343 argv = sync_pipe_add_arg(argv, &argc, "-f");
344 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
346 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
347 argv = sync_pipe_add_arg(argv, &argc, "-s");
348 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
349 argv = sync_pipe_add_arg(argv, &argc, ssnap);
352 if (interface_opts.linktype != -1) {
353 const char *linktype = linktype_val_to_name(interface_opts.linktype);
354 if ( linktype != NULL )
356 argv = sync_pipe_add_arg(argv, &argc, "-y");
357 argv = sync_pipe_add_arg(argv, &argc, linktype);
361 if (!interface_opts.promisc_mode) {
362 argv = sync_pipe_add_arg(argv, &argc, "-p");
365 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
366 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
367 argv = sync_pipe_add_arg(argv, &argc, "-B");
368 if(interface_opts.buffer_size == 0x00)
369 interface_opts.buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
370 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
371 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
375 #ifdef HAVE_PCAP_CREATE
376 if (interface_opts.monitor_mode) {
377 argv = sync_pipe_add_arg(argv, &argc, "-I");
381 #ifdef HAVE_PCAP_REMOTE
382 if (interface_opts.datatx_udp)
383 argv = sync_pipe_add_arg(argv, &argc, "-u");
385 if (!interface_opts.nocap_rpcap)
386 argv = sync_pipe_add_arg(argv, &argc, "-r");
388 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
389 argv = sync_pipe_add_arg(argv, &argc, "-A");
390 g_snprintf(sauth, sizeof(sauth), "%s:%s",
391 interface_opts.auth_username,
392 interface_opts.auth_password);
393 argv = sync_pipe_add_arg(argv, &argc, sauth);
397 #ifdef HAVE_PCAP_SETSAMPLING
398 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
399 argv = sync_pipe_add_arg(argv, &argc, "-m");
400 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
401 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
402 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
404 interface_opts.sampling_param);
405 argv = sync_pipe_add_arg(argv, &argc, ssampling);
410 /* dumpcap should be running in capture child mode (hidden feature) */
412 argv = sync_pipe_add_arg(argv, &argc, "-Z");
414 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
415 argv = sync_pipe_add_arg(argv, &argc, control_id);
417 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
421 if (capture_opts->save_file) {
422 argv = sync_pipe_add_arg(argv, &argc, "-w");
423 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
425 for (i = 0; i < argc; i++) {
426 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
430 /* init SECURITY_ATTRIBUTES */
431 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
432 sa.bInheritHandle = TRUE;
433 sa.lpSecurityDescriptor = NULL;
435 /* Create a pipe for the child process */
436 /* (increase this value if you have trouble while fast capture file switches) */
437 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
438 /* Couldn't create the pipe between parent and child. */
439 report_failure("Couldn't create sync pipe: %s",
440 win32strerror(GetLastError()));
441 for (i = 0; i < argc; i++) {
442 g_free( (gpointer) argv[i]);
444 g_free( (gpointer) argv);
449 * Associate a C run-time file handle with the Windows HANDLE for the
450 * read side of the message pipe.
452 * (See http://www.flounder.com/handles.htm for information on various
453 * types of file handle in C/C++ on Windows.)
455 sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
456 if (sync_pipe_read_fd == -1) {
457 /* Couldn't create the pipe between parent and child. */
458 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
459 CloseHandle(sync_pipe_read);
460 CloseHandle(sync_pipe_write);
461 for (i = 0; i < argc; i++) {
462 g_free( (gpointer) argv[i]);
468 /* Create the signal pipe */
469 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
470 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
471 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
472 g_free(signal_pipe_name);
474 if (signal_pipe == INVALID_HANDLE_VALUE) {
475 /* Couldn't create the signal pipe between parent and child. */
476 report_failure("Couldn't create signal pipe: %s",
477 win32strerror(GetLastError()));
478 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
479 CloseHandle(sync_pipe_write);
480 for (i = 0; i < argc; i++) {
481 g_free( (gpointer) argv[i]);
483 g_free( (gpointer) argv);
488 * Associate a C run-time file handle with the Windows HANDLE for the
489 * read side of the message pipe.
491 * (See http://www.flounder.com/handles.htm for information on various
492 * types of file handle in C/C++ on Windows.)
494 signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
495 if (sync_pipe_read_fd == -1) {
496 /* Couldn't create the pipe between parent and child. */
497 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
498 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
499 CloseHandle(sync_pipe_write);
500 CloseHandle(signal_pipe);
501 for (i = 0; i < argc; i++) {
502 g_free( (gpointer) argv[i]);
508 /* init STARTUPINFO & PROCESS_INFORMATION */
509 memset(&si, 0, sizeof(si));
511 memset(&pi, 0, sizeof(pi));
513 si.dwFlags = STARTF_USESHOWWINDOW;
514 si.wShowWindow = SW_SHOW;
516 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
517 si.wShowWindow = SW_HIDE; /* this hides the console window */
519 /* needs first a check if NULL *
520 * otherwise wouldn't work with non extcap interfaces */
521 if(interface_opts.extcap_fifo != NULL)
523 if(strncmp(interface_opts.extcap_fifo,"\\\\.\\pipe\\",9)== 0)
525 si.hStdInput = extcap_get_win32_handle();
530 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
532 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
533 si.hStdError = sync_pipe_write;
534 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
537 /* convert args array into a single string */
538 /* XXX - could change sync_pipe_add_arg() instead */
539 /* there is a drawback here: the length is internally limited to 1024 bytes */
540 for(i=0; argv[i] != 0; i++) {
541 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
542 quoted_arg = protect_arg(argv[i]);
543 g_string_append(args, quoted_arg);
546 wcommandline = g_utf8_to_utf16(args->str, (glong)args->len, NULL, NULL, NULL);
549 if(!CreateProcess(utf_8to16(argv[0]), wcommandline, NULL, NULL, TRUE,
550 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
551 report_failure("Couldn't run %s in child process: %s",
552 args->str, win32strerror(GetLastError()));
553 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
554 CloseHandle(sync_pipe_write);
555 CloseHandle(signal_pipe);
556 for (i = 0; i < argc; i++) {
557 g_free( (gpointer) argv[i]);
559 g_free( (gpointer) argv);
560 g_string_free(args, TRUE);
561 g_free(wcommandline);
564 cap_session->fork_child = pi.hProcess;
565 /* We may need to store this and close it later */
566 CloseHandle(pi.hThread);
567 g_string_free(args, TRUE);
568 g_free(wcommandline);
570 cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
573 if (pipe(sync_pipe) < 0) {
574 /* Couldn't create the pipe between parent and child. */
575 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
576 for (i = 0; i < argc; i++) {
577 g_free( (gpointer) argv[i]);
583 if ((cap_session->fork_child = fork()) == 0) {
585 * Child process - run dumpcap with the right arguments to make
586 * it just capture with the specified capture parameters
588 dup2(sync_pipe[PIPE_WRITE], 2);
589 ws_close(sync_pipe[PIPE_READ]);
590 execv(argv[0], argv);
591 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
592 argv[0], g_strerror(errno));
593 sync_pipe_errmsg_to_parent(2, errmsg, "");
595 /* Exit with "_exit()", so that we don't close the connection
596 to the X server (and cause stuff buffered up by our parent but
597 not yet sent to be sent, as that stuff should only be sent by
598 our parent). We've sent an error message to the parent, so
599 we exit with an exit status of 1 (any exit status other than
600 0 or 1 will cause an additional message to report that exit
601 status, over and above the error message we sent to the parent). */
605 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
606 fetch_dumpcap_pid(cap_session->fork_child);
608 sync_pipe_read_fd = sync_pipe[PIPE_READ];
611 for (i = 0; i < argc; i++) {
612 g_free( (gpointer) argv[i]);
615 /* Parent process - read messages from the child process over the
617 g_free( (gpointer) argv); /* free up arg array */
619 /* Close the write side of the pipe, so that only the child has it
620 open, and thus it completely closes, and thus returns to us
621 an EOF indication, if the child closes it (either deliberately
622 or by exiting abnormally). */
624 CloseHandle(sync_pipe_write);
626 ws_close(sync_pipe[PIPE_WRITE]);
629 if (cap_session->fork_child == WS_INVALID_PID) {
630 /* We couldn't even create the child process. */
631 report_failure("Couldn't create child process: %s", g_strerror(errno));
632 ws_close(sync_pipe_read_fd);
634 ws_close(cap_session->signal_pipe_write_fd);
639 cap_session->fork_child_status = 0;
640 cap_session->capture_opts = capture_opts;
641 cap_session->cap_data_info = cap_data;
643 /* we might wait for a moment till child is ready, so update screen now */
644 if (update_cb) update_cb();
646 /* We were able to set up to read the capture file;
647 arrange that our callback be called whenever it's possible
648 to read from the sync pipe, so that it's called when
649 the child process wants to tell us something. */
651 /* we have a running capture, now wait for the real capture filename */
652 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
653 &cap_session->fork_child, sync_pipe_input_cb);
659 * Open two pipes to dumpcap with the supplied arguments, one for its
660 * standard output and one for its standard error.
662 * On success, *msg is unchanged and 0 is returned; data_read_fd,
663 * message_read_fd, and fork_child point to the standard output pipe's
664 * file descriptor, the standard error pipe's file descriptor, and
665 * the child's PID/handle, respectively.
667 * On failure, *msg points to an error message for the failure, and -1 is
668 * returned, in which case *msg must be freed with g_free().
670 /* XXX - This duplicates a lot of code in sync_pipe_start() */
671 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
672 #define PIPE_BUF_SIZE 5120
674 sync_pipe_open_command(char** argv, int *data_read_fd,
675 int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
677 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
679 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
680 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
681 GString *args = g_string_sized_new(200);
683 gunichar2 *wcommandline;
684 SECURITY_ATTRIBUTES sa;
686 PROCESS_INFORMATION pi;
689 int sync_pipe[2]; /* pipe used to send messages from child to parent */
690 int data_pipe[2]; /* pipe used to send data from child to parent */
693 *fork_child = WS_INVALID_PID;
695 *message_read_fd = -1;
696 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
699 /* We can't return anything */
701 g_string_free(args, TRUE);
707 /* init SECURITY_ATTRIBUTES */
708 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
709 sa.bInheritHandle = TRUE;
710 sa.lpSecurityDescriptor = NULL;
712 /* Create a pipe for the child process to send us messages */
713 /* (increase this value if you have trouble while fast capture file switches) */
714 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
715 /* Couldn't create the message pipe between parent and child. */
716 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
717 win32strerror(GetLastError()));
718 for (i = 0; argv[i] != NULL; i++) {
719 g_free( (gpointer) argv[i]);
721 g_free( (gpointer) argv);
726 * Associate a C run-time file handle with the Windows HANDLE for the
727 * read side of the message pipe.
729 * (See http://www.flounder.com/handles.htm for information on various
730 * types of file handle in C/C++ on Windows.)
732 *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
733 if (*message_read_fd == -1) {
734 *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
735 CloseHandle(sync_pipe[PIPE_READ]);
736 CloseHandle(sync_pipe[PIPE_WRITE]);
737 for (i = 0; argv[i] != NULL; i++) {
738 g_free( (gpointer) argv[i]);
740 g_free( (gpointer) argv);
744 /* Create a pipe for the child process to send us data */
745 /* (increase this value if you have trouble while fast capture file switches) */
746 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
747 /* Couldn't create the message pipe between parent and child. */
748 *msg = g_strdup_printf("Couldn't create data pipe: %s",
749 win32strerror(GetLastError()));
750 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
751 CloseHandle(sync_pipe[PIPE_WRITE]);
752 for (i = 0; argv[i] != NULL; i++) {
753 g_free( (gpointer) argv[i]);
755 g_free( (gpointer) argv);
760 * Associate a C run-time file handle with the Windows HANDLE for the
761 * read side of the data pipe.
763 * (See http://www.flounder.com/handles.htm for information on various
764 * types of file handle in C/C++ on Windows.)
766 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
767 if (*data_read_fd == -1) {
768 *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
769 CloseHandle(data_pipe[PIPE_READ]);
770 CloseHandle(data_pipe[PIPE_WRITE]);
771 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
772 CloseHandle(sync_pipe[PIPE_WRITE]);
773 for (i = 0; argv[i] != NULL; i++) {
774 g_free( (gpointer) argv[i]);
776 g_free( (gpointer) argv);
780 /* init STARTUPINFO & PROCESS_INFORMATION */
781 memset(&si, 0, sizeof(si));
783 memset(&pi, 0, sizeof(pi));
785 si.dwFlags = STARTF_USESHOWWINDOW;
786 si.wShowWindow = SW_SHOW;
788 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
789 si.wShowWindow = SW_HIDE; /* this hides the console window */
790 si.hStdInput = NULL; /* handle for named pipe*/
792 si.hStdOutput = data_pipe[PIPE_WRITE];
793 si.hStdError = sync_pipe[PIPE_WRITE];
796 /* convert args array into a single string */
797 /* XXX - could change sync_pipe_add_arg() instead */
798 /* there is a drawback here: the length is internally limited to 1024 bytes */
799 for(i=0; argv[i] != 0; i++) {
800 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
801 quoted_arg = protect_arg(argv[i]);
802 g_string_append(args, quoted_arg);
805 wcommandline = g_utf8_to_utf16(args->str, (glong)args->len, NULL, NULL, NULL);
808 if(!CreateProcess(utf_8to16(argv[0]), wcommandline, NULL, NULL, TRUE,
809 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
810 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
811 args->str, win32strerror(GetLastError()));
812 ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
813 CloseHandle(data_pipe[PIPE_WRITE]);
814 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
815 CloseHandle(sync_pipe[PIPE_WRITE]);
816 for (i = 0; argv[i] != NULL; i++) {
817 g_free( (gpointer) argv[i]);
819 g_free( (gpointer) argv);
820 g_string_free(args, TRUE);
821 g_free(wcommandline);
824 *fork_child = pi.hProcess;
825 /* We may need to store this and close it later */
826 CloseHandle(pi.hThread);
827 g_string_free(args, TRUE);
828 g_free(wcommandline);
830 /* Create a pipe for the child process to send us messages */
831 if (pipe(sync_pipe) < 0) {
832 /* Couldn't create the message pipe between parent and child. */
833 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
834 for (i = 0; argv[i] != NULL; i++) {
835 g_free( (gpointer) argv[i]);
841 /* Create a pipe for the child process to send us data */
842 if (pipe(data_pipe) < 0) {
843 /* Couldn't create the data pipe between parent and child. */
844 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
845 ws_close(sync_pipe[PIPE_READ]);
846 ws_close(sync_pipe[PIPE_WRITE]);
847 for (i = 0; argv[i] != NULL; i++) {
848 g_free( (gpointer) argv[i]);
854 if ((*fork_child = fork()) == 0) {
856 * Child process - run dumpcap with the right arguments to make
857 * it just capture with the specified capture parameters
859 dup2(data_pipe[PIPE_WRITE], 1);
860 ws_close(data_pipe[PIPE_READ]);
861 ws_close(data_pipe[PIPE_WRITE]);
862 dup2(sync_pipe[PIPE_WRITE], 2);
863 ws_close(sync_pipe[PIPE_READ]);
864 ws_close(sync_pipe[PIPE_WRITE]);
865 execv(argv[0], argv);
866 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
867 argv[0], g_strerror(errno));
868 sync_pipe_errmsg_to_parent(2, errmsg, "");
870 /* Exit with "_exit()", so that we don't close the connection
871 to the X server (and cause stuff buffered up by our parent but
872 not yet sent to be sent, as that stuff should only be sent by
873 our parent). We've sent an error message to the parent, so
874 we exit with an exit status of 1 (any exit status other than
875 0 or 1 will cause an additional message to report that exit
876 status, over and above the error message we sent to the parent). */
880 if (fetch_dumpcap_pid && *fork_child > 0)
881 fetch_dumpcap_pid(*fork_child);
883 *data_read_fd = data_pipe[PIPE_READ];
884 *message_read_fd = sync_pipe[PIPE_READ];
887 for (i = 0; argv[i] != NULL; i++) {
888 g_free( (gpointer) argv[i]);
891 /* Parent process - read messages from the child process over the
893 g_free( (gpointer) argv); /* free up arg array */
895 /* Close the write sides of the pipes, so that only the child has them
896 open, and thus they completely close, and thus return to us
897 an EOF indication, if the child closes them (either deliberately
898 or by exiting abnormally). */
900 CloseHandle(data_pipe[PIPE_WRITE]);
901 CloseHandle(sync_pipe[PIPE_WRITE]);
903 ws_close(data_pipe[PIPE_WRITE]);
904 ws_close(sync_pipe[PIPE_WRITE]);
907 if (*fork_child == WS_INVALID_PID) {
908 /* We couldn't even create the child process. */
909 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
910 ws_close(*data_read_fd);
911 ws_close(*message_read_fd);
915 /* we might wait for a moment till child is ready, so update screen now */
916 if (update_cb) update_cb();
921 * Close the pipes we're using to read from dumpcap, and wait for it
922 * to exit. On success, *msgp is unchanged, and the exit status of
923 * dumpcap is returned. On failure (which includes "dumpcap exited
924 * due to being killed by a signal or an exception"), *msgp points
925 * to an error message for the failure, and -1 is returned. In the
926 * latter case, *msgp must be freed with g_free().
929 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
930 ws_process_id *fork_child, gchar **msgp)
932 ws_close(*data_read_fd);
933 if (message_read_fd != NULL)
934 ws_close(*message_read_fd);
937 /* XXX - Should we signal the child somehow? */
938 sync_pipe_kill(*fork_child);
941 return sync_pipe_wait_for_child(*fork_child, msgp);
945 * Run dumpcap with the supplied arguments.
947 * On success, *data points to a buffer containing the dumpcap output,
948 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
949 * must be freed with g_free().
951 * On failure, *data is NULL, *primary_msg points to an error message,
952 * *secondary_msg either points to an additional error message or is
953 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
954 * must be freed with g_free().
956 /* XXX - This duplicates a lot of code in sync_pipe_start() */
957 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
958 #define PIPE_BUF_SIZE 5120
960 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
961 gchar **secondary_msg, void(*update_cb)(void))
964 int data_pipe_read_fd, sync_pipe_read_fd, ret;
965 ws_process_id fork_child;
967 gchar buffer[PIPE_BUF_SIZE+1] = {0};
971 char *primary_msg_text;
972 int secondary_msg_len;
973 char *secondary_msg_text;
975 GString *data_buf = NULL;
978 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
979 &fork_child, &msg, update_cb);
982 *secondary_msg = NULL;
988 * We were able to set up to read dumpcap's output. Do so.
990 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
992 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
993 buffer, primary_msg);
995 /* We got a read error from the sync pipe, or we got no data at
996 all from the sync pipe, so we're not going to be getting any
997 data or error message from the child process. Pick up its
998 exit status, and complain.
1000 We don't have to worry about killing the child, if the sync pipe
1001 returned an error. Usually this error is caused as the child killed
1002 itself while going down. Even in the rare cases that this isn't the
1003 case, the child will get an error when writing to the broken pipe
1004 the next time, cleaning itself up then. */
1005 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1007 /* We got an EOF from the sync pipe. That means that it exited
1008 before giving us any data to read. If ret is -1, we report
1009 that as a bad exit (e.g., exiting due to a signal); otherwise,
1010 we report it as a premature exit. */
1012 *primary_msg = wait_msg;
1014 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1016 /* We got an error from the sync pipe. If ret is -1, report
1017 both the sync pipe I/O error and the wait error. */
1019 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1020 g_free(*primary_msg);
1022 *primary_msg = combined_msg;
1025 *secondary_msg = NULL;
1031 /* we got a valid message block from the child, process it */
1036 * Error from dumpcap; there will be a primary message and a
1037 * secondary message.
1040 /* convert primary message */
1041 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1042 primary_msg_text = buffer+4;
1043 /* convert secondary message */
1044 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1045 &secondary_msg_len);
1046 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1047 /* the capture child will close the sync_pipe, nothing to do */
1050 * Pick up the child status.
1052 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1056 * Child process failed unexpectedly, or wait failed; msg is the
1060 *secondary_msg = NULL;
1063 * Child process failed, but returned the expected exit status.
1064 * Return the messages it gave us, and indicate failure.
1066 *primary_msg = g_strdup(primary_msg_text);
1067 *secondary_msg = g_strdup(secondary_msg_text);
1074 /* read the output from the command */
1075 data_buf = g_string_new("");
1076 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1077 buffer[count] = '\0';
1078 g_string_append(data_buf, buffer);
1082 * Pick up the child status.
1084 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1088 * Child process failed unexpectedly, or wait failed; msg is the
1092 *secondary_msg = NULL;
1093 g_string_free(data_buf, TRUE);
1097 * Child process succeeded.
1099 *primary_msg = NULL;
1100 *secondary_msg = NULL;
1101 *data = g_string_free(data_buf, FALSE);
1107 * Pick up the child status.
1109 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1113 * Child process failed unexpectedly, or wait failed; msg is the
1117 *secondary_msg = NULL;
1120 * Child process returned an unknown status.
1122 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1124 *secondary_msg = NULL;
1133 /* centralised logging and timing for sync_pipe_run_command_actual(),
1134 * redirects to sync_pipe_run_command_actual()
1137 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1138 gchar **secondary_msg, void (*update_cb)(void))
1141 GTimeVal start_time;
1144 int logging_enabled;
1146 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1147 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1148 if(logging_enabled){
1149 g_get_current_time(&start_time);
1150 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1151 for(i=0; argv[i] != 0; i++) {
1152 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1155 /* do the actual sync pipe run command */
1156 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1158 if(logging_enabled){
1159 g_get_current_time(&end_time);
1160 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1161 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1163 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1171 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1172 const gchar *center_freq1, const gchar *center_freq2,
1173 gchar **data, gchar **primary_msg,
1174 gchar **secondary_msg, void (*update_cb)(void))
1180 argv = init_pipe_args(&argc);
1183 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1184 *secondary_msg = NULL;
1189 argv = sync_pipe_add_arg(argv, &argc, "-i");
1190 argv = sync_pipe_add_arg(argv, &argc, iface);
1193 opt = g_strdup_printf("%s,%s,%s,%s", freq, type, center_freq1, center_freq2);
1195 opt = g_strdup(freq);
1198 *primary_msg = g_strdup("Out of mem.");
1199 *secondary_msg = NULL;
1204 argv = sync_pipe_add_arg(argv, &argc, "-k");
1205 argv = sync_pipe_add_arg(argv, &argc, opt);
1208 /* Run dumpcap in capture child mode */
1209 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1210 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1213 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1219 * Get the list of interfaces using dumpcap.
1221 * On success, *data points to a buffer containing the dumpcap output,
1222 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1223 * must be freed with g_free().
1225 * On failure, *data is NULL, *primary_msg points to an error message,
1226 * *secondary_msg either points to an additional error message or is
1227 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1228 * must be freed with g_free().
1231 sync_interface_list_open(gchar **data, gchar **primary_msg,
1232 gchar **secondary_msg, void (*update_cb)(void))
1237 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1239 argv = init_pipe_args(&argc);
1242 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1243 *secondary_msg = NULL;
1248 /* Ask for the interface list */
1249 argv = sync_pipe_add_arg(argv, &argc, "-D");
1252 /* Run dumpcap in capture child mode */
1253 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1254 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1256 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1260 * Get the capabilities of an interface using dumpcap.
1262 * On success, *data points to a buffer containing the dumpcap output,
1263 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1264 * must be freed with g_free().
1266 * On failure, *data is NULL, *primary_msg points to an error message,
1267 * *secondary_msg either points to an additional error message or is
1268 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1269 * must be freed with g_free().
1272 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gchar* auth,
1273 gchar **data, gchar **primary_msg,
1274 gchar **secondary_msg, void (*update_cb)(void))
1279 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1281 argv = init_pipe_args(&argc);
1284 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1285 *secondary_msg = NULL;
1290 /* Ask for the interface capabilities */
1291 argv = sync_pipe_add_arg(argv, &argc, "-i");
1292 argv = sync_pipe_add_arg(argv, &argc, ifname);
1293 argv = sync_pipe_add_arg(argv, &argc, "-L");
1295 argv = sync_pipe_add_arg(argv, &argc, "-I");
1297 argv = sync_pipe_add_arg(argv, &argc, "-A");
1298 argv = sync_pipe_add_arg(argv, &argc, auth);
1302 /* Run dumpcap in capture child mode */
1303 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1304 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1306 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1310 * Start getting interface statistics using dumpcap. On success, read_fd
1311 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1312 * and zero is returned. On failure, *msg will point to an error message
1313 * that must be g_free()d, and -1 will be returned.
1316 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1320 int message_read_fd, ret;
1322 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1325 int primary_msg_len;
1326 char *primary_msg_text;
1327 int secondary_msg_len;
1328 /*char *secondary_msg_text;*/
1331 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1333 argv = init_pipe_args(&argc);
1336 *msg = g_strdup("We don't know where to find dumpcap.");
1340 /* Ask for the interface statistics */
1341 argv = sync_pipe_add_arg(argv, &argc, "-S");
1344 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1346 create_dummy_signal_pipe();
1347 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1349 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1352 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1353 fork_child, msg, update_cb);
1358 * We were able to set up to read dumpcap's output. Do so.
1360 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1362 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1365 /* We got a read error from the sync pipe, or we got no data at
1366 all from the sync pipe, so we're not going to be getting any
1367 data or error message from the child process. Pick up its
1368 exit status, and complain.
1370 We don't have to worry about killing the child, if the sync pipe
1371 returned an error. Usually this error is caused as the child killed
1372 itself while going down. Even in the rare cases that this isn't the
1373 case, the child will get an error when writing to the broken pipe
1374 the next time, cleaning itself up then. */
1375 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1376 ws_close(message_read_fd);
1377 ws_close(*data_read_fd);
1379 /* We got an EOF from the sync pipe. That means that it exited
1380 before giving us any data to read. If ret is -1, we report
1381 that as a bad exit (e.g., exiting due to a signal); otherwise,
1382 we report it as a premature exit. */
1386 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1388 /* We got an error from the sync pipe. If ret is -1, report
1389 both the sync pipe I/O error and the wait error. */
1391 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1394 *msg = combined_msg;
1401 /* we got a valid message block from the child, process it */
1406 * Error from dumpcap; there will be a primary message and a
1407 * secondary message.
1410 /* convert primary message */
1411 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1412 primary_msg_text = buffer+4;
1413 /* convert secondary message */
1414 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1415 &secondary_msg_len);
1416 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1417 /* the capture child will close the sync_pipe, nothing to do */
1420 * Pick up the child status.
1422 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1426 * Child process failed unexpectedly, or wait failed; msg is the
1431 * Child process failed, but returned the expected exit status.
1432 * Return the messages it gave us, and indicate failure.
1434 *msg = g_strdup(primary_msg_text);
1440 /* Close the message pipe. */
1441 ws_close(message_read_fd);
1446 * Pick up the child status.
1448 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1452 * Child process failed unexpectedly, or wait failed; msg is the
1457 * Child process returned an unknown status.
1459 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1468 /* Close down the stats process */
1470 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1474 * Don't bother waiting for the child. sync_pipe_close_command
1475 * does this for us on Windows.
1477 sync_pipe_kill(*fork_child);
1479 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1482 /* read a number of bytes from a pipe */
1483 /* (blocks until enough bytes read or an error occurs) */
1485 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1492 newly = ws_read(pipe_fd, &bytes[offset], required);
1495 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1496 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1503 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1504 "read from pipe %d: error(%u): %s", pipe_fd, error,
1506 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1511 required -= (int)newly;
1519 static gboolean pipe_data_available(int pipe_fd) {
1520 #ifdef _WIN32 /* PeekNamedPipe */
1521 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1524 if (hPipe == INVALID_HANDLE_VALUE)
1527 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1530 if (bytes_avail > 0)
1535 struct timeval timeout;
1538 FD_SET(pipe_fd, &rfds);
1540 timeout.tv_usec = 0;
1542 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1549 /* Read a line from a pipe, similar to fgets */
1551 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1555 while(offset < max - 1) {
1557 if (! pipe_data_available(pipe_fd))
1559 newly = ws_read(pipe_fd, &bytes[offset], 1);
1561 /* EOF - not necessarily an error */
1563 } else if (newly == -1) {
1565 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1566 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1568 } else if (bytes[offset] == '\n') {
1574 bytes[offset] = '\0';
1580 /* convert header values (indicator and 3-byte length) */
1582 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1584 g_assert(header_len == 4);
1586 /* convert header values */
1587 *indicator = header[0];
1588 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1591 /* read a message from the sending pipe in the standard format
1592 (1-byte message indicator, 3-byte message length (excluding length
1593 and indicator field), and the rest is the message) */
1595 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1602 /* read header (indicator and 3-byte length) */
1603 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1607 * Immediate EOF; if the capture child exits normally, this
1608 * is an "I'm done" indication, so don't report it as an
1611 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1612 "read %d got an EOF", pipe_fd);
1615 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1616 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1619 * Short read, but not an immediate EOF.
1621 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1627 /* convert header values */
1628 pipe_convert_header((guchar*)header, 4, indicator, &required);
1630 /* only indicator with no value? */
1632 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1633 "read %d indicator: %c empty value", pipe_fd, *indicator);
1637 /* does the data fit into the given buffer? */
1638 if(required > len) {
1639 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1640 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1641 pipe_fd, required, len,
1642 header[0], header[1], header[2], header[3]);
1644 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1645 memcpy(msg, header, sizeof(header));
1646 newly = ws_read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1647 if (newly < 0) { /* error */
1648 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1649 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1651 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1657 /* read the actual block data */
1658 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1659 if(newly != required) {
1661 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1667 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1668 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1669 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1676 /* There's stuff to read from the sync pipe, meaning the child has sent
1677 us a message, or the sync pipe has closed, meaning the child has
1678 closed it (perhaps because it exited). */
1680 sync_pipe_input_cb(gint source, gpointer user_data)
1682 capture_session *cap_session = (capture_session *)user_data;
1684 char buffer[SP_MAX_MSG_LEN+1] = {0};
1690 char *secondary_msg;
1691 char *wait_msg, *combined_msg;
1692 guint32 npackets = 0;
1694 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1697 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1699 If we got a read error or a bad message, nread is -1 and
1700 primary_msg is set to point to an error message. We don't
1701 have to worry about killing the child; usually this error
1702 is caused as the child killed itself while going down.
1703 Even in the rare cases that this isn't the case, the child
1704 will get an error when writing to the broken pipe the next time,
1705 cleaning itself up then.
1707 If we got an EOF, nread is 0 and primary_msg isn't set. This
1708 is an indication that the capture is finished. */
1709 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1711 /* We got an EOF from the sync pipe. That means that the capture
1712 child exited, and not in the middle of a message; we treat
1713 that as an indication that it's done, and only report an
1714 error if ret is -1, in which case wait_msg is the error
1717 primary_msg = wait_msg;
1719 /* We got an error from the sync pipe. If ret is -1, report
1720 both the sync pipe I/O error and the wait error. */
1722 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1723 g_free(primary_msg);
1725 primary_msg = combined_msg;
1729 /* No more child process. */
1730 cap_session->fork_child = WS_INVALID_PID;
1731 cap_session->fork_child_status = ret;
1734 ws_close(cap_session->signal_pipe_write_fd);
1737 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1738 extcap_if_cleanup(cap_session->capture_opts, &primary_msg);
1740 capture_input_closed(cap_session, primary_msg);
1741 g_free(primary_msg);
1745 /* we got a valid message block from the child, process it */
1748 if(!capture_input_new_file(cap_session, buffer)) {
1749 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1751 /* We weren't able to open the new capture file; user has been
1752 alerted. Close the sync pipe. */
1755 /* The child has sent us a filename which we couldn't open.
1757 This could mean that the child is creating and deleting files
1758 (ring buffer mode) faster than we can handle it.
1760 That should only be the case for very fast file switches;
1761 We can't do much more than telling the child to stop.
1762 (This is the "emergency brake" if the user e.g. wants to
1763 switch files every second).
1765 This can also happen if the user specified "-", meaning
1766 "standard output", as the capture file. */
1767 sync_pipe_stop(cap_session);
1768 capture_input_closed(cap_session, NULL);
1772 case SP_PACKET_COUNT:
1773 if (!ws_strtou32(buffer, NULL, &npackets)) {
1774 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "Invalid packets number: %s", buffer);
1776 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1777 cap_session->count += npackets;
1778 capture_input_new_packets(cap_session, npackets);
1781 /* convert primary message */
1782 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1783 primary_msg = buffer+4;
1784 /* convert secondary message */
1785 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1786 secondary_msg = primary_msg + primary_len + 4;
1787 /* message output */
1788 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1789 /* the capture child will close the sync_pipe, nothing to do for now */
1790 /* (an error message doesn't mean we have to stop capturing) */
1792 case SP_BAD_FILTER: {
1796 ch = strtok(buffer, ":");
1798 indx = (int)strtol(ch, NULL, 10);
1799 ch = strtok(NULL, ":");
1801 capture_input_cfilter_error_message(cap_session, indx, ch);
1802 /* the capture child will close the sync_pipe, nothing to do for now */
1806 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1809 g_assert_not_reached();
1818 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1819 * unchanged, and the exit status of dumpcap is returned. On
1820 * failure (which includes "dumpcap exited due to being killed by
1821 * a signal or an exception"), *msgp points to an error message
1822 * for the failure, and -1 is returned. In the latter case, *msgp
1823 * must be freed with g_free().
1826 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1828 int fork_child_status;
1830 int retry_waitpid = 3;
1833 GTimeVal start_time;
1838 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1841 g_get_current_time(&start_time);
1843 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1844 g_assert(fork_child != WS_INVALID_PID);
1846 *msgp = NULL; /* assume no error */
1848 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1849 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1853 * The child exited; return its exit status. Do not treat this as
1856 ret = fork_child_status;
1857 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1858 /* Probably an exception code */
1859 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1860 win32strexception(fork_child_status));
1865 while (--retry_waitpid >= 0) {
1866 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1867 /* waitpid() succeeded */
1868 if (WIFEXITED(fork_child_status)) {
1870 * The child exited; return its exit status. Do not treat this as
1873 ret = WEXITSTATUS(fork_child_status);
1874 } else if (WIFSTOPPED(fork_child_status)) {
1875 /* It stopped, rather than exiting. "Should not happen." */
1876 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1877 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1879 } else if (WIFSIGNALED(fork_child_status)) {
1880 /* It died with a signal. */
1881 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1882 sync_pipe_signame(WTERMSIG(fork_child_status)),
1883 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1886 /* What? It had to either have exited, or stopped, or died with
1887 a signal; what happened here? */
1888 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1893 /* waitpid() failed */
1894 if (errno == EINTR) {
1896 * Signal interrupted waitpid().
1898 * If it's SIGALRM, we just want to keep waiting, in case
1899 * there's some timer using it (e.g., in a GUI toolkit).
1901 * If you ^C TShark (or Wireshark), that should deliver
1902 * SIGINT to dumpcap as well. dumpcap catches SIGINT,
1903 * and should clean up and exit, so we should eventually
1904 * see that and clean up and terminate.
1906 * If we're sent a SIGTERM, we should (and do) catch it,
1907 * and TShark, at least, calls sync_pipe_stop(). which
1908 * kills dumpcap, so we should eventually see that and
1909 * clean up and terminate.
1911 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
1913 } else if (errno == ECHILD) {
1915 * The process identified by fork_child either doesn't
1916 * exist any more or isn't our child process (anymore?).
1918 * echld might have already reaped the child.
1920 ret = fetch_dumpcap_pid ? 0 : -1;
1922 /* Unknown error. */
1923 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1931 g_get_current_time(&end_time);
1932 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1933 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1934 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1940 /* convert signal to corresponding name */
1942 sync_pipe_signame(int sig)
1945 static char sigmsg_buf[6+1+3+1];
1954 sigmsg = "Interrupted";
1962 sigmsg = "Illegal instruction";
1966 sigmsg = "Trace trap";
1974 sigmsg = "Arithmetic exception";
1982 sigmsg = "Bus error";
1986 sigmsg = "Segmentation violation";
1989 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1990 Linux is POSIX compliant. These are not POSIX-defined signals ---
1991 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1993 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1994 were omitted from POSIX.1 because their behavior is
1995 implementation dependent and could not be adequately catego-
1996 rized. Conforming implementations may deliver these sig-
1997 nals, but must document the circumstances under which they
1998 are delivered and note any restrictions concerning their
2001 So we only check for SIGSYS on those systems that happen to
2002 implement them (a system can be POSIX-compliant and implement
2003 them, it's just that POSIX doesn't *require* a POSIX-compliant
2004 system to implement them).
2009 sigmsg = "Bad system call";
2014 sigmsg = "Broken pipe";
2018 sigmsg = "Alarm clock";
2022 sigmsg = "Terminated";
2026 /* Returning a static buffer is ok in the context we use it here */
2027 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2028 sigmsg = sigmsg_buf;
2038 static void create_dummy_signal_pipe() {
2039 gchar *dummy_signal_pipe_name;
2041 if (dummy_signal_pipe != NULL) return;
2043 if (!dummy_control_id) {
2044 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2047 /* Create the signal pipe */
2048 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2049 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2050 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2051 g_free(dummy_signal_pipe_name);
2054 /* tell the child through the signal pipe that we want to quit the capture */
2056 signal_pipe_capquit_to_child(capture_session *cap_session)
2058 const char quit_msg[] = "QUIT";
2061 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2063 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2064 /* simply sending a "QUIT" string */
2065 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2066 ret = ws_write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2068 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2069 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2075 /* user wants to stop the capture run */
2077 sync_pipe_stop(capture_session *cap_session)
2082 gboolean terminate = TRUE;
2084 if (cap_session->fork_child != WS_INVALID_PID) {
2086 /* send the SIGINT signal to close the capture child gracefully. */
2087 int sts = kill(cap_session->fork_child, SIGINT);
2089 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2090 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2093 #define STOP_SLEEP_TIME 500 /* ms */
2094 #define STOP_CHECK_TIME 50
2095 /* First, use the special signal pipe to try to close the capture child
2098 signal_pipe_capquit_to_child(cap_session);
2100 /* Next, wait for the process to exit on its own */
2101 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2102 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2103 childstatus != STILL_ACTIVE) {
2107 Sleep(STOP_CHECK_TIME);
2110 /* Force the issue. */
2112 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2113 "sync_pipe_stop: forcing child to exit");
2114 sync_pipe_kill(cap_session->fork_child);
2121 /* Wireshark has to exit, force the capture child to close */
2123 sync_pipe_kill(ws_process_id fork_child)
2125 if (fork_child != WS_INVALID_PID) {
2127 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2129 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2130 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2133 /* Remark: This is not the preferred method of closing a process!
2134 * the clean way would be getting the process id of the child process,
2135 * then getting window handle hWnd of that process (using EnumChildWindows),
2136 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2138 * Unfortunately, I don't know how to get the process id from the
2139 * handle. OpenProcess will get an handle (not a window handle)
2140 * from the process ID; it will not get a window handle from the
2141 * process ID. (How could it? A process can have more than one
2142 * window. For that matter, a process might have *no* windows,
2143 * as a process running dumpcap, the normal child process program,
2146 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2147 * running in the same console; that's not necessarily the case for
2148 * us, as we might not be running in a console.
2149 * And this also will require to have the process id.
2151 TerminateProcess((HANDLE) (fork_child), 0);
2157 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2158 fetch_dumpcap_pid = cb;
2161 #endif /* HAVE_LIBPCAP */