2 * Synchronisation between Wireshark capture parent and child instances
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
45 #include <wsutil/unicode-utils.h>
48 #ifdef HAVE_SYS_WAIT_H
49 # include <sys/wait.h>
52 #include "capture-pcap-util.h"
56 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
57 * macros) on UNIX systems that don't have them.
60 # define WIFEXITED(status) (((status) & 0177) == 0)
63 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
66 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
69 # define WEXITSTATUS(status) ((status) >> 8)
72 # define WTERMSIG(status) ((status) & 0177)
75 # define WCOREDUMP(status) ((status) & 0200)
78 # define WSTOPSIG(status) ((status) >> 8)
82 #include <epan/packet.h>
83 #include <epan/prefs.h>
87 #include <epan/filesystem.h>
88 #include <epan/report_err.h>
91 #include "capture_sync.h"
93 #include "sync_pipe.h"
96 #include "capture-wpcap.h"
99 #include "ui/ui_util.h"
101 #include <wsutil/file_util.h>
105 #include <process.h> /* For spawning child process */
111 static const char *sync_pipe_signame(int);
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
117 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
118 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
122 capture_session_init(capture_session *cap_session, void *cf)
124 cap_session->cf = cf;
125 cap_session->fork_child = -1; /* invalid process handle */
127 cap_session->signal_pipe_write_fd = -1;
129 cap_session->state = CAPTURE_STOPPED;
131 cap_session->owner = getuid();
132 cap_session->group = getgid();
134 cap_session->session_started = FALSE;
137 /* Append an arg (realloc) to an argc/argv array */
138 /* (add a string pointer to a NULL-terminated array of string pointers) */
140 sync_pipe_add_arg(char **args, int *argc, const char *arg)
142 /* Grow the array; "*argc" currently contains the number of string
143 pointers, *not* counting the NULL pointer at the end, so we have
144 to add 2 in order to get the new size of the array, including the
145 new pointer and the terminating NULL pointer. */
146 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
148 /* Stuff the pointer into the penultimate element of the array, which
149 is the one at the index specified by "*argc". */
150 args[*argc] = g_strdup(arg);
151 /* Now bump the count. */
154 /* We overwrite the NULL pointer; put it back right after the
164 /* Quote the argument element if necessary, so that it will get
165 * reconstructed correctly in the C runtime startup code. Note that
166 * the unquoting algorithm in the C runtime is really weird, and
167 * rather different than what Unix shells do. See stdargv.c in the C
168 * runtime sources (in the Platform SDK, in src/crt).
170 * Stolen from GLib's protect_argv(), an internal routine that quotes
171 * string in an argument list so that they arguments will be handled
172 * correctly in the command-line string passed to CreateProcess()
173 * if that string is constructed by gluing those strings together.
176 protect_arg (const gchar *argv)
179 const gchar *p = argv;
182 gboolean need_dblquotes = FALSE;
185 if (*p == ' ' || *p == '\t')
186 need_dblquotes = TRUE;
189 else if (*p == '\\') {
192 while (*pp && *pp == '\\')
201 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
210 else if (*p == '\\') {
213 while (*pp && *pp == '\\')
230 * Generate a string for a Win32 error.
232 #define ERRBUF_SIZE 1024
234 win32strerror(DWORD error)
236 static char errbuf[ERRBUF_SIZE+1];
240 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
241 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
244 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
245 * message. Get rid of it.
247 errlen = strlen(errbuf);
249 errbuf[errlen - 1] = '\0';
250 errbuf[errlen - 2] = '\0';
252 p = strchr(errbuf, '\0');
253 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
258 * Generate a string for a Win32 exception code.
261 win32strexception(DWORD exception)
263 static char errbuf[ERRBUF_SIZE+1];
264 static const struct exception_msg {
268 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
269 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
270 { EXCEPTION_BREAKPOINT, "Breakpoint" },
271 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
272 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
273 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
274 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
275 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
276 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
277 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
278 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
279 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
280 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
281 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
282 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
283 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
284 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
285 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
286 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
287 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
288 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
289 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
292 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
295 for (i = 0; i < N_EXCEPTIONS; i++) {
296 if (exceptions[i].code == exception)
297 return exceptions[i].msg;
299 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
304 /* Initialize an argument list and add dumpcap to it. */
306 init_pipe_args(int *argc) {
308 const char *progfile_dir;
311 progfile_dir = get_progfile_dir();
312 if (progfile_dir == NULL) {
316 /* Allocate the string pointer array with enough space for the
317 terminating NULL pointer. */
319 argv = (char **)g_malloc(sizeof (char *));
322 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
323 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
325 /* Make that the first argument in the argument list (argv[0]). */
326 argv = sync_pipe_add_arg(argv, argc, exename);
328 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
334 #define ARGV_NUMBER_LEN 24
335 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
337 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session)
339 char ssnap[ARGV_NUMBER_LEN];
340 char scount[ARGV_NUMBER_LEN];
341 char sfilesize[ARGV_NUMBER_LEN];
342 char sfile_duration[ARGV_NUMBER_LEN];
343 char sring_num_files[ARGV_NUMBER_LEN];
344 char sautostop_files[ARGV_NUMBER_LEN];
345 char sautostop_filesize[ARGV_NUMBER_LEN];
346 char sautostop_duration[ARGV_NUMBER_LEN];
347 #ifdef HAVE_PCAP_REMOTE
350 #ifdef HAVE_PCAP_SETSAMPLING
351 char ssampling[ARGV_NUMBER_LEN];
354 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
355 char buffer_size[ARGV_NUMBER_LEN];
359 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
360 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
361 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
362 GString *args = g_string_sized_new(200);
364 SECURITY_ATTRIBUTES sa;
366 PROCESS_INFORMATION pi;
367 char control_id[ARGV_NUMBER_LEN];
368 gchar *signal_pipe_name;
371 int sync_pipe[2]; /* pipe used to send messages from child to parent */
372 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
374 int sync_pipe_read_fd;
379 interface_options interface_opts;
381 if (capture_opts->ifaces->len > 1)
382 capture_opts->use_pcapng = TRUE;
383 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
384 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
386 cap_session->fork_child = -1;
388 argv = init_pipe_args(&argc);
390 /* We don't know where to find dumpcap. */
391 report_failure("We don't know where to find dumpcap.");
395 if (capture_opts->ifaces->len > 1)
396 argv = sync_pipe_add_arg(argv, &argc, "-t");
398 if (capture_opts->use_pcapng)
399 argv = sync_pipe_add_arg(argv, &argc, "-n");
401 argv = sync_pipe_add_arg(argv, &argc, "-P");
403 if (capture_opts->multi_files_on) {
404 if (capture_opts->has_autostop_filesize) {
405 argv = sync_pipe_add_arg(argv, &argc, "-b");
406 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
407 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
410 if (capture_opts->has_file_duration) {
411 argv = sync_pipe_add_arg(argv, &argc, "-b");
412 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
413 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
416 if (capture_opts->has_ring_num_files) {
417 argv = sync_pipe_add_arg(argv, &argc, "-b");
418 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
419 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
422 if (capture_opts->has_autostop_files) {
423 argv = sync_pipe_add_arg(argv, &argc, "-a");
424 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
425 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
428 if (capture_opts->has_autostop_filesize) {
429 argv = sync_pipe_add_arg(argv, &argc, "-a");
430 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
431 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
435 if (capture_opts->has_autostop_packets) {
436 argv = sync_pipe_add_arg(argv, &argc, "-c");
437 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
438 argv = sync_pipe_add_arg(argv, &argc, scount);
441 if (capture_opts->has_autostop_duration) {
442 argv = sync_pipe_add_arg(argv, &argc, "-a");
443 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
444 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
447 if (capture_opts->group_read_access) {
448 argv = sync_pipe_add_arg(argv, &argc, "-g");
451 for (j = 0; j < capture_opts->ifaces->len; j++) {
452 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
454 argv = sync_pipe_add_arg(argv, &argc, "-i");
455 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
457 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
458 argv = sync_pipe_add_arg(argv, &argc, "-f");
459 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
461 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
462 argv = sync_pipe_add_arg(argv, &argc, "-s");
463 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
464 argv = sync_pipe_add_arg(argv, &argc, ssnap);
467 if (interface_opts.linktype != -1) {
468 argv = sync_pipe_add_arg(argv, &argc, "-y");
469 argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
472 if (!interface_opts.promisc_mode) {
473 argv = sync_pipe_add_arg(argv, &argc, "-p");
476 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
477 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
478 argv = sync_pipe_add_arg(argv, &argc, "-B");
479 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
480 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
484 #ifdef HAVE_PCAP_CREATE
485 if (interface_opts.monitor_mode) {
486 argv = sync_pipe_add_arg(argv, &argc, "-I");
490 #ifdef HAVE_PCAP_REMOTE
491 if (interface_opts.datatx_udp)
492 argv = sync_pipe_add_arg(argv, &argc, "-u");
494 if (!interface_opts.nocap_rpcap)
495 argv = sync_pipe_add_arg(argv, &argc, "-r");
497 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
498 argv = sync_pipe_add_arg(argv, &argc, "-A");
499 g_snprintf(sauth, sizeof(sauth), "%s:%s",
500 interface_opts.auth_username,
501 interface_opts.auth_password);
502 argv = sync_pipe_add_arg(argv, &argc, sauth);
506 #ifdef HAVE_PCAP_SETSAMPLING
507 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
508 argv = sync_pipe_add_arg(argv, &argc, "-m");
509 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
510 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
511 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
513 interface_opts.sampling_param);
514 argv = sync_pipe_add_arg(argv, &argc, ssampling);
519 /* dumpcap should be running in capture child mode (hidden feature) */
521 argv = sync_pipe_add_arg(argv, &argc, "-Z");
523 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
524 argv = sync_pipe_add_arg(argv, &argc, control_id);
526 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
530 if (capture_opts->save_file) {
531 argv = sync_pipe_add_arg(argv, &argc, "-w");
532 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
534 for (i = 0; i < argc; i++) {
535 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
539 /* init SECURITY_ATTRIBUTES */
540 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
541 sa.bInheritHandle = TRUE;
542 sa.lpSecurityDescriptor = NULL;
544 /* Create a pipe for the child process */
545 /* (increase this value if you have trouble while fast capture file switches) */
546 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
547 /* Couldn't create the pipe between parent and child. */
548 report_failure("Couldn't create sync pipe: %s",
549 win32strerror(GetLastError()));
550 for (i = 0; i < argc; i++) {
551 g_free( (gpointer) argv[i]);
553 g_free( (gpointer) argv);
557 /* Create the signal pipe */
558 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
559 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
560 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
561 g_free(signal_pipe_name);
563 if (signal_pipe == INVALID_HANDLE_VALUE) {
564 /* Couldn't create the signal pipe between parent and child. */
565 report_failure("Couldn't create signal pipe: %s",
566 win32strerror(GetLastError()));
567 for (i = 0; i < argc; i++) {
568 g_free( (gpointer) argv[i]);
570 g_free( (gpointer) argv);
574 /* init STARTUPINFO */
575 memset(&si, 0, sizeof(si));
578 si.dwFlags = STARTF_USESHOWWINDOW;
579 si.wShowWindow = SW_SHOW;
581 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
582 si.wShowWindow = SW_HIDE; /* this hides the console window */
583 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
584 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
585 si.hStdError = sync_pipe_write;
586 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
589 /* convert args array into a single string */
590 /* XXX - could change sync_pipe_add_arg() instead */
591 /* there is a drawback here: the length is internally limited to 1024 bytes */
592 for(i=0; argv[i] != 0; i++) {
593 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
594 quoted_arg = protect_arg(argv[i]);
595 g_string_append(args, quoted_arg);
600 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
601 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
602 report_failure("Couldn't run %s in child process: %s",
603 args->str, win32strerror(GetLastError()));
604 CloseHandle(sync_pipe_read);
605 CloseHandle(sync_pipe_write);
606 for (i = 0; i < argc; i++) {
607 g_free( (gpointer) argv[i]);
609 g_free( (gpointer) argv);
612 cap_session->fork_child = (int) pi.hProcess;
613 g_string_free(args, TRUE);
615 /* associate the operating system filehandle to a C run-time file handle */
616 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
617 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
619 /* associate the operating system filehandle to a C run-time file handle */
620 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
623 if (pipe(sync_pipe) < 0) {
624 /* Couldn't create the pipe between parent and child. */
625 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
626 for (i = 0; i < argc; i++) {
627 g_free( (gpointer) argv[i]);
633 if ((cap_session->fork_child = fork()) == 0) {
635 * Child process - run dumpcap with the right arguments to make
636 * it just capture with the specified capture parameters
638 dup2(sync_pipe[PIPE_WRITE], 2);
639 ws_close(sync_pipe[PIPE_READ]);
640 execv(argv[0], argv);
641 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
642 argv[0], g_strerror(errno));
643 sync_pipe_errmsg_to_parent(2, errmsg, "");
645 /* Exit with "_exit()", so that we don't close the connection
646 to the X server (and cause stuff buffered up by our parent but
647 not yet sent to be sent, as that stuff should only be sent by
648 our parent). We've sent an error message to the parent, so
649 we exit with an exit status of 1 (any exit status other than
650 0 or 1 will cause an additional message to report that exit
651 status, over and above the error message we sent to the parent). */
655 sync_pipe_read_fd = sync_pipe[PIPE_READ];
658 for (i = 0; i < argc; i++) {
659 g_free( (gpointer) argv[i]);
662 /* Parent process - read messages from the child process over the
664 g_free( (gpointer) argv); /* free up arg array */
666 /* Close the write side of the pipe, so that only the child has it
667 open, and thus it completely closes, and thus returns to us
668 an EOF indication, if the child closes it (either deliberately
669 or by exiting abnormally). */
671 CloseHandle(sync_pipe_write);
673 ws_close(sync_pipe[PIPE_WRITE]);
676 if (cap_session->fork_child == -1) {
677 /* We couldn't even create the child process. */
678 report_failure("Couldn't create child process: %s", g_strerror(errno));
679 ws_close(sync_pipe_read_fd);
681 ws_close(cap_session->signal_pipe_write_fd);
686 cap_session->fork_child_status = 0;
687 cap_session->capture_opts = capture_opts;
689 /* we might wait for a moment till child is ready, so update screen now */
690 main_window_update();
692 /* We were able to set up to read the capture file;
693 arrange that our callback be called whenever it's possible
694 to read from the sync pipe, so that it's called when
695 the child process wants to tell us something. */
697 /* we have a running capture, now wait for the real capture filename */
698 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
699 &cap_session->fork_child, sync_pipe_input_cb);
705 * Open two pipes to dumpcap with the supplied arguments, one for its
706 * standard output and one for its standard error.
708 * On success, *msg is unchanged and 0 is returned; data_read_fd,
709 * messsage_read_fd, and fork_child point to the standard output pipe's
710 * file descriptor, the standard error pipe's file descriptor, and
711 * the child's PID/handle, respectively.
713 * On failure, *msg points to an error message for the failure, and -1 is
714 * returned, in which case *msg must be freed with g_free().
716 /* XXX - This duplicates a lot of code in sync_pipe_start() */
717 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
718 #define PIPE_BUF_SIZE 5120
720 sync_pipe_open_command(char** argv, int *data_read_fd,
721 int *message_read_fd, int *fork_child, gchar **msg)
723 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
725 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
726 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
727 GString *args = g_string_sized_new(200);
729 SECURITY_ATTRIBUTES sa;
731 PROCESS_INFORMATION pi;
734 int sync_pipe[2]; /* pipe used to send messages from child to parent */
735 int data_pipe[2]; /* pipe used to send data from child to parent */
740 *message_read_fd = -1;
741 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
744 /* We can't return anything */
746 g_string_free(args, TRUE);
752 /* init SECURITY_ATTRIBUTES */
753 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
754 sa.bInheritHandle = TRUE;
755 sa.lpSecurityDescriptor = NULL;
757 /* Create a pipe for the child process to send us messages */
758 /* (increase this value if you have trouble while fast capture file switches) */
759 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
760 /* Couldn't create the message pipe between parent and child. */
761 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
762 win32strerror(GetLastError()));
763 for (i = 0; argv[i] != NULL; i++) {
764 g_free( (gpointer) argv[i]);
766 g_free( (gpointer) argv);
770 /* Create a pipe for the child process to send us data */
771 /* (increase this value if you have trouble while fast capture file switches) */
772 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
773 /* Couldn't create the message pipe between parent and child. */
774 *msg = g_strdup_printf("Couldn't create data pipe: %s",
775 win32strerror(GetLastError()));
776 CloseHandle(sync_pipe[PIPE_READ]);
777 CloseHandle(sync_pipe[PIPE_WRITE]);
778 for (i = 0; argv[i] != NULL; i++) {
779 g_free( (gpointer) argv[i]);
781 g_free( (gpointer) argv);
785 /* init STARTUPINFO */
786 memset(&si, 0, sizeof(si));
789 si.dwFlags = STARTF_USESHOWWINDOW;
790 si.wShowWindow = SW_SHOW;
792 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
793 si.wShowWindow = SW_HIDE; /* this hides the console window */
795 si.hStdOutput = data_pipe[PIPE_WRITE];
796 si.hStdError = sync_pipe[PIPE_WRITE];
799 /* convert args array into a single string */
800 /* XXX - could change sync_pipe_add_arg() instead */
801 /* there is a drawback here: the length is internally limited to 1024 bytes */
802 for(i=0; argv[i] != 0; i++) {
803 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
804 quoted_arg = protect_arg(argv[i]);
805 g_string_append(args, quoted_arg);
810 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
811 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
812 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
813 args->str, win32strerror(GetLastError()));
814 CloseHandle(data_pipe[PIPE_READ]);
815 CloseHandle(data_pipe[PIPE_WRITE]);
816 CloseHandle(sync_pipe[PIPE_READ]);
817 CloseHandle(sync_pipe[PIPE_WRITE]);
818 for (i = 0; argv[i] != NULL; i++) {
819 g_free( (gpointer) argv[i]);
821 g_free( (gpointer) argv);
824 *fork_child = (int) pi.hProcess;
825 g_string_free(args, TRUE);
827 /* associate the operating system filehandles to C run-time file handles */
828 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
829 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
830 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
832 /* Create a pipe for the child process to send us messages */
833 if (pipe(sync_pipe) < 0) {
834 /* Couldn't create the message pipe between parent and child. */
835 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
836 for (i = 0; argv[i] != NULL; i++) {
837 g_free( (gpointer) argv[i]);
843 /* Create a pipe for the child process to send us data */
844 if (pipe(data_pipe) < 0) {
845 /* Couldn't create the data pipe between parent and child. */
846 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
847 ws_close(sync_pipe[PIPE_READ]);
848 ws_close(sync_pipe[PIPE_WRITE]);
849 for (i = 0; argv[i] != NULL; i++) {
850 g_free( (gpointer) argv[i]);
856 if ((*fork_child = fork()) == 0) {
858 * Child process - run dumpcap with the right arguments to make
859 * it just capture with the specified capture parameters
861 dup2(data_pipe[PIPE_WRITE], 1);
862 ws_close(data_pipe[PIPE_READ]);
863 ws_close(data_pipe[PIPE_WRITE]);
864 dup2(sync_pipe[PIPE_WRITE], 2);
865 ws_close(sync_pipe[PIPE_READ]);
866 ws_close(sync_pipe[PIPE_WRITE]);
867 execv(argv[0], argv);
868 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
869 argv[0], g_strerror(errno));
870 sync_pipe_errmsg_to_parent(2, errmsg, "");
872 /* Exit with "_exit()", so that we don't close the connection
873 to the X server (and cause stuff buffered up by our parent but
874 not yet sent to be sent, as that stuff should only be sent by
875 our parent). We've sent an error message to the parent, so
876 we exit with an exit status of 1 (any exit status other than
877 0 or 1 will cause an additional message to report that exit
878 status, over and above the error message we sent to the parent). */
882 *data_read_fd = data_pipe[PIPE_READ];
883 *message_read_fd = sync_pipe[PIPE_READ];
886 for (i = 0; argv[i] != NULL; i++) {
887 g_free( (gpointer) argv[i]);
890 /* Parent process - read messages from the child process over the
892 g_free( (gpointer) argv); /* free up arg array */
894 /* Close the write sides of the pipes, so that only the child has them
895 open, and thus they completely close, and thus return to us
896 an EOF indication, if the child closes them (either deliberately
897 or by exiting abnormally). */
899 CloseHandle(data_pipe[PIPE_WRITE]);
900 CloseHandle(sync_pipe[PIPE_WRITE]);
902 ws_close(data_pipe[PIPE_WRITE]);
903 ws_close(sync_pipe[PIPE_WRITE]);
906 if (*fork_child == -1) {
907 /* We couldn't even create the child process. */
908 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
909 ws_close(*data_read_fd);
910 ws_close(*message_read_fd);
914 /* we might wait for a moment till child is ready, so update screen now */
915 main_window_update();
920 * Close the pipes we're using to read from dumpcap, and wait for it
921 * to exit. On success, *msgp is unchanged, and the exit status of
922 * dumpcap is returned. On failure (which includes "dumpcap exited
923 * due to being killed by a signal or an exception"), *msgp points
924 * to an error message for the failure, and -1 is returned. In the
925 * latter case, *msgp must be freed with g_free().
928 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
929 int *fork_child, gchar **msgp)
931 ws_close(*data_read_fd);
932 if (message_read_fd != NULL)
933 ws_close(*message_read_fd);
936 /* XXX - Should we signal the child somehow? */
937 sync_pipe_kill(*fork_child);
940 return sync_pipe_wait_for_child(*fork_child, msgp);
944 * Run dumpcap with the supplied arguments.
946 * On success, *data points to a buffer containing the dumpcap output,
947 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
948 * must be freed with g_free().
950 * On failure, *data is NULL, *primary_msg points to an error message,
951 * *secondary_msg either points to an additional error message or is
952 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
953 * must be freed with g_free().
955 /* XXX - This duplicates a lot of code in sync_pipe_start() */
956 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
957 #define PIPE_BUF_SIZE 5120
959 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
960 gchar **secondary_msg)
963 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
965 gchar buffer[PIPE_BUF_SIZE+1];
969 char *primary_msg_text;
970 int secondary_msg_len;
971 char *secondary_msg_text;
973 GString *data_buf = NULL;
976 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
980 *secondary_msg = NULL;
986 * We were able to set up to read dumpcap's output. Do so.
988 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
990 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
991 buffer, primary_msg);
993 /* We got a read error from the sync pipe, or we got no data at
994 all from the sync pipe, so we're not going to be getting any
995 data or error message from the child process. Pick up its
996 exit status, and complain.
998 We don't have to worry about killing the child, if the sync pipe
999 returned an error. Usually this error is caused as the child killed
1000 itself while going down. Even in the rare cases that this isn't the
1001 case, the child will get an error when writing to the broken pipe
1002 the next time, cleaning itself up then. */
1003 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1005 /* We got an EOF from the sync pipe. That means that it exited
1006 before giving us any data to read. If ret is -1, we report
1007 that as a bad exit (e.g., exiting due to a signal); otherwise,
1008 we report it as a premature exit. */
1010 *primary_msg = wait_msg;
1012 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1014 /* We got an error from the sync pipe. If ret is -1, report
1015 both the sync pipe I/O error and the wait error. */
1017 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1018 g_free(*primary_msg);
1020 *primary_msg = combined_msg;
1023 *secondary_msg = NULL;
1028 /* we got a valid message block from the child, process it */
1033 * Error from dumpcap; there will be a primary message and a
1034 * secondary message.
1037 /* convert primary message */
1038 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1039 primary_msg_text = buffer+4;
1040 /* convert secondary message */
1041 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1042 &secondary_msg_len);
1043 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1044 /* the capture child will close the sync_pipe, nothing to do */
1047 * Pick up the child status.
1049 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1053 * Child process failed unexpectedly, or wait failed; msg is the
1057 *secondary_msg = NULL;
1060 * Child process failed, but returned the expected exit status.
1061 * Return the messages it gave us, and indicate failure.
1063 *primary_msg = g_strdup(primary_msg_text);
1064 *secondary_msg = g_strdup(secondary_msg_text);
1071 /* read the output from the command */
1072 data_buf = g_string_new("");
1073 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1074 buffer[count] = '\0';
1075 g_string_append(data_buf, buffer);
1079 * Pick up the child status.
1081 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1085 * Child process failed unexpectedly, or wait failed; msg is the
1089 *secondary_msg = NULL;
1090 g_string_free(data_buf, TRUE);
1094 * Child process succeeded.
1096 *primary_msg = NULL;
1097 *secondary_msg = NULL;
1098 *data = data_buf->str;
1099 g_string_free(data_buf, FALSE);
1105 * Pick up the child status.
1107 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1111 * Child process failed unexpectedly, or wait failed; msg is the
1115 *secondary_msg = NULL;
1118 * Child process returned an unknown status.
1120 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1122 *secondary_msg = NULL;
1131 /* centralised logging and timing for sync_pipe_run_command_actual(),
1132 * redirects to sync_pipe_run_command_actual()
1135 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1136 gchar **secondary_msg)
1139 GTimeVal start_time;
1142 int logging_enabled;
1144 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1145 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1146 if(logging_enabled){
1147 g_get_current_time(&start_time);
1148 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1149 for(i=0; argv[i] != 0; i++) {
1150 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1153 /* do the actual sync pipe run command */
1154 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg);
1156 if(logging_enabled){
1157 g_get_current_time(&end_time);
1158 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1159 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1161 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1169 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1170 gchar **data, gchar **primary_msg,
1171 gchar **secondary_msg)
1177 argv = init_pipe_args(&argc);
1180 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1181 *secondary_msg = NULL;
1186 argv = sync_pipe_add_arg(argv, &argc, "-i");
1187 argv = sync_pipe_add_arg(argv, &argc, iface);
1190 opt = g_strdup_printf("%s,%s", freq, type);
1192 opt = g_strdup_printf("%s", freq);
1195 *primary_msg = g_strdup("Out of mem.");
1196 *secondary_msg = NULL;
1201 argv = sync_pipe_add_arg(argv, &argc, "-k");
1202 argv = sync_pipe_add_arg(argv, &argc, opt);
1205 /* Run dumpcap in capture child mode */
1206 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1207 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1210 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1216 * Get the list of interfaces using dumpcap.
1218 * On success, *data points to a buffer containing the dumpcap output,
1219 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1220 * must be freed with g_free().
1222 * On failure, *data is NULL, *primary_msg points to an error message,
1223 * *secondary_msg either points to an additional error message or is
1224 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1225 * must be freed with g_free().
1228 sync_interface_list_open(gchar **data, gchar **primary_msg,
1229 gchar **secondary_msg)
1234 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1236 argv = init_pipe_args(&argc);
1239 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1240 *secondary_msg = NULL;
1245 /* Ask for the interface list */
1246 argv = sync_pipe_add_arg(argv, &argc, "-D");
1249 /* Run dumpcap in capture child mode */
1250 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1251 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1253 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1257 * Get the capabilities of an interface using dumpcap.
1259 * On success, *data points to a buffer containing the dumpcap output,
1260 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1261 * must be freed with g_free().
1263 * On failure, *data is NULL, *primary_msg points to an error message,
1264 * *secondary_msg either points to an additional error message or is
1265 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1266 * must be freed with g_free().
1269 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1270 gchar **data, gchar **primary_msg,
1271 gchar **secondary_msg)
1276 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1278 argv = init_pipe_args(&argc);
1281 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1282 *secondary_msg = NULL;
1287 /* Ask for the interface capabilities */
1288 argv = sync_pipe_add_arg(argv, &argc, "-i");
1289 argv = sync_pipe_add_arg(argv, &argc, ifname);
1290 argv = sync_pipe_add_arg(argv, &argc, "-L");
1292 argv = sync_pipe_add_arg(argv, &argc, "-I");
1295 /* Run dumpcap in capture child mode */
1296 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1297 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1299 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1303 * Start getting interface statistics using dumpcap. On success, read_fd
1304 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1305 * and zero is returned. On failure, *msg will point to an error message
1306 * that must be g_free()d, and -1 will be returned.
1309 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1313 int message_read_fd, ret;
1315 gchar buffer[PIPE_BUF_SIZE+1];
1318 int primary_msg_len;
1319 char *primary_msg_text;
1320 int secondary_msg_len;
1321 /*char *secondary_msg_text;*/
1324 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1326 argv = init_pipe_args(&argc);
1329 *msg = g_strdup("We don't know where to find dumpcap.");
1333 /* Ask for the interface statistics */
1334 argv = sync_pipe_add_arg(argv, &argc, "-S");
1337 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1338 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1340 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1346 * We were able to set up to read dumpcap's output. Do so.
1348 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1350 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1353 /* We got a read error from the sync pipe, or we got no data at
1354 all from the sync pipe, so we're not going to be getting any
1355 data or error message from the child process. Pick up its
1356 exit status, and complain.
1358 We don't have to worry about killing the child, if the sync pipe
1359 returned an error. Usually this error is caused as the child killed
1360 itself while going down. Even in the rare cases that this isn't the
1361 case, the child will get an error when writing to the broken pipe
1362 the next time, cleaning itself up then. */
1363 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1365 /* We got an EOF from the sync pipe. That means that it exited
1366 before giving us any data to read. If ret is -1, we report
1367 that as a bad exit (e.g., exiting due to a signal); otherwise,
1368 we report it as a premature exit. */
1372 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1374 /* We got an error from the sync pipe. If ret is -1, report
1375 both the sync pipe I/O error and the wait error. */
1377 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1380 *msg = combined_msg;
1387 /* we got a valid message block from the child, process it */
1392 * Error from dumpcap; there will be a primary message and a
1393 * secondary message.
1396 /* convert primary message */
1397 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1398 primary_msg_text = buffer+4;
1399 /* convert secondary message */
1400 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1401 &secondary_msg_len);
1402 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1403 /* the capture child will close the sync_pipe, nothing to do */
1406 * Pick up the child status.
1408 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1412 * Child process failed unexpectedly, or wait failed; msg is the
1417 * Child process failed, but returned the expected exit status.
1418 * Return the messages it gave us, and indicate failure.
1420 *msg = g_strdup(primary_msg_text);
1426 /* Close the message pipe. */
1427 ws_close(message_read_fd);
1432 * Pick up the child status.
1434 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1438 * Child process failed unexpectedly, or wait failed; msg is the
1443 * Child process returned an unknown status.
1445 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1454 /* Close down the stats process */
1456 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1460 * Don't bother waiting for the child. sync_pipe_close_command
1461 * does this for us on Windows.
1463 sync_pipe_kill(*fork_child);
1465 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1468 /* read a number of bytes from a pipe */
1469 /* (blocks until enough bytes read or an error occurs) */
1471 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1478 newly = read(pipe_fd, &bytes[offset], required);
1481 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1482 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1489 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1490 "read from pipe %d: error(%u): %s", pipe_fd, error,
1492 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1497 required -= (int)newly;
1505 static gboolean pipe_data_available(int pipe_fd) {
1506 #ifdef _WIN32 /* PeekNamedPipe */
1507 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1510 if (hPipe == INVALID_HANDLE_VALUE)
1513 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1516 if (bytes_avail > 0)
1521 struct timeval timeout;
1524 FD_SET(pipe_fd, &rfds);
1526 timeout.tv_usec = 0;
1528 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1535 /* Read a line from a pipe, similar to fgets */
1537 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1541 while(offset < max - 1) {
1543 if (! pipe_data_available(pipe_fd))
1545 newly = read(pipe_fd, &bytes[offset], 1);
1547 /* EOF - not necessarily an error */
1549 } else if (newly == -1) {
1551 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1552 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1554 } else if (bytes[offset] == '\n') {
1560 bytes[offset] = '\0';
1566 /* convert header values (indicator and 3-byte length) */
1568 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1570 g_assert(header_len == 4);
1572 /* convert header values */
1573 *indicator = header[0];
1574 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1577 /* read a message from the sending pipe in the standard format
1578 (1-byte message indicator, 3-byte message length (excluding length
1579 and indicator field), and the rest is the message) */
1581 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1588 /* read header (indicator and 3-byte length) */
1589 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1593 * Immediate EOF; if the capture child exits normally, this
1594 * is an "I'm done" indication, so don't report it as an
1597 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1598 "read %d got an EOF", pipe_fd);
1601 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1602 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1605 * Short read, but not an immediate EOF.
1607 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1613 /* convert header values */
1614 pipe_convert_header((guchar*)header, 4, indicator, &required);
1616 /* only indicator with no value? */
1618 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1619 "read %d indicator: %c empty value", pipe_fd, *indicator);
1623 /* does the data fit into the given buffer? */
1624 if(required > len) {
1625 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1626 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1627 pipe_fd, required, len,
1628 header[0], header[1], header[2], header[3]);
1630 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1631 memcpy(msg, header, sizeof(header));
1632 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1633 if (newly < 0) { /* error */
1634 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1635 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1637 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1643 /* read the actual block data */
1644 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1645 if(newly != required) {
1647 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1653 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1654 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1655 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1662 /* There's stuff to read from the sync pipe, meaning the child has sent
1663 us a message, or the sync pipe has closed, meaning the child has
1664 closed it (perhaps because it exited). */
1666 sync_pipe_input_cb(gint source, gpointer user_data)
1668 capture_session *cap_session = (capture_session *)user_data;
1670 char buffer[SP_MAX_MSG_LEN+1];
1676 char *secondary_msg;
1677 char *wait_msg, *combined_msg;
1680 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1683 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1685 If we got a read error or a bad message, nread is -1 and
1686 primary_msg is set to point to an error message. We don't
1687 have to worry about killing the child; usually this error
1688 is caused as the child killed itself while going down.
1689 Even in the rare cases that this isn't the case, the child
1690 will get an error when writing to the broken pipe the next time,
1691 cleaning itself up then.
1693 If we got an EOF, nread is 0 and primary_msg isn't set. This
1694 is an indication that the capture is finished. */
1695 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1697 /* We got an EOF from the sync pipe. That means that the capture
1698 child exited, and not in the middle of a message; we treat
1699 that as an indication that it's done, and only report an
1700 error if ret is -1, in which case wait_msg is the error
1703 primary_msg = wait_msg;
1705 /* We got an error from the sync pipe. If ret is -1, report
1706 both the sync pipe I/O error and the wait error. */
1708 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1709 g_free(primary_msg);
1711 primary_msg = combined_msg;
1715 /* No more child process. */
1716 cap_session->fork_child = -1;
1717 cap_session->fork_child_status = ret;
1720 ws_close(cap_session->signal_pipe_write_fd);
1722 capture_input_closed(cap_session, primary_msg);
1723 g_free(primary_msg);
1727 /* we got a valid message block from the child, process it */
1730 if(!capture_input_new_file(cap_session, buffer)) {
1731 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1733 /* We weren't able to open the new capture file; user has been
1734 alerted. Close the sync pipe. */
1737 /* The child has sent us a filename which we couldn't open.
1739 This could mean that the child is creating files faster
1740 than we can handle it. (XXX - why would that result in
1741 a failure to open the file?)
1743 That should only be the case for very fast file switches;
1744 We can't do much more than telling the child to stop.
1745 (This is the "emergency brake" if the user e.g. wants to
1746 switch files every second).
1748 This can also happen if the user specified "-", meaning
1749 "standard output", as the capture file. */
1750 sync_pipe_stop(cap_session);
1751 capture_input_closed(cap_session, NULL);
1755 case SP_PACKET_COUNT:
1756 npackets = atoi(buffer);
1757 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1758 capture_input_new_packets(cap_session, npackets);
1761 /* convert primary message */
1762 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1763 primary_msg = buffer+4;
1764 /* convert secondary message */
1765 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1766 secondary_msg = primary_msg + primary_len + 4;
1767 /* message output */
1768 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1769 /* the capture child will close the sync_pipe, nothing to do for now */
1770 /* (an error message doesn't mean we have to stop capturing) */
1772 case SP_BAD_FILTER: {
1776 ch = strtok(buffer, ":");
1777 indx = (int)strtol(ch, NULL, 10);
1778 ch = strtok(NULL, ":");
1779 capture_input_cfilter_error_message(cap_session, indx, ch);
1780 /* the capture child will close the sync_pipe, nothing to do for now */
1784 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1787 g_assert_not_reached();
1796 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1797 * unchanged, and the exit status of dumpcap is returned. On
1798 * failure (which includes "dumpcap exited due to being killed by
1799 * a signal or an exception"), *msgp points to an error message
1800 * for the failure, and -1 is returned. In the latter case, *msgp
1801 * must be freed with g_free().
1804 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1806 int fork_child_status;
1808 GTimeVal start_time;
1813 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1816 g_get_current_time(&start_time);
1818 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1819 g_assert(fork_child != -1);
1821 *msgp = NULL; /* assume no error */
1823 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1824 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1828 * The child exited; return its exit status. Do not treat this as
1831 ret = fork_child_status;
1832 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1833 /* Probably an exception code */
1834 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1835 win32strexception(fork_child_status));
1840 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1841 if (WIFEXITED(fork_child_status)) {
1843 * The child exited; return its exit status. Do not treat this as
1846 ret = WEXITSTATUS(fork_child_status);
1847 } else if (WIFSTOPPED(fork_child_status)) {
1848 /* It stopped, rather than exiting. "Should not happen." */
1849 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1850 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1852 } else if (WIFSIGNALED(fork_child_status)) {
1853 /* It died with a signal. */
1854 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1855 sync_pipe_signame(WTERMSIG(fork_child_status)),
1856 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1859 /* What? It had to either have exited, or stopped, or died with
1860 a signal; what happened here? */
1861 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1866 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1871 g_get_current_time(&end_time);
1872 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1873 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1874 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1880 /* convert signal to corresponding name */
1882 sync_pipe_signame(int sig)
1885 static char sigmsg_buf[6+1+3+1];
1894 sigmsg = "Interrupted";
1902 sigmsg = "Illegal instruction";
1906 sigmsg = "Trace trap";
1914 sigmsg = "Arithmetic exception";
1922 sigmsg = "Bus error";
1926 sigmsg = "Segmentation violation";
1929 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1930 Linux is POSIX compliant. These are not POSIX-defined signals ---
1931 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1933 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1934 were omitted from POSIX.1 because their behavior is
1935 implementation dependent and could not be adequately catego-
1936 rized. Conforming implementations may deliver these sig-
1937 nals, but must document the circumstances under which they
1938 are delivered and note any restrictions concerning their
1941 So we only check for SIGSYS on those systems that happen to
1942 implement them (a system can be POSIX-compliant and implement
1943 them, it's just that POSIX doesn't *require* a POSIX-compliant
1944 system to implement them).
1949 sigmsg = "Bad system call";
1954 sigmsg = "Broken pipe";
1958 sigmsg = "Alarm clock";
1962 sigmsg = "Terminated";
1966 /* Returning a static buffer is ok in the context we use it here */
1967 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1968 sigmsg = sigmsg_buf;
1977 /* tell the child through the signal pipe that we want to quit the capture */
1979 signal_pipe_capquit_to_child(capture_session *cap_session)
1981 const char quit_msg[] = "QUIT";
1984 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1986 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1987 /* simply sending a "QUIT" string */
1988 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1989 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1991 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1992 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
1998 /* user wants to stop the capture run */
2000 sync_pipe_stop(capture_session *cap_session)
2005 gboolean terminate = TRUE;
2008 if (cap_session->fork_child != -1) {
2010 /* send the SIGINT signal to close the capture child gracefully. */
2011 int sts = kill(cap_session->fork_child, SIGINT);
2013 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2014 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2017 #define STOP_SLEEP_TIME 500 /* ms */
2018 #define STOP_CHECK_TIME 50
2019 /* First, use the special signal pipe to try to close the capture child
2022 signal_pipe_capquit_to_child(cap_session);
2024 /* Next, wait for the process to exit on its own */
2025 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2026 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2027 childstatus != STILL_ACTIVE) {
2031 Sleep(STOP_CHECK_TIME);
2034 /* Force the issue. */
2036 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2037 "sync_pipe_stop: forcing child to exit");
2038 sync_pipe_kill(cap_session->fork_child);
2045 /* Wireshark has to exit, force the capture child to close */
2047 sync_pipe_kill(int fork_child)
2049 if (fork_child != -1) {
2051 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2053 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2054 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2057 /* Remark: This is not the preferred method of closing a process!
2058 * the clean way would be getting the process id of the child process,
2059 * then getting window handle hWnd of that process (using EnumChildWindows),
2060 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2062 * Unfortunately, I don't know how to get the process id from the
2063 * handle. OpenProcess will get an handle (not a window handle)
2064 * from the process ID; it will not get a window handle from the
2065 * process ID. (How could it? A process can have more than one
2066 * window. For that matter, a process might have *no* windows,
2067 * as a process running dumpcap, the normal child process program,
2070 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2071 * running in the same console; that's not necessarily the case for
2072 * us, as we might not be running in a console.
2073 * And this also will require to have the process id.
2075 TerminateProcess((HANDLE) (fork_child), 0);
2080 #endif /* HAVE_LIBPCAP */