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)
222 static char errbuf[ERRBUF_SIZE+1];
226 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
230 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
231 * message. Get rid of it.
233 errlen = strlen(errbuf);
235 errbuf[errlen - 1] = '\0';
236 errbuf[errlen - 2] = '\0';
238 p = strchr(errbuf, '\0');
239 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
244 /* Initialize an argument list and add dumpcap to it. */
246 init_pipe_args(int *argc) {
248 const char *progfile_dir;
251 progfile_dir = get_progfile_dir();
252 if (progfile_dir == NULL) {
256 /* Allocate the string pointer array with enough space for the
257 terminating NULL pointer. */
259 argv = g_malloc(sizeof (char *));
262 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
263 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
265 /* Make that the first argument in the argument list (argv[0]). */
266 argv = sync_pipe_add_arg(argv, argc, exename);
271 #define ARGV_NUMBER_LEN 24
272 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
274 sync_pipe_start(capture_options *capture_opts) {
275 char ssnap[ARGV_NUMBER_LEN];
276 char sdlt[ARGV_NUMBER_LEN];
277 char scount[ARGV_NUMBER_LEN];
278 char sfilesize[ARGV_NUMBER_LEN];
279 char sfile_duration[ARGV_NUMBER_LEN];
280 char sring_num_files[ARGV_NUMBER_LEN];
281 char sautostop_files[ARGV_NUMBER_LEN];
282 char sautostop_filesize[ARGV_NUMBER_LEN];
283 char sautostop_duration[ARGV_NUMBER_LEN];
284 #ifdef HAVE_PCAP_REMOTE
287 #ifdef HAVE_PCAP_SETSAMPLING
288 char ssampling[ARGV_NUMBER_LEN];
290 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
291 char buffer_size[ARGV_NUMBER_LEN];
294 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
295 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
296 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
297 GString *args = g_string_sized_new(200);
299 SECURITY_ATTRIBUTES sa;
301 PROCESS_INFORMATION pi;
303 char control_id[ARGV_NUMBER_LEN];
304 gchar *signal_pipe_name;
307 int sync_pipe[2]; /* pipe used to send messages from child to parent */
308 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
310 int sync_pipe_read_fd;
315 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
316 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
318 capture_opts->fork_child = -1;
320 argv = init_pipe_args(&argc);
322 /* We don't know where to find dumpcap. */
323 report_failure("We don't know where to find dumpcap.");
327 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
329 argv = sync_pipe_add_arg(argv, &argc, "-i");
330 argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
332 if (capture_opts->has_snaplen) {
333 argv = sync_pipe_add_arg(argv, &argc, "-s");
334 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
335 argv = sync_pipe_add_arg(argv, &argc, ssnap);
338 if (capture_opts->linktype != -1) {
339 argv = sync_pipe_add_arg(argv, &argc, "-y");
340 g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
341 argv = sync_pipe_add_arg(argv, &argc, sdlt);
344 if(capture_opts->multi_files_on) {
345 if (capture_opts->has_autostop_filesize) {
346 argv = sync_pipe_add_arg(argv, &argc, "-b");
347 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
348 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
351 if (capture_opts->has_file_duration) {
352 argv = sync_pipe_add_arg(argv, &argc, "-b");
353 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
354 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
357 if (capture_opts->has_ring_num_files) {
358 argv = sync_pipe_add_arg(argv, &argc, "-b");
359 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
360 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
363 if (capture_opts->has_autostop_files) {
364 argv = sync_pipe_add_arg(argv, &argc, "-a");
365 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
366 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
369 if (capture_opts->has_autostop_filesize) {
370 argv = sync_pipe_add_arg(argv, &argc, "-a");
371 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
372 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
376 if (capture_opts->has_autostop_packets) {
377 argv = sync_pipe_add_arg(argv, &argc, "-c");
378 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
379 argv = sync_pipe_add_arg(argv, &argc, scount);
382 if (capture_opts->has_autostop_duration) {
383 argv = sync_pipe_add_arg(argv, &argc, "-a");
384 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
385 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
388 if (!capture_opts->promisc_mode)
389 argv = sync_pipe_add_arg(argv, &argc, "-p");
390 #ifdef HAVE_PCAP_CREATE
391 if (capture_opts->monitor_mode)
392 argv = sync_pipe_add_arg(argv, &argc, "-I");
394 if (capture_opts->use_pcapng)
395 argv = sync_pipe_add_arg(argv, &argc, "-n");
396 #ifdef HAVE_PCAP_REMOTE
397 if (capture_opts->datatx_udp)
398 argv = sync_pipe_add_arg(argv, &argc, "-u");
400 if (!capture_opts->nocap_rpcap)
401 argv = sync_pipe_add_arg(argv, &argc, "-r");
403 if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
405 argv = sync_pipe_add_arg(argv, &argc, "-A");
406 g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
407 capture_opts->auth_password);
408 argv = sync_pipe_add_arg(argv, &argc, sauth);
411 #ifdef HAVE_PCAP_SETSAMPLING
412 if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
414 argv = sync_pipe_add_arg(argv, &argc, "-m");
415 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
416 capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
417 capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
419 capture_opts->sampling_param);
420 argv = sync_pipe_add_arg(argv, &argc, ssampling);
424 /* dumpcap should be running in capture child mode (hidden feature) */
426 argv = sync_pipe_add_arg(argv, &argc, "-Z");
428 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
429 argv = sync_pipe_add_arg(argv, &argc, control_id);
431 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
435 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
436 argv = sync_pipe_add_arg(argv, &argc, "-B");
437 #ifdef HAVE_PCAP_REMOTE
438 if (capture_opts->src_type == CAPTURE_IFREMOTE)
439 /* No buffer size when using remote interfaces */
440 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
443 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
444 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
447 if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
448 argv = sync_pipe_add_arg(argv, &argc, "-f");
449 argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
452 if(capture_opts->save_file) {
453 argv = sync_pipe_add_arg(argv, &argc, "-w");
454 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
458 /* init SECURITY_ATTRIBUTES */
459 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
460 sa.bInheritHandle = TRUE;
461 sa.lpSecurityDescriptor = NULL;
463 /* Create a pipe for the child process */
464 /* (increase this value if you have trouble while fast capture file switches) */
465 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
466 /* Couldn't create the pipe between parent and child. */
467 report_failure("Couldn't create sync pipe: %s",
468 win32strerror(GetLastError()));
469 g_free( (gpointer) argv[0]);
470 g_free( (gpointer) argv);
474 /* Create the signal pipe */
475 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
476 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
477 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
478 g_free(signal_pipe_name);
480 if (signal_pipe == INVALID_HANDLE_VALUE) {
481 /* Couldn't create the signal pipe between parent and child. */
482 report_failure("Couldn't create signal pipe: %s",
483 win32strerror(GetLastError()));
484 g_free( (gpointer) argv[0]);
485 g_free( (gpointer) argv);
489 /* init STARTUPINFO */
490 memset(&si, 0, sizeof(si));
493 si.dwFlags = STARTF_USESHOWWINDOW;
494 si.wShowWindow = SW_SHOW;
496 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
497 si.wShowWindow = SW_HIDE; /* this hides the console window */
498 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
499 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
500 si.hStdError = sync_pipe_write;
501 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
504 /* convert args array into a single string */
505 /* XXX - could change sync_pipe_add_arg() instead */
506 /* there is a drawback here: the length is internally limited to 1024 bytes */
507 for(i=0; argv[i] != 0; i++) {
508 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
509 quoted_arg = protect_arg(argv[i]);
510 g_string_append(args, quoted_arg);
515 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
516 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
517 report_failure("Couldn't run %s in child process: %s",
518 args->str, win32strerror(GetLastError()));
519 CloseHandle(sync_pipe_read);
520 CloseHandle(sync_pipe_write);
521 g_free( (gpointer) argv[0]);
522 g_free( (gpointer) argv);
525 capture_opts->fork_child = (int) pi.hProcess;
526 g_string_free(args, TRUE);
528 /* associate the operating system filehandle to a C run-time file handle */
529 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
530 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
532 /* associate the operating system filehandle to a C run-time file handle */
533 capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
536 if (pipe(sync_pipe) < 0) {
537 /* Couldn't create the pipe between parent and child. */
538 report_failure("Couldn't create sync pipe: %s", strerror(errno));
539 g_free( (gpointer) argv[0]);
544 if ((capture_opts->fork_child = fork()) == 0) {
546 * Child process - run dumpcap with the right arguments to make
547 * it just capture with the specified capture parameters
549 dup2(sync_pipe[PIPE_WRITE], 2);
550 ws_close(sync_pipe[PIPE_READ]);
551 execv(argv[0], (gpointer)argv);
552 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
553 argv[0], strerror(errno));
554 sync_pipe_errmsg_to_parent(2, errmsg, "");
556 /* Exit with "_exit()", so that we don't close the connection
557 to the X server (and cause stuff buffered up by our parent but
558 not yet sent to be sent, as that stuff should only be sent by
559 our parent). We've sent an error message to the parent, so
560 we exit with an exit status of 1 (any exit status other than
561 0 or 1 will cause an additional message to report that exit
562 status, over and above the error message we sent to the parent). */
566 sync_pipe_read_fd = sync_pipe[PIPE_READ];
569 g_free( (gpointer) argv[0]); /* exename */
571 /* Parent process - read messages from the child process over the
573 g_free( (gpointer) argv); /* free up arg array */
575 /* Close the write side of the pipe, so that only the child has it
576 open, and thus it completely closes, and thus returns to us
577 an EOF indication, if the child closes it (either deliberately
578 or by exiting abnormally). */
580 CloseHandle(sync_pipe_write);
582 ws_close(sync_pipe[PIPE_WRITE]);
585 if (capture_opts->fork_child == -1) {
586 /* We couldn't even create the child process. */
587 report_failure("Couldn't create child process: %s", strerror(errno));
588 ws_close(sync_pipe_read_fd);
590 ws_close(capture_opts->signal_pipe_write_fd);
595 /* we might wait for a moment till child is ready, so update screen now */
596 main_window_update();
598 /* We were able to set up to read the capture file;
599 arrange that our callback be called whenever it's possible
600 to read from the sync pipe, so that it's called when
601 the child process wants to tell us something. */
603 /* we have a running capture, now wait for the real capture filename */
604 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
605 &capture_opts->fork_child, sync_pipe_input_cb);
611 * Open two pipes to dumpcap with the supplied arguments, one for its
612 * standard output and one for its standard error.
614 * On success, *msg is unchanged and 0 is returned; data_read_fd,
615 * messsage_read_fd, and fork_child point to the standard output pipe's
616 * file descriptor, the standard error pipe's file descriptor, and
617 * the child's PID/handle, respectively.
619 * On failure, *msg points to an error message for the failure, and -1 is
620 * returned, in which case *msg must be freed with g_free().
622 /* XXX - This duplicates a lot of code in sync_pipe_start() */
623 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
624 #define PIPE_BUF_SIZE 5120
626 sync_pipe_open_command(const char** argv, int *data_read_fd,
627 int *message_read_fd, int *fork_child, gchar **msg)
629 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
631 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
632 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
633 GString *args = g_string_sized_new(200);
635 SECURITY_ATTRIBUTES sa;
637 PROCESS_INFORMATION pi;
641 int sync_pipe[2]; /* pipe used to send messages from child to parent */
642 int data_pipe[2]; /* pipe used to send data from child to parent */
647 *message_read_fd = -1;
648 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
651 /* We can't return anything */
653 g_string_free(args, TRUE);
659 /* init SECURITY_ATTRIBUTES */
660 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
661 sa.bInheritHandle = TRUE;
662 sa.lpSecurityDescriptor = NULL;
664 /* Create a pipe for the child process to send us messages */
665 /* (increase this value if you have trouble while fast capture file switches) */
666 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
667 /* Couldn't create the message pipe between parent and child. */
668 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
669 win32strerror(GetLastError()));
670 g_free( (gpointer) argv[0]);
671 g_free( (gpointer) argv);
675 /* Create a pipe for the child process to send us data */
676 /* (increase this value if you have trouble while fast capture file switches) */
677 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
678 /* Couldn't create the message pipe between parent and child. */
679 *msg = g_strdup_printf("Couldn't create data pipe: %s",
680 win32strerror(GetLastError()));
681 CloseHandle(sync_pipe[PIPE_READ]);
682 CloseHandle(sync_pipe[PIPE_WRITE]);
683 g_free( (gpointer) argv[0]);
684 g_free( (gpointer) argv);
688 /* init STARTUPINFO */
689 memset(&si, 0, sizeof(si));
692 si.dwFlags = STARTF_USESHOWWINDOW;
693 si.wShowWindow = SW_SHOW;
695 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
696 si.wShowWindow = SW_HIDE; /* this hides the console window */
698 si.hStdOutput = data_pipe[PIPE_WRITE];
699 si.hStdError = sync_pipe[PIPE_WRITE];
702 /* convert args array into a single string */
703 /* XXX - could change sync_pipe_add_arg() instead */
704 /* there is a drawback here: the length is internally limited to 1024 bytes */
705 for(i=0; argv[i] != 0; i++) {
706 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
707 quoted_arg = protect_arg(argv[i]);
708 g_string_append(args, quoted_arg);
713 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
714 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
715 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
716 args->str, win32strerror(GetLastError()));
717 CloseHandle(data_pipe[PIPE_READ]);
718 CloseHandle(data_pipe[PIPE_WRITE]);
719 CloseHandle(sync_pipe[PIPE_READ]);
720 CloseHandle(sync_pipe[PIPE_WRITE]);
721 g_free( (gpointer) argv[0]);
722 g_free( (gpointer) argv);
725 *fork_child = (int) pi.hProcess;
726 g_string_free(args, TRUE);
728 /* associate the operating system filehandles to C run-time file handles */
729 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
730 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
731 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
733 /* Create a pipe for the child process to send us messages */
734 if (pipe(sync_pipe) < 0) {
735 /* Couldn't create the message pipe between parent and child. */
736 *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
737 g_free( (gpointer) argv[0]);
742 /* Create a pipe for the child process to send us data */
743 if (pipe(data_pipe) < 0) {
744 /* Couldn't create the data pipe between parent and child. */
745 *msg = g_strdup_printf("Couldn't create data pipe: %s", strerror(errno));
746 ws_close(sync_pipe[PIPE_READ]);
747 ws_close(sync_pipe[PIPE_WRITE]);
748 g_free( (gpointer) argv[0]);
753 if ((*fork_child = fork()) == 0) {
755 * Child process - run dumpcap with the right arguments to make
756 * it just capture with the specified capture parameters
758 dup2(data_pipe[PIPE_WRITE], 1);
759 ws_close(data_pipe[PIPE_READ]);
760 ws_close(data_pipe[PIPE_WRITE]);
761 dup2(sync_pipe[PIPE_WRITE], 2);
762 ws_close(sync_pipe[PIPE_READ]);
763 ws_close(sync_pipe[PIPE_WRITE]);
764 execv(argv[0], (gpointer)argv);
765 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
766 argv[0], strerror(errno));
767 sync_pipe_errmsg_to_parent(2, errmsg, "");
769 /* Exit with "_exit()", so that we don't close the connection
770 to the X server (and cause stuff buffered up by our parent but
771 not yet sent to be sent, as that stuff should only be sent by
772 our parent). We've sent an error message to the parent, so
773 we exit with an exit status of 1 (any exit status other than
774 0 or 1 will cause an additional message to report that exit
775 status, over and above the error message we sent to the parent). */
779 *data_read_fd = data_pipe[PIPE_READ];
780 *message_read_fd = sync_pipe[PIPE_READ];
783 g_free( (gpointer) argv[0]); /* exename */
785 /* Parent process - read messages from the child process over the
787 g_free( (gpointer) argv); /* free up arg array */
789 /* Close the write sides of the pipes, so that only the child has them
790 open, and thus they completely close, and thus return to us
791 an EOF indication, if the child closes them (either deliberately
792 or by exiting abnormally). */
794 CloseHandle(data_pipe[PIPE_WRITE]);
795 CloseHandle(sync_pipe[PIPE_WRITE]);
797 ws_close(data_pipe[PIPE_WRITE]);
798 ws_close(sync_pipe[PIPE_WRITE]);
801 if (*fork_child == -1) {
802 /* We couldn't even create the child process. */
803 *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
804 ws_close(*data_read_fd);
805 ws_close(*message_read_fd);
809 /* we might wait for a moment till child is ready, so update screen now */
810 main_window_update();
815 * Wait for dumpcap to finish. On success, *msg is unchanged, and 0 is
816 * returned. On failure, *msg points to an error message for the
817 * failure, and -1 is returned. In the latter case, *msg must be
818 * freed with g_free().
821 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
822 int *fork_child, gchar **msg)
824 ws_close(*data_read_fd);
825 if (message_read_fd != NULL)
826 ws_close(*message_read_fd);
829 /* XXX - Should we signal the child somehow? */
830 sync_pipe_kill(*fork_child);
833 return sync_pipe_wait_for_child(*fork_child, msg);
837 * Run dumpcap with the supplied arguments.
839 * On success, *data points to a buffer containing the dumpcap output,
840 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
841 * must be freed with g_free().
843 * On failure, *data is NULL, *primary_msg points to an error message,
844 * *secondary_msg either points to an additional error message or is
845 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
846 * must be freed with g_free().
848 /* XXX - This duplicates a lot of code in sync_pipe_start() */
849 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
850 #define PIPE_BUF_SIZE 5120
852 sync_pipe_run_command(const char** argv, gchar **data, gchar **primary_msg,
853 gchar **secondary_msg)
856 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
857 gchar buffer[PIPE_BUF_SIZE+1];
861 char *primary_msg_text;
862 int secondary_msg_len;
863 char *secondary_msg_text;
864 GString *data_buf = NULL;
867 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
871 *secondary_msg = NULL;
877 * We were able to set up to read dumpcap's output. Do so.
879 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
881 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
884 /* We got a read error from the sync pipe, or we got no data at
885 all from the sync pipe, so we're not going to be getting any
886 data or error message from the child process. Pick up its
887 exit status, and complain.
889 We don't have to worry about killing the child, if the sync pipe
890 returned an error. Usually this error is caused as the child killed
891 itself while going down. Even in the rare cases that this isn't the
892 case, the child will get an error when writing to the broken pipe
893 the next time, cleaning itself up then. */
894 ret = sync_pipe_wait_for_child(fork_child, primary_msg);
896 /* No unusual exit status; just report the read problem. */
898 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
900 /* Don't report EINTR - that might just be from a ^C. */
904 *primary_msg = g_strdup_printf("Error reading from sync pipe: %s",
908 *secondary_msg = NULL;
913 /* we got a valid message block from the child, process it */
918 * Error from dumpcap; there will be a primary message and a
922 /* convert primary message */
923 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
924 primary_msg_text = buffer+4;
925 /* convert secondary message */
926 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
928 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
929 /* the capture child will close the sync_pipe, nothing to do */
932 * Pick up the child status.
934 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
938 * Child process failed unexpectedly, or wait failed; msg is the
942 *secondary_msg = NULL;
945 * Child process failed, but returned the expected exit status.
946 * Return the messages it gave us, and indicate failure.
948 *primary_msg = g_strdup(primary_msg_text);
949 *secondary_msg = g_strdup(secondary_msg_text);
956 /* read the output from the command */
957 data_buf = g_string_new("");
958 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
959 buffer[count] = '\0';
960 g_string_append(data_buf, buffer);
964 * Pick up the child status.
966 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
970 * Child process failed unexpectedly, or wait failed; msg is the
974 *secondary_msg = NULL;
975 g_string_free(data_buf, TRUE);
979 * Child process succeeded.
982 *secondary_msg = NULL;
983 *data = data_buf->str;
984 g_string_free(data_buf, FALSE);
990 * Pick up the child status.
992 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
996 * Child process failed unexpectedly, or wait failed; msg is the
1000 *secondary_msg = NULL;
1003 * Child process returned an unknown status.
1005 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1007 *secondary_msg = NULL;
1017 * Get the list of interfaces using dumpcap.
1019 * On success, *data points to a buffer containing the dumpcap output,
1020 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1021 * must be freed with g_free().
1023 * On failure, *data is NULL, *primary_msg points to an error message,
1024 * *secondary_msg either points to an additional error message or is
1025 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1026 * must be freed with g_free().
1029 sync_interface_list_open(gchar **data, gchar **primary_msg,
1030 gchar **secondary_msg)
1035 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1037 argv = init_pipe_args(&argc);
1040 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1041 *secondary_msg = NULL;
1046 /* Ask for the interface list */
1047 argv = sync_pipe_add_arg(argv, &argc, "-D");
1050 /* Run dumpcap in capture child mode */
1051 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1052 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1054 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1058 * Get the capabilities of an interface using dumpcap.
1060 * On success, *data points to a buffer containing the dumpcap output,
1061 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1062 * must be freed with g_free().
1064 * On failure, *data is NULL, *primary_msg points to an error message,
1065 * *secondary_msg either points to an additional error message or is
1066 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1067 * must be freed with g_free().
1070 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1071 gchar **data, gchar **primary_msg,
1072 gchar **secondary_msg)
1077 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
1079 argv = init_pipe_args(&argc);
1082 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1083 *secondary_msg = NULL;
1088 /* Ask for the interface capabilities */
1089 argv = sync_pipe_add_arg(argv, &argc, "-i");
1090 argv = sync_pipe_add_arg(argv, &argc, ifname);
1091 argv = sync_pipe_add_arg(argv, &argc, "-L");
1093 argv = sync_pipe_add_arg(argv, &argc, "-I");
1096 /* Run dumpcap in capture child mode */
1097 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1098 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1100 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg);
1104 * Start getting interface statistics using dumpcap. On success, read_fd
1105 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1106 * and zero is returned. On failure, *msg will point to an error message
1107 * that must be g_free()d, and -1 will be returned.
1110 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg)
1114 int message_read_fd, ret;
1115 gchar buffer[PIPE_BUF_SIZE+1];
1118 int primary_msg_len;
1119 char *primary_msg_text;
1120 int secondary_msg_len;
1121 char *secondary_msg_text;
1123 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1125 argv = init_pipe_args(&argc);
1128 *msg = g_strdup("We don't know where to find dumpcap.");
1132 /* Ask for the interface statistics */
1133 argv = sync_pipe_add_arg(argv, &argc, "-S");
1136 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1137 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1139 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1145 * We were able to set up to read dumpcap's output. Do so.
1147 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1149 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1152 /* We got a read error from the sync pipe, or we got no data at
1153 all from the sync pipe, so we're not going to be getting any
1154 data or error message from the child process. Pick up its
1155 exit status, and complain.
1157 We don't have to worry about killing the child, if the sync pipe
1158 returned an error. Usually this error is caused as the child killed
1159 itself while going down. Even in the rare cases that this isn't the
1160 case, the child will get an error when writing to the broken pipe
1161 the next time, cleaning itself up then. */
1162 ret = sync_pipe_wait_for_child(*fork_child, msg);
1164 /* No unusual exit status; just report the read problem. */
1166 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1168 /* Don't report EINTR - that might just be from a ^C. */
1172 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1180 /* we got a valid message block from the child, process it */
1185 * Error from dumpcap; there will be a primary message and a
1186 * secondary message.
1189 /* convert primary message */
1190 pipe_convert_header(buffer, 4, &indicator, &primary_msg_len);
1191 primary_msg_text = buffer+4;
1192 /* convert secondary message */
1193 pipe_convert_header(primary_msg_text + primary_msg_len, 4, &indicator,
1194 &secondary_msg_len);
1195 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1196 /* the capture child will close the sync_pipe, nothing to do */
1199 * Pick up the child status.
1201 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1205 * Child process failed unexpectedly, or wait failed; msg is the
1210 * Child process failed, but returned the expected exit status.
1211 * Return the messages it gave us, and indicate failure.
1213 *msg = g_strdup(primary_msg_text);
1219 /* Close the message pipe. */
1220 ws_close(message_read_fd);
1225 * Pick up the child status.
1227 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1231 * Child process failed unexpectedly, or wait failed; msg is the
1236 * Child process returned an unknown status.
1238 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1247 /* Close down the stats process */
1249 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1251 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1254 /* read a number of bytes from a pipe */
1255 /* (blocks until enough bytes read or an error occurs) */
1257 pipe_read_bytes(int pipe_fd, char *bytes, int required)
1263 newly = read(pipe_fd, &bytes[offset], required);
1266 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1267 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1272 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1273 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1284 static gboolean pipe_data_available(int pipe_fd) {
1285 #ifdef _WIN32 /* PeekNamedPipe */
1286 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1289 if (hPipe == INVALID_HANDLE_VALUE)
1292 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1295 if (bytes_avail > 0)
1300 struct timeval timeout;
1303 FD_SET(pipe_fd, &rfds);
1305 timeout.tv_usec = 0;
1307 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1314 /* Read a line from a pipe, similar to fgets */
1316 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1320 while(offset < max - 1) {
1322 if (! pipe_data_available(pipe_fd))
1324 newly = read(pipe_fd, &bytes[offset], 1);
1326 /* EOF - not necessarily an error */
1328 } else if (newly < 0) {
1330 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1331 "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1333 } else if (bytes[offset] == '\n') {
1339 bytes[offset] = '\0';
1345 /* convert header values (indicator and 3-byte length) */
1347 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1349 g_assert(header_len == 4);
1351 /* convert header values */
1352 *indicator = header[0];
1353 *block_len = header[1]<<16 | header[2]<<8 | header[3];
1356 /* read a message from the sending pipe in the standard format
1357 (1-byte message indicator, 3-byte message length (excluding length
1358 and indicator field), and the rest is the message) */
1360 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg)
1366 /* read header (indicator and 3-byte length) */
1367 newly = pipe_read_bytes(pipe_fd, header, 4);
1369 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1370 "read %d failed to read header: %u", pipe_fd, newly);
1374 /* convert header values */
1375 pipe_convert_header(header, 4, indicator, &required);
1377 /* only indicator with no value? */
1379 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1380 "read %d indicator: %c empty value", pipe_fd, *indicator);
1384 /* does the data fit into the given buffer? */
1385 if(required > len) {
1386 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1387 "read %d length error, required %d > len %d, indicator: %u",
1388 pipe_fd, required, len, *indicator);
1390 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1391 memcpy(msg, header, sizeof(header));
1392 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1393 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1398 /* read the actual block data */
1399 newly = pipe_read_bytes(pipe_fd, msg, required);
1400 if(newly != required) {
1401 g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1405 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1406 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1407 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1413 /* There's stuff to read from the sync pipe, meaning the child has sent
1414 us a message, or the sync pipe has closed, meaning the child has
1415 closed it (perhaps because it exited). */
1417 sync_pipe_input_cb(gint source, gpointer user_data)
1419 capture_options *capture_opts = (capture_options *)user_data;
1421 char buffer[SP_MAX_MSG_LEN+1];
1427 char * secondary_msg;
1429 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1431 /* We got a read error from the sync pipe, or we got no data at
1432 all from the sync pipe, so we're not going to be getting any
1433 data or error message from the child process. Pick up its
1434 exit status, and complain.
1436 We don't have to worry about killing the child, if the sync pipe
1437 returned an error. Usually this error is caused as the child killed itself
1438 while going down. Even in the rare cases that this isn't the case,
1439 the child will get an error when writing to the broken pipe the next time,
1440 cleaning itself up then. */
1441 ret = sync_pipe_wait_for_child(capture_opts->fork_child, &primary_msg);
1443 /* No unusual exit status; just report the read problem. */
1445 primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1447 /* Don't report EINTR - that might just be from a ^C. */
1451 primary_msg = g_strdup_printf("Error reading from sync pipe: %s",
1456 /* No more child process. */
1457 capture_opts->fork_child = -1;
1460 ws_close(capture_opts->signal_pipe_write_fd);
1462 capture_input_closed(capture_opts, primary_msg);
1463 g_free(primary_msg);
1467 /* we got a valid message block from the child, process it */
1470 if(!capture_input_new_file(capture_opts, buffer)) {
1471 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1473 /* We weren't able to open the new capture file; user has been
1474 alerted. Close the sync pipe. */
1477 /* the child has send us a filename which we couldn't open.
1478 this probably means, the child is creating files faster than we can handle it.
1479 this should only be the case for very fast file switches
1480 we can't do much more than telling the child to stop
1481 (this is the "emergency brake" if user e.g. wants to switch files every second) */
1482 sync_pipe_stop(capture_opts);
1485 case SP_PACKET_COUNT:
1486 nread = atoi(buffer);
1487 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1488 capture_input_new_packets(capture_opts, nread);
1491 /* convert primary message */
1492 pipe_convert_header(buffer, 4, &indicator, &primary_len);
1493 primary_msg = buffer+4;
1494 /* convert secondary message */
1495 pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1496 secondary_msg = primary_msg + primary_len + 4;
1497 /* message output */
1498 capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1499 /* the capture child will close the sync_pipe, nothing to do for now */
1500 /* (an error message doesn't mean we have to stop capturing) */
1503 capture_input_cfilter_error_message(capture_opts, buffer);
1504 /* the capture child will close the sync_pipe, nothing to do for now */
1507 capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1510 g_assert_not_reached();
1518 /* the child process is going down, wait until it's completely terminated */
1520 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1522 int fork_child_status;
1525 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1526 g_assert(fork_child != -1);
1528 *msgp = NULL; /* assume no error */
1531 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1532 *msgp = g_strdup_printf("Error from cwait(): %s", strerror(errno));
1536 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1537 if (WIFEXITED(fork_child_status)) {
1539 * The child exited; return its exit status, if it seems uncommon
1540 * (0=ok, 1=command syntax error, 2=other error).
1542 * For an exit status of 0, there's no error to tell the user about.
1543 * For an exit status of 1 or 2, the child will inform us about errors
1544 * through the sync_pipe, so don't return an error.
1545 * If there are situations where the child won't send us such an error
1546 * message, this should be fixed in the child and not worked around
1549 if (WEXITSTATUS(fork_child_status) != 0 &&
1550 WEXITSTATUS(fork_child_status) != 1 &&
1551 WEXITSTATUS(fork_child_status) != 2) {
1552 *msgp = g_strdup_printf("Child dumpcap process exited: exit status %d",
1553 WEXITSTATUS(fork_child_status));
1556 } else if (WIFSTOPPED(fork_child_status)) {
1557 /* It stopped, rather than exiting. "Should not happen." */
1558 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1559 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1561 } else if (WIFSIGNALED(fork_child_status)) {
1562 /* It died with a signal. */
1563 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1564 sync_pipe_signame(WTERMSIG(fork_child_status)),
1565 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1568 /* What? It had to either have exited, or stopped, or died with
1569 a signal; what happened here? */
1570 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1575 *msgp = g_strdup_printf("Error from waitpid(): %s", strerror(errno));
1580 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1586 /* convert signal to corresponding name */
1588 sync_pipe_signame(int sig)
1591 static char sigmsg_buf[6+1+3+1];
1600 sigmsg = "Interrupted";
1608 sigmsg = "Illegal instruction";
1612 sigmsg = "Trace trap";
1620 sigmsg = "Arithmetic exception";
1628 sigmsg = "Bus error";
1632 sigmsg = "Segmentation violation";
1635 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1636 Linux is POSIX compliant. These are not POSIX-defined signals ---
1637 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1639 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1640 were omitted from POSIX.1 because their behavior is
1641 implementation dependent and could not be adequately catego-
1642 rized. Conforming implementations may deliver these sig-
1643 nals, but must document the circumstances under which they
1644 are delivered and note any restrictions concerning their
1647 So we only check for SIGSYS on those systems that happen to
1648 implement them (a system can be POSIX-compliant and implement
1649 them, it's just that POSIX doesn't *require* a POSIX-compliant
1650 system to implement them).
1655 sigmsg = "Bad system call";
1660 sigmsg = "Broken pipe";
1664 sigmsg = "Alarm clock";
1668 sigmsg = "Terminated";
1672 /* Returning a static buffer is ok in the context we use it here */
1673 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1674 sigmsg = sigmsg_buf;
1683 /* tell the child through the signal pipe that we want to quit the capture */
1685 signal_pipe_capquit_to_child(capture_options *capture_opts)
1687 const char quit_msg[] = "QUIT";
1691 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1693 /* it doesn't matter *what* we send here, the first byte will stop the capture */
1694 /* simply sending a "QUIT" string */
1695 /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1696 ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1698 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1699 "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1705 /* user wants to stop the capture run */
1707 sync_pipe_stop(capture_options *capture_opts)
1712 gboolean terminate = TRUE;
1715 if (capture_opts->fork_child != -1) {
1717 /* send the SIGINT signal to close the capture child gracefully. */
1718 int sts = kill(capture_opts->fork_child, SIGINT);
1720 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1721 "Sending SIGINT to child failed: %s\n", strerror(errno));
1724 #define STOP_SLEEP_TIME 500 /* ms */
1725 #define STOP_CHECK_TIME 50
1726 /* First, use the special signal pipe to try to close the capture child
1729 signal_pipe_capquit_to_child(capture_opts);
1731 /* Next, wait for the process to exit on its own */
1732 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1733 if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1734 childstatus != STILL_ACTIVE) {
1738 Sleep(STOP_CHECK_TIME);
1741 /* Force the issue. */
1743 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1744 "sync_pipe_stop: forcing child to exit");
1745 sync_pipe_kill(capture_opts->fork_child);
1752 /* Wireshark has to exit, force the capture child to close */
1754 sync_pipe_kill(int fork_child)
1756 if (fork_child != -1) {
1758 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
1760 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1761 "Sending SIGTERM to child failed: %s\n", strerror(errno));
1764 /* Remark: This is not the preferred method of closing a process!
1765 * the clean way would be getting the process id of the child process,
1766 * then getting window handle hWnd of that process (using EnumChildWindows),
1767 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1769 * Unfortunately, I don't know how to get the process id from the
1770 * handle. OpenProcess will get an handle (not a window handle)
1771 * from the process ID; it will not get a window handle from the
1772 * process ID. (How could it? A process can have more than one
1773 * window. For that matter, a process might have *no* windows,
1774 * as a process running dumpcap, the normal child process program,
1777 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1778 * running in the same console; that's not necessarily the case for
1779 * us, as we might not be running in a console.
1780 * And this also will require to have the process id.
1782 TerminateProcess((HANDLE) (fork_child), 0);
1787 #endif /* HAVE_LIBPCAP */