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
12 #define WS_LOG_DOMAIN LOG_DOMAIN_CAPTURE
14 #include <wireshark.h>
24 #include <ws_exit_codes.h>
26 #include <wsutil/strtoi.h>
27 #include <wsutil/ws_assert.h>
30 #include <wsutil/unicode-utils.h>
31 #include <wsutil/win32-utils.h>
32 #include <wsutil/ws_pipe.h>
34 #include <glib-unix.h>
37 #ifdef HAVE_SYS_WAIT_H
38 # include <sys/wait.h>
41 #include "capture/capture-pcap-util.h"
45 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
46 * macros) on UNIX systems that don't have them.
49 # define WIFEXITED(status) (((status) & 0177) == 0)
52 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
55 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
58 # define WEXITSTATUS(status) ((status) >> 8)
61 # define WTERMSIG(status) ((status) & 0177)
64 # define WCOREDUMP(status) ((status) & 0200)
67 # define WSTOPSIG(status) ((status) >> 8)
71 #include <epan/packet.h>
72 #include <epan/prefs.h>
76 #include "ui/capture.h"
77 #include <capture/capture_sync.h>
79 #include "sync_pipe.h"
82 #include "capture/capture-wpcap.h"
85 #include "ui/ws_ui_util.h"
87 #include <wsutil/filesystem.h>
88 #include <wsutil/file_util.h>
89 #include <wsutil/report_message.h>
93 #include <process.h> /* For spawning child process */
96 #include <wsutil/ws_pipe.h>
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
;
103 static const char *sync_pipe_signame(int);
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
,
118 static void (*fetch_dumpcap_pid
)(ws_process_id
);
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;
130 cap_session
->signal_pipe_write_fd
= -1;
132 cap_session
->state
= CAPTURE_STOPPED
;
134 cap_session
->owner
= getuid();
135 cap_session
->group
= getgid();
137 cap_session
->count
= 0;
138 cap_session
->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
;
157 if (!extcap_session_stop(cap_session
)) {
158 /* At least one extcap process did not fully finish yet, wait for it */
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 */
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
) {
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.
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. */
216 /* We overwrite the NULL pointer; put it back right after the
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.)
229 sync_pipe_handle_log_msg(const char *buffer
) {
230 const char *log_msg
= NULL
;
234 if (ws_strtou32(buffer
, &end
, &level
) && end
[0] == ':') {
237 ws_log(LOG_DOMAIN_CAPCHILD
, level
, "%s", log_msg
);
240 /* Initialize an argument list and add dumpcap to it. */
242 init_pipe_args(int *argc
) {
246 /* Find the absolute path of the dumpcap executable. */
247 exename
= get_executable_path("dumpcap");
248 if (exename
== NULL
) {
252 /* Allocate the string pointer array with enough space for the
253 terminating NULL pointer. */
255 argv
= (char **)g_malloc(sizeof (char *));
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
));
273 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
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
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))
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))
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
];
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;
328 GString
*args
= g_string_sized_new(200);
330 SECURITY_ATTRIBUTES sa
;
332 PROCESS_INFORMATION pi
;
335 interface_options
*interface_opts
;
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 */
340 *fork_child
= WS_INVALID_PID
;
341 if (data_read_fd
!= NULL
) {
344 *message_read_io
= NULL
;
345 ws_debug("sync_pipe_open_command");
348 /* We can't return anything */
351 g_string_free(args
, TRUE
);
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()));
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
));
383 CloseHandle(sync_pipe
[PIPE_READ
]);
384 CloseHandle(sync_pipe
[PIPE_WRITE
]);
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()));
396 ws_close(message_read_fd
); /* Should close sync_pipe[PIPE_READ] */
397 CloseHandle(sync_pipe
[PIPE_WRITE
]);
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
));
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
]);
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()));
433 ws_close(message_read_fd
); /* Should close sync_pipe[PIPE_READ] */
434 CloseHandle(sync_pipe
[PIPE_WRITE
]);
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
));
450 ws_close(message_read_fd
); /* Should close sync_pipe[PIPE_READ] */
451 CloseHandle(sync_pipe
[PIPE_WRITE
]);
452 CloseHandle(signal_pipe
);
457 /* init STARTUPINFO & PROCESS_INFORMATION */
458 memset(&si
, 0, sizeof(si
));
460 memset(&pi
, 0, sizeof(pi
));
462 si
.dwFlags
= STARTF_USESHOWWINDOW
;
463 si
.wShowWindow
= SW_SHOW
;
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
);
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
);
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
) {
504 handles
= g_new(HANDLE
, 3 + i_handles
);
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
];
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
);
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()));
538 ws_close(*data_read_fd
); /* Should close data_pipe[PIPE_READ] */
539 CloseHandle(data_pipe
[PIPE_WRITE
]);
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
]);
546 g_string_free(args
, TRUE
);
550 *fork_child
= pi
.hProcess
;
551 /* We may need to store this and close it later */
552 CloseHandle(pi
.hThread
);
554 g_string_free(args
, TRUE
);
557 if (signal_write_fd
!= NULL
) {
558 *signal_write_fd
= signal_pipe_write_fd
;
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
));
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
));
575 ws_close(sync_pipe
[PIPE_READ
]);
576 ws_close(sync_pipe
[PIPE_WRITE
]);
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) */
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
);
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). */
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
];
624 /* Parent process - read messages from the child process over the
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). */
632 if (data_read_fd
!= NULL
) {
633 CloseHandle(data_pipe
[PIPE_WRITE
]);
635 CloseHandle(sync_pipe
[PIPE_WRITE
]);
637 if (data_read_fd
!= NULL
) {
638 ws_close(data_pipe
[PIPE_WRITE
]);
640 ws_close(sync_pipe
[PIPE_WRITE
]);
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
);
650 if (signal_write_fd
!= NULL
) {
651 ws_close(signal_pipe_write_fd
);
654 ws_close(message_read_fd
);
659 *message_read_io
= g_io_channel_win32_new_fd(message_read_fd
);
661 *message_read_io
= g_io_channel_unix_new(message_read_fd
);
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();
672 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
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))
679 size_t i_handles
= 0;
680 char control_id
[ARGV_NUMBER_LEN
];
682 GIOChannel
*sync_pipe_read_io
;
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?)");
702 argv
= init_pipe_args(&argc
);
704 /* We don't know where to find dumpcap. */
705 report_failure("We don't know where to find dumpcap.");
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");
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
);
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
);
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
)
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
);
839 argv
= sync_pipe_add_arg(argv
, &argc
, interface_opts
->extcap_fifo
);
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
);
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
);
891 #ifdef HAVE_PCAP_CREATE
892 if (interface_opts
->monitor_mode
) {
893 argv
= sync_pipe_add_arg(argv
, &argc
, "-I");
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
) {
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
);
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" :
922 interface_opts
->sampling_param
);
923 argv
= sync_pipe_add_arg(argv
, &argc
, ssampling
);
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
);
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
);
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
);
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
);
959 ret
= sync_pipe_open_command(argv
, NULL
, &sync_pipe_read_io
, NULL
,
960 &cap_session
->fork_child
, NULL
, &msg
, update_cb
);
964 report_failure("%s", msg
);
969 /* Parent process - read messages from the child process over the
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
);
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().
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
);
1009 /* XXX - Should we signal the child somehow? */
1010 sync_pipe_kill(*fork_child
);
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().
1029 sync_pipe_run_command_actual(char **argv
, char **data
, char **primary_msg
,
1030 char **secondary_msg
, void(*update_cb
)(void))
1033 int data_pipe_read_fd
, ret
;
1034 GIOChannel
*sync_pipe_read_io
;
1035 ws_process_id fork_child
;
1037 char *buffer
= g_malloc(PIPE_BUF_SIZE
+ 1);
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
;
1046 GString
*data_buf
= NULL
;
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
1054 *primary_msg
= ws_strdup_printf("Couldn't allocate memory for dumpcap output buffer: %s",
1056 *secondary_msg
= NULL
;
1061 ret
= sync_pipe_open_command(argv
, &data_pipe_read_fd
, &sync_pipe_read_io
, NULL
,
1062 &fork_child
, NULL
, &msg
, update_cb
);
1065 *secondary_msg
= NULL
;
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.
1077 nread
= pipe_read_block(sync_pipe_read_io
, &indicator
, SP_MAX_MSG_LEN
,
1078 buffer
, primary_msg
);
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
);
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. */
1098 *primary_msg
= wait_msg
;
1100 *primary_msg
= g_strdup("Child dumpcap closed sync pipe prematurely");
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. */
1105 combined_msg
= ws_strdup_printf("%s\n\n%s", *primary_msg
, wait_msg
);
1106 g_free(*primary_msg
);
1108 *primary_msg
= combined_msg
;
1111 *secondary_msg
= NULL
;
1118 /* we got a valid message block from the child, process it */
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
,
1136 * Child process failed unexpectedly, or wait failed; msg is the
1140 *secondary_msg
= NULL
;
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
;
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
,
1176 * Child process failed unexpectedly, or wait failed; msg is the
1180 *secondary_msg
= NULL
;
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
);
1195 * Log from dumpcap; pass to our log
1197 sync_pipe_handle_log_msg(buffer
);
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
,
1215 * Child process failed unexpectedly, or wait failed; msg is the
1219 *secondary_msg
= NULL
;
1220 g_string_free(data_buf
, TRUE
);
1224 * Child process succeeded.
1226 *primary_msg
= NULL
;
1227 *secondary_msg
= NULL
;
1228 *data
= g_string_free(data_buf
, FALSE
);
1234 * Pick up the child status.
1236 ret
= sync_pipe_close_command(&data_pipe_read_fd
, sync_pipe_read_io
,
1240 * Child process failed unexpectedly, or wait failed; msg is the
1244 *secondary_msg
= NULL
;
1247 * Child process returned an unknown status.
1249 *primary_msg
= ws_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1251 *secondary_msg
= NULL
;
1257 } while (indicator
!= SP_SUCCESS
&& ret
!= -1);
1263 /* centralised logging and timing for sync_pipe_run_command_actual(),
1264 * redirects to sync_pipe_run_command_actual()
1267 sync_pipe_run_command(char **argv
, char **data
, char **primary_msg
,
1268 char **secondary_msg
, void (*update_cb
)(void))
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
);
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))
1307 argv
= init_pipe_args(&argc
);
1310 *primary_msg
= g_strdup("We don't know where to find dumpcap.");
1311 *secondary_msg
= NULL
;
1316 argv
= sync_pipe_add_arg(argv
, &argc
, "-i");
1317 argv
= sync_pipe_add_arg(argv
, &argc
, iface
);
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
);
1324 opt
= ws_strdup_printf("%s,%s", freq
, type
);
1326 opt
= g_strdup(freq
);
1329 *primary_msg
= g_strdup("Out of mem.");
1330 *secondary_msg
= NULL
;
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
);
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))
1363 ws_debug("sync_interface_list_open");
1365 argv
= init_pipe_args(&argc
);
1368 *primary_msg
= g_strdup("We don't know where to find dumpcap..");
1369 *secondary_msg
= NULL
;
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
);
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))
1402 ws_debug("sync_if_capabilities_open");
1404 argv
= init_pipe_args(&argc
);
1407 *primary_msg
= g_strdup("We don't know where to find dumpcap.");
1408 *secondary_msg
= NULL
;
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");
1419 argv
= sync_pipe_add_arg(argv
, &argc
, "-I");
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
);
1430 sync_if_list_capabilities_open(GList
*if_queries
,
1431 char **data
, char **primary_msg
,
1432 char **secondary_msg
, void (*update_cb
)(void))
1437 if_cap_query_t
*if_cap_query
;
1439 ws_debug("sync_if_list_capabilities_open");
1441 argv
= init_pipe_args(&argc
);
1444 *primary_msg
= g_strdup("We don't know where to find dumpcap.");
1445 *secondary_msg
= NULL
;
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
) {
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
);
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))
1487 GIOChannel
*message_read_io
;
1489 char *buffer
= g_malloc(PIPE_BUF_SIZE
+ 1);
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;*/
1499 ws_debug("sync_interface_stats_open");
1501 argv
= init_pipe_args(&argc
);
1504 *msg
= g_strdup("We don't know where to find dumpcap.");
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. */
1514 argv
= sync_pipe_add_arg(argv
, &argc
, "-D");
1515 argv
= sync_pipe_add_arg(argv
, &argc
, "-L");
1520 argv
= sync_pipe_add_arg(argv
, &argc
, "--signal-pipe");
1521 ret
= create_dummy_signal_pipe(msg
);
1526 argv
= sync_pipe_add_arg(argv
, &argc
, dummy_control_id
);
1529 ret
= sync_pipe_open_command(argv
, data_read_fd
, &message_read_io
, NULL
,
1530 fork_child
, NULL
, msg
, update_cb
);
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.
1542 nread
= pipe_read_block(message_read_io
, &indicator
, SP_MAX_MSG_LEN
,
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
);
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. */
1566 *msg
= g_strdup("Child dumpcap closed sync pipe prematurely");
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. */
1571 combined_msg
= ws_strdup_printf("%s\n\n%s", *msg
, wait_msg
);
1574 *msg
= combined_msg
;
1581 /* we got a valid message block from the child, process it */
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.
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
,
1630 * Child process failed unexpectedly, or wait failed; msg is the
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
);
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
);
1653 * Log from dumpcap; pass to our log
1655 sync_pipe_handle_log_msg(buffer
);
1660 * Dumpcap giving us the interface list
1663 /* convert primary message */
1665 *data
= g_strdup(buffer
);
1670 /* Close the message pipe. */
1671 g_io_channel_unref(message_read_io
);
1676 * Pick up the child status.
1678 ret
= sync_pipe_close_command(data_read_fd
, message_read_io
,
1682 * Child process failed unexpectedly, or wait failed; msg is the
1687 * Child process returned an unknown status.
1689 *msg
= ws_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1695 } while (indicator
!= SP_SUCCESS
&& ret
!= -1);
1701 /* Close down the stats process */
1703 sync_interface_stats_close(int *read_fd
, ws_process_id
*fork_child
, char **msg
)
1706 CloseHandle(dummy_signal_pipe
);
1707 dummy_signal_pipe
= NULL
;
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
);
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) */
1721 pipe_read_bytes(GIOChannel
*pipe_io
, char *bytes
, size_t required
, char **msg
)
1728 g_io_channel_read_chars(pipe_io
, &bytes
[offset
], required
, &newly
, &err
);
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
);
1737 ws_debug("read from pipe %p: EOF (capture closed?)", pipe_io
);
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
) {
1761 while(offset
< max
- 1) {
1763 if (! ws_pipe_data_available(pipe_fd
))
1765 newly
= ws_read(pipe_fd
, &bytes
[offset
], 1);
1767 /* EOF - not necessarily an error */
1769 } else if (newly
== -1) {
1771 ws_debug("read from pipe %d: error(%u): %s", pipe_fd
, errno
, g_strerror(errno
));
1773 } else if (bytes
[offset
] == '\n') {
1779 bytes
[offset
] = '\0';
1785 /* convert header values (indicator and 3-byte length) */
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) */
1800 pipe_read_block(GIOChannel
*pipe_io
, char *indicator
, int len
, char *msg
,
1807 /* read header (indicator and 3-byte length) */
1808 newly
= pipe_read_bytes(pipe_io
, header
, 4, err_msg
);
1812 * Immediate EOF; if the capture child exits normally, this
1813 * is an "I'm done" indication, so don't report it as an
1816 ws_debug("read %p got an EOF", pipe_io
);
1819 ws_debug("read %p failed to read header: %lu", pipe_io
, (long)newly
);
1822 * Short read, but not an immediate EOF.
1824 *err_msg
= ws_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1830 /* convert header values */
1831 pipe_convert_header((unsigned char*)header
, 4, indicator
, &required
);
1833 /* only indicator with no value? */
1835 ws_debug("read %p indicator: %c empty value", pipe_io
, *indicator
);
1839 /* does the data fit into the given buffer? */
1840 if(required
> len
) {
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
);
1859 /* read the actual block data */
1860 newly
= pipe_read_bytes(pipe_io
, msg
, required
, err_msg
);
1861 if(newly
!= required
) {
1863 *err_msg
= ws_strdup_printf("Unknown message from dumpcap reading data, try to show it as a string: %s",
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
);
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). */
1880 sync_pipe_input_cb(GIOChannel
*pipe_io
, capture_session
*cap_session
)
1883 char *buffer
= g_malloc(SP_MAX_MSG_LEN
+ 1);
1886 int32_t exec_errno
= 0;
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
,
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
);
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
1917 primary_msg
= wait_msg
;
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. */
1922 combined_msg
= ws_strdup_printf("%s\n\n%s", primary_msg
, wait_msg
);
1923 g_free(primary_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
;
1934 ws_close(cap_session
->signal_pipe_write_fd
);
1936 cap_session
->capture_opts
->closed_msg
= primary_msg
;
1937 if (extcap_session_stop(cap_session
)) {
1938 capture_process_finished(cap_session
);
1940 extcap_request_stop(cap_session
);
1946 /* we got a valid message block from the child, process it */
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
);
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
);
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) */
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) */
2008 * Log from dumpcap; pass to our log
2010 sync_pipe_handle_log_msg(buffer
);
2012 case SP_BAD_FILTER
: {
2013 const char *message
=NULL
;
2017 if (ws_strtou32(buffer
, &end
, &indx
) && end
[0] == ':') {
2021 cap_session
->cfilter_error(cap_session
, indx
, message
);
2022 /* the capture child will close the sync_pipe, nothing to do for now */
2026 const char *name
= NULL
;
2030 if (ws_strtou32(buffer
, &end
, &num
) && end
[0] == ':') {
2034 cap_session
->drops(cap_session
, num
, name
);
2038 if (g_ascii_isprint(indicator
))
2039 ws_warning("Unknown indicator '%c'", indicator
);
2041 ws_warning("Unknown indicator '\\x%02x", indicator
);
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().
2060 sync_pipe_wait_for_child(ws_process_id fork_child
, char **msgp
)
2062 int fork_child_status
;
2064 int retry_waitpid
= 3;
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 */
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
));
2082 * The child exited; return its exit status. Do not treat this as
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
));
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
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
)));
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" : "");
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",
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.");
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;
2151 /* Unknown error. */
2152 *msgp
= ws_strdup_printf("Error from waitpid(): %s", g_strerror(errno
));
2160 elapsed
= (g_get_monotonic_time() - start_time
) / 1e6
;
2161 ws_debug("capture child closed after %.3fs", elapsed
);
2167 /* convert signal to corresponding name */
2169 sync_pipe_signame(int sig
)
2172 static char sigmsg_buf
[6+1+3+1];
2181 sigmsg
= "Interrupted";
2189 sigmsg
= "Illegal instruction";
2193 sigmsg
= "Trace trap";
2201 sigmsg
= "Arithmetic exception";
2209 sigmsg
= "Bus error";
2213 sigmsg
= "Segmentation violation";
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
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).
2236 sigmsg
= "Bad system call";
2241 sigmsg
= "Broken pipe";
2245 sigmsg
= "Alarm clock";
2249 sigmsg
= "Terminated";
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
;
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()));
2287 /* tell the child through the signal pipe that we want to quit the capture */
2289 signal_pipe_capquit_to_child(capture_session
*cap_session
)
2291 const char quit_msg
[] = "QUIT";
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
);
2301 ws_warning("%d header: error %s", cap_session
->signal_pipe_write_fd
, win32strerror(GetLastError()));
2307 /* user wants to stop the capture run */
2309 sync_pipe_stop(capture_session
*cap_session
)
2311 if (cap_session
->fork_child
!= WS_INVALID_PID
) {
2313 /* send the SIGINT signal to close the capture child gracefully. */
2314 int sts
= kill(cap_session
->fork_child
, SIGINT
);
2316 ws_warning("Sending SIGINT to child failed: %s\n", g_strerror(errno
));
2319 #define STOP_SLEEP_TIME 500 /* ms */
2322 /* First, use the special signal pipe to try to close the capture child
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
);
2340 /* Wireshark has to exit, force the capture child to close */
2342 sync_pipe_kill(ws_process_id fork_child
)
2344 if (fork_child
!= WS_INVALID_PID
) {
2346 int sts
= kill(fork_child
, SIGTERM
); /* SIGTERM so it can clean up if necessary */
2348 ws_warning("Sending SIGTERM to child failed: %s\n", g_strerror(errno
));
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,
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);
2375 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb
)(ws_process_id pid
)) {
2376 fetch_dumpcap_pid
= cb
;
2379 #endif /* HAVE_LIBPCAP */