epan/dissectors/pidl/drsuapi/drsuapi.cnf unicodePwd, ntPasswdHistory, Newer-Keys
[wireshark-sm.git] / capture / capture_sync.c
blob946dc810dbdcb74d782d787c63515d33cfaae39e
1 /* capture_sync.c
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
9 */
11 #include "config.h"
12 #define WS_LOG_DOMAIN LOG_DOMAIN_CAPTURE
14 #include <wireshark.h>
16 #ifdef HAVE_LIBPCAP
18 #include <glib.h>
19 #include <stdio.h>
20 #include <stdlib.h>
22 #include <signal.h>
24 #include <ws_exit_codes.h>
26 #include <wsutil/strtoi.h>
27 #include <wsutil/ws_assert.h>
29 #ifdef _WIN32
30 #include <wsutil/unicode-utils.h>
31 #include <wsutil/win32-utils.h>
32 #include <wsutil/ws_pipe.h>
33 #else
34 #include <glib-unix.h>
35 #endif
37 #ifdef HAVE_SYS_WAIT_H
38 # include <sys/wait.h>
39 #endif
41 #include "capture/capture-pcap-util.h"
43 #ifndef _WIN32
45 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
46 * macros) on UNIX systems that don't have them.
48 #ifndef WIFEXITED
49 # define WIFEXITED(status) (((status) & 0177) == 0)
50 #endif
51 #ifndef WIFSTOPPED
52 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
53 #endif
54 #ifndef WIFSIGNALED
55 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
56 #endif
57 #ifndef WEXITSTATUS
58 # define WEXITSTATUS(status) ((status) >> 8)
59 #endif
60 #ifndef WTERMSIG
61 # define WTERMSIG(status) ((status) & 0177)
62 #endif
63 #ifndef WCOREDUMP
64 # define WCOREDUMP(status) ((status) & 0200)
65 #endif
66 #ifndef WSTOPSIG
67 # define WSTOPSIG(status) ((status) >> 8)
68 #endif
69 #endif /* _WIN32 */
71 #include <epan/packet.h>
72 #include <epan/prefs.h>
74 #include "file.h"
76 #include "ui/capture.h"
77 #include <capture/capture_sync.h>
79 #include "sync_pipe.h"
81 #ifdef _WIN32
82 #include "capture/capture-wpcap.h"
83 #endif
85 #include "ui/ws_ui_util.h"
87 #include <wsutil/filesystem.h>
88 #include <wsutil/file_util.h>
89 #include <wsutil/report_message.h>
90 #include "extcap.h"
92 #ifdef _WIN32
93 #include <process.h> /* For spawning child process */
94 #endif
96 #include <wsutil/ws_pipe.h>
98 #ifdef _WIN32
99 static int create_dummy_signal_pipe(char **msg);
100 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
101 static char *dummy_control_id;
102 #else
103 static const char *sync_pipe_signame(int);
104 #endif
106 /* We use this pipe buffer size for both the sync message pipe and the
107 * data pipe. Ensure that it's large enough for the indicator and header
108 * plus maximum message size.
110 #define PIPE_BUF_SIZE (SP_MAX_MSG_LEN+4)
112 static gboolean sync_pipe_input_cb(GIOChannel *pipe_io, capture_session *cap_session);
113 static int sync_pipe_wait_for_child(ws_process_id fork_child, char **msgp);
114 static void pipe_convert_header(const unsigned char *header, int header_len, char *indicator, int *block_len);
115 static ssize_t pipe_read_block(GIOChannel *pipe_io, char *indicator, int len, char *msg,
116 char **err_msg);
118 static void (*fetch_dumpcap_pid)(ws_process_id);
120 void
121 capture_session_init(capture_session *cap_session, capture_file *cf,
122 new_file_fn new_file, new_packets_fn new_packets,
123 drops_fn drops, error_fn error,
124 cfilter_error_fn cfilter_error, closed_fn closed)
126 cap_session->cf = cf;
127 cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
128 cap_session->pipe_input_id = 0;
129 #ifdef _WIN32
130 cap_session->signal_pipe_write_fd = -1;
131 #endif
132 cap_session->state = CAPTURE_STOPPED;
133 #ifndef _WIN32
134 cap_session->owner = getuid();
135 cap_session->group = getgid();
136 #endif
137 cap_session->count = 0;
138 cap_session->count_pending = 0;
139 cap_session->session_will_restart = false;
141 cap_session->new_file = new_file;
142 cap_session->new_packets = new_packets;
143 cap_session->drops = drops;
144 cap_session->error = error;
145 cap_session->cfilter_error = cfilter_error;
146 cap_session->closed = closed;
147 cap_session->frame_cksum = NULL;
150 void capture_process_finished(capture_session *cap_session)
152 capture_options *capture_opts = cap_session->capture_opts;
153 interface_options *interface_opts;
154 GString *message;
155 unsigned i;
157 if (!extcap_session_stop(cap_session)) {
158 /* At least one extcap process did not fully finish yet, wait for it */
159 return;
162 if (cap_session->fork_child != WS_INVALID_PID) {
163 if (capture_opts->stop_after_extcaps) {
164 /* User has requested capture stop and all extcaps are gone now */
165 capture_opts->stop_after_extcaps = false;
166 sync_pipe_stop(cap_session);
168 /* Wait for child process to end, session is not closed yet */
169 return;
172 /* Construct message and close session */
173 message = g_string_new(capture_opts->closed_msg);
174 for (i = 0; i < capture_opts->ifaces->len; i++) {
175 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
176 if (interface_opts->if_type != IF_EXTCAP) {
177 continue;
180 if ((interface_opts->extcap_stderr != NULL) &&
181 (interface_opts->extcap_stderr->len > 0)) {
182 if (message->len > 0) {
183 g_string_append(message, "\n");
185 g_string_append(message, "Error from extcap pipe: ");
186 g_string_append(message, interface_opts->extcap_stderr->str);
190 cap_session->closed(cap_session, message->str);
191 g_string_free(message, TRUE);
192 g_free(capture_opts->closed_msg);
193 capture_opts->closed_msg = NULL;
194 capture_opts->stop_after_extcaps = false;
197 /* Append an arg (realloc) to an argc/argv array */
198 /* (add a string pointer to a NULL-terminated array of string pointers) */
199 /* XXX: For glib >= 2.68 we could use a GStrvBuilder.
201 static char **
202 sync_pipe_add_arg(char **args, int *argc, const char *arg)
204 /* Grow the array; "*argc" currently contains the number of string
205 pointers, *not* counting the NULL pointer at the end, so we have
206 to add 2 in order to get the new size of the array, including the
207 new pointer and the terminating NULL pointer. */
208 args = (char **)g_realloc( (void *) args, (*argc + 2) * sizeof (char *));
210 /* Stuff the pointer into the penultimate element of the array, which
211 is the one at the index specified by "*argc". */
212 args[*argc] = g_strdup(arg);
213 /* Now bump the count. */
214 (*argc)++;
216 /* We overwrite the NULL pointer; put it back right after the
217 element we added. */
218 args[*argc] = NULL;
220 return args;
223 /* Take a buffer from an SP_LOG_MSG from dumpcap and send it to our
224 * current logger. Keep this in sync with the format used in
225 * dumpcap_log_writer. (We might want to do more proper serialization
226 * of more than just the log level.)
228 static void
229 sync_pipe_handle_log_msg(const char *buffer) {
230 const char *log_msg = NULL;
231 const char* end;
232 uint32_t level = 0;
234 if (ws_strtou32(buffer, &end, &level) && end[0] == ':') {
235 log_msg = end + 1;
237 ws_log(LOG_DOMAIN_CAPCHILD, level, "%s", log_msg);
240 /* Initialize an argument list and add dumpcap to it. */
241 static char **
242 init_pipe_args(int *argc) {
243 char *exename;
244 char **argv;
246 /* Find the absolute path of the dumpcap executable. */
247 exename = get_executable_path("dumpcap");
248 if (exename == NULL) {
249 return NULL;
252 /* Allocate the string pointer array with enough space for the
253 terminating NULL pointer. */
254 *argc = 0;
255 argv = (char **)g_malloc(sizeof (char *));
256 *argv = NULL;
258 /* Make that the first argument in the argument list (argv[0]). */
259 argv = sync_pipe_add_arg(argv, argc, exename);
261 /* Tell dumpcap to log at the lowest level its domain (Capchild) is
262 * set to log in the main program. (It might be in the special noisy
263 * or debug filter, so we can't just check the overall level.)
265 for (enum ws_log_level level = LOG_LEVEL_NOISY; level != _LOG_LEVEL_LAST; level++) {
266 if (ws_log_msg_is_active(LOG_DOMAIN_CAPCHILD, level)) {
267 argv = sync_pipe_add_arg(argv, argc, "--log-level");
268 argv = sync_pipe_add_arg(argv, argc, ws_log_level_to_string(level));
269 break;
273 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
274 g_free(exename);
276 return argv;
279 static gboolean
280 pipe_io_cb(GIOChannel *pipe_io, GIOCondition condition _U_, void * user_data)
282 capture_session *cap_session = (capture_session *)user_data;
283 if (!sync_pipe_input_cb(pipe_io, cap_session)) {
284 cap_session->pipe_input_id = 0;
285 return G_SOURCE_REMOVE;
287 return G_SOURCE_CONTINUE;
291 * Open two pipes to dumpcap with the supplied arguments, one for its
292 * standard output and one for its standard error.
294 * On success, *msg is unchanged and 0 is returned; data_read_fd,
295 * message_read_fd, and fork_child point to the standard output pipe's
296 * file descriptor, the standard error pipe's file descriptor, and
297 * the child's PID/handle, respectively.
299 * On failure, *msg points to an error message for the failure, and -1 is
300 * returned, in which case *msg must be freed with g_free().
302 #define ARGV_NUMBER_LEN 24
303 static int
304 #ifdef _WIN32
305 sync_pipe_open_command(char **argv, int *data_read_fd,
306 GIOChannel **message_read_io, int *signal_write_fd,
307 ws_process_id *fork_child, GArray *ifaces,
308 char **msg, void(*update_cb)(void))
309 #else
310 sync_pipe_open_command(char **argv, int *data_read_fd,
311 GIOChannel **message_read_io, int *signal_write_fd _U_,
312 ws_process_id *fork_child, GArray *ifaces _U_,
313 char **msg, void(*update_cb)(void))
314 #endif
316 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
317 int message_read_fd = -1;
318 char sync_id[ARGV_NUMBER_LEN];
319 #ifdef _WIN32
320 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
321 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
322 int signal_pipe_write_fd = -1;
323 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
324 char control_id[ARGV_NUMBER_LEN];
325 char *signal_pipe_name;
326 size_t i_handles = 0;
327 HANDLE *handles;
328 GString *args = g_string_sized_new(200);
329 char *quoted_arg;
330 SECURITY_ATTRIBUTES sa;
331 STARTUPINFO si;
332 PROCESS_INFORMATION pi;
333 int i;
334 unsigned j;
335 interface_options *interface_opts;
336 #else
337 int sync_pipe[2]; /* pipe used to send messages from child to parent */
338 int data_pipe[2]; /* pipe used to send data from child to parent */
339 #endif
340 *fork_child = WS_INVALID_PID;
341 if (data_read_fd != NULL) {
342 *data_read_fd = -1;
344 *message_read_io = NULL;
345 ws_debug("sync_pipe_open_command");
347 if (!msg) {
348 /* We can't return anything */
349 g_strfreev(argv);
350 #ifdef _WIN32
351 g_string_free(args, TRUE);
352 #endif
353 return -1;
356 #ifdef _WIN32
357 /* init SECURITY_ATTRIBUTES */
358 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
359 sa.bInheritHandle = false;
360 sa.lpSecurityDescriptor = NULL;
362 /* Create a pipe for the child process to send us messages */
363 /* (increase this value if you have trouble while fast capture file switches) */
364 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, PIPE_BUF_SIZE)) {
365 /* Couldn't create the message pipe between parent and child. */
366 *msg = ws_strdup_printf("Couldn't create sync pipe: %s",
367 win32strerror(GetLastError()));
368 g_strfreev(argv);
369 return -1;
373 * Associate a C run-time file handle with the Windows HANDLE for the
374 * read side of the message pipe.
376 * (See http://www.flounder.com/handles.htm for information on various
377 * types of file handle in C/C++ on Windows.)
379 message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
380 if (message_read_fd == -1) {
381 *msg = ws_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
382 g_strfreev(argv);
383 CloseHandle(sync_pipe[PIPE_READ]);
384 CloseHandle(sync_pipe[PIPE_WRITE]);
385 return -1;
388 if (data_read_fd != NULL) {
389 /* Create a pipe for the child process to send us data */
390 /* (increase this value if you have trouble while fast capture file switches) */
391 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, PIPE_BUF_SIZE)) {
392 /* Couldn't create the message pipe between parent and child. */
393 *msg = ws_strdup_printf("Couldn't create data pipe: %s",
394 win32strerror(GetLastError()));
395 g_strfreev(argv);
396 ws_close(message_read_fd); /* Should close sync_pipe[PIPE_READ] */
397 CloseHandle(sync_pipe[PIPE_WRITE]);
398 return -1;
402 * Associate a C run-time file handle with the Windows HANDLE for the
403 * read side of the data pipe.
405 * (See http://www.flounder.com/handles.htm for information on various
406 * types of file handle in C/C++ on Windows.)
408 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
409 if (*data_read_fd == -1) {
410 *msg = ws_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
411 g_strfreev(argv);
412 CloseHandle(data_pipe[PIPE_READ]);
413 CloseHandle(data_pipe[PIPE_WRITE]);
414 ws_close(message_read_fd); /* Should close sync_pipe[PIPE_READ] */
415 CloseHandle(sync_pipe[PIPE_WRITE]);
416 return -1;
420 if (signal_write_fd != NULL) {
421 /* Create the signal pipe */
422 snprintf(control_id, ARGV_NUMBER_LEN, "%ld", GetCurrentProcessId());
423 signal_pipe_name = ws_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
424 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
425 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
426 g_free(signal_pipe_name);
428 if (signal_pipe == INVALID_HANDLE_VALUE) {
429 /* Couldn't create the signal pipe between parent and child. */
430 *msg = ws_strdup_printf("Couldn't create signal pipe: %s",
431 win32strerror(GetLastError()));
432 g_strfreev(argv);
433 ws_close(message_read_fd); /* Should close sync_pipe[PIPE_READ] */
434 CloseHandle(sync_pipe[PIPE_WRITE]);
435 return -1;
439 * Associate a C run-time file handle with the Windows HANDLE for the
440 * read side of the message pipe.
442 * (See http://www.flounder.com/handles.htm for information on various
443 * types of file handle in C/C++ on Windows.)
445 signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
446 if (signal_pipe_write_fd == -1) {
447 /* Couldn't create the pipe between parent and child. */
448 *msg = ws_strdup_printf("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
449 g_strfreev(argv);
450 ws_close(message_read_fd); /* Should close sync_pipe[PIPE_READ] */
451 CloseHandle(sync_pipe[PIPE_WRITE]);
452 CloseHandle(signal_pipe);
453 return -1;
457 /* init STARTUPINFO & PROCESS_INFORMATION */
458 memset(&si, 0, sizeof(si));
459 si.cb = sizeof(si);
460 memset(&pi, 0, sizeof(pi));
461 #ifdef DEBUG_CHILD
462 si.dwFlags = STARTF_USESHOWWINDOW;
463 si.wShowWindow = SW_SHOW;
464 #else
465 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
466 si.wShowWindow = SW_HIDE; /* this hides the console window */
468 if (data_read_fd == NULL) {
469 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
470 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
471 } else {
472 si.hStdInput = NULL; /* handle for named pipe*/
473 si.hStdOutput = data_pipe[PIPE_WRITE];
475 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
477 /* On Windows, "[a]n inherited handle refers to the same object in the child
478 * process as it does in the parent process. It also has the same value."
479 * https://learn.microsoft.com/en-us/windows/win32/procthread/inheritance
480 * When converted to a file descriptor (via _open_osfhandle), the fd
481 * value is not necessarily the same in the two processes, but the handle
482 * value can be shared.
483 * A HANDLE is a void* though "64-bit versions of Windows use 32-bit handles
484 * for interoperability... only the lower 32 bits are significant, so it is
485 * safe to truncate the handle... or sign-extend the handle"
486 * https://learn.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
487 * So it should be fine to call PtrToLong instead of casting to intptr_t.
488 * https://learn.microsoft.com/en-us/windows/win32/WinProg64/rules-for-using-pointers
490 int argc = g_strv_length(argv);
491 argv = sync_pipe_add_arg(argv, &argc, "-Z");
492 snprintf(sync_id, ARGV_NUMBER_LEN, "%ld", PtrToLong(sync_pipe[PIPE_WRITE]));
493 argv = sync_pipe_add_arg(argv, &argc, sync_id);
494 #endif
496 if (ifaces) {
497 for (j = 0; j < ifaces->len; j++) {
498 interface_opts = &g_array_index(ifaces, interface_options, j);
499 if (interface_opts->extcap_fifo != NULL) {
500 i_handles++;
504 handles = g_new(HANDLE, 3 + i_handles);
505 i_handles = 0;
506 if (si.hStdInput) {
507 handles[i_handles++] = si.hStdInput;
509 if (si.hStdOutput && (si.hStdOutput != si.hStdInput)) {
510 handles[i_handles++] = si.hStdOutput;
512 handles[i_handles++] = sync_pipe[PIPE_WRITE];
513 if (ifaces) {
514 for (j = 0; j < ifaces->len; j++) {
515 interface_opts = &g_array_index(ifaces, interface_options, j);
516 if (interface_opts->extcap_fifo != NULL) {
517 handles[i_handles++] = interface_opts->extcap_pipe_h;
522 /* convert args array into a single string */
523 /* XXX - could change sync_pipe_add_arg() instead */
524 /* there is a drawback here: the length is internally limited to 1024 bytes */
525 for(i=0; argv[i] != 0; i++) {
526 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
527 quoted_arg = protect_arg(argv[i]);
528 g_string_append(args, quoted_arg);
529 g_free(quoted_arg);
532 /* call dumpcap */
533 if(!win32_create_process(argv[0], args->str, NULL, NULL, i_handles, handles,
534 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
535 *msg = ws_strdup_printf("Couldn't run %s in child process: %s",
536 args->str, win32strerror(GetLastError()));
537 if (data_read_fd) {
538 ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
539 CloseHandle(data_pipe[PIPE_WRITE]);
540 } else {
541 ws_close(signal_pipe_write_fd);
543 ws_close(message_read_fd); /* Should close sync_pipe[PIPE_READ] */
544 CloseHandle(sync_pipe[PIPE_WRITE]);
545 g_strfreev(argv);
546 g_string_free(args, TRUE);
547 g_free(handles);
548 return -1;
550 *fork_child = pi.hProcess;
551 /* We may need to store this and close it later */
552 CloseHandle(pi.hThread);
553 g_strfreev(argv);
554 g_string_free(args, TRUE);
555 g_free(handles);
557 if (signal_write_fd != NULL) {
558 *signal_write_fd = signal_pipe_write_fd;
560 #else /* _WIN32 */
561 /* Create a pipe for the child process to send us messages */
562 if (pipe(sync_pipe) < 0) {
563 /* Couldn't create the message pipe between parent and child. */
564 *msg = ws_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
565 g_strfreev(argv);
566 return -1;
569 if (data_read_fd != NULL) {
570 /* Create a pipe for the child process to send us data */
571 if (pipe(data_pipe) < 0) {
572 /* Couldn't create the data pipe between parent and child. */
573 *msg = ws_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
574 g_strfreev(argv);
575 ws_close(sync_pipe[PIPE_READ]);
576 ws_close(sync_pipe[PIPE_WRITE]);
577 return -1;
581 if ((*fork_child = fork()) == 0) {
583 * Child process - run dumpcap with the right arguments to make
584 * it just capture with the specified capture parameters
586 if (data_read_fd != NULL) {
587 dup2(data_pipe[PIPE_WRITE], 1);
588 ws_close(data_pipe[PIPE_READ]);
589 ws_close(data_pipe[PIPE_WRITE]);
591 ws_close(sync_pipe[PIPE_READ]);
592 /* dumpcap should be running in capture child mode (hidden feature) */
593 #ifndef DEBUG_CHILD
594 int argc = g_strv_length(argv);
595 argv = sync_pipe_add_arg(argv, &argc, "-Z");
596 snprintf(sync_id, ARGV_NUMBER_LEN, "%d", sync_pipe[PIPE_WRITE]);
597 argv = sync_pipe_add_arg(argv, &argc, sync_id);
598 #endif
599 execv(argv[0], argv);
600 sync_pipe_write_int_msg(sync_pipe[PIPE_WRITE], SP_EXEC_FAILED, errno);
602 /* Exit with "_exit()", so that we don't close the connection
603 to the X server (and cause stuff buffered up by our parent but
604 not yet sent to be sent, as that stuff should only be sent by
605 our parent). We've sent an error message to the parent, so
606 we exit with an exit status of 1 (any exit status other than
607 0 or 1 will cause an additional message to report that exit
608 status, over and above the error message we sent to the parent). */
609 _exit(1);
612 g_strfreev(argv);
614 if (fetch_dumpcap_pid && *fork_child > 0)
615 fetch_dumpcap_pid(*fork_child);
617 if (data_read_fd != NULL) {
618 *data_read_fd = data_pipe[PIPE_READ];
620 message_read_fd = sync_pipe[PIPE_READ];
622 #endif
624 /* Parent process - read messages from the child process over the
625 sync pipe. */
627 /* Close the write sides of the pipes, so that only the child has them
628 open, and thus they completely close, and thus return to us
629 an EOF indication, if the child closes them (either deliberately
630 or by exiting abnormally). */
631 #ifdef _WIN32
632 if (data_read_fd != NULL) {
633 CloseHandle(data_pipe[PIPE_WRITE]);
635 CloseHandle(sync_pipe[PIPE_WRITE]);
636 #else
637 if (data_read_fd != NULL) {
638 ws_close(data_pipe[PIPE_WRITE]);
640 ws_close(sync_pipe[PIPE_WRITE]);
641 #endif
643 if (*fork_child == WS_INVALID_PID) {
644 /* We couldn't even create the child process. */
645 *msg = ws_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
646 if (data_read_fd != NULL) {
647 ws_close(*data_read_fd);
649 #ifdef _WIN32
650 if (signal_write_fd != NULL) {
651 ws_close(signal_pipe_write_fd);
653 #endif
654 ws_close(message_read_fd);
655 return -1;
658 #ifdef _WIN32
659 *message_read_io = g_io_channel_win32_new_fd(message_read_fd);
660 #else
661 *message_read_io = g_io_channel_unix_new(message_read_fd);
662 #endif
663 g_io_channel_set_encoding(*message_read_io, NULL, NULL);
664 g_io_channel_set_buffered(*message_read_io, false);
665 g_io_channel_set_close_on_unref(*message_read_io, true);
667 /* we might wait for a moment till child is ready, so update screen now */
668 if (update_cb) update_cb();
669 return 0;
672 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
673 bool
674 sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
675 capture_session *cap_session, info_data_t* cap_data,
676 void (*update_cb)(void))
678 #ifdef _WIN32
679 size_t i_handles = 0;
680 char control_id[ARGV_NUMBER_LEN];
681 #endif
682 GIOChannel *sync_pipe_read_io;
683 int argc;
684 char **argv;
685 int i;
686 unsigned j;
687 interface_options *interface_opts;
689 if (capture_opts->ifaces->len > 1)
690 capture_opts->use_pcapng = true;
691 ws_debug("sync_pipe_start");
692 capture_opts_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, capture_opts);
694 cap_session->fork_child = WS_INVALID_PID;
695 cap_session->capture_opts = capture_opts;
697 if (!extcap_init_interfaces(cap_session)) {
698 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
699 return false;
702 argv = init_pipe_args(&argc);
703 if (!argv) {
704 /* We don't know where to find dumpcap. */
705 report_failure("We don't know where to find dumpcap.");
706 return false;
709 if (capture_opts->ifaces->len > 1)
710 argv = sync_pipe_add_arg(argv, &argc, "-t");
712 argv = sync_pipe_add_arg(argv, &argc, "-F");
713 if (capture_opts->use_pcapng)
714 argv = sync_pipe_add_arg(argv, &argc, "pcapng");
715 else
716 argv = sync_pipe_add_arg(argv, &argc, "pcap");
718 if (capture_comments != NULL) {
719 for (j = 0; j < capture_comments->len; j++) {
720 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
721 argv = sync_pipe_add_arg(argv, &argc, (char*)g_ptr_array_index(capture_comments, j));
725 if (capture_opts->temp_dir) {
726 argv = sync_pipe_add_arg(argv, &argc, "--temp-dir");
727 argv = sync_pipe_add_arg(argv, &argc, capture_opts->temp_dir);
730 if (capture_opts->multi_files_on) {
731 if (capture_opts->has_autostop_filesize) {
732 char sfilesize[ARGV_NUMBER_LEN];
733 argv = sync_pipe_add_arg(argv, &argc, "-b");
734 snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
735 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
738 if (capture_opts->has_file_duration) {
739 char sfile_duration[ARGV_NUMBER_LEN];
740 argv = sync_pipe_add_arg(argv, &argc, "-b");
741 snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->file_duration);
742 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
745 if (capture_opts->has_file_interval) {
746 char sfile_interval[ARGV_NUMBER_LEN];
747 argv = sync_pipe_add_arg(argv, &argc, "-b");
748 snprintf(sfile_interval, ARGV_NUMBER_LEN, "interval:%d",capture_opts->file_interval);
749 argv = sync_pipe_add_arg(argv, &argc, sfile_interval);
752 if (capture_opts->has_file_packets) {
753 char sfile_packets[ARGV_NUMBER_LEN];
754 argv = sync_pipe_add_arg(argv, &argc, "-b");
755 snprintf(sfile_packets, ARGV_NUMBER_LEN, "packets:%d",capture_opts->file_packets);
756 argv = sync_pipe_add_arg(argv, &argc, sfile_packets);
759 if (capture_opts->has_ring_num_files) {
760 char sring_num_files[ARGV_NUMBER_LEN];
761 argv = sync_pipe_add_arg(argv, &argc, "-b");
762 snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
763 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
766 if (capture_opts->print_file_names) {
767 char *print_name = g_strdup_printf("printname:%s", capture_opts->print_name_to);
768 argv = sync_pipe_add_arg(argv, &argc, "-b");
769 argv = sync_pipe_add_arg(argv, &argc, print_name);
770 g_free(print_name);
773 if (capture_opts->has_nametimenum) {
774 char nametimenum[ARGV_NUMBER_LEN];
775 argv = sync_pipe_add_arg(argv, &argc, "-b");
776 snprintf(nametimenum, ARGV_NUMBER_LEN, "nametimenum:2");
777 argv = sync_pipe_add_arg(argv, &argc, nametimenum);
780 if (capture_opts->has_autostop_files) {
781 char sautostop_files[ARGV_NUMBER_LEN];
782 argv = sync_pipe_add_arg(argv, &argc, "-a");
783 snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
784 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
786 } else {
787 if (capture_opts->has_autostop_filesize) {
788 char sautostop_filesize[ARGV_NUMBER_LEN];
789 argv = sync_pipe_add_arg(argv, &argc, "-a");
790 snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
791 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
795 if (capture_opts->has_autostop_packets) {
796 char scount[ARGV_NUMBER_LEN];
797 argv = sync_pipe_add_arg(argv, &argc, "-c");
798 snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
799 argv = sync_pipe_add_arg(argv, &argc, scount);
802 if (capture_opts->has_autostop_duration) {
803 char sautostop_duration[ARGV_NUMBER_LEN];
804 argv = sync_pipe_add_arg(argv, &argc, "-a");
805 snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->autostop_duration);
806 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
809 if (capture_opts->has_autostop_written_packets) {
810 char scount[ARGV_NUMBER_LEN];
811 argv = sync_pipe_add_arg(argv, &argc, "-a");
812 snprintf(scount, ARGV_NUMBER_LEN, "packets:%d",capture_opts->autostop_written_packets);
813 argv = sync_pipe_add_arg(argv, &argc, scount);
816 if (capture_opts->group_read_access) {
817 argv = sync_pipe_add_arg(argv, &argc, "-g");
820 if (capture_opts->update_interval != DEFAULT_UPDATE_INTERVAL) {
821 char scount[ARGV_NUMBER_LEN];
822 argv = sync_pipe_add_arg(argv, &argc, "--update-interval");
823 snprintf(scount, ARGV_NUMBER_LEN, "%d", capture_opts->update_interval);
824 argv = sync_pipe_add_arg(argv, &argc, scount);
827 for (j = 0; j < capture_opts->ifaces->len; j++) {
828 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, j);
830 argv = sync_pipe_add_arg(argv, &argc, "-i");
831 if (interface_opts->extcap_fifo != NULL)
833 #ifdef _WIN32
834 char *pipe = ws_strdup_printf("%s%" PRIuMAX, EXTCAP_PIPE_PREFIX, (uintmax_t)interface_opts->extcap_pipe_h);
835 argv = sync_pipe_add_arg(argv, &argc, pipe);
836 g_free(pipe);
837 i_handles++;
838 #else
839 argv = sync_pipe_add_arg(argv, &argc, interface_opts->extcap_fifo);
840 #endif
841 /* Add a name for the interface, to put into an IDB. */
842 argv = sync_pipe_add_arg(argv, &argc, "--ifname");
843 argv = sync_pipe_add_arg(argv, &argc, interface_opts->name);
845 else
846 argv = sync_pipe_add_arg(argv, &argc, interface_opts->name);
848 if (interface_opts->descr != NULL)
850 /* Add a description for the interface to put into an IDB and
851 * use for the temporary filename. */
852 argv = sync_pipe_add_arg(argv, &argc, "--ifdescr");
853 argv = sync_pipe_add_arg(argv, &argc, interface_opts->descr);
856 if (interface_opts->cfilter != NULL && strlen(interface_opts->cfilter) != 0) {
857 argv = sync_pipe_add_arg(argv, &argc, "-f");
858 argv = sync_pipe_add_arg(argv, &argc, interface_opts->cfilter);
860 if (interface_opts->has_snaplen) {
861 char ssnap[ARGV_NUMBER_LEN];
862 argv = sync_pipe_add_arg(argv, &argc, "-s");
863 snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts->snaplen);
864 argv = sync_pipe_add_arg(argv, &argc, ssnap);
867 if (interface_opts->linktype != -1) {
868 const char *linktype = linktype_val_to_name(interface_opts->linktype);
869 if ( linktype != NULL )
871 argv = sync_pipe_add_arg(argv, &argc, "-y");
872 argv = sync_pipe_add_arg(argv, &argc, linktype);
876 if (!interface_opts->promisc_mode) {
877 argv = sync_pipe_add_arg(argv, &argc, "-p");
880 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
881 if (interface_opts->buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
882 char buffer_size[ARGV_NUMBER_LEN];
883 argv = sync_pipe_add_arg(argv, &argc, "-B");
884 if(interface_opts->buffer_size == 0x00)
885 interface_opts->buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
886 snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts->buffer_size);
887 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
889 #endif
891 #ifdef HAVE_PCAP_CREATE
892 if (interface_opts->monitor_mode) {
893 argv = sync_pipe_add_arg(argv, &argc, "-I");
895 #endif
897 #ifdef HAVE_PCAP_REMOTE
898 if (interface_opts->datatx_udp)
899 argv = sync_pipe_add_arg(argv, &argc, "-u");
901 if (!interface_opts->nocap_rpcap)
902 argv = sync_pipe_add_arg(argv, &argc, "-r");
904 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
905 char sauth[256];
906 argv = sync_pipe_add_arg(argv, &argc, "-A");
907 snprintf(sauth, sizeof(sauth), "%s:%s",
908 interface_opts->auth_username,
909 interface_opts->auth_password);
910 argv = sync_pipe_add_arg(argv, &argc, sauth);
912 #endif
914 #ifdef HAVE_PCAP_SETSAMPLING
915 if (interface_opts->sampling_method != CAPTURE_SAMP_NONE) {
916 char ssampling[ARGV_NUMBER_LEN];
917 argv = sync_pipe_add_arg(argv, &argc, "-m");
918 snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
919 interface_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
920 interface_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
921 "undef",
922 interface_opts->sampling_param);
923 argv = sync_pipe_add_arg(argv, &argc, ssampling);
925 #endif
926 if (interface_opts->timestamp_type) {
927 argv = sync_pipe_add_arg(argv, &argc, "--time-stamp-type");
928 argv = sync_pipe_add_arg(argv, &argc, interface_opts->timestamp_type);
932 #ifndef DEBUG_CHILD
933 #ifdef _WIN32
934 /* pass process id to dumpcap for named signal pipe */
935 argv = sync_pipe_add_arg(argv, &argc, "--signal-pipe");
936 snprintf(control_id, ARGV_NUMBER_LEN, "%ld", GetCurrentProcessId());
937 argv = sync_pipe_add_arg(argv, &argc, control_id);
938 #endif
939 #endif
941 if (capture_opts->save_file) {
942 argv = sync_pipe_add_arg(argv, &argc, "-w");
943 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
945 for (i = 0; i < argc; i++) {
946 ws_debug("argv[%d]: %s", i, argv[i]);
948 if (capture_opts->compress_type) {
949 argv = sync_pipe_add_arg(argv, &argc, "--compress-type");
950 argv = sync_pipe_add_arg(argv, &argc, capture_opts->compress_type);
953 int ret;
954 char* msg;
955 #ifdef _WIN32
956 ret = sync_pipe_open_command(argv, NULL, &sync_pipe_read_io, &cap_session->signal_pipe_write_fd,
957 &cap_session->fork_child, capture_opts->ifaces, &msg, update_cb);
958 #else
959 ret = sync_pipe_open_command(argv, NULL, &sync_pipe_read_io, NULL,
960 &cap_session->fork_child, NULL, &msg, update_cb);
961 #endif
963 if (ret == -1) {
964 report_failure("%s", msg);
965 g_free(msg);
966 return false;
969 /* Parent process - read messages from the child process over the
970 sync pipe. */
972 cap_session->fork_child_status = 0;
973 cap_session->cap_data_info = cap_data;
975 /* We were able to set up to read the capture file;
976 arrange that our callback be called whenever it's possible
977 to read from the sync pipe, so that it's called when
978 the child process wants to tell us something. */
980 /* we have a running capture, now wait for the real capture filename */
981 if (cap_session->pipe_input_id) {
982 g_source_remove(cap_session->pipe_input_id);
983 cap_session->pipe_input_id = 0;
985 cap_session->pipe_input_id = g_io_add_watch(sync_pipe_read_io, G_IO_IN | G_IO_HUP, pipe_io_cb, cap_session);
986 /* Pipe will be closed when watch is removed */
987 g_io_channel_unref(sync_pipe_read_io);
989 return true;
993 * Close the pipes we're using to read from dumpcap, and wait for it
994 * to exit. On success, *msgp is unchanged, and the exit status of
995 * dumpcap is returned. On failure (which includes "dumpcap exited
996 * due to being killed by a signal or an exception"), *msgp points
997 * to an error message for the failure, and -1 is returned. In the
998 * latter case, *msgp must be freed with g_free().
1000 static int
1001 sync_pipe_close_command(int *data_read_fd, GIOChannel *message_read_io,
1002 ws_process_id *fork_child, char **msgp)
1004 ws_close(*data_read_fd);
1005 if (message_read_io != NULL)
1006 g_io_channel_unref(message_read_io);
1008 #ifdef _WIN32
1009 /* XXX - Should we signal the child somehow? */
1010 sync_pipe_kill(*fork_child);
1011 #endif
1013 return sync_pipe_wait_for_child(*fork_child, msgp);
1017 * Run dumpcap with the supplied arguments.
1019 * On success, *data points to a buffer containing the dumpcap output,
1020 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
1021 * must be freed with g_free().
1023 * On failure, *data is NULL, *primary_msg points to an error message,
1024 * *secondary_msg either points to an additional error message or is
1025 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1026 * must be freed with g_free().
1028 static int
1029 sync_pipe_run_command_actual(char **argv, char **data, char **primary_msg,
1030 char **secondary_msg, void(*update_cb)(void))
1032 char *msg;
1033 int data_pipe_read_fd, ret;
1034 GIOChannel *sync_pipe_read_io;
1035 ws_process_id fork_child;
1036 char *wait_msg;
1037 char *buffer = g_malloc(PIPE_BUF_SIZE + 1);
1038 ssize_t nread;
1039 char indicator;
1040 int32_t exec_errno = 0;
1041 int primary_msg_len;
1042 char *primary_msg_text;
1043 int secondary_msg_len;
1044 char *secondary_msg_text;
1045 char *combined_msg;
1046 GString *data_buf = NULL;
1047 ssize_t count;
1049 if (buffer == NULL) {
1050 /* g_malloc is supposed to terminate the program if this fails, but,
1051 * at least on a RELEASE build, some versions of gcc don't think that
1052 * happens.
1054 *primary_msg = ws_strdup_printf("Couldn't allocate memory for dumpcap output buffer: %s",
1055 g_strerror(errno));
1056 *secondary_msg = NULL;
1057 *data = NULL;
1058 return -1;
1061 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_io, NULL,
1062 &fork_child, NULL, &msg, update_cb);
1063 if (ret == -1) {
1064 *primary_msg = msg;
1065 *secondary_msg = NULL;
1066 *data = NULL;
1067 g_free(buffer);
1068 return -1;
1072 * We were able to set up to read dumpcap's output. Do so.
1074 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1076 do {
1077 nread = pipe_read_block(sync_pipe_read_io, &indicator, SP_MAX_MSG_LEN,
1078 buffer, primary_msg);
1079 if(nread <= 0) {
1080 /* We got a read error from the sync pipe, or we got no data at
1081 all from the sync pipe, so we're not going to be getting any
1082 data or error message from the child process. Pick up its
1083 exit status, and complain.
1085 We don't have to worry about killing the child, if the sync pipe
1086 returned an error. Usually this error is caused as the child killed
1087 itself while going down. Even in the rare cases that this isn't the
1088 case, the child will get an error when writing to the broken pipe
1089 the next time, cleaning itself up then. */
1090 g_io_channel_unref(sync_pipe_read_io);
1091 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1092 if(nread == 0) {
1093 /* We got an EOF from the sync pipe. That means that it exited
1094 before giving us any data to read. If ret is -1, we report
1095 that as a bad exit (e.g., exiting due to a signal); otherwise,
1096 we report it as a premature exit. */
1097 if (ret == -1)
1098 *primary_msg = wait_msg;
1099 else
1100 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1101 } else {
1102 /* We got an error from the sync pipe. If ret is -1, report
1103 both the sync pipe I/O error and the wait error. */
1104 if (ret == -1) {
1105 combined_msg = ws_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1106 g_free(*primary_msg);
1107 g_free(wait_msg);
1108 *primary_msg = combined_msg;
1111 *secondary_msg = NULL;
1112 *data = NULL;
1113 g_free(buffer);
1115 return -1;
1118 /* we got a valid message block from the child, process it */
1119 switch(indicator) {
1121 case SP_EXEC_FAILED:
1123 * Exec of dumpcap failed. Get the errno for the failure.
1125 if (!ws_strtoi32(buffer, NULL, &exec_errno)) {
1126 ws_warning("Invalid errno: %s", buffer);
1130 * Pick up the child status.
1132 ret = sync_pipe_close_command(&data_pipe_read_fd, sync_pipe_read_io,
1133 &fork_child, &msg);
1134 if (ret == -1) {
1136 * Child process failed unexpectedly, or wait failed; msg is the
1137 * error message.
1139 *primary_msg = msg;
1140 *secondary_msg = NULL;
1141 } else {
1143 * Child process failed, but returned the expected exit status.
1144 * Return the messages it gave us, and indicate failure.
1146 *primary_msg = ws_strdup_printf("Couldn't run dumpcap in child process: %s",
1147 g_strerror(exec_errno));
1148 *secondary_msg = NULL;
1149 ret = -1;
1151 *data = NULL;
1152 break;
1154 case SP_ERROR_MSG:
1156 * Error from dumpcap; there will be a primary message and a
1157 * secondary message.
1160 /* convert primary message */
1161 pipe_convert_header((unsigned char*)buffer, 4, &indicator, &primary_msg_len);
1162 primary_msg_text = buffer+4;
1163 /* convert secondary message */
1164 pipe_convert_header((unsigned char*)primary_msg_text + primary_msg_len, 4, &indicator,
1165 &secondary_msg_len);
1166 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1167 /* the capture child will close the sync_pipe, nothing to do */
1170 * Pick up the child status.
1172 ret = sync_pipe_close_command(&data_pipe_read_fd, sync_pipe_read_io,
1173 &fork_child, &msg);
1174 if (ret == -1) {
1176 * Child process failed unexpectedly, or wait failed; msg is the
1177 * error message.
1179 *primary_msg = msg;
1180 *secondary_msg = NULL;
1181 } else {
1183 * Child process failed, but returned the expected exit status.
1184 * Return the messages it gave us, and indicate failure.
1186 *primary_msg = g_strdup(primary_msg_text);
1187 *secondary_msg = g_strdup(secondary_msg_text);
1188 ret = -1;
1190 *data = NULL;
1191 break;
1193 case SP_LOG_MSG:
1195 * Log from dumpcap; pass to our log
1197 sync_pipe_handle_log_msg(buffer);
1198 break;
1200 case SP_SUCCESS:
1201 /* read the output from the command */
1202 data_buf = g_string_new("");
1203 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1204 buffer[count] = '\0';
1205 g_string_append(data_buf, buffer);
1209 * Pick up the child status.
1211 ret = sync_pipe_close_command(&data_pipe_read_fd, sync_pipe_read_io,
1212 &fork_child, &msg);
1213 if (ret == -1) {
1215 * Child process failed unexpectedly, or wait failed; msg is the
1216 * error message.
1218 *primary_msg = msg;
1219 *secondary_msg = NULL;
1220 g_string_free(data_buf, TRUE);
1221 *data = NULL;
1222 } else {
1224 * Child process succeeded.
1226 *primary_msg = NULL;
1227 *secondary_msg = NULL;
1228 *data = g_string_free(data_buf, FALSE);
1230 break;
1232 default:
1234 * Pick up the child status.
1236 ret = sync_pipe_close_command(&data_pipe_read_fd, sync_pipe_read_io,
1237 &fork_child, &msg);
1238 if (ret == -1) {
1240 * Child process failed unexpectedly, or wait failed; msg is the
1241 * error message.
1243 *primary_msg = msg;
1244 *secondary_msg = NULL;
1245 } else {
1247 * Child process returned an unknown status.
1249 *primary_msg = ws_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1250 indicator);
1251 *secondary_msg = NULL;
1252 ret = -1;
1254 *data = NULL;
1255 break;
1257 } while (indicator != SP_SUCCESS && ret != -1);
1259 g_free(buffer);
1260 return ret;
1263 /* centralised logging and timing for sync_pipe_run_command_actual(),
1264 * redirects to sync_pipe_run_command_actual()
1266 static int
1267 sync_pipe_run_command(char **argv, char **data, char **primary_msg,
1268 char **secondary_msg, void (*update_cb)(void))
1270 int ret, i;
1271 int64_t start_time;
1272 double elapsed;
1273 int logging_enabled;
1275 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1276 logging_enabled = ws_log_msg_is_active(WS_LOG_DOMAIN, LOG_LEVEL_INFO);
1277 if (logging_enabled) {
1278 start_time = g_get_monotonic_time();
1279 ws_debug("sync_pipe_run_command() starts");
1280 for (i=0; argv[i] != 0; i++) {
1281 ws_noisy(" argv[%d]: %s", i, argv[i]);
1284 /* do the actual sync pipe run command */
1285 ret = sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1287 if (logging_enabled) {
1288 elapsed = (g_get_monotonic_time() - start_time) / 1e6;
1290 ws_debug("sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1293 return ret;
1298 sync_interface_set_80211_chan(const char *iface, const char *freq, const char *type,
1299 const char *center_freq1, const char *center_freq2,
1300 char **data, char **primary_msg,
1301 char **secondary_msg, void (*update_cb)(void))
1303 int argc, ret;
1304 char **argv;
1305 char *opt;
1307 argv = init_pipe_args(&argc);
1309 if (!argv) {
1310 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1311 *secondary_msg = NULL;
1312 *data = NULL;
1313 return -1;
1316 argv = sync_pipe_add_arg(argv, &argc, "-i");
1317 argv = sync_pipe_add_arg(argv, &argc, iface);
1319 if (center_freq2)
1320 opt = ws_strdup_printf("%s,%s,%s,%s", freq, type, center_freq1, center_freq2);
1321 else if (center_freq1)
1322 opt = ws_strdup_printf("%s,%s,%s", freq, type, center_freq1);
1323 else if (type)
1324 opt = ws_strdup_printf("%s,%s", freq, type);
1325 else
1326 opt = g_strdup(freq);
1328 if (!opt) {
1329 *primary_msg = g_strdup("Out of mem.");
1330 *secondary_msg = NULL;
1331 *data = NULL;
1332 return -1;
1335 argv = sync_pipe_add_arg(argv, &argc, "-k");
1336 argv = sync_pipe_add_arg(argv, &argc, opt);
1338 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1339 g_free(opt);
1340 return ret;
1344 * Get the list of interfaces using dumpcap.
1346 * On success, *data points to a buffer containing the dumpcap output,
1347 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1348 * must be freed with g_free().
1350 * On failure, *data is NULL, *primary_msg points to an error message,
1351 * *secondary_msg either points to an additional error message or is
1352 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1353 * must be freed with g_free().
1356 sync_interface_list_open(char **data, char **primary_msg,
1357 char **secondary_msg, void (*update_cb)(void))
1359 int argc;
1360 char **argv;
1361 int ret;
1363 ws_debug("sync_interface_list_open");
1365 argv = init_pipe_args(&argc);
1367 if (!argv) {
1368 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1369 *secondary_msg = NULL;
1370 *data = NULL;
1371 return -1;
1374 /* Ask for the interface list */
1375 argv = sync_pipe_add_arg(argv, &argc, "-D");
1377 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1378 return ret;
1382 * Get the capabilities of an interface using dumpcap.
1384 * On success, *data points to a buffer containing the dumpcap output,
1385 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1386 * must be freed with g_free().
1388 * On failure, *data is NULL, *primary_msg points to an error message,
1389 * *secondary_msg either points to an additional error message or is
1390 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1391 * must be freed with g_free().
1394 sync_if_capabilities_open(const char *ifname, bool monitor_mode, const char* auth,
1395 char **data, char **primary_msg,
1396 char **secondary_msg, void (*update_cb)(void))
1398 int argc;
1399 char **argv;
1400 int ret;
1402 ws_debug("sync_if_capabilities_open");
1404 argv = init_pipe_args(&argc);
1406 if (!argv) {
1407 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1408 *secondary_msg = NULL;
1409 *data = NULL;
1410 return -1;
1413 /* Ask for the interface capabilities */
1414 argv = sync_pipe_add_arg(argv, &argc, "-i");
1415 argv = sync_pipe_add_arg(argv, &argc, ifname);
1416 argv = sync_pipe_add_arg(argv, &argc, "-L");
1417 argv = sync_pipe_add_arg(argv, &argc, "--list-time-stamp-types");
1418 if (monitor_mode)
1419 argv = sync_pipe_add_arg(argv, &argc, "-I");
1420 if (auth) {
1421 argv = sync_pipe_add_arg(argv, &argc, "-A");
1422 argv = sync_pipe_add_arg(argv, &argc, auth);
1425 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1426 return ret;
1430 sync_if_list_capabilities_open(GList *if_queries,
1431 char **data, char **primary_msg,
1432 char **secondary_msg, void (*update_cb)(void))
1434 int argc;
1435 char **argv;
1436 int ret;
1437 if_cap_query_t *if_cap_query;
1439 ws_debug("sync_if_list_capabilities_open");
1441 argv = init_pipe_args(&argc);
1443 if (!argv) {
1444 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1445 *secondary_msg = NULL;
1446 *data = NULL;
1447 return -1;
1450 for (GList *li = if_queries; li != NULL; li = g_list_next(li)) {
1451 if_cap_query = (if_cap_query_t*)li->data;
1452 /* Ask for the interface capabilities */
1453 argv = sync_pipe_add_arg(argv, &argc, "-i");
1454 argv = sync_pipe_add_arg(argv, &argc, if_cap_query->name);
1455 if (if_cap_query->monitor_mode)
1456 argv = sync_pipe_add_arg(argv, &argc, "-I");
1457 if (if_cap_query->auth_username && if_cap_query->auth_password) {
1458 char sauth[256];
1459 argv = sync_pipe_add_arg(argv, &argc, "-A");
1460 snprintf(sauth, sizeof(sauth), "%s:%s",
1461 if_cap_query->auth_username,
1462 if_cap_query->auth_password);
1463 argv = sync_pipe_add_arg(argv, &argc, sauth);
1466 argv = sync_pipe_add_arg(argv, &argc, "-L");
1467 argv = sync_pipe_add_arg(argv, &argc, "--list-time-stamp-types");
1469 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1470 return ret;
1474 * Start getting interface statistics using dumpcap. On success, read_fd
1475 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1476 * and zero is returned. On failure, *msg will point to an error message
1477 * that must be g_free()d, and -1 will be returned.
1478 * If data is not NULL, then it will also be set to point to a JSON
1479 * serialization of the list of local interfaces and their capabilities.
1482 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, char **data, char **msg, void (*update_cb)(void))
1484 int argc;
1485 char **argv;
1486 int ret;
1487 GIOChannel *message_read_io;
1488 char *wait_msg;
1489 char *buffer = g_malloc(PIPE_BUF_SIZE + 1);
1490 ssize_t nread;
1491 char indicator;
1492 int32_t exec_errno = 0;
1493 int primary_msg_len;
1494 char *primary_msg_text;
1495 int secondary_msg_len;
1496 /*char *secondary_msg_text;*/
1497 char *combined_msg;
1499 ws_debug("sync_interface_stats_open");
1501 argv = init_pipe_args(&argc);
1503 if (!argv) {
1504 *msg = g_strdup("We don't know where to find dumpcap.");
1505 g_free(buffer);
1506 return -1;
1509 /* Ask for the interface statistics */
1510 argv = sync_pipe_add_arg(argv, &argc, "-S");
1512 /* If requested, ask for the interface list and capabilities. */
1513 if (data) {
1514 argv = sync_pipe_add_arg(argv, &argc, "-D");
1515 argv = sync_pipe_add_arg(argv, &argc, "-L");
1518 #ifndef DEBUG_CHILD
1519 #ifdef _WIN32
1520 argv = sync_pipe_add_arg(argv, &argc, "--signal-pipe");
1521 ret = create_dummy_signal_pipe(msg);
1522 if (ret == -1) {
1523 g_free(buffer);
1524 return -1;
1526 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1527 #endif
1528 #endif
1529 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_io, NULL,
1530 fork_child, NULL, msg, update_cb);
1531 if (ret == -1) {
1532 g_free(buffer);
1533 return -1;
1537 * We were able to set up to read dumpcap's output. Do so.
1539 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1541 do {
1542 nread = pipe_read_block(message_read_io, &indicator, SP_MAX_MSG_LEN,
1543 buffer, msg);
1544 if(nread <= 0) {
1545 /* We got a read error from the sync pipe, or we got no data at
1546 all from the sync pipe, so we're not going to be getting any
1547 data or error message from the child process. Pick up its
1548 exit status, and complain.
1550 We don't have to worry about killing the child, if the sync pipe
1551 returned an error. Usually this error is caused as the child killed
1552 itself while going down. Even in the rare cases that this isn't the
1553 case, the child will get an error when writing to the broken pipe
1554 the next time, cleaning itself up then. */
1555 g_io_channel_unref(message_read_io);
1556 ws_close(*data_read_fd);
1557 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1558 if(nread == 0) {
1559 /* We got an EOF from the sync pipe. That means that it exited
1560 before giving us any data to read. If ret is -1, we report
1561 that as a bad exit (e.g., exiting due to a signal); otherwise,
1562 we report it as a premature exit. */
1563 if (ret == -1)
1564 *msg = wait_msg;
1565 else
1566 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1567 } else {
1568 /* We got an error from the sync pipe. If ret is -1, report
1569 both the sync pipe I/O error and the wait error. */
1570 if (ret == -1) {
1571 combined_msg = ws_strdup_printf("%s\n\n%s", *msg, wait_msg);
1572 g_free(*msg);
1573 g_free(wait_msg);
1574 *msg = combined_msg;
1577 g_free(buffer);
1578 return -1;
1581 /* we got a valid message block from the child, process it */
1582 switch(indicator) {
1584 case SP_EXEC_FAILED:
1586 * Exec of dumpcap failed. Get the errno for the failure.
1588 if (!ws_strtoi32(buffer, NULL, &exec_errno)) {
1589 ws_warning("Invalid errno: %s", buffer);
1591 *msg = ws_strdup_printf("Couldn't run dumpcap in child process: %s",
1592 g_strerror(exec_errno));
1595 * Pick up the child status.
1597 char *close_msg = NULL;
1598 sync_pipe_close_command(data_read_fd, message_read_io,
1599 fork_child, &close_msg);
1601 * Ignore the error from sync_pipe_close_command, presumably the one
1602 * returned by the child is more pertinent to what went wrong.
1604 g_free(close_msg);
1605 ret = -1;
1606 break;
1608 case SP_ERROR_MSG:
1610 * Error from dumpcap; there will be a primary message and a
1611 * secondary message.
1614 /* convert primary message */
1615 pipe_convert_header((unsigned char*)buffer, 4, &indicator, &primary_msg_len);
1616 primary_msg_text = buffer+4;
1617 /* convert secondary message */
1618 pipe_convert_header((unsigned char*)primary_msg_text + primary_msg_len, 4, &indicator,
1619 &secondary_msg_len);
1620 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1621 /* the capture child will close the sync_pipe, nothing to do */
1624 * Pick up the child status.
1626 ret = sync_pipe_close_command(data_read_fd, message_read_io,
1627 fork_child, msg);
1628 if (ret == -1) {
1630 * Child process failed unexpectedly, or wait failed; msg is the
1631 * error message.
1633 } else if (ret == WS_EXIT_NO_INTERFACES) {
1635 * No interfaces were found. If that's not the
1636 * result of an error when fetching the local
1637 * interfaces, let the user know.
1639 *msg = g_strdup(primary_msg_text);
1640 } else {
1642 * Child process failed, but returned the expected exit status.
1643 * Return the messages it gave us, and indicate failure.
1645 *msg = g_strdup(primary_msg_text);
1646 ret = -1;
1648 g_free(buffer);
1649 return ret;
1651 case SP_LOG_MSG:
1653 * Log from dumpcap; pass to our log
1655 sync_pipe_handle_log_msg(buffer);
1656 break;
1658 case SP_IFACE_LIST:
1660 * Dumpcap giving us the interface list
1663 /* convert primary message */
1664 if (data) {
1665 *data = g_strdup(buffer);
1667 break;
1669 case SP_SUCCESS:
1670 /* Close the message pipe. */
1671 g_io_channel_unref(message_read_io);
1672 break;
1674 default:
1676 * Pick up the child status.
1678 ret = sync_pipe_close_command(data_read_fd, message_read_io,
1679 fork_child, msg);
1680 if (ret == -1) {
1682 * Child process failed unexpectedly, or wait failed; msg is the
1683 * error message.
1685 } else {
1687 * Child process returned an unknown status.
1689 *msg = ws_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1690 indicator);
1691 ret = -1;
1693 break;
1695 } while (indicator != SP_SUCCESS && ret != -1);
1697 g_free(buffer);
1698 return ret;
1701 /* Close down the stats process */
1703 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, char **msg)
1705 #ifdef _WIN32
1706 CloseHandle(dummy_signal_pipe);
1707 dummy_signal_pipe = NULL;
1708 #else
1710 * Don't bother waiting for the child. sync_pipe_close_command
1711 * does this for us on Windows.
1713 sync_pipe_kill(*fork_child);
1714 #endif
1715 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1718 /* read a number of bytes from a pipe */
1719 /* (blocks until enough bytes read or an error occurs) */
1720 static ssize_t
1721 pipe_read_bytes(GIOChannel *pipe_io, char *bytes, size_t required, char **msg)
1723 GError *err = NULL;
1724 size_t newly;
1725 size_t offset = 0;
1727 while(required) {
1728 g_io_channel_read_chars(pipe_io, &bytes[offset], required, &newly, &err);
1729 if (err != NULL) {
1730 ws_debug("read from pipe %p: error(%u): %s", pipe_io, err->code, err->message);
1731 *msg = ws_strdup_printf("Error reading from sync pipe: %s", err->message);
1732 g_clear_error(&err);
1733 return -1;
1735 if (newly == 0) {
1736 /* EOF */
1737 ws_debug("read from pipe %p: EOF (capture closed?)", pipe_io);
1738 *msg = 0;
1739 return offset;
1742 required -= newly;
1743 offset += newly;
1746 *msg = NULL;
1747 return offset;
1751 * Read a line from a pipe; similar to fgets, but doesn't block.
1753 * XXX - just stops reading if there's nothing to be read right now;
1754 * that could conceivably mean that you don't get a complete line.
1757 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1758 ssize_t newly;
1759 int offset = -1;
1761 while(offset < max - 1) {
1762 offset++;
1763 if (! ws_pipe_data_available(pipe_fd))
1764 break;
1765 newly = ws_read(pipe_fd, &bytes[offset], 1);
1766 if (newly == 0) {
1767 /* EOF - not necessarily an error */
1768 break;
1769 } else if (newly == -1) {
1770 /* error */
1771 ws_debug("read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1772 return -1;
1773 } else if (bytes[offset] == '\n') {
1774 break;
1778 if (offset >= 0)
1779 bytes[offset] = '\0';
1781 return offset;
1785 /* convert header values (indicator and 3-byte length) */
1786 static void
1787 pipe_convert_header(const unsigned char *header, int header_len _U_, char *indicator, int *block_len) {
1789 ws_assert(header_len == 4);
1791 /* convert header values */
1792 *indicator = header[0];
1793 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1796 /* read a message from the sending pipe in the standard format
1797 (1-byte message indicator, 3-byte message length (excluding length
1798 and indicator field), and the rest is the message) */
1799 static ssize_t
1800 pipe_read_block(GIOChannel *pipe_io, char *indicator, int len, char *msg,
1801 char **err_msg)
1803 int required;
1804 ssize_t newly;
1805 char header[4];
1807 /* read header (indicator and 3-byte length) */
1808 newly = pipe_read_bytes(pipe_io, header, 4, err_msg);
1809 if(newly != 4) {
1810 if (newly == 0) {
1812 * Immediate EOF; if the capture child exits normally, this
1813 * is an "I'm done" indication, so don't report it as an
1814 * error.
1816 ws_debug("read %p got an EOF", pipe_io);
1817 return 0;
1819 ws_debug("read %p failed to read header: %lu", pipe_io, (long)newly);
1820 if (newly != -1) {
1822 * Short read, but not an immediate EOF.
1824 *err_msg = ws_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1825 (long)newly);
1827 return -1;
1830 /* convert header values */
1831 pipe_convert_header((unsigned char*)header, 4, indicator, &required);
1833 /* only indicator with no value? */
1834 if(required == 0) {
1835 ws_debug("read %p indicator: %c empty value", pipe_io, *indicator);
1836 return 4;
1839 /* does the data fit into the given buffer? */
1840 if(required > len) {
1841 size_t bytes_read;
1842 GError *err = NULL;
1843 ws_debug("read %p length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1844 pipe_io, required, len,
1845 header[0], header[1], header[2], header[3]);
1847 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1848 g_io_channel_read_chars(pipe_io, msg, len, &bytes_read, &err);
1849 if (err != NULL) { /* error */
1850 ws_debug("read from pipe %p: error(%u): %s", pipe_io, err->code, err->message);
1851 g_clear_error(&err);
1853 *err_msg = ws_strdup_printf("Message %c from dumpcap with length %d > buffer size %d! Partial message: %s",
1854 *indicator, required, len, msg);
1855 return -1;
1857 len = required;
1859 /* read the actual block data */
1860 newly = pipe_read_bytes(pipe_io, msg, required, err_msg);
1861 if(newly != required) {
1862 if (newly != -1) {
1863 *err_msg = ws_strdup_printf("Unknown message from dumpcap reading data, try to show it as a string: %s",
1864 msg);
1866 return -1;
1869 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1870 ws_debug("read %p ok indicator: %c len: %u msg: %s", pipe_io, *indicator, len, msg);
1871 *err_msg = NULL;
1872 return newly + 4;
1876 /* There's stuff to read from the sync pipe, meaning the child has sent
1877 us a message, or the sync pipe has closed, meaning the child has
1878 closed it (perhaps because it exited). */
1879 static gboolean
1880 sync_pipe_input_cb(GIOChannel *pipe_io, capture_session *cap_session)
1882 int ret;
1883 char *buffer = g_malloc(SP_MAX_MSG_LEN + 1);
1884 ssize_t nread;
1885 char indicator;
1886 int32_t exec_errno = 0;
1887 int primary_len;
1888 char *primary_msg;
1889 int secondary_len;
1890 char *secondary_msg;
1891 char *wait_msg, *combined_msg;
1892 uint32_t npackets = 0;
1894 nread = pipe_read_block(pipe_io, &indicator, SP_MAX_MSG_LEN, buffer,
1895 &primary_msg);
1896 if(nread <= 0) {
1897 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1899 If we got a read error or a bad message, nread is -1 and
1900 primary_msg is set to point to an error message. We don't
1901 have to worry about killing the child; usually this error
1902 is caused as the child killed itself while going down.
1903 Even in the rare cases that this isn't the case, the child
1904 will get an error when writing to the broken pipe the next time,
1905 cleaning itself up then.
1907 If we got an EOF, nread is 0 and primary_msg isn't set. This
1908 is an indication that the capture is finished. */
1909 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1910 if(nread == 0) {
1911 /* We got an EOF from the sync pipe. That means that the capture
1912 child exited, and not in the middle of a message; we treat
1913 that as an indication that it's done, and only report an
1914 error if ret is -1, in which case wait_msg is the error
1915 message. */
1916 if (ret == -1)
1917 primary_msg = wait_msg;
1918 } else {
1919 /* We got an error from the sync pipe. If ret is -1, report
1920 both the sync pipe I/O error and the wait error. */
1921 if (ret == -1) {
1922 combined_msg = ws_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1923 g_free(primary_msg);
1924 g_free(wait_msg);
1925 primary_msg = combined_msg;
1929 /* No more child process. */
1930 cap_session->fork_child = WS_INVALID_PID;
1931 cap_session->fork_child_status = ret;
1933 #ifdef _WIN32
1934 ws_close(cap_session->signal_pipe_write_fd);
1935 #endif
1936 cap_session->capture_opts->closed_msg = primary_msg;
1937 if (extcap_session_stop(cap_session)) {
1938 capture_process_finished(cap_session);
1939 } else {
1940 extcap_request_stop(cap_session);
1942 g_free(buffer);
1943 return false;
1946 /* we got a valid message block from the child, process it */
1947 switch(indicator) {
1948 case SP_FILE:
1949 if(!cap_session->new_file(cap_session, buffer)) {
1950 ws_debug("file failed, closing capture");
1952 /* We weren't able to open the new capture file; user has been
1953 alerted. The sync pipe will close after we return false. */
1955 /* The child has sent us a filename which we couldn't open.
1957 This could mean that the child is creating and deleting files
1958 (ring buffer mode) faster than we can handle it.
1960 That should only be the case for very fast file switches;
1961 We can't do much more than telling the child to stop.
1962 (This is the "emergency brake" if the user e.g. wants to
1963 switch files every second).
1965 This can also happen if the user specified "-", meaning
1966 "standard output", as the capture file. */
1967 sync_pipe_stop(cap_session);
1968 cap_session->closed(cap_session, NULL);
1969 g_free(buffer);
1970 return false;
1972 break;
1973 case SP_PACKET_COUNT:
1974 if (!ws_strtou32(buffer, NULL, &npackets)) {
1975 ws_warning("Invalid packets number: %s", buffer);
1977 ws_debug("new packets %u", npackets);
1978 cap_session->count += npackets;
1979 cap_session->new_packets(cap_session, npackets);
1980 break;
1981 case SP_EXEC_FAILED:
1983 * Exec of dumpcap failed. Get the errno for the failure.
1985 if (!ws_strtoi32(buffer, NULL, &exec_errno)) {
1986 ws_warning("Invalid errno: %s", buffer);
1988 primary_msg = ws_strdup_printf("Couldn't run dumpcap in child process: %s",
1989 g_strerror(exec_errno));
1990 cap_session->error(cap_session, primary_msg, NULL);
1991 /* the capture child will close the sync_pipe, nothing to do for now */
1992 /* (an error message doesn't mean we have to stop capturing) */
1993 break;
1994 case SP_ERROR_MSG:
1995 /* convert primary message */
1996 pipe_convert_header((unsigned char*)buffer, 4, &indicator, &primary_len);
1997 primary_msg = buffer+4;
1998 /* convert secondary message */
1999 pipe_convert_header((unsigned char*)primary_msg + primary_len, 4, &indicator, &secondary_len);
2000 secondary_msg = primary_msg + primary_len + 4;
2001 /* message output */
2002 cap_session->error(cap_session, primary_msg, secondary_msg);
2003 /* the capture child will close the sync_pipe, nothing to do for now */
2004 /* (an error message doesn't mean we have to stop capturing) */
2005 break;
2006 case SP_LOG_MSG:
2008 * Log from dumpcap; pass to our log
2010 sync_pipe_handle_log_msg(buffer);
2011 break;
2012 case SP_BAD_FILTER: {
2013 const char *message=NULL;
2014 uint32_t indx = 0;
2015 const char* end;
2017 if (ws_strtou32(buffer, &end, &indx) && end[0] == ':') {
2018 message = end + 1;
2021 cap_session->cfilter_error(cap_session, indx, message);
2022 /* the capture child will close the sync_pipe, nothing to do for now */
2023 break;
2025 case SP_DROPS: {
2026 const char *name = NULL;
2027 const char* end;
2028 uint32_t num = 0;
2030 if (ws_strtou32(buffer, &end, &num) && end[0] == ':') {
2031 name = end + 1;
2034 cap_session->drops(cap_session, num, name);
2035 break;
2037 default:
2038 if (g_ascii_isprint(indicator))
2039 ws_warning("Unknown indicator '%c'", indicator);
2040 else
2041 ws_warning("Unknown indicator '\\x%02x", indicator);
2042 break;
2045 g_free(buffer);
2046 return true;
2052 * dumpcap is exiting; wait for it to exit. On success, *msgp is
2053 * unchanged, and the exit status of dumpcap is returned. On
2054 * failure (which includes "dumpcap exited due to being killed by
2055 * a signal or an exception"), *msgp points to an error message
2056 * for the failure, and -1 is returned. In the latter case, *msgp
2057 * must be freed with g_free().
2059 static int
2060 sync_pipe_wait_for_child(ws_process_id fork_child, char **msgp)
2062 int fork_child_status;
2063 #ifndef _WIN32
2064 int retry_waitpid = 3;
2065 #endif
2066 int ret = -1;
2067 int64_t start_time;
2068 double elapsed;
2070 start_time = g_get_monotonic_time();
2072 ws_debug("wait till child closed");
2073 ws_assert(fork_child != WS_INVALID_PID);
2075 *msgp = NULL; /* assume no error */
2076 #ifdef _WIN32
2077 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
2078 *msgp = ws_strdup_printf("Error from cwait(): %s", g_strerror(errno));
2079 ret = -1;
2080 } else {
2082 * The child exited; return its exit status. Do not treat this as
2083 * an error.
2085 ret = fork_child_status;
2086 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
2087 /* Probably an exception code */
2088 *msgp = ws_strdup_printf("Child dumpcap process died: %s",
2089 win32strexception(fork_child_status));
2090 ret = -1;
2093 #else
2094 while (--retry_waitpid >= 0) {
2095 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
2096 /* waitpid() succeeded */
2097 if (WIFEXITED(fork_child_status)) {
2099 * The child exited; return its exit status. Do not treat this as
2100 * an error.
2102 ret = WEXITSTATUS(fork_child_status);
2103 } else if (WIFSTOPPED(fork_child_status)) {
2104 /* It stopped, rather than exiting. "Should not happen." */
2105 *msgp = ws_strdup_printf("Child dumpcap process stopped: %s",
2106 sync_pipe_signame(WSTOPSIG(fork_child_status)));
2107 ret = -1;
2108 } else if (WIFSIGNALED(fork_child_status)) {
2109 /* It died with a signal. */
2110 *msgp = ws_strdup_printf("Child dumpcap process died: %s%s",
2111 sync_pipe_signame(WTERMSIG(fork_child_status)),
2112 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
2113 ret = -1;
2114 } else {
2115 /* What? It had to either have exited, or stopped, or died with
2116 a signal; what happened here? */
2117 *msgp = ws_strdup_printf("Bad status from waitpid(): %#o",
2118 fork_child_status);
2119 ret = -1;
2121 } else {
2122 /* waitpid() failed */
2123 if (errno == EINTR) {
2125 * Signal interrupted waitpid().
2127 * If it's SIGALRM, we just want to keep waiting, in case
2128 * there's some timer using it (e.g., in a GUI toolkit).
2130 * If you ^C TShark (or Wireshark), that should deliver
2131 * SIGINT to dumpcap as well. dumpcap catches SIGINT,
2132 * and should clean up and exit, so we should eventually
2133 * see that and clean up and terminate.
2135 * If we're sent a SIGTERM, we should (and do) catch it,
2136 * and TShark, at least, calls sync_pipe_stop(). which
2137 * kills dumpcap, so we should eventually see that and
2138 * clean up and terminate.
2140 ws_warning("waitpid returned EINTR. retrying.");
2141 continue;
2142 } else if (errno == ECHILD) {
2144 * The process identified by fork_child either doesn't
2145 * exist any more or isn't our child process (anymore?).
2147 * echld might have already reaped the child.
2149 ret = fetch_dumpcap_pid ? 0 : -1;
2150 } else {
2151 /* Unknown error. */
2152 *msgp = ws_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
2153 ret = -1;
2156 break;
2158 #endif
2160 elapsed = (g_get_monotonic_time() - start_time) / 1e6;
2161 ws_debug("capture child closed after %.3fs", elapsed);
2162 return ret;
2166 #ifndef _WIN32
2167 /* convert signal to corresponding name */
2168 static const char *
2169 sync_pipe_signame(int sig)
2171 const char *sigmsg;
2172 static char sigmsg_buf[6+1+3+1];
2174 switch (sig) {
2176 case SIGHUP:
2177 sigmsg = "Hangup";
2178 break;
2180 case SIGINT:
2181 sigmsg = "Interrupted";
2182 break;
2184 case SIGQUIT:
2185 sigmsg = "Quit";
2186 break;
2188 case SIGILL:
2189 sigmsg = "Illegal instruction";
2190 break;
2192 case SIGTRAP:
2193 sigmsg = "Trace trap";
2194 break;
2196 case SIGABRT:
2197 sigmsg = "Abort";
2198 break;
2200 case SIGFPE:
2201 sigmsg = "Arithmetic exception";
2202 break;
2204 case SIGKILL:
2205 sigmsg = "Killed";
2206 break;
2208 case SIGBUS:
2209 sigmsg = "Bus error";
2210 break;
2212 case SIGSEGV:
2213 sigmsg = "Segmentation violation";
2214 break;
2216 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
2217 Linux is POSIX compliant. These are not POSIX-defined signals ---
2218 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
2220 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
2221 were omitted from POSIX.1 because their behavior is
2222 implementation dependent and could not be adequately catego-
2223 rized. Conforming implementations may deliver these sig-
2224 nals, but must document the circumstances under which they
2225 are delivered and note any restrictions concerning their
2226 delivery.''
2228 So we only check for SIGSYS on those systems that happen to
2229 implement them (a system can be POSIX-compliant and implement
2230 them, it's just that POSIX doesn't *require* a POSIX-compliant
2231 system to implement them).
2234 #ifdef SIGSYS
2235 case SIGSYS:
2236 sigmsg = "Bad system call";
2237 break;
2238 #endif
2240 case SIGPIPE:
2241 sigmsg = "Broken pipe";
2242 break;
2244 case SIGALRM:
2245 sigmsg = "Alarm clock";
2246 break;
2248 case SIGTERM:
2249 sigmsg = "Terminated";
2250 break;
2252 default:
2253 /* Returning a static buffer is ok in the context we use it here */
2254 snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
2255 sigmsg = sigmsg_buf;
2256 break;
2258 return sigmsg;
2260 #endif
2263 #ifdef _WIN32
2265 static int create_dummy_signal_pipe(char **msg) {
2266 char *dummy_signal_pipe_name;
2268 if (dummy_signal_pipe != NULL) return 0;
2270 if (!dummy_control_id) {
2271 dummy_control_id = ws_strdup_printf("%ld.dummy", GetCurrentProcessId());
2274 /* Create the signal pipe */
2275 dummy_signal_pipe_name = ws_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2276 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2277 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2278 g_free(dummy_signal_pipe_name);
2279 if (dummy_signal_pipe == INVALID_HANDLE_VALUE) {
2280 *msg = ws_strdup_printf("Couldn't create signal pipe: %s",
2281 win32strerror(GetLastError()));
2282 return -1;
2284 return 0;
2287 /* tell the child through the signal pipe that we want to quit the capture */
2288 static void
2289 signal_pipe_capquit_to_child(capture_session *cap_session)
2291 const char quit_msg[] = "QUIT";
2292 int ret;
2294 ws_debug("signal_pipe_capquit_to_child");
2296 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2297 /* simply sending a "QUIT" string */
2298 /*sync_pipe_write_string_msg(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2299 ret = ws_write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2300 if(ret == -1) {
2301 ws_warning("%d header: error %s", cap_session->signal_pipe_write_fd, win32strerror(GetLastError()));
2304 #endif
2307 /* user wants to stop the capture run */
2308 void
2309 sync_pipe_stop(capture_session *cap_session)
2311 if (cap_session->fork_child != WS_INVALID_PID) {
2312 #ifndef _WIN32
2313 /* send the SIGINT signal to close the capture child gracefully. */
2314 int sts = kill(cap_session->fork_child, SIGINT);
2315 if (sts != 0) {
2316 ws_warning("Sending SIGINT to child failed: %s\n", g_strerror(errno));
2318 #else
2319 #define STOP_SLEEP_TIME 500 /* ms */
2320 DWORD status;
2322 /* First, use the special signal pipe to try to close the capture child
2323 * gracefully.
2325 signal_pipe_capquit_to_child(cap_session);
2327 /* Next, wait for the process to exit on its own */
2328 status = WaitForSingleObject((HANDLE) cap_session->fork_child, STOP_SLEEP_TIME);
2330 /* Force the issue. */
2331 if (status != WAIT_OBJECT_0) {
2332 ws_warning("sync_pipe_stop: forcing child to exit");
2333 sync_pipe_kill(cap_session->fork_child);
2335 #endif
2340 /* Wireshark has to exit, force the capture child to close */
2341 void
2342 sync_pipe_kill(ws_process_id fork_child)
2344 if (fork_child != WS_INVALID_PID) {
2345 #ifndef _WIN32
2346 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2347 if (sts != 0) {
2348 ws_warning("Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2350 #else
2351 /* Remark: This is not the preferred method of closing a process!
2352 * the clean way would be getting the process id of the child process,
2353 * then getting window handle hWnd of that process (using EnumChildWindows),
2354 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2356 * Unfortunately, I don't know how to get the process id from the
2357 * handle. OpenProcess will get an handle (not a window handle)
2358 * from the process ID; it will not get a window handle from the
2359 * process ID. (How could it? A process can have more than one
2360 * window. For that matter, a process might have *no* windows,
2361 * as a process running dumpcap, the normal child process program,
2362 * probably does.)
2364 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2365 * running in the same console; that's not necessarily the case for
2366 * us, as we might not be running in a console.
2367 * And this also will require to have the process id.
2369 TerminateProcess((HANDLE) (fork_child), 0);
2371 #endif
2375 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2376 fetch_dumpcap_pid = cb;
2379 #endif /* HAVE_LIBPCAP */