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 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <wsutil/strtoi.h>
25 #include <wsutil/unicode-utils.h>
26 #include <wsutil/win32-utils.h>
27 #include <wsutil/ws_pipe.h>
30 #ifdef HAVE_SYS_WAIT_H
31 # include <sys/wait.h>
34 #include "caputils/capture-pcap-util.h"
38 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
39 * macros) on UNIX systems that don't have them.
42 # define WIFEXITED(status) (((status) & 0177) == 0)
45 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
48 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
51 # define WEXITSTATUS(status) ((status) >> 8)
54 # define WTERMSIG(status) ((status) & 0177)
57 # define WCOREDUMP(status) ((status) & 0200)
60 # define WSTOPSIG(status) ((status) >> 8)
64 #include <epan/packet.h>
65 #include <epan/prefs.h>
69 #include "ui/capture.h"
70 #include <capchild/capture_sync.h>
72 #include "sync_pipe.h"
75 #include "caputils/capture-wpcap.h"
78 #include "ui/ws_ui_util.h"
80 #include <wsutil/filesystem.h>
81 #include <wsutil/file_util.h>
82 #include <wsutil/report_message.h>
87 #include <process.h> /* For spawning child process */
90 #include <wsutil/ws_pipe.h>
93 static void create_dummy_signal_pipe();
94 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
95 static gchar *dummy_control_id;
97 static const char *sync_pipe_signame(int);
101 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
102 static int sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp);
103 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
104 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
107 static void (*fetch_dumpcap_pid)(ws_process_id) = NULL;
109 static void free_argv(char** argv, int argc)
112 for (i = 0; i < argc; i++)
118 capture_session_init(capture_session *cap_session, capture_file *cf)
120 cap_session->cf = cf;
121 cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
123 cap_session->signal_pipe_write_fd = -1;
125 cap_session->state = CAPTURE_STOPPED;
127 cap_session->owner = getuid();
128 cap_session->group = getgid();
130 cap_session->count = 0;
131 cap_session->session_started = FALSE;
134 /* Append an arg (realloc) to an argc/argv array */
135 /* (add a string pointer to a NULL-terminated array of string pointers) */
137 sync_pipe_add_arg(char **args, int *argc, const char *arg)
139 /* Grow the array; "*argc" currently contains the number of string
140 pointers, *not* counting the NULL pointer at the end, so we have
141 to add 2 in order to get the new size of the array, including the
142 new pointer and the terminating NULL pointer. */
143 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
145 /* Stuff the pointer into the penultimate element of the array, which
146 is the one at the index specified by "*argc". */
147 args[*argc] = g_strdup(arg);
148 /* Now bump the count. */
151 /* We overwrite the NULL pointer; put it back right after the
158 /* Initialize an argument list and add dumpcap to it. */
160 init_pipe_args(int *argc) {
162 const char *progfile_dir;
165 progfile_dir = get_progfile_dir();
166 if (progfile_dir == NULL) {
170 /* Allocate the string pointer array with enough space for the
171 terminating NULL pointer. */
173 argv = (char **)g_malloc(sizeof (char *));
176 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
178 exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
180 exename = g_strdup_printf("%s/dumpcap", progfile_dir);
183 /* Make that the first argument in the argument list (argv[0]). */
184 argv = sync_pipe_add_arg(argv, argc, exename);
186 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
192 #define ARGV_NUMBER_LEN 24
193 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
195 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, info_data_t* cap_data, void (*update_cb)(void))
197 char ssnap[ARGV_NUMBER_LEN];
198 char scount[ARGV_NUMBER_LEN];
199 char sfilesize[ARGV_NUMBER_LEN];
200 char sfile_duration[ARGV_NUMBER_LEN];
201 char sfile_interval[ARGV_NUMBER_LEN];
202 char sring_num_files[ARGV_NUMBER_LEN];
203 char sautostop_files[ARGV_NUMBER_LEN];
204 char sautostop_filesize[ARGV_NUMBER_LEN];
205 char sautostop_duration[ARGV_NUMBER_LEN];
206 #ifdef HAVE_PCAP_REMOTE
209 #ifdef HAVE_PCAP_SETSAMPLING
210 char ssampling[ARGV_NUMBER_LEN];
213 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
214 char buffer_size[ARGV_NUMBER_LEN];
218 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
219 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
220 int signal_pipe_write_fd;
221 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
222 GString *args = g_string_sized_new(200);
224 SECURITY_ATTRIBUTES sa;
226 PROCESS_INFORMATION pi;
227 char control_id[ARGV_NUMBER_LEN];
228 gchar *signal_pipe_name;
231 int sync_pipe[2]; /* pipe used to send messages from child to parent */
232 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
234 int sync_pipe_read_fd;
239 interface_options *interface_opts;
241 if (capture_opts->ifaces->len > 1)
242 capture_opts->use_pcapng = TRUE;
243 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
244 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
246 cap_session->fork_child = WS_INVALID_PID;
248 if (!extcap_init_interfaces(capture_opts)) {
249 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
253 argv = init_pipe_args(&argc);
255 /* We don't know where to find dumpcap. */
256 report_failure("We don't know where to find dumpcap.");
260 if (capture_opts->ifaces->len > 1)
261 argv = sync_pipe_add_arg(argv, &argc, "-t");
263 if (capture_opts->use_pcapng)
264 argv = sync_pipe_add_arg(argv, &argc, "-n");
266 argv = sync_pipe_add_arg(argv, &argc, "-P");
268 if (capture_opts->capture_comment) {
269 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
270 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
273 if (capture_opts->multi_files_on) {
274 if (capture_opts->has_autostop_filesize) {
275 argv = sync_pipe_add_arg(argv, &argc, "-b");
276 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
277 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
280 if (capture_opts->has_file_duration) {
281 argv = sync_pipe_add_arg(argv, &argc, "-b");
282 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
283 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
286 if (capture_opts->has_file_interval) {
287 argv = sync_pipe_add_arg(argv, &argc, "-b");
288 g_snprintf(sfile_interval, ARGV_NUMBER_LEN, "interval:%d",capture_opts->file_interval);
289 argv = sync_pipe_add_arg(argv, &argc, sfile_interval);
292 if (capture_opts->has_ring_num_files) {
293 argv = sync_pipe_add_arg(argv, &argc, "-b");
294 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
295 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
298 if (capture_opts->has_autostop_files) {
299 argv = sync_pipe_add_arg(argv, &argc, "-a");
300 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
301 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
304 if (capture_opts->has_autostop_filesize) {
305 argv = sync_pipe_add_arg(argv, &argc, "-a");
306 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
307 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
311 if (capture_opts->has_autostop_packets) {
312 argv = sync_pipe_add_arg(argv, &argc, "-c");
313 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
314 argv = sync_pipe_add_arg(argv, &argc, scount);
317 if (capture_opts->has_autostop_duration) {
318 argv = sync_pipe_add_arg(argv, &argc, "-a");
319 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
320 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
323 if (capture_opts->group_read_access) {
324 argv = sync_pipe_add_arg(argv, &argc, "-g");
327 for (j = 0; j < capture_opts->ifaces->len; j++) {
328 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, j);
330 argv = sync_pipe_add_arg(argv, &argc, "-i");
331 if (interface_opts->extcap_fifo != NULL)
332 argv = sync_pipe_add_arg(argv, &argc, interface_opts->extcap_fifo);
334 argv = sync_pipe_add_arg(argv, &argc, interface_opts->name);
336 if (interface_opts->cfilter != NULL && strlen(interface_opts->cfilter) != 0) {
337 argv = sync_pipe_add_arg(argv, &argc, "-f");
338 argv = sync_pipe_add_arg(argv, &argc, interface_opts->cfilter);
340 if (interface_opts->has_snaplen) {
341 argv = sync_pipe_add_arg(argv, &argc, "-s");
342 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts->snaplen);
343 argv = sync_pipe_add_arg(argv, &argc, ssnap);
346 if (interface_opts->linktype != -1) {
347 const char *linktype = linktype_val_to_name(interface_opts->linktype);
348 if ( linktype != NULL )
350 argv = sync_pipe_add_arg(argv, &argc, "-y");
351 argv = sync_pipe_add_arg(argv, &argc, linktype);
355 if (!interface_opts->promisc_mode) {
356 argv = sync_pipe_add_arg(argv, &argc, "-p");
359 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
360 if (interface_opts->buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
361 argv = sync_pipe_add_arg(argv, &argc, "-B");
362 if(interface_opts->buffer_size == 0x00)
363 interface_opts->buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
364 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts->buffer_size);
365 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
369 #ifdef HAVE_PCAP_CREATE
370 if (interface_opts->monitor_mode) {
371 argv = sync_pipe_add_arg(argv, &argc, "-I");
375 #ifdef HAVE_PCAP_REMOTE
376 if (interface_opts->datatx_udp)
377 argv = sync_pipe_add_arg(argv, &argc, "-u");
379 if (!interface_opts->nocap_rpcap)
380 argv = sync_pipe_add_arg(argv, &argc, "-r");
382 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
383 argv = sync_pipe_add_arg(argv, &argc, "-A");
384 g_snprintf(sauth, sizeof(sauth), "%s:%s",
385 interface_opts->auth_username,
386 interface_opts->auth_password);
387 argv = sync_pipe_add_arg(argv, &argc, sauth);
391 #ifdef HAVE_PCAP_SETSAMPLING
392 if (interface_opts->sampling_method != CAPTURE_SAMP_NONE) {
393 argv = sync_pipe_add_arg(argv, &argc, "-m");
394 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
395 interface_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
396 interface_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
398 interface_opts->sampling_param);
399 argv = sync_pipe_add_arg(argv, &argc, ssampling);
402 if (interface_opts->timestamp_type) {
403 argv = sync_pipe_add_arg(argv, &argc, "--time-stamp-type");
404 argv = sync_pipe_add_arg(argv, &argc, interface_opts->timestamp_type);
408 /* dumpcap should be running in capture child mode (hidden feature) */
410 argv = sync_pipe_add_arg(argv, &argc, "-Z");
412 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
413 argv = sync_pipe_add_arg(argv, &argc, control_id);
415 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
419 if (capture_opts->save_file) {
420 argv = sync_pipe_add_arg(argv, &argc, "-w");
421 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
423 for (i = 0; i < argc; i++) {
424 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
428 /* init SECURITY_ATTRIBUTES */
429 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
430 sa.bInheritHandle = TRUE;
431 sa.lpSecurityDescriptor = NULL;
433 /* Create a pipe for the child process */
434 /* (increase this value if you have trouble while fast capture file switches) */
435 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
436 /* Couldn't create the pipe between parent and child. */
437 report_failure("Couldn't create sync pipe: %s",
438 win32strerror(GetLastError()));
439 free_argv(argv, argc);
444 * Associate a C run-time file handle with the Windows HANDLE for the
445 * read side of the message pipe.
447 * (See http://www.flounder.com/handles.htm for information on various
448 * types of file handle in C/C++ on Windows.)
450 sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
451 if (sync_pipe_read_fd == -1) {
452 /* Couldn't create the pipe between parent and child. */
453 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
454 CloseHandle(sync_pipe_read);
455 CloseHandle(sync_pipe_write);
456 free_argv(argv, argc);
460 /* Create the signal pipe */
461 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
462 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
463 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
464 g_free(signal_pipe_name);
466 if (signal_pipe == INVALID_HANDLE_VALUE) {
467 /* Couldn't create the signal pipe between parent and child. */
468 report_failure("Couldn't create signal pipe: %s",
469 win32strerror(GetLastError()));
470 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
471 CloseHandle(sync_pipe_write);
472 free_argv(argv, argc);
477 * Associate a C run-time file handle with the Windows HANDLE for the
478 * read side of the message pipe.
480 * (See http://www.flounder.com/handles.htm for information on various
481 * types of file handle in C/C++ on Windows.)
483 signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
484 if (sync_pipe_read_fd == -1) {
485 /* Couldn't create the pipe between parent and child. */
486 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
487 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
488 CloseHandle(sync_pipe_write);
489 CloseHandle(signal_pipe);
490 free_argv(argv, argc);
494 /* init STARTUPINFO & PROCESS_INFORMATION */
495 memset(&si, 0, sizeof(si));
497 memset(&pi, 0, sizeof(pi));
499 si.dwFlags = STARTF_USESHOWWINDOW;
500 si.wShowWindow = SW_SHOW;
502 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
503 si.wShowWindow = SW_HIDE; /* this hides the console window */
504 if(interface_opts->extcap_pipe_h != INVALID_HANDLE_VALUE)
505 si.hStdInput = interface_opts->extcap_pipe_h;
507 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
509 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
510 si.hStdError = sync_pipe_write;
511 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
514 /* convert args array into a single string */
515 /* XXX - could change sync_pipe_add_arg() instead */
516 /* there is a drawback here: the length is internally limited to 1024 bytes */
517 for(i=0; argv[i] != 0; i++) {
518 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
519 quoted_arg = protect_arg(argv[i]);
520 g_string_append(args, quoted_arg);
525 if(!win32_create_process(argv[0], args->str, NULL, NULL, TRUE,
526 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
527 report_failure("Couldn't run %s in child process: %s",
528 args->str, win32strerror(GetLastError()));
529 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
530 CloseHandle(sync_pipe_write);
531 CloseHandle(signal_pipe);
532 free_argv(argv, argc);
533 g_string_free(args, TRUE);
536 cap_session->fork_child = pi.hProcess;
537 /* We may need to store this and close it later */
538 CloseHandle(pi.hThread);
539 g_string_free(args, TRUE);
541 cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
544 if (pipe(sync_pipe) < 0) {
545 /* Couldn't create the pipe between parent and child. */
546 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
547 free_argv(argv, argc);
551 if ((cap_session->fork_child = fork()) == 0) {
553 * Child process - run dumpcap with the right arguments to make
554 * it just capture with the specified capture parameters
556 dup2(sync_pipe[PIPE_WRITE], 2);
557 ws_close(sync_pipe[PIPE_READ]);
558 execv(argv[0], argv);
559 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
560 argv[0], g_strerror(errno));
561 sync_pipe_errmsg_to_parent(2, errmsg, "");
563 /* Exit with "_exit()", so that we don't close the connection
564 to the X server (and cause stuff buffered up by our parent but
565 not yet sent to be sent, as that stuff should only be sent by
566 our parent). We've sent an error message to the parent, so
567 we exit with an exit status of 1 (any exit status other than
568 0 or 1 will cause an additional message to report that exit
569 status, over and above the error message we sent to the parent). */
573 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
574 fetch_dumpcap_pid(cap_session->fork_child);
576 sync_pipe_read_fd = sync_pipe[PIPE_READ];
579 /* Parent process - read messages from the child process over the
581 free_argv(argv, argc);
583 /* Close the write side of the pipe, so that only the child has it
584 open, and thus it completely closes, and thus returns to us
585 an EOF indication, if the child closes it (either deliberately
586 or by exiting abnormally). */
588 CloseHandle(sync_pipe_write);
590 ws_close(sync_pipe[PIPE_WRITE]);
593 if (cap_session->fork_child == WS_INVALID_PID) {
594 /* We couldn't even create the child process. */
595 report_failure("Couldn't create child process: %s", g_strerror(errno));
596 ws_close(sync_pipe_read_fd);
598 ws_close(cap_session->signal_pipe_write_fd);
603 cap_session->fork_child_status = 0;
604 cap_session->capture_opts = capture_opts;
605 cap_session->cap_data_info = cap_data;
607 /* we might wait for a moment till child is ready, so update screen now */
608 if (update_cb) update_cb();
610 /* We were able to set up to read the capture file;
611 arrange that our callback be called whenever it's possible
612 to read from the sync pipe, so that it's called when
613 the child process wants to tell us something. */
615 /* we have a running capture, now wait for the real capture filename */
616 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
617 &cap_session->fork_child, sync_pipe_input_cb);
623 * Open two pipes to dumpcap with the supplied arguments, one for its
624 * standard output and one for its standard error.
626 * On success, *msg is unchanged and 0 is returned; data_read_fd,
627 * message_read_fd, and fork_child point to the standard output pipe's
628 * file descriptor, the standard error pipe's file descriptor, and
629 * the child's PID/handle, respectively.
631 * On failure, *msg points to an error message for the failure, and -1 is
632 * returned, in which case *msg must be freed with g_free().
634 /* XXX - This duplicates a lot of code in sync_pipe_start() */
635 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
636 #define PIPE_BUF_SIZE 5120
638 sync_pipe_open_command(char* const argv[], int *data_read_fd,
639 int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
641 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
643 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
644 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
645 GString *args = g_string_sized_new(200);
647 SECURITY_ATTRIBUTES sa;
649 PROCESS_INFORMATION pi;
653 int sync_pipe[2]; /* pipe used to send messages from child to parent */
654 int data_pipe[2]; /* pipe used to send data from child to parent */
656 *fork_child = WS_INVALID_PID;
658 *message_read_fd = -1;
659 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
662 /* We can't return anything */
664 g_string_free(args, TRUE);
670 /* init SECURITY_ATTRIBUTES */
671 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
672 sa.bInheritHandle = TRUE;
673 sa.lpSecurityDescriptor = NULL;
675 /* Create a pipe for the child process to send us messages */
676 /* (increase this value if you have trouble while fast capture file switches) */
677 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
678 /* Couldn't create the message pipe between parent and child. */
679 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
680 win32strerror(GetLastError()));
685 * Associate a C run-time file handle with the Windows HANDLE for the
686 * read side of the message pipe.
688 * (See http://www.flounder.com/handles.htm for information on various
689 * types of file handle in C/C++ on Windows.)
691 *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
692 if (*message_read_fd == -1) {
693 *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
694 CloseHandle(sync_pipe[PIPE_READ]);
695 CloseHandle(sync_pipe[PIPE_WRITE]);
699 /* Create a pipe for the child process to send us data */
700 /* (increase this value if you have trouble while fast capture file switches) */
701 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
702 /* Couldn't create the message pipe between parent and child. */
703 *msg = g_strdup_printf("Couldn't create data pipe: %s",
704 win32strerror(GetLastError()));
705 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
706 CloseHandle(sync_pipe[PIPE_WRITE]);
711 * Associate a C run-time file handle with the Windows HANDLE for the
712 * read side of the data pipe.
714 * (See http://www.flounder.com/handles.htm for information on various
715 * types of file handle in C/C++ on Windows.)
717 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
718 if (*data_read_fd == -1) {
719 *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
720 CloseHandle(data_pipe[PIPE_READ]);
721 CloseHandle(data_pipe[PIPE_WRITE]);
722 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
723 CloseHandle(sync_pipe[PIPE_WRITE]);
727 /* init STARTUPINFO & PROCESS_INFORMATION */
728 memset(&si, 0, sizeof(si));
730 memset(&pi, 0, sizeof(pi));
732 si.dwFlags = STARTF_USESHOWWINDOW;
733 si.wShowWindow = SW_SHOW;
735 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
736 si.wShowWindow = SW_HIDE; /* this hides the console window */
737 si.hStdInput = NULL; /* handle for named pipe*/
739 si.hStdOutput = data_pipe[PIPE_WRITE];
740 si.hStdError = sync_pipe[PIPE_WRITE];
743 /* convert args array into a single string */
744 /* XXX - could change sync_pipe_add_arg() instead */
745 /* there is a drawback here: the length is internally limited to 1024 bytes */
746 for(i=0; argv[i] != 0; i++) {
747 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
748 quoted_arg = protect_arg(argv[i]);
749 g_string_append(args, quoted_arg);
754 if(!win32_create_process(argv[0], args->str, NULL, NULL, TRUE,
755 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
756 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
757 args->str, win32strerror(GetLastError()));
758 ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
759 CloseHandle(data_pipe[PIPE_WRITE]);
760 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
761 CloseHandle(sync_pipe[PIPE_WRITE]);
762 g_string_free(args, TRUE);
765 *fork_child = pi.hProcess;
766 /* We may need to store this and close it later */
767 CloseHandle(pi.hThread);
768 g_string_free(args, TRUE);
770 /* Create a pipe for the child process to send us messages */
771 if (pipe(sync_pipe) < 0) {
772 /* Couldn't create the message pipe between parent and child. */
773 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
777 /* Create a pipe for the child process to send us data */
778 if (pipe(data_pipe) < 0) {
779 /* Couldn't create the data pipe between parent and child. */
780 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
781 ws_close(sync_pipe[PIPE_READ]);
782 ws_close(sync_pipe[PIPE_WRITE]);
786 if ((*fork_child = fork()) == 0) {
788 * Child process - run dumpcap with the right arguments to make
789 * it just capture with the specified capture parameters
791 dup2(data_pipe[PIPE_WRITE], 1);
792 ws_close(data_pipe[PIPE_READ]);
793 ws_close(data_pipe[PIPE_WRITE]);
794 dup2(sync_pipe[PIPE_WRITE], 2);
795 ws_close(sync_pipe[PIPE_READ]);
796 ws_close(sync_pipe[PIPE_WRITE]);
797 execv(argv[0], argv);
798 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
799 argv[0], g_strerror(errno));
800 sync_pipe_errmsg_to_parent(2, errmsg, "");
802 /* Exit with "_exit()", so that we don't close the connection
803 to the X server (and cause stuff buffered up by our parent but
804 not yet sent to be sent, as that stuff should only be sent by
805 our parent). We've sent an error message to the parent, so
806 we exit with an exit status of 1 (any exit status other than
807 0 or 1 will cause an additional message to report that exit
808 status, over and above the error message we sent to the parent). */
812 if (fetch_dumpcap_pid && *fork_child > 0)
813 fetch_dumpcap_pid(*fork_child);
815 *data_read_fd = data_pipe[PIPE_READ];
816 *message_read_fd = sync_pipe[PIPE_READ];
819 /* Parent process - read messages from the child process over the
822 /* Close the write sides of the pipes, so that only the child has them
823 open, and thus they completely close, and thus return to us
824 an EOF indication, if the child closes them (either deliberately
825 or by exiting abnormally). */
827 CloseHandle(data_pipe[PIPE_WRITE]);
828 CloseHandle(sync_pipe[PIPE_WRITE]);
830 ws_close(data_pipe[PIPE_WRITE]);
831 ws_close(sync_pipe[PIPE_WRITE]);
834 if (*fork_child == WS_INVALID_PID) {
835 /* We couldn't even create the child process. */
836 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
837 ws_close(*data_read_fd);
838 ws_close(*message_read_fd);
842 /* we might wait for a moment till child is ready, so update screen now */
843 if (update_cb) update_cb();
848 * Close the pipes we're using to read from dumpcap, and wait for it
849 * to exit. On success, *msgp is unchanged, and the exit status of
850 * dumpcap is returned. On failure (which includes "dumpcap exited
851 * due to being killed by a signal or an exception"), *msgp points
852 * to an error message for the failure, and -1 is returned. In the
853 * latter case, *msgp must be freed with g_free().
856 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
857 ws_process_id *fork_child, gchar **msgp)
859 ws_close(*data_read_fd);
860 if (message_read_fd != NULL)
861 ws_close(*message_read_fd);
864 /* XXX - Should we signal the child somehow? */
865 sync_pipe_kill(*fork_child);
868 return sync_pipe_wait_for_child(*fork_child, msgp);
872 * Run dumpcap with the supplied arguments.
874 * On success, *data points to a buffer containing the dumpcap output,
875 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
876 * must be freed with g_free().
878 * On failure, *data is NULL, *primary_msg points to an error message,
879 * *secondary_msg either points to an additional error message or is
880 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
881 * must be freed with g_free().
883 /* XXX - This duplicates a lot of code in sync_pipe_start() */
884 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
885 #define PIPE_BUF_SIZE 5120
887 sync_pipe_run_command_actual(char* const argv[], gchar **data, gchar **primary_msg,
888 gchar **secondary_msg, void(*update_cb)(void))
891 int data_pipe_read_fd, sync_pipe_read_fd, ret;
892 ws_process_id fork_child;
894 gchar buffer[PIPE_BUF_SIZE+1] = {0};
898 char *primary_msg_text;
899 int secondary_msg_len;
900 char *secondary_msg_text;
902 GString *data_buf = NULL;
905 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
906 &fork_child, &msg, update_cb);
909 *secondary_msg = NULL;
915 * We were able to set up to read dumpcap's output. Do so.
917 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
919 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
920 buffer, primary_msg);
922 /* We got a read error from the sync pipe, or we got no data at
923 all from the sync pipe, so we're not going to be getting any
924 data or error message from the child process. Pick up its
925 exit status, and complain.
927 We don't have to worry about killing the child, if the sync pipe
928 returned an error. Usually this error is caused as the child killed
929 itself while going down. Even in the rare cases that this isn't the
930 case, the child will get an error when writing to the broken pipe
931 the next time, cleaning itself up then. */
932 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
934 /* We got an EOF from the sync pipe. That means that it exited
935 before giving us any data to read. If ret is -1, we report
936 that as a bad exit (e.g., exiting due to a signal); otherwise,
937 we report it as a premature exit. */
939 *primary_msg = wait_msg;
941 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
943 /* We got an error from the sync pipe. If ret is -1, report
944 both the sync pipe I/O error and the wait error. */
946 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
947 g_free(*primary_msg);
949 *primary_msg = combined_msg;
952 *secondary_msg = NULL;
958 /* we got a valid message block from the child, process it */
963 * Error from dumpcap; there will be a primary message and a
967 /* convert primary message */
968 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
969 primary_msg_text = buffer+4;
970 /* convert secondary message */
971 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
973 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
974 /* the capture child will close the sync_pipe, nothing to do */
977 * Pick up the child status.
979 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
983 * Child process failed unexpectedly, or wait failed; msg is the
987 *secondary_msg = NULL;
990 * Child process failed, but returned the expected exit status.
991 * Return the messages it gave us, and indicate failure.
993 *primary_msg = g_strdup(primary_msg_text);
994 *secondary_msg = g_strdup(secondary_msg_text);
1001 /* read the output from the command */
1002 data_buf = g_string_new("");
1003 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1004 buffer[count] = '\0';
1005 g_string_append(data_buf, buffer);
1009 * Pick up the child status.
1011 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1015 * Child process failed unexpectedly, or wait failed; msg is the
1019 *secondary_msg = NULL;
1020 g_string_free(data_buf, TRUE);
1024 * Child process succeeded.
1026 *primary_msg = NULL;
1027 *secondary_msg = NULL;
1028 *data = g_string_free(data_buf, FALSE);
1034 * Pick up the child status.
1036 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1040 * Child process failed unexpectedly, or wait failed; msg is the
1044 *secondary_msg = NULL;
1047 * Child process returned an unknown status.
1049 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1051 *secondary_msg = NULL;
1060 /* centralised logging and timing for sync_pipe_run_command_actual(),
1061 * redirects to sync_pipe_run_command_actual()
1064 sync_pipe_run_command(char* const argv[], gchar **data, gchar **primary_msg,
1065 gchar **secondary_msg, void (*update_cb)(void))
1068 GTimeVal start_time;
1071 int logging_enabled;
1073 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1074 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1075 if(logging_enabled){
1076 g_get_current_time(&start_time);
1077 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1078 for(i=0; argv[i] != 0; i++) {
1079 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1082 /* do the actual sync pipe run command */
1083 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1085 if(logging_enabled){
1086 g_get_current_time(&end_time);
1087 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1088 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1090 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1098 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1099 const gchar *center_freq1, const gchar *center_freq2,
1100 gchar **data, gchar **primary_msg,
1101 gchar **secondary_msg, void (*update_cb)(void))
1107 argv = init_pipe_args(&argc);
1110 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1111 *secondary_msg = NULL;
1116 argv = sync_pipe_add_arg(argv, &argc, "-i");
1117 argv = sync_pipe_add_arg(argv, &argc, iface);
1120 opt = g_strdup_printf("%s,%s,%s,%s", freq, type, center_freq1, center_freq2);
1121 else if (center_freq1)
1122 opt = g_strdup_printf("%s,%s,%s", freq, type, center_freq1);
1124 opt = g_strdup_printf("%s,%s", freq, type);
1126 opt = g_strdup(freq);
1129 *primary_msg = g_strdup("Out of mem.");
1130 *secondary_msg = NULL;
1132 free_argv(argv, argc);
1136 argv = sync_pipe_add_arg(argv, &argc, "-k");
1137 argv = sync_pipe_add_arg(argv, &argc, opt);
1140 /* Run dumpcap in capture child mode */
1141 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1142 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1145 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1147 free_argv(argv, argc);
1152 * Get the list of interfaces using dumpcap.
1154 * On success, *data points to a buffer containing the dumpcap output,
1155 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1156 * must be freed with g_free().
1158 * On failure, *data is NULL, *primary_msg points to an error message,
1159 * *secondary_msg either points to an additional error message or is
1160 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1161 * must be freed with g_free().
1164 sync_interface_list_open(gchar **data, gchar **primary_msg,
1165 gchar **secondary_msg, void (*update_cb)(void))
1171 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1173 argv = init_pipe_args(&argc);
1176 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1177 *secondary_msg = NULL;
1182 /* Ask for the interface list */
1183 argv = sync_pipe_add_arg(argv, &argc, "-D");
1186 /* Run dumpcap in capture child mode */
1187 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1188 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1190 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1191 free_argv(argv, argc);
1196 * Get the capabilities of an interface using dumpcap.
1198 * On success, *data points to a buffer containing the dumpcap output,
1199 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1200 * must be freed with g_free().
1202 * On failure, *data is NULL, *primary_msg points to an error message,
1203 * *secondary_msg either points to an additional error message or is
1204 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1205 * must be freed with g_free().
1208 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gchar* auth,
1209 gchar **data, gchar **primary_msg,
1210 gchar **secondary_msg, void (*update_cb)(void))
1216 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1218 argv = init_pipe_args(&argc);
1221 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1222 *secondary_msg = NULL;
1227 /* Ask for the interface capabilities */
1228 argv = sync_pipe_add_arg(argv, &argc, "-i");
1229 argv = sync_pipe_add_arg(argv, &argc, ifname);
1230 argv = sync_pipe_add_arg(argv, &argc, "-L");
1231 argv = sync_pipe_add_arg(argv, &argc, "--list-time-stamp-types");
1233 argv = sync_pipe_add_arg(argv, &argc, "-I");
1235 argv = sync_pipe_add_arg(argv, &argc, "-A");
1236 argv = sync_pipe_add_arg(argv, &argc, auth);
1240 /* Run dumpcap in capture child mode */
1241 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1242 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1244 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1245 free_argv(argv, argc);
1250 * Start getting interface statistics using dumpcap. On success, read_fd
1251 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1252 * and zero is returned. On failure, *msg will point to an error message
1253 * that must be g_free()d, and -1 will be returned.
1256 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1260 int message_read_fd, ret;
1262 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1265 int primary_msg_len;
1266 char *primary_msg_text;
1267 int secondary_msg_len;
1268 /*char *secondary_msg_text;*/
1271 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1273 argv = init_pipe_args(&argc);
1276 *msg = g_strdup("We don't know where to find dumpcap.");
1280 /* Ask for the interface statistics */
1281 argv = sync_pipe_add_arg(argv, &argc, "-S");
1284 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1286 create_dummy_signal_pipe();
1287 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1289 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1292 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1293 fork_child, msg, update_cb);
1294 free_argv(argv, argc);
1300 * We were able to set up to read dumpcap's output. Do so.
1302 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1304 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1307 /* We got a read error from the sync pipe, or we got no data at
1308 all from the sync pipe, so we're not going to be getting any
1309 data or error message from the child process. Pick up its
1310 exit status, and complain.
1312 We don't have to worry about killing the child, if the sync pipe
1313 returned an error. Usually this error is caused as the child killed
1314 itself while going down. Even in the rare cases that this isn't the
1315 case, the child will get an error when writing to the broken pipe
1316 the next time, cleaning itself up then. */
1317 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1318 ws_close(message_read_fd);
1319 ws_close(*data_read_fd);
1321 /* We got an EOF from the sync pipe. That means that it exited
1322 before giving us any data to read. If ret is -1, we report
1323 that as a bad exit (e.g., exiting due to a signal); otherwise,
1324 we report it as a premature exit. */
1328 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1330 /* We got an error from the sync pipe. If ret is -1, report
1331 both the sync pipe I/O error and the wait error. */
1333 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1336 *msg = combined_msg;
1342 /* we got a valid message block from the child, process it */
1347 * Error from dumpcap; there will be a primary message and a
1348 * secondary message.
1351 /* convert primary message */
1352 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1353 primary_msg_text = buffer+4;
1354 /* convert secondary message */
1355 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1356 &secondary_msg_len);
1357 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1358 /* the capture child will close the sync_pipe, nothing to do */
1361 * Pick up the child status.
1363 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1367 * Child process failed unexpectedly, or wait failed; msg is the
1372 * Child process failed, but returned the expected exit status.
1373 * Return the messages it gave us, and indicate failure.
1375 *msg = g_strdup(primary_msg_text);
1381 /* Close the message pipe. */
1382 ws_close(message_read_fd);
1387 * Pick up the child status.
1389 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1393 * Child process failed unexpectedly, or wait failed; msg is the
1398 * Child process returned an unknown status.
1400 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1409 /* Close down the stats process */
1411 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1415 * Don't bother waiting for the child. sync_pipe_close_command
1416 * does this for us on Windows.
1418 sync_pipe_kill(*fork_child);
1420 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1423 /* read a number of bytes from a pipe */
1424 /* (blocks until enough bytes read or an error occurs) */
1426 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1433 newly = ws_read(pipe_fd, &bytes[offset], required);
1436 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1437 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1444 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1445 "read from pipe %d: error(%u): %s", pipe_fd, error,
1447 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1452 required -= (int)newly;
1461 * Read a line from a pipe; similar to fgets, but doesn't block.
1463 * XXX - just stops reading if there's nothing to be read right now;
1464 * that could conceivably mean that you don't get a complete line.
1467 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1471 while(offset < max - 1) {
1473 if (! ws_pipe_data_available(pipe_fd))
1475 newly = ws_read(pipe_fd, &bytes[offset], 1);
1477 /* EOF - not necessarily an error */
1479 } else if (newly == -1) {
1481 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1482 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1484 } else if (bytes[offset] == '\n') {
1490 bytes[offset] = '\0';
1496 /* convert header values (indicator and 3-byte length) */
1498 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1500 g_assert(header_len == 4);
1502 /* convert header values */
1503 *indicator = header[0];
1504 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1507 /* read a message from the sending pipe in the standard format
1508 (1-byte message indicator, 3-byte message length (excluding length
1509 and indicator field), and the rest is the message) */
1511 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1518 /* read header (indicator and 3-byte length) */
1519 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1523 * Immediate EOF; if the capture child exits normally, this
1524 * is an "I'm done" indication, so don't report it as an
1527 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1528 "read %d got an EOF", pipe_fd);
1531 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1532 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1535 * Short read, but not an immediate EOF.
1537 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1543 /* convert header values */
1544 pipe_convert_header((guchar*)header, 4, indicator, &required);
1546 /* only indicator with no value? */
1548 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1549 "read %d indicator: %c empty value", pipe_fd, *indicator);
1553 /* does the data fit into the given buffer? */
1554 if(required > len) {
1555 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1556 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1557 pipe_fd, required, len,
1558 header[0], header[1], header[2], header[3]);
1560 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1561 memcpy(msg, header, sizeof(header));
1562 newly = ws_read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1563 if (newly < 0) { /* error */
1564 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1565 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1567 *err_msg = g_strdup_printf("Unknown message from dumpcap reading header, try to show it as a string: %s",
1573 /* read the actual block data */
1574 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1575 if(newly != required) {
1577 *err_msg = g_strdup_printf("Unknown message from dumpcap reading data, try to show it as a string: %s",
1583 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1584 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1585 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1592 /* There's stuff to read from the sync pipe, meaning the child has sent
1593 us a message, or the sync pipe has closed, meaning the child has
1594 closed it (perhaps because it exited). */
1596 sync_pipe_input_cb(gint source, gpointer user_data)
1598 capture_session *cap_session = (capture_session *)user_data;
1600 char buffer[SP_MAX_MSG_LEN+1] = {0};
1606 char *secondary_msg;
1607 char *wait_msg, *combined_msg;
1608 guint32 npackets = 0;
1610 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1613 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1615 If we got a read error or a bad message, nread is -1 and
1616 primary_msg is set to point to an error message. We don't
1617 have to worry about killing the child; usually this error
1618 is caused as the child killed itself while going down.
1619 Even in the rare cases that this isn't the case, the child
1620 will get an error when writing to the broken pipe the next time,
1621 cleaning itself up then.
1623 If we got an EOF, nread is 0 and primary_msg isn't set. This
1624 is an indication that the capture is finished. */
1625 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1627 /* We got an EOF from the sync pipe. That means that the capture
1628 child exited, and not in the middle of a message; we treat
1629 that as an indication that it's done, and only report an
1630 error if ret is -1, in which case wait_msg is the error
1633 primary_msg = wait_msg;
1635 /* We got an error from the sync pipe. If ret is -1, report
1636 both the sync pipe I/O error and the wait error. */
1638 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1639 g_free(primary_msg);
1641 primary_msg = combined_msg;
1645 /* No more child process. */
1646 cap_session->fork_child = WS_INVALID_PID;
1647 cap_session->fork_child_status = ret;
1650 ws_close(cap_session->signal_pipe_write_fd);
1652 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: cleaning extcap pipe");
1653 extcap_if_cleanup(cap_session->capture_opts, &primary_msg);
1654 capture_input_closed(cap_session, primary_msg);
1655 g_free(primary_msg);
1659 /* we got a valid message block from the child, process it */
1662 if(!capture_input_new_file(cap_session, buffer)) {
1663 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1665 /* We weren't able to open the new capture file; user has been
1666 alerted. Close the sync pipe. */
1669 /* The child has sent us a filename which we couldn't open.
1671 This could mean that the child is creating and deleting files
1672 (ring buffer mode) faster than we can handle it.
1674 That should only be the case for very fast file switches;
1675 We can't do much more than telling the child to stop.
1676 (This is the "emergency brake" if the user e.g. wants to
1677 switch files every second).
1679 This can also happen if the user specified "-", meaning
1680 "standard output", as the capture file. */
1681 sync_pipe_stop(cap_session);
1682 capture_input_closed(cap_session, NULL);
1686 case SP_PACKET_COUNT:
1687 if (!ws_strtou32(buffer, NULL, &npackets)) {
1688 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "Invalid packets number: %s", buffer);
1690 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1691 cap_session->count += npackets;
1692 capture_input_new_packets(cap_session, npackets);
1695 /* convert primary message */
1696 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1697 primary_msg = buffer+4;
1698 /* convert secondary message */
1699 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1700 secondary_msg = primary_msg + primary_len + 4;
1701 /* message output */
1702 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1703 /* the capture child will close the sync_pipe, nothing to do for now */
1704 /* (an error message doesn't mean we have to stop capturing) */
1706 case SP_BAD_FILTER: {
1710 ch = strtok(buffer, ":");
1712 indx = (int)strtol(ch, NULL, 10);
1713 ch = strtok(NULL, ":");
1715 capture_input_cfilter_error_message(cap_session, indx, ch);
1716 /* the capture child will close the sync_pipe, nothing to do for now */
1720 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1723 g_assert_not_reached();
1732 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1733 * unchanged, and the exit status of dumpcap is returned. On
1734 * failure (which includes "dumpcap exited due to being killed by
1735 * a signal or an exception"), *msgp points to an error message
1736 * for the failure, and -1 is returned. In the latter case, *msgp
1737 * must be freed with g_free().
1740 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1742 int fork_child_status;
1744 int retry_waitpid = 3;
1747 GTimeVal start_time;
1752 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1755 g_get_current_time(&start_time);
1757 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1758 g_assert(fork_child != WS_INVALID_PID);
1760 *msgp = NULL; /* assume no error */
1762 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1763 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1767 * The child exited; return its exit status. Do not treat this as
1770 ret = fork_child_status;
1771 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1772 /* Probably an exception code */
1773 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1774 win32strexception(fork_child_status));
1779 while (--retry_waitpid >= 0) {
1780 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1781 /* waitpid() succeeded */
1782 if (WIFEXITED(fork_child_status)) {
1784 * The child exited; return its exit status. Do not treat this as
1787 ret = WEXITSTATUS(fork_child_status);
1788 } else if (WIFSTOPPED(fork_child_status)) {
1789 /* It stopped, rather than exiting. "Should not happen." */
1790 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1791 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1793 } else if (WIFSIGNALED(fork_child_status)) {
1794 /* It died with a signal. */
1795 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1796 sync_pipe_signame(WTERMSIG(fork_child_status)),
1797 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1800 /* What? It had to either have exited, or stopped, or died with
1801 a signal; what happened here? */
1802 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1807 /* waitpid() failed */
1808 if (errno == EINTR) {
1810 * Signal interrupted waitpid().
1812 * If it's SIGALRM, we just want to keep waiting, in case
1813 * there's some timer using it (e.g., in a GUI toolkit).
1815 * If you ^C TShark (or Wireshark), that should deliver
1816 * SIGINT to dumpcap as well. dumpcap catches SIGINT,
1817 * and should clean up and exit, so we should eventually
1818 * see that and clean up and terminate.
1820 * If we're sent a SIGTERM, we should (and do) catch it,
1821 * and TShark, at least, calls sync_pipe_stop(). which
1822 * kills dumpcap, so we should eventually see that and
1823 * clean up and terminate.
1825 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
1827 } else if (errno == ECHILD) {
1829 * The process identified by fork_child either doesn't
1830 * exist any more or isn't our child process (anymore?).
1832 * echld might have already reaped the child.
1834 ret = fetch_dumpcap_pid ? 0 : -1;
1836 /* Unknown error. */
1837 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1845 g_get_current_time(&end_time);
1846 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1847 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1848 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1854 /* convert signal to corresponding name */
1856 sync_pipe_signame(int sig)
1859 static char sigmsg_buf[6+1+3+1];
1868 sigmsg = "Interrupted";
1876 sigmsg = "Illegal instruction";
1880 sigmsg = "Trace trap";
1888 sigmsg = "Arithmetic exception";
1896 sigmsg = "Bus error";
1900 sigmsg = "Segmentation violation";
1903 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1904 Linux is POSIX compliant. These are not POSIX-defined signals ---
1905 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1907 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1908 were omitted from POSIX.1 because their behavior is
1909 implementation dependent and could not be adequately catego-
1910 rized. Conforming implementations may deliver these sig-
1911 nals, but must document the circumstances under which they
1912 are delivered and note any restrictions concerning their
1915 So we only check for SIGSYS on those systems that happen to
1916 implement them (a system can be POSIX-compliant and implement
1917 them, it's just that POSIX doesn't *require* a POSIX-compliant
1918 system to implement them).
1923 sigmsg = "Bad system call";
1928 sigmsg = "Broken pipe";
1932 sigmsg = "Alarm clock";
1936 sigmsg = "Terminated";
1940 /* Returning a static buffer is ok in the context we use it here */
1941 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1942 sigmsg = sigmsg_buf;
1952 static void create_dummy_signal_pipe() {
1953 gchar *dummy_signal_pipe_name;
1955 if (dummy_signal_pipe != NULL) return;
1957 if (!dummy_control_id) {
1958 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
1961 /* Create the signal pipe */
1962 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
1963 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
1964 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
1965 g_free(dummy_signal_pipe_name);
1968 /* tell the child through the signal pipe that we want to quit the capture */
1970 signal_pipe_capquit_to_child(capture_session *cap_session)
1972 const char quit_msg[] = "QUIT";
1975 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1977 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1978 /* simply sending a "QUIT" string */
1979 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1980 ret = ws_write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1982 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1983 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
1989 /* user wants to stop the capture run */
1991 sync_pipe_stop(capture_session *cap_session)
1996 gboolean terminate = TRUE;
1998 if (cap_session->fork_child != WS_INVALID_PID) {
2000 /* send the SIGINT signal to close the capture child gracefully. */
2001 int sts = kill(cap_session->fork_child, SIGINT);
2003 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2004 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2007 #define STOP_SLEEP_TIME 500 /* ms */
2008 #define STOP_CHECK_TIME 50
2009 /* First, use the special signal pipe to try to close the capture child
2012 signal_pipe_capquit_to_child(cap_session);
2014 /* Next, wait for the process to exit on its own */
2015 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2016 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2017 childstatus != STILL_ACTIVE) {
2021 Sleep(STOP_CHECK_TIME);
2024 /* Force the issue. */
2026 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2027 "sync_pipe_stop: forcing child to exit");
2028 sync_pipe_kill(cap_session->fork_child);
2035 /* Wireshark has to exit, force the capture child to close */
2037 sync_pipe_kill(ws_process_id fork_child)
2039 if (fork_child != WS_INVALID_PID) {
2041 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2043 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2044 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2047 /* Remark: This is not the preferred method of closing a process!
2048 * the clean way would be getting the process id of the child process,
2049 * then getting window handle hWnd of that process (using EnumChildWindows),
2050 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2052 * Unfortunately, I don't know how to get the process id from the
2053 * handle. OpenProcess will get an handle (not a window handle)
2054 * from the process ID; it will not get a window handle from the
2055 * process ID. (How could it? A process can have more than one
2056 * window. For that matter, a process might have *no* windows,
2057 * as a process running dumpcap, the normal child process program,
2060 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2061 * running in the same console; that's not necessarily the case for
2062 * us, as we might not be running in a console.
2063 * And this also will require to have the process id.
2065 TerminateProcess((HANDLE) (fork_child), 0);
2071 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2072 fetch_dumpcap_pid = cb;
2075 #endif /* HAVE_LIBPCAP */