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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
47 #include <wsutil/unicode-utils.h>
50 #ifdef HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
54 #include "capture-pcap-util.h"
58 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
59 * macros) on UNIX systems that don't have them.
62 # define WIFEXITED(status) (((status) & 0177) == 0)
65 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
68 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
71 # define WEXITSTATUS(status) ((status) >> 8)
74 # define WTERMSIG(status) ((status) & 0177)
77 # define WCOREDUMP(status) ((status) & 0200)
80 # define WSTOPSIG(status) ((status) >> 8)
84 #include <epan/packet.h>
85 #include <epan/prefs.h>
89 #include <epan/filesystem.h>
90 #include <epan/report_err.h>
93 #include "capture_sync.h"
95 #include "sync_pipe.h"
98 #include "capture-wpcap.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 int pipe_read_block(int pipe_fd, char *indicator, int len, char *msg);
122 /* Append an arg (realloc) to an argc/argv array */
123 /* (add a string pointer to a NULL-terminated array of string pointers) */
125 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
127 /* Grow the array; "*argc" currently contains the number of string
128 pointers, *not* counting the NULL pointer at the end, so we have
129 to add 2 in order to get the new size of the array, including the
130 new pointer and the terminating NULL pointer. */
131 args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
133 /* Stuff the pointer into the penultimate element of the array, which
134 is the one at the index specified by "*argc". */
137 /* Now bump the count. */
140 /* We overwrite the NULL pointer; put it back right after the
150 /* Quote the argument element if necessary, so that it will get
151 * reconstructed correctly in the C runtime startup code. Note that
152 * the unquoting algorithm in the C runtime is really weird, and
153 * rather different than what Unix shells do. See stdargv.c in the C
154 * runtime sources (in the Platform SDK, in src/crt).
156 * Stolen from GLib's protect_argv(), an internal routine that quotes
157 * string in an argument list so that they arguments will be handled
158 * correctly in the command-line string passed to CreateProcess()
159 * if that string is constructed by gluing those strings together.
162 protect_arg (const gchar *argv)
165 const gchar *p = argv;
168 gboolean need_dblquotes = FALSE;
171 if (*p == ' ' || *p == '\t')
172 need_dblquotes = TRUE;
175 else if (*p == '\\') {
178 while (*pp && *pp == '\\')
187 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
196 else if (*p == '\\') {
199 while (*pp && *pp == '\\')
216 * Generate a string for a Win32 error.
218 #define ERRBUF_SIZE 1024
220 win32strerror(DWORD error)
223 static char errbuf[ERRBUF_SIZE+1];
227 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
231 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
232 * message. Get rid of it.
234 errlen = strlen(errbuf);
236 errbuf[errlen - 1] = '\0';
237 errbuf[errlen - 2] = '\0';
239 p = strchr(errbuf, '\0');
240 g_snprintf(p, sizeof errbuf - (p-errbuf), " (%lu)", error);
245 /* Initialize an argument list and add dumpcap to it. */
247 init_pipe_args(int *argc) {
249 const char *progfile_dir;
252 progfile_dir = get_progfile_dir();
253 if (progfile_dir == NULL) {
257 /* Allocate the string pointer array with enough space for the
258 terminating NULL pointer. */
260 argv = g_malloc(sizeof (char *));
263 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
264 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
266 /* Make that the first argument in the argument list (argv[0]). */
267 argv = sync_pipe_add_arg(argv, argc, exename);
272 #define ARGV_NUMBER_LEN 24
273 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
275 sync_pipe_start(capture_options *capture_opts) {
276 char ssnap[ARGV_NUMBER_LEN];
277 char sdlt[ARGV_NUMBER_LEN];
278 char scount[ARGV_NUMBER_LEN];
279 char sfilesize[ARGV_NUMBER_LEN];
280 char sfile_duration[ARGV_NUMBER_LEN];
281 char sring_num_files[ARGV_NUMBER_LEN];
282 char sautostop_files[ARGV_NUMBER_LEN];
283 char sautostop_filesize[ARGV_NUMBER_LEN];
284 char sautostop_duration[ARGV_NUMBER_LEN];
285 #ifdef HAVE_PCAP_REMOTE
288 #ifdef HAVE_PCAP_SETSAMPLING
289 char ssampling[ARGV_NUMBER_LEN];
291 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
292 char buffer_size[ARGV_NUMBER_LEN];
295 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
296 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
297 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
298 GString *args = g_string_sized_new(200);
300 SECURITY_ATTRIBUTES sa;
302 PROCESS_INFORMATION pi;
304 char control_id[ARGV_NUMBER_LEN];
305 gchar *signal_pipe_name;
308 int sync_pipe[2]; /* pipe used to send messages from child to parent */
309 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
311 int sync_pipe_read_fd;
316 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
317 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
319 capture_opts->fork_child = -1;
321 argv = init_pipe_args(&argc);
323 /* We don't know where to find dumpcap. */
324 report_failure("We don't know where to find dumpcap.");
328 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
330 argv = sync_pipe_add_arg(argv, &argc, "-i");
331 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
333 if (capture_opts->has_snaplen) {
334 argv = sync_pipe_add_arg(argv, &argc, "-s");
335 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
336 argv = sync_pipe_add_arg(argv, &argc, ssnap);
339 if (capture_opts->linktype != -1) {
340 argv = sync_pipe_add_arg(argv, &argc, "-y");
341 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
342 argv = sync_pipe_add_arg(argv, &argc, sdlt);
345 if(capture_opts->multi_files_on) {
346 if (capture_opts->has_autostop_filesize) {
347 argv = sync_pipe_add_arg(argv, &argc, "-b");
348 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
349 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
352 if (capture_opts->has_file_duration) {
353 argv = sync_pipe_add_arg(argv, &argc, "-b");
354 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
355 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
358 if (capture_opts->has_ring_num_files) {
359 argv = sync_pipe_add_arg(argv, &argc, "-b");
360 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
361 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
364 if (capture_opts->has_autostop_files) {
365 argv = sync_pipe_add_arg(argv, &argc, "-a");
366 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
367 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
370 if (capture_opts->has_autostop_filesize) {
371 argv = sync_pipe_add_arg(argv, &argc, "-a");
372 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
373 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
377 if (capture_opts->has_autostop_packets) {
378 argv = sync_pipe_add_arg(argv, &argc, "-c");
379 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
380 argv = sync_pipe_add_arg(argv, &argc, scount);
383 if (capture_opts->has_autostop_duration) {
384 argv = sync_pipe_add_arg(argv, &argc, "-a");
385 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
386 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
389 if (!capture_opts->promisc_mode)
390 argv = sync_pipe_add_arg(argv, &argc, "-p");
391 #ifdef HAVE_PCAP_CREATE
392 if (capture_opts->monitor_mode)
393 argv = sync_pipe_add_arg(argv, &argc, "-I");
395 if (capture_opts->use_pcapng)
396 argv = sync_pipe_add_arg(argv, &argc, "-n");
397 #ifdef HAVE_PCAP_REMOTE
398 if (capture_opts->datatx_udp)
399 argv = sync_pipe_add_arg(argv, &argc, "-u");
401 if (!capture_opts->nocap_rpcap)
402 argv = sync_pipe_add_arg(argv, &argc, "-r");
404 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
406 argv = sync_pipe_add_arg(argv, &argc, "-A");
407 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
408 capture_opts->auth_password);
409 argv = sync_pipe_add_arg(argv, &argc, sauth);
412 #ifdef HAVE_PCAP_SETSAMPLING
413 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
415 argv = sync_pipe_add_arg(argv, &argc, "-m");
416 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
417 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
418 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
420 capture_opts->sampling_param);
421 argv = sync_pipe_add_arg(argv, &argc, ssampling);
425 /* dumpcap should be running in capture child mode (hidden feature) */
427 argv = sync_pipe_add_arg(argv, &argc, "-Z");
429 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
430 argv = sync_pipe_add_arg(argv, &argc, control_id);
432 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
436 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
437 argv = sync_pipe_add_arg(argv, &argc, "-B");
438 #ifdef HAVE_PCAP_REMOTE
439 if (capture_opts->src_type == CAPTURE_IFREMOTE)
440 /* No buffer size when using remote interfaces */
441 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
444 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
445 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
448 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
449 argv = sync_pipe_add_arg(argv, &argc, "-f");
450 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
453 if(capture_opts->save_file) {
454 argv = sync_pipe_add_arg(argv, &argc, "-w");
455 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
459 /* init SECURITY_ATTRIBUTES */
460 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
461 sa.bInheritHandle = TRUE;
462 sa.lpSecurityDescriptor = NULL;
464 /* Create a pipe for the child process */
465 /* (increase this value if you have trouble while fast capture file switches) */
466 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
467 /* Couldn't create the pipe between parent and child. */
468 report_failure("Couldn't create sync pipe: %s",
469 win32strerror(GetLastError()));
470 g_free( (gpointer) argv[0]);
471 g_free( (gpointer) argv);
475 /* Create the signal pipe */
476 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
477 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
478 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
479 g_free(signal_pipe_name);
481 if (signal_pipe == INVALID_HANDLE_VALUE) {
482 /* Couldn't create the signal pipe between parent and child. */
483 report_failure("Couldn't create signal pipe: %s",
484 win32strerror(GetLastError()));
485 g_free( (gpointer) argv[0]);
486 g_free( (gpointer) argv);
490 /* init STARTUPINFO */
491 memset(&si, 0, sizeof(si));
494 si.dwFlags = STARTF_USESHOWWINDOW;
495 si.wShowWindow = SW_SHOW;
497 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
498 si.wShowWindow = SW_HIDE; /* this hides the console window */
499 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
500 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
501 si.hStdError = sync_pipe_write;
502 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
505 /* convert args array into a single string */
506 /* XXX - could change sync_pipe_add_arg() instead */
507 /* there is a drawback here: the length is internally limited to 1024 bytes */
508 for(i=0; argv[i] != 0; i++) {
509 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
510 quoted_arg = protect_arg(argv[i]);
511 g_string_append(args, quoted_arg);
516 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
517 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
518 report_failure("Couldn't run %s in child process: %s",
519 args->str, win32strerror(GetLastError()));
520 CloseHandle(sync_pipe_read);
521 CloseHandle(sync_pipe_write);
522 g_free( (gpointer) argv[0]);
523 g_free( (gpointer) argv);
526 capture_opts->fork_child = (int) pi.hProcess;
527 g_string_free(args, TRUE);
529 /* associate the operating system filehandle to a C run-time file handle */
530 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
531 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
533 /* associate the operating system filehandle to a C run-time file handle */
534 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
537 if (pipe(sync_pipe) < 0) {
538 /* Couldn't create the pipe between parent and child. */
539 report_failure("Couldn't create sync pipe: %s", strerror(errno));
540 g_free( (gpointer) argv[0]);
545 if ((capture_opts->fork_child = fork()) == 0) {
547 * Child process - run dumpcap with the right arguments to make
548 * it just capture with the specified capture parameters
550 dup2(sync_pipe[PIPE_WRITE], 2);
551 ws_close(sync_pipe[PIPE_READ]);
552 execv(argv[0], (gpointer)argv);
553 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
554 argv[0], strerror(errno));
555 sync_pipe_errmsg_to_parent(2, errmsg, "");
557 /* Exit with "_exit()", so that we don't close the connection
558 to the X server (and cause stuff buffered up by our parent but
559 not yet sent to be sent, as that stuff should only be sent by
560 our parent). We've sent an error message to the parent, so
561 we exit with an exit status of 1 (any exit status other than
562 0 or 1 will cause an additional message to report that exit
563 status, over and above the error message we sent to the parent). */
567 sync_pipe_read_fd = sync_pipe[PIPE_READ];
570 g_free( (gpointer) argv[0]); /* exename */
572 /* Parent process - read messages from the child process over the
574 g_free( (gpointer) argv); /* free up arg array */
576 /* Close the write side of the pipe, so that only the child has it
577 open, and thus it completely closes, and thus returns to us
578 an EOF indication, if the child closes it (either deliberately
579 or by exiting abnormally). */
581 CloseHandle(sync_pipe_write);
583 ws_close(sync_pipe[PIPE_WRITE]);
586 if (capture_opts->fork_child == -1) {
587 /* We couldn't even create the child process. */
588 report_failure("Couldn't create child process: %s", strerror(errno));
589 ws_close(sync_pipe_read_fd);
591 ws_close(capture_opts->signal_pipe_write_fd);
596 /* we might wait for a moment till child is ready, so update screen now */
597 main_window_update();
599 /* We were able to set up to read the capture file;
600 arrange that our callback be called whenever it's possible
601 to read from the sync pipe, so that it's called when
602 the child process wants to tell us something. */
604 /* we have a running capture, now wait for the real capture filename */
605 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
606 &capture_opts->fork_child, sync_pipe_input_cb);
612 * Open two pipes to dumpcap with the supplied arguments, one for its
613 * standard output and one for its standard error.
615 * On success, *msg is unchanged and 0 is returned; data_read_fd,
616 * messsage_read_fd, and fork_child point to the standard output pipe's
617 * file descriptor, the standard error pipe's file descriptor, and
618 * the child's PID/handle, respectively.
620 * On failure, *msg points to an error message for the failure, and -1 is
621 * returned, in which case *msg must be freed with g_free().
623 /* XXX - This duplicates a lot of code in sync_pipe_start() */
624 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
625 #define PIPE_BUF_SIZE 5120
627 sync_pipe_open_command(const char** argv, int *data_read_fd,
628 int *message_read_fd, int *fork_child, gchar **msg)
630 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
632 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
633 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
634 GString *args = g_string_sized_new(200);
636 SECURITY_ATTRIBUTES sa;
638 PROCESS_INFORMATION pi;
642 int sync_pipe[2]; /* pipe used to send messages from child to parent */
643 int data_pipe[2]; /* pipe used to send data from child to parent */
648 *message_read_fd = -1;
649 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
652 /* We can't return anything */
654 g_string_free(args, TRUE);
660 /* init SECURITY_ATTRIBUTES */
661 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
662 sa.bInheritHandle = TRUE;
663 sa.lpSecurityDescriptor = NULL;
665 /* Create a pipe for the child process to send us messages */
666 /* (increase this value if you have trouble while fast capture file switches) */
667 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
668 /* Couldn't create the message pipe between parent and child. */
669 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
670 win32strerror(GetLastError()));
671 g_free( (gpointer) argv[0]);
672 g_free( (gpointer) argv);
676 /* Create a pipe for the child process to send us data */
677 /* (increase this value if you have trouble while fast capture file switches) */
678 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
679 /* Couldn't create the message pipe between parent and child. */
680 *msg = g_strdup_printf("Couldn't create data pipe: %s",
681 win32strerror(GetLastError()));
682 CloseHandle(sync_pipe[PIPE_READ]);
683 CloseHandle(sync_pipe[PIPE_WRITE]);
684 g_free( (gpointer) argv[0]);
685 g_free( (gpointer) argv);
689 /* init STARTUPINFO */
690 memset(&si, 0, sizeof(si));
693 si.dwFlags = STARTF_USESHOWWINDOW;
694 si.wShowWindow = SW_SHOW;
696 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
697 si.wShowWindow = SW_HIDE; /* this hides the console window */
699 si.hStdOutput = data_pipe[PIPE_WRITE];
700 si.hStdError = sync_pipe[PIPE_WRITE];
703 /* convert args array into a single string */
704 /* XXX - could change sync_pipe_add_arg() instead */
705 /* there is a drawback here: the length is internally limited to 1024 bytes */
706 for(i=0; argv[i] != 0; i++) {
707 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
708 quoted_arg = protect_arg(argv[i]);
709 g_string_append(args, quoted_arg);
714 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
715 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
716 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
717 args->str, win32strerror(GetLastError()));
718 CloseHandle(data_pipe[PIPE_READ]);
719 CloseHandle(data_pipe[PIPE_WRITE]);
720 CloseHandle(sync_pipe[PIPE_READ]);
721 CloseHandle(sync_pipe[PIPE_WRITE]);
722 g_free( (gpointer) argv[0]);
723 g_free( (gpointer) argv);
726 *fork_child = (int) pi.hProcess;
727 g_string_free(args, TRUE);
729 /* associate the operating system filehandles to C run-time file handles */
730 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
731 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
732 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
734 /* Create a pipe for the child process to send us messages */
735 if (pipe(sync_pipe) < 0) {
736 /* Couldn't create the message pipe between parent and child. */
737 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
738 g_free( (gpointer) argv[0]);
743 /* Create a pipe for the child process to send us data */
744 if (pipe(data_pipe) < 0) {
745 /* Couldn't create the data pipe between parent and child. */
746 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
747 ws_close(sync_pipe[PIPE_READ]);
748 ws_close(sync_pipe[PIPE_WRITE]);
749 g_free( (gpointer) argv[0]);
754 if ((*fork_child = fork()) == 0) {
756 * Child process - run dumpcap with the right arguments to make
757 * it just capture with the specified capture parameters
759 dup2(data_pipe[PIPE_WRITE], 1);
760 ws_close(data_pipe[PIPE_READ]);
761 ws_close(data_pipe[PIPE_WRITE]);
762 dup2(sync_pipe[PIPE_WRITE], 2);
763 ws_close(sync_pipe[PIPE_READ]);
764 ws_close(sync_pipe[PIPE_WRITE]);
765 execv(argv[0], (gpointer)argv);
766 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
767 argv[0], strerror(errno));
768 sync_pipe_errmsg_to_parent(2, errmsg, "");
770 /* Exit with "_exit()", so that we don't close the connection
771 to the X server (and cause stuff buffered up by our parent but
772 not yet sent to be sent, as that stuff should only be sent by
773 our parent). We've sent an error message to the parent, so
774 we exit with an exit status of 1 (any exit status other than
775 0 or 1 will cause an additional message to report that exit
776 status, over and above the error message we sent to the parent). */
780 *data_read_fd = data_pipe[PIPE_READ];
781 *message_read_fd = sync_pipe[PIPE_READ];
784 g_free( (gpointer) argv[0]); /* exename */
786 /* Parent process - read messages from the child process over the
788 g_free( (gpointer) argv); /* free up arg array */
790 /* Close the write sides of the pipes, so that only the child has them
791 open, and thus they completely close, and thus return to us
792 an EOF indication, if the child closes them (either deliberately
793 or by exiting abnormally). */
795 CloseHandle(data_pipe[PIPE_WRITE]);
796 CloseHandle(sync_pipe[PIPE_WRITE]);
798 ws_close(data_pipe[PIPE_WRITE]);
799 ws_close(sync_pipe[PIPE_WRITE]);
802 if (*fork_child == -1) {
803 /* We couldn't even create the child process. */
804 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
805 ws_close(*data_read_fd);
806 ws_close(*message_read_fd);
810 /* we might wait for a moment till child is ready, so update screen now */
811 main_window_update();
816 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
817 * returned. On failure, *msg points to an error message for the
818 * failure, and -1 is returned. In the latter case, *msg must be
819 * freed with g_free().
822 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
823 int *fork_child, gchar **msg)
825 ws_close(*data_read_fd);
826 if (message_read_fd != NULL)
827 ws_close(*message_read_fd);
830 /* XXX - Should we signal the child somehow? */
831 sync_pipe_kill(*fork_child);
834 return sync_pipe_wait_for_child(*fork_child, msg);
838 * Run dumpcap with the supplied arguments.
840 * On success, *data points to a buffer containing the dumpcap output,
841 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
842 * must be freed with g_free().
844 * On failure, *data is NULL, *primary_msg points to an error message,
845 * *secondary_msg either points to an additional error message or is
846 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
847 * must be freed with g_free().
849 /* XXX - This duplicates a lot of code in sync_pipe_start() */
850 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
851 #define PIPE_BUF_SIZE 5120
853 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
854 gchar **secondary_msg)
857 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
858 gchar buffer[PIPE_BUF_SIZE+1];
862 char *primary_msg_text;
863 int secondary_msg_len;
864 char *secondary_msg_text;
865 GString *data_buf = NULL;
868 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
872 *secondary_msg = NULL;
878 * We were able to set up to read dumpcap's output. Do so.
880 * First, wait for an SP_ERROR_MESSAGE or SP_SUCCESS message.
882 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
885 /* We got a read error from the sync pipe, or we got no data at
886 all from the sync pipe, so we're not going to be getting any
887 data or error message from the child process. Pick up its
888 exit status, and complain.
890 We don't have to worry about killing the child, if the sync pipe
891 returned an error. Usually this error is caused as the child killed
892 itself while going down. Even in the rare cases that this isn't the
893 case, the child will get an error when writing to the broken pipe
894 the next time, cleaning itself up then. */
895 ret = sync_pipe_wait_for_child(fork_child, primary_msg);
897 /* No unusual exit status; just report the read problem. */
899 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
901 *primary_msg = g_strdup("Error reading from sync pipe");
903 *secondary_msg = NULL;
908 /* we got a valid message block from the child, process it */
913 * Error from dumpcap; there will be a primary message and a
917 /* convert primary message */
918 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
919 primary_msg_text = buffer+4;
920 /* convert secondary message */
921 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
923 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
924 /* the capture child will close the sync_pipe, nothing to do */
927 * Pick up the child status.
929 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
933 * Child process failed unexpectedly, or wait failed; msg is the
937 *secondary_msg = NULL;
940 * Child process failed, but returned the expected exit status.
941 * Return the messages it gave us, and indicate failure.
943 *primary_msg = g_strdup(primary_msg_text);
944 *secondary_msg = g_strdup(secondary_msg_text);
951 /* read the output from the command */
952 data_buf = g_string_new("");
953 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
954 buffer[count] = '\0';
955 g_string_append(data_buf, buffer);
959 * Pick up the child status.
961 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
965 * Child process failed unexpectedly, or wait failed; msg is the
969 *secondary_msg = NULL;
970 g_string_free(data_buf, TRUE);
974 * Child process succeeded.
977 *secondary_msg = NULL;
978 *data = data_buf->str;
979 g_string_free(data_buf, FALSE);
985 * Pick up the child status.
987 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
991 * Child process failed unexpectedly, or wait failed; msg is the
995 *secondary_msg = NULL;
998 * Child process returned an unknown status.
1000 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1002 *secondary_msg = NULL;
1012 * Get the list of interfaces using dumpcap.
1014 * On success, *data points to a buffer containing the dumpcap output,
1015 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1016 * must be freed with g_free().
1018 * On failure, *data is NULL, *primary_msg points to an error message,
1019 * *secondary_msg either points to an additional error message or is
1020 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1021 * must be freed with g_free().
1024 sync_interface_list_open(gchar **data, gchar **primary_msg,
1025 gchar **secondary_msg)
1030 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1032 argv = init_pipe_args(&argc);
1035 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1036 *secondary_msg = NULL;
1041 /* Ask for the interface list */
1042 argv = sync_pipe_add_arg(argv, &argc, "-D");
1045 /* Run dumpcap in capture child mode */
1046 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1047 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1049 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1053 * Get the capabilities of an interface using dumpcap.
1055 * On success, *data points to a buffer containing the dumpcap output,
1056 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1057 * must be freed with g_free().
1059 * On failure, *data is NULL, *primary_msg points to an error message,
1060 * *secondary_msg either points to an additional error message or is
1061 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1062 * must be freed with g_free().
1065 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1066 gchar **data, gchar **primary_msg,
1067 gchar **secondary_msg)
1072 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1074 argv = init_pipe_args(&argc);
1077 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1078 *secondary_msg = NULL;
1083 /* Ask for the interface capabilities */
1084 argv = sync_pipe_add_arg(argv, &argc, "-i");
1085 argv = sync_pipe_add_arg(argv, &argc, ifname);
1086 argv = sync_pipe_add_arg(argv, &argc, "-L");
1088 argv = sync_pipe_add_arg(argv, &argc, "-I");
1091 /* Run dumpcap in capture child mode */
1092 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1093 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1095 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1099 * Start getting interface statistics using dumpcap. On success, read_fd
1100 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1101 * and zero is returned. On failure, *msg will point to an error message
1102 * that must be g_free()d, and -1 will be returned.
1105 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1109 int message_read_fd, ret;
1110 gchar buffer[PIPE_BUF_SIZE+1];
1113 int primary_msg_len;
1114 char *primary_msg_text;
1115 int secondary_msg_len;
1116 char *secondary_msg_text;
1118 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1120 argv = init_pipe_args(&argc);
1123 *msg = g_strdup("We don't know where to find dumpcap.");
1127 /* Ask for the interface statistics */
1128 argv = sync_pipe_add_arg(argv, &argc, "-S");
1131 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1132 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1134 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1140 * We were able to set up to read dumpcap's output. Do so.
1142 * First, wait for an SP_ERROR_MESSAGE or SP_SUCCESS message.
1144 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1147 /* We got a read error from the sync pipe, or we got no data at
1148 all from the sync pipe, so we're not going to be getting any
1149 data or error message from the child process. Pick up its
1150 exit status, and complain.
1152 We don't have to worry about killing the child, if the sync pipe
1153 returned an error. Usually this error is caused as the child killed
1154 itself while going down. Even in the rare cases that this isn't the
1155 case, the child will get an error when writing to the broken pipe
1156 the next time, cleaning itself up then. */
1157 ret = sync_pipe_wait_for_child(*fork_child, msg);
1159 /* No unusual exit status; just report the read problem. */
1161 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1163 *msg = g_strdup("Error reading from sync pipe");
1169 /* we got a valid message block from the child, process it */
1174 * Error from dumpcap; there will be a primary message and a
1175 * secondary message.
1178 /* convert primary message */
1179 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1180 primary_msg_text = buffer+4;
1181 /* convert secondary message */
1182 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1183 &secondary_msg_len);
1184 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1185 /* the capture child will close the sync_pipe, nothing to do */
1188 * Pick up the child status.
1190 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1194 * Child process failed unexpectedly, or wait failed; msg is the
1199 * Child process failed, but returned the expected exit status.
1200 * Return the messages it gave us, and indicate failure.
1202 *msg = g_strdup(primary_msg_text);
1208 /* Close the message pipe. */
1209 ws_close(message_read_fd);
1214 * Pick up the child status.
1216 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1220 * Child process failed unexpectedly, or wait failed; msg is the
1225 * Child process returned an unknown status.
1227 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1236 /* Close down the stats process */
1238 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1240 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1243 /* read a number of bytes from a pipe */
1244 /* (blocks until enough bytes read or an error occurs) */
1246 pipe_read_bytes(int pipe_fd, char *bytes, int required)
1252 newly = read(pipe_fd, &bytes[offset], required);
1255 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1256 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1261 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1262 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1273 static gboolean pipe_data_available(int pipe_fd) {
1274 #ifdef _WIN32 /* PeekNamedPipe */
1275 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1278 if (hPipe == INVALID_HANDLE_VALUE)
1281 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1284 if (bytes_avail > 0)
1289 struct timeval timeout;
1292 FD_SET(pipe_fd, &rfds);
1294 timeout.tv_usec = 0;
1296 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1303 /* Read a line from a pipe, similar to fgets */
1305 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1309 while(offset < max - 1) {
1311 if (! pipe_data_available(pipe_fd))
1313 newly = read(pipe_fd, &bytes[offset], 1);
1315 /* EOF - not necessarily an error */
1317 } else if (newly < 0) {
1319 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1320 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1322 } else if (bytes[offset] == '\n') {
1328 bytes[offset] = '\0';
1334 /* convert header values (indicator and 3-byte length) */
1336 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1338 g_assert(header_len == 4);
1340 /* convert header values */
1341 *indicator = header[0];
1342 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1345 /* read a message from the sending pipe in the standard format
1346 (1-byte message indicator, 3-byte message length (excluding length
1347 and indicator field), and the rest is the message) */
1349 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg)
1355 /* read header (indicator and 3-byte length) */
1356 newly = pipe_read_bytes(pipe_fd, header, 4);
1358 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1359 "read %d failed to read header: %u", pipe_fd, newly);
1363 /* convert header values */
1364 pipe_convert_header(header, 4, indicator, &required);
1366 /* only indicator with no value? */
1368 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1369 "read %d indicator: %c empty value", pipe_fd, *indicator);
1373 /* does the data fit into the given buffer? */
1374 if(required > len) {
1375 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1376 "read %d length error, required %d > len %d, indicator: %u",
1377 pipe_fd, required, len, *indicator);
1379 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1380 memcpy(msg, header, sizeof(header));
1381 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1382 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1387 /* read the actual block data */
1388 newly = pipe_read_bytes(pipe_fd, msg, required);
1389 if(newly != required) {
1390 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1394 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1395 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1396 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1402 /* There's stuff to read from the sync pipe, meaning the child has sent
1403 us a message, or the sync pipe has closed, meaning the child has
1404 closed it (perhaps because it exited). */
1406 sync_pipe_input_cb(gint source, gpointer user_data)
1408 capture_options *capture_opts = (capture_options *)user_data;
1410 char buffer[SP_MAX_MSG_LEN+1];
1416 char * secondary_msg;
1418 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1420 /* We got a read error from the sync pipe, or we got no data at
1421 all from the sync pipe, so we're not going to be getting any
1422 data or error message from the child process. Pick up its
1423 exit status, and complain.
1425 We don't have to worry about killing the child, if the sync pipe
1426 returned an error. Usually this error is caused as the child killed itself
1427 while going down. Even in the rare cases that this isn't the case,
1428 the child will get an error when writing to the broken pipe the next time,
1429 cleaning itself up then. */
1430 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &primary_msg);
1432 /* No unusual exit status; just report the read problem. */
1434 primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1436 primary_msg = g_strdup("Error reading from sync pipe");
1438 g_free(primary_msg); /* XXX - display this */
1440 /* No more child process. */
1441 capture_opts->fork_child = -1;
1444 ws_close(capture_opts->signal_pipe_write_fd);
1446 capture_input_closed(capture_opts);
1450 /* we got a valid message block from the child, process it */
1453 if(!capture_input_new_file(capture_opts, buffer)) {
1454 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1456 /* We weren't able to open the new capture file; user has been
1457 alerted. Close the sync pipe. */
1460 /* the child has send us a filename which we couldn't open.
1461 this probably means, the child is creating files faster than we can handle it.
1462 this should only be the case for very fast file switches
1463 we can't do much more than telling the child to stop
1464 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1465 sync_pipe_stop(capture_opts);
1468 case SP_PACKET_COUNT:
1469 nread = atoi(buffer);
1470 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1471 capture_input_new_packets(capture_opts, nread);
1474 /* convert primary message */
1475 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1476 primary_msg = buffer+4;
1477 /* convert secondary message */
1478 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1479 secondary_msg = primary_msg + primary_len + 4;
1480 /* message output */
1481 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1482 /* the capture child will close the sync_pipe, nothing to do for now */
1483 /* (an error message doesn't mean we have to stop capturing) */
1486 capture_input_cfilter_error_message(capture_opts, buffer);
1487 /* the capture child will close the sync_pipe, nothing to do for now */
1490 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1493 g_assert_not_reached();
1501 /* the child process is going down, wait until it's completely terminated */
1503 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1505 int fork_child_status;
1508 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1509 g_assert(fork_child != -1);
1511 *msgp = NULL; /* assume no error */
1514 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1515 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1519 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1520 if (WIFEXITED(fork_child_status)) {
1522 * The child exited; return its exit status, if it seems uncommon
1523 * (0=ok, 1=command syntax error, 2=other error).
1525 * For an exit status of 0, there's no error to tell the user about.
1526 * For an exit status of 1 or 2, the child will inform us about errors
1527 * through the sync_pipe, so don't return an error.
1528 * If there are situations where the child won't send us such an error
1529 * message, this should be fixed in the child and not worked around
1532 if (WEXITSTATUS(fork_child_status) != 0 &&
1533 WEXITSTATUS(fork_child_status) != 1 &&
1534 WEXITSTATUS(fork_child_status) != 2) {
1535 *msgp = g_strdup_printf("Child dumpcap process exited: exit status %d",
1536 WEXITSTATUS(fork_child_status));
1539 } else if (WIFSTOPPED(fork_child_status)) {
1540 /* It stopped, rather than exiting. "Should not happen." */
1541 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1542 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1544 } else if (WIFSIGNALED(fork_child_status)) {
1545 /* It died with a signal. */
1546 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1547 sync_pipe_signame(WTERMSIG(fork_child_status)),
1548 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1551 /* What? It had to either have exited, or stopped, or died with
1552 a signal; what happened here? */
1553 *msgp = g_strdup_printf("Bad status from wait(): %#o",
1558 *msgp = g_strdup_printf("Error from wait(): %s", strerror(errno));
1563 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1569 /* convert signal to corresponding name */
1571 sync_pipe_signame(int sig)
1574 static char sigmsg_buf[6+1+3+1];
1583 sigmsg = "Interrupted";
1591 sigmsg = "Illegal instruction";
1595 sigmsg = "Trace trap";
1603 sigmsg = "Arithmetic exception";
1611 sigmsg = "Bus error";
1615 sigmsg = "Segmentation violation";
1618 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1619 Linux is POSIX compliant. These are not POSIX-defined signals ---
1620 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1622 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1623 were omitted from POSIX.1 because their behavior is
1624 implementation dependent and could not be adequately catego-
1625 rized. Conforming implementations may deliver these sig-
1626 nals, but must document the circumstances under which they
1627 are delivered and note any restrictions concerning their
1630 So we only check for SIGSYS on those systems that happen to
1631 implement them (a system can be POSIX-compliant and implement
1632 them, it's just that POSIX doesn't *require* a POSIX-compliant
1633 system to implement them).
1638 sigmsg = "Bad system call";
1643 sigmsg = "Broken pipe";
1647 sigmsg = "Alarm clock";
1651 sigmsg = "Terminated";
1655 /* Returning a static buffer is ok in the context we use it here */
1656 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1657 sigmsg = sigmsg_buf;
1666 /* tell the child through the signal pipe that we want to quit the capture */
1668 signal_pipe_capquit_to_child(capture_options *capture_opts)
1670 const char quit_msg[] = "QUIT";
1674 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1676 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1677 /* simply sending a "QUIT" string */
1678 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1679 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1681 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1682 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1688 /* user wants to stop the capture run */
1690 sync_pipe_stop(capture_options *capture_opts)
1695 gboolean terminate = TRUE;
1698 if (capture_opts->fork_child != -1) {
1700 /* send the SIGINT signal to close the capture child gracefully. */
1701 int sts = kill(capture_opts->fork_child, SIGINT);
1703 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1704 "Sending SIGINT to child failed: %s\n", strerror(errno));
1707 #define STOP_SLEEP_TIME 500 /* ms */
1708 #define STOP_CHECK_TIME 50
1709 /* First, use the special signal pipe to try to close the capture child
1712 signal_pipe_capquit_to_child(capture_opts);
1714 /* Next, wait for the process to exit on its own */
1715 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1716 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1717 childstatus != STILL_ACTIVE) {
1721 Sleep(STOP_CHECK_TIME);
1724 /* Force the issue. */
1726 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1727 "sync_pipe_stop: forcing child to exit");
1728 sync_pipe_kill(capture_opts->fork_child);
1735 /* Wireshark has to exit, force the capture child to close */
1737 sync_pipe_kill(int fork_child)
1739 if (fork_child != -1) {
1741 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1743 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1744 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1747 /* Remark: This is not the preferred method of closing a process!
1748 * the clean way would be getting the process id of the child process,
1749 * then getting window handle hWnd of that process (using EnumChildWindows),
1750 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1752 * Unfortunately, I don't know how to get the process id from the
1753 * handle. OpenProcess will get an handle (not a window handle)
1754 * from the process ID; it will not get a window handle from the
1755 * process ID. (How could it? A process can have more than one
1756 * window. For that matter, a process might have *no* windows,
1757 * as a process running dumpcap, the normal child process program,
1760 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1761 * running in the same console; that's not necessarily the case for
1762 * us, as we might not be running in a console.
1763 * And this also will require to have the process id.
1765 TerminateProcess((HANDLE) (fork_child), 0);
1770 #endif /* HAVE_LIBPCAP */