sec_vt_header: dissect drep
[wireshark-wip.git] / capture_sync.c
blob252e5e99c2afc6557c91ad9a5570bb231ee2de47
1 /* capture_sync.c
2 * Synchronisation between Wireshark capture parent and child instances
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #ifdef HAVE_LIBPCAP
29 #include <glib.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <string.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
42 #include <signal.h>
44 #ifdef _WIN32
45 #include <wsutil/unicode-utils.h>
46 #endif
48 #ifdef HAVE_SYS_WAIT_H
49 # include <sys/wait.h>
50 #endif
52 #include "capture-pcap-util.h"
54 #ifndef _WIN32
56 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
57 * macros) on UNIX systems that don't have them.
59 #ifndef WIFEXITED
60 # define WIFEXITED(status) (((status) & 0177) == 0)
61 #endif
62 #ifndef WIFSTOPPED
63 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
64 #endif
65 #ifndef WIFSIGNALED
66 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
67 #endif
68 #ifndef WEXITSTATUS
69 # define WEXITSTATUS(status) ((status) >> 8)
70 #endif
71 #ifndef WTERMSIG
72 # define WTERMSIG(status) ((status) & 0177)
73 #endif
74 #ifndef WCOREDUMP
75 # define WCOREDUMP(status) ((status) & 0200)
76 #endif
77 #ifndef WSTOPSIG
78 # define WSTOPSIG(status) ((status) >> 8)
79 #endif
80 #endif /* _WIN32 */
82 #include <epan/packet.h>
83 #include <epan/prefs.h>
85 #include "globals.h"
86 #include "file.h"
87 #include <epan/filesystem.h>
89 #include "capture.h"
90 #include "capture_sync.h"
92 #include "sync_pipe.h"
94 #ifdef _WIN32
95 #include "capture-wpcap.h"
96 #endif
98 #include "ui/ui_util.h"
100 #include <wsutil/file_util.h>
101 #include <wsutil/report_err.h>
102 #include "log.h"
104 #ifdef _WIN32
105 #include <process.h> /* For spawning child process */
106 #endif
110 #ifdef _WIN32
111 static void create_dummy_signal_pipe();
112 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
113 static gchar *dummy_control_id;
114 #else
115 static const char *sync_pipe_signame(int);
116 #endif
119 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
120 static int sync_pipe_wait_for_child(int fork_child, gchar **msgp);
121 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
122 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
123 char **err_msg);
125 static void (*fetch_dumpcap_pid)(int) = NULL;
128 void
129 capture_session_init(capture_session *cap_session, void *cf)
131 cap_session->cf = cf;
132 cap_session->fork_child = -1; /* invalid process handle */
133 #ifdef _WIN32
134 cap_session->signal_pipe_write_fd = -1;
135 #endif
136 cap_session->state = CAPTURE_STOPPED;
137 #ifndef _WIN32
138 cap_session->owner = getuid();
139 cap_session->group = getgid();
140 #endif
141 cap_session->session_started = FALSE;
144 /* Append an arg (realloc) to an argc/argv array */
145 /* (add a string pointer to a NULL-terminated array of string pointers) */
146 static char **
147 sync_pipe_add_arg(char **args, int *argc, const char *arg)
149 /* Grow the array; "*argc" currently contains the number of string
150 pointers, *not* counting the NULL pointer at the end, so we have
151 to add 2 in order to get the new size of the array, including the
152 new pointer and the terminating NULL pointer. */
153 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
155 /* Stuff the pointer into the penultimate element of the array, which
156 is the one at the index specified by "*argc". */
157 args[*argc] = g_strdup(arg);
158 /* Now bump the count. */
159 (*argc)++;
161 /* We overwrite the NULL pointer; put it back right after the
162 element we added. */
163 args[*argc] = NULL;
165 return args;
170 #ifdef _WIN32
171 /* Quote the argument element if necessary, so that it will get
172 * reconstructed correctly in the C runtime startup code. Note that
173 * the unquoting algorithm in the C runtime is really weird, and
174 * rather different than what Unix shells do. See stdargv.c in the C
175 * runtime sources (in the Platform SDK, in src/crt).
177 * Stolen from GLib's protect_argv(), an internal routine that quotes
178 * string in an argument list so that they arguments will be handled
179 * correctly in the command-line string passed to CreateProcess()
180 * if that string is constructed by gluing those strings together.
182 static gchar *
183 protect_arg (const gchar *argv)
185 gchar *new_arg;
186 const gchar *p = argv;
187 gchar *q;
188 gint len = 0;
189 gboolean need_dblquotes = FALSE;
191 while (*p) {
192 if (*p == ' ' || *p == '\t')
193 need_dblquotes = TRUE;
194 else if (*p == '"')
195 len++;
196 else if (*p == '\\') {
197 const gchar *pp = p;
199 while (*pp && *pp == '\\')
200 pp++;
201 if (*pp == '"')
202 len++;
204 len++;
205 p++;
208 q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
209 p = argv;
211 if (need_dblquotes)
212 *q++ = '"';
214 while (*p) {
215 if (*p == '"')
216 *q++ = '\\';
217 else if (*p == '\\') {
218 const gchar *pp = p;
220 while (*pp && *pp == '\\')
221 pp++;
222 if (*pp == '"')
223 *q++ = '\\';
225 *q++ = *p;
226 p++;
229 if (need_dblquotes)
230 *q++ = '"';
231 *q++ = '\0';
233 return new_arg;
237 * Generate a string for a Win32 error.
239 #define ERRBUF_SIZE 1024
240 static const char *
241 win32strerror(DWORD error)
243 static char errbuf[ERRBUF_SIZE+1];
244 size_t errlen;
245 char *p;
247 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
248 NULL, error, 0, errbuf, ERRBUF_SIZE, NULL);
251 * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
252 * message. Get rid of it.
254 errlen = strlen(errbuf);
255 if (errlen >= 2) {
256 errbuf[errlen - 1] = '\0';
257 errbuf[errlen - 2] = '\0';
259 p = strchr(errbuf, '\0');
260 g_snprintf(p, (gulong)(sizeof errbuf - (p-errbuf)), " (%lu)", error);
261 return errbuf;
265 * Generate a string for a Win32 exception code.
267 static const char *
268 win32strexception(DWORD exception)
270 static char errbuf[ERRBUF_SIZE+1];
271 static const struct exception_msg {
272 int code;
273 char *msg;
274 } exceptions[] = {
275 { EXCEPTION_ACCESS_VIOLATION, "Access violation" },
276 { EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "Array bounds exceeded" },
277 { EXCEPTION_BREAKPOINT, "Breakpoint" },
278 { EXCEPTION_DATATYPE_MISALIGNMENT, "Data type misalignment" },
279 { EXCEPTION_FLT_DENORMAL_OPERAND, "Denormal floating-point operand" },
280 { EXCEPTION_FLT_DIVIDE_BY_ZERO, "Floating-point divide by zero" },
281 { EXCEPTION_FLT_INEXACT_RESULT, "Floating-point inexact result" },
282 { EXCEPTION_FLT_INVALID_OPERATION, "Invalid floating-point operation" },
283 { EXCEPTION_FLT_OVERFLOW, "Floating-point overflow" },
284 { EXCEPTION_FLT_STACK_CHECK, "Floating-point stack check" },
285 { EXCEPTION_FLT_UNDERFLOW, "Floating-point underflow" },
286 { EXCEPTION_GUARD_PAGE, "Guard page violation" },
287 { EXCEPTION_ILLEGAL_INSTRUCTION, "Illegal instruction" },
288 { EXCEPTION_IN_PAGE_ERROR, "Page-in error" },
289 { EXCEPTION_INT_DIVIDE_BY_ZERO, "Integer divide by zero" },
290 { EXCEPTION_INT_OVERFLOW, "Integer overflow" },
291 { EXCEPTION_INVALID_DISPOSITION, "Invalid disposition" },
292 { EXCEPTION_INVALID_HANDLE, "Invalid handle" },
293 { EXCEPTION_NONCONTINUABLE_EXCEPTION, "Non-continuable exception" },
294 { EXCEPTION_PRIV_INSTRUCTION, "Privileged instruction" },
295 { EXCEPTION_SINGLE_STEP, "Single-step complete" },
296 { EXCEPTION_STACK_OVERFLOW, "Stack overflow" },
297 { 0, NULL }
299 #define N_EXCEPTIONS (sizeof exceptions / sizeof exceptions[0])
300 int i;
302 for (i = 0; i < N_EXCEPTIONS; i++) {
303 if (exceptions[i].code == exception)
304 return exceptions[i].msg;
306 g_snprintf(errbuf, (gulong)sizeof errbuf, "Exception 0x%08x", exception);
307 return errbuf;
309 #endif
311 /* Initialize an argument list and add dumpcap to it. */
312 static char **
313 init_pipe_args(int *argc) {
314 char **argv;
315 const char *progfile_dir;
316 char *exename;
318 progfile_dir = get_progfile_dir();
319 if (progfile_dir == NULL) {
320 return NULL;
323 /* Allocate the string pointer array with enough space for the
324 terminating NULL pointer. */
325 *argc = 0;
326 argv = (char **)g_malloc(sizeof (char *));
327 *argv = NULL;
329 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
330 exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
332 /* Make that the first argument in the argument list (argv[0]). */
333 argv = sync_pipe_add_arg(argv, argc, exename);
335 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
336 g_free(exename);
338 return argv;
341 #define ARGV_NUMBER_LEN 24
342 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
343 gboolean
344 sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, void (*update_cb)(void))
346 char ssnap[ARGV_NUMBER_LEN];
347 char scount[ARGV_NUMBER_LEN];
348 char sfilesize[ARGV_NUMBER_LEN];
349 char sfile_duration[ARGV_NUMBER_LEN];
350 char sring_num_files[ARGV_NUMBER_LEN];
351 char sautostop_files[ARGV_NUMBER_LEN];
352 char sautostop_filesize[ARGV_NUMBER_LEN];
353 char sautostop_duration[ARGV_NUMBER_LEN];
354 #ifdef HAVE_PCAP_REMOTE
355 char sauth[256];
356 #endif
357 #ifdef HAVE_PCAP_SETSAMPLING
358 char ssampling[ARGV_NUMBER_LEN];
359 #endif
361 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
362 char buffer_size[ARGV_NUMBER_LEN];
363 #endif
365 #ifdef _WIN32
366 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
367 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
368 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
369 GString *args = g_string_sized_new(200);
370 gchar *quoted_arg;
371 SECURITY_ATTRIBUTES sa;
372 STARTUPINFO si;
373 PROCESS_INFORMATION pi;
374 char control_id[ARGV_NUMBER_LEN];
375 gchar *signal_pipe_name;
376 #else
377 char errmsg[1024+1];
378 int sync_pipe[2]; /* pipe used to send messages from child to parent */
379 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
380 #endif
381 int sync_pipe_read_fd;
382 int argc;
383 char **argv;
384 int i;
385 guint j;
386 interface_options interface_opts;
388 if (capture_opts->ifaces->len > 1)
389 capture_opts->use_pcapng = TRUE;
390 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
391 capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
393 cap_session->fork_child = -1;
395 argv = init_pipe_args(&argc);
396 if (!argv) {
397 /* We don't know where to find dumpcap. */
398 report_failure("We don't know where to find dumpcap.");
399 return FALSE;
402 if (capture_opts->ifaces->len > 1)
403 argv = sync_pipe_add_arg(argv, &argc, "-t");
405 if (capture_opts->use_pcapng)
406 argv = sync_pipe_add_arg(argv, &argc, "-n");
407 else
408 argv = sync_pipe_add_arg(argv, &argc, "-P");
410 if (capture_opts->capture_comment) {
411 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
412 argv = sync_pipe_add_arg(argv, &argc, capture_opts->capture_comment);
415 if (capture_opts->multi_files_on) {
416 if (capture_opts->has_autostop_filesize) {
417 argv = sync_pipe_add_arg(argv, &argc, "-b");
418 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
419 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
422 if (capture_opts->has_file_duration) {
423 argv = sync_pipe_add_arg(argv, &argc, "-b");
424 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
425 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
428 if (capture_opts->has_ring_num_files) {
429 argv = sync_pipe_add_arg(argv, &argc, "-b");
430 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
431 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
434 if (capture_opts->has_autostop_files) {
435 argv = sync_pipe_add_arg(argv, &argc, "-a");
436 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
437 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
439 } else {
440 if (capture_opts->has_autostop_filesize) {
441 argv = sync_pipe_add_arg(argv, &argc, "-a");
442 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
443 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
447 if (capture_opts->has_autostop_packets) {
448 argv = sync_pipe_add_arg(argv, &argc, "-c");
449 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
450 argv = sync_pipe_add_arg(argv, &argc, scount);
453 if (capture_opts->has_autostop_duration) {
454 argv = sync_pipe_add_arg(argv, &argc, "-a");
455 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
456 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
459 if (capture_opts->group_read_access) {
460 argv = sync_pipe_add_arg(argv, &argc, "-g");
463 for (j = 0; j < capture_opts->ifaces->len; j++) {
464 interface_opts = g_array_index(capture_opts->ifaces, interface_options, j);
466 argv = sync_pipe_add_arg(argv, &argc, "-i");
467 argv = sync_pipe_add_arg(argv, &argc, interface_opts.name);
469 if (interface_opts.cfilter != NULL && strlen(interface_opts.cfilter) != 0) {
470 argv = sync_pipe_add_arg(argv, &argc, "-f");
471 argv = sync_pipe_add_arg(argv, &argc, interface_opts.cfilter);
473 if (interface_opts.snaplen != WTAP_MAX_PACKET_SIZE) {
474 argv = sync_pipe_add_arg(argv, &argc, "-s");
475 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts.snaplen);
476 argv = sync_pipe_add_arg(argv, &argc, ssnap);
479 if (interface_opts.linktype != -1) {
480 argv = sync_pipe_add_arg(argv, &argc, "-y");
481 argv = sync_pipe_add_arg(argv, &argc, linktype_val_to_name(interface_opts.linktype));
484 if (!interface_opts.promisc_mode) {
485 argv = sync_pipe_add_arg(argv, &argc, "-p");
488 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
489 if (interface_opts.buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
490 argv = sync_pipe_add_arg(argv, &argc, "-B");
491 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts.buffer_size);
492 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
494 #endif
496 #ifdef HAVE_PCAP_CREATE
497 if (interface_opts.monitor_mode) {
498 argv = sync_pipe_add_arg(argv, &argc, "-I");
500 #endif
502 #ifdef HAVE_PCAP_REMOTE
503 if (interface_opts.datatx_udp)
504 argv = sync_pipe_add_arg(argv, &argc, "-u");
506 if (!interface_opts.nocap_rpcap)
507 argv = sync_pipe_add_arg(argv, &argc, "-r");
509 if (interface_opts.auth_type == CAPTURE_AUTH_PWD) {
510 argv = sync_pipe_add_arg(argv, &argc, "-A");
511 g_snprintf(sauth, sizeof(sauth), "%s:%s",
512 interface_opts.auth_username,
513 interface_opts.auth_password);
514 argv = sync_pipe_add_arg(argv, &argc, sauth);
516 #endif
518 #ifdef HAVE_PCAP_SETSAMPLING
519 if (interface_opts.sampling_method != CAPTURE_SAMP_NONE) {
520 argv = sync_pipe_add_arg(argv, &argc, "-m");
521 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
522 interface_opts.sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
523 interface_opts.sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
524 "undef",
525 interface_opts.sampling_param);
526 argv = sync_pipe_add_arg(argv, &argc, ssampling);
528 #endif
531 /* dumpcap should be running in capture child mode (hidden feature) */
532 #ifndef DEBUG_CHILD
533 argv = sync_pipe_add_arg(argv, &argc, "-Z");
534 #ifdef _WIN32
535 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
536 argv = sync_pipe_add_arg(argv, &argc, control_id);
537 #else
538 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
539 #endif
540 #endif
542 if (capture_opts->save_file) {
543 argv = sync_pipe_add_arg(argv, &argc, "-w");
544 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
546 for (i = 0; i < argc; i++) {
547 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[%d]: %s", i, argv[i]);
550 #ifdef _WIN32
551 /* init SECURITY_ATTRIBUTES */
552 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
553 sa.bInheritHandle = TRUE;
554 sa.lpSecurityDescriptor = NULL;
556 /* Create a pipe for the child process */
557 /* (increase this value if you have trouble while fast capture file switches) */
558 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
559 /* Couldn't create the pipe between parent and child. */
560 report_failure("Couldn't create sync pipe: %s",
561 win32strerror(GetLastError()));
562 for (i = 0; i < argc; i++) {
563 g_free( (gpointer) argv[i]);
565 g_free( (gpointer) argv);
566 return FALSE;
569 /* Create the signal pipe */
570 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
571 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
572 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
573 g_free(signal_pipe_name);
575 if (signal_pipe == INVALID_HANDLE_VALUE) {
576 /* Couldn't create the signal pipe between parent and child. */
577 report_failure("Couldn't create signal pipe: %s",
578 win32strerror(GetLastError()));
579 for (i = 0; i < argc; i++) {
580 g_free( (gpointer) argv[i]);
582 g_free( (gpointer) argv);
583 return FALSE;
586 /* init STARTUPINFO */
587 memset(&si, 0, sizeof(si));
588 si.cb = sizeof(si);
589 #ifdef DEBUG_CHILD
590 si.dwFlags = STARTF_USESHOWWINDOW;
591 si.wShowWindow = SW_SHOW;
592 #else
593 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
594 si.wShowWindow = SW_HIDE; /* this hides the console window */
595 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
596 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
597 si.hStdError = sync_pipe_write;
598 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
599 #endif
601 /* convert args array into a single string */
602 /* XXX - could change sync_pipe_add_arg() instead */
603 /* there is a drawback here: the length is internally limited to 1024 bytes */
604 for(i=0; argv[i] != 0; i++) {
605 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
606 quoted_arg = protect_arg(argv[i]);
607 g_string_append(args, quoted_arg);
608 g_free(quoted_arg);
611 /* call dumpcap */
612 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
613 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
614 report_failure("Couldn't run %s in child process: %s",
615 args->str, win32strerror(GetLastError()));
616 CloseHandle(sync_pipe_read);
617 CloseHandle(sync_pipe_write);
618 for (i = 0; i < argc; i++) {
619 g_free( (gpointer) argv[i]);
621 g_free( (gpointer) argv);
622 return FALSE;
624 cap_session->fork_child = (int) pi.hProcess;
625 g_string_free(args, TRUE);
627 /* associate the operating system filehandle to a C run-time file handle */
628 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
629 sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
631 /* associate the operating system filehandle to a C run-time file handle */
632 cap_session->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
634 #else /* _WIN32 */
635 if (pipe(sync_pipe) < 0) {
636 /* Couldn't create the pipe between parent and child. */
637 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
638 for (i = 0; i < argc; i++) {
639 g_free( (gpointer) argv[i]);
641 g_free(argv);
642 return FALSE;
645 if ((cap_session->fork_child = fork()) == 0) {
647 * Child process - run dumpcap with the right arguments to make
648 * it just capture with the specified capture parameters
650 dup2(sync_pipe[PIPE_WRITE], 2);
651 ws_close(sync_pipe[PIPE_READ]);
652 execv(argv[0], argv);
653 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
654 argv[0], g_strerror(errno));
655 sync_pipe_errmsg_to_parent(2, errmsg, "");
657 /* Exit with "_exit()", so that we don't close the connection
658 to the X server (and cause stuff buffered up by our parent but
659 not yet sent to be sent, as that stuff should only be sent by
660 our parent). We've sent an error message to the parent, so
661 we exit with an exit status of 1 (any exit status other than
662 0 or 1 will cause an additional message to report that exit
663 status, over and above the error message we sent to the parent). */
664 _exit(1);
667 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
668 fetch_dumpcap_pid(cap_session->fork_child);
670 sync_pipe_read_fd = sync_pipe[PIPE_READ];
671 #endif
673 for (i = 0; i < argc; i++) {
674 g_free( (gpointer) argv[i]);
677 /* Parent process - read messages from the child process over the
678 sync pipe. */
679 g_free( (gpointer) argv); /* free up arg array */
681 /* Close the write side of the pipe, so that only the child has it
682 open, and thus it completely closes, and thus returns to us
683 an EOF indication, if the child closes it (either deliberately
684 or by exiting abnormally). */
685 #ifdef _WIN32
686 CloseHandle(sync_pipe_write);
687 #else
688 ws_close(sync_pipe[PIPE_WRITE]);
689 #endif
691 if (cap_session->fork_child == -1) {
692 /* We couldn't even create the child process. */
693 report_failure("Couldn't create child process: %s", g_strerror(errno));
694 ws_close(sync_pipe_read_fd);
695 #ifdef _WIN32
696 ws_close(cap_session->signal_pipe_write_fd);
697 #endif
698 return FALSE;
701 cap_session->fork_child_status = 0;
702 cap_session->capture_opts = capture_opts;
704 /* we might wait for a moment till child is ready, so update screen now */
705 if (update_cb) update_cb();
707 /* We were able to set up to read the capture file;
708 arrange that our callback be called whenever it's possible
709 to read from the sync pipe, so that it's called when
710 the child process wants to tell us something. */
712 /* we have a running capture, now wait for the real capture filename */
713 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
714 &cap_session->fork_child, sync_pipe_input_cb);
716 return TRUE;
720 * Open two pipes to dumpcap with the supplied arguments, one for its
721 * standard output and one for its standard error.
723 * On success, *msg is unchanged and 0 is returned; data_read_fd,
724 * messsage_read_fd, and fork_child point to the standard output pipe's
725 * file descriptor, the standard error pipe's file descriptor, and
726 * the child's PID/handle, respectively.
728 * On failure, *msg points to an error message for the failure, and -1 is
729 * returned, in which case *msg must be freed with g_free().
731 /* XXX - This duplicates a lot of code in sync_pipe_start() */
732 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
733 #define PIPE_BUF_SIZE 5120
734 static int
735 sync_pipe_open_command(char** argv, int *data_read_fd,
736 int *message_read_fd, int *fork_child, gchar **msg, void(*update_cb)(void))
738 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
739 #ifdef _WIN32
740 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
741 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
742 GString *args = g_string_sized_new(200);
743 gchar *quoted_arg;
744 SECURITY_ATTRIBUTES sa;
745 STARTUPINFO si;
746 PROCESS_INFORMATION pi;
747 #else
748 char errmsg[1024+1];
749 int sync_pipe[2]; /* pipe used to send messages from child to parent */
750 int data_pipe[2]; /* pipe used to send data from child to parent */
751 #endif
752 int i;
753 *fork_child = -1;
754 *data_read_fd = -1;
755 *message_read_fd = -1;
756 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_open_command");
758 if (!msg) {
759 /* We can't return anything */
760 #ifdef _WIN32
761 g_string_free(args, TRUE);
762 #endif
763 return -1;
766 #ifdef _WIN32
767 /* init SECURITY_ATTRIBUTES */
768 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
769 sa.bInheritHandle = TRUE;
770 sa.lpSecurityDescriptor = NULL;
772 /* Create a pipe for the child process to send us messages */
773 /* (increase this value if you have trouble while fast capture file switches) */
774 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
775 /* Couldn't create the message pipe between parent and child. */
776 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
777 win32strerror(GetLastError()));
778 for (i = 0; argv[i] != NULL; i++) {
779 g_free( (gpointer) argv[i]);
781 g_free( (gpointer) argv);
782 return -1;
785 /* Create a pipe for the child process to send us data */
786 /* (increase this value if you have trouble while fast capture file switches) */
787 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
788 /* Couldn't create the message pipe between parent and child. */
789 *msg = g_strdup_printf("Couldn't create data pipe: %s",
790 win32strerror(GetLastError()));
791 CloseHandle(sync_pipe[PIPE_READ]);
792 CloseHandle(sync_pipe[PIPE_WRITE]);
793 for (i = 0; argv[i] != NULL; i++) {
794 g_free( (gpointer) argv[i]);
796 g_free( (gpointer) argv);
797 return -1;
800 /* init STARTUPINFO */
801 memset(&si, 0, sizeof(si));
802 si.cb = sizeof(si);
803 #ifdef DEBUG_CHILD
804 si.dwFlags = STARTF_USESHOWWINDOW;
805 si.wShowWindow = SW_SHOW;
806 #else
807 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
808 si.wShowWindow = SW_HIDE; /* this hides the console window */
809 si.hStdInput = NULL;
810 si.hStdOutput = data_pipe[PIPE_WRITE];
811 si.hStdError = sync_pipe[PIPE_WRITE];
812 #endif
814 /* convert args array into a single string */
815 /* XXX - could change sync_pipe_add_arg() instead */
816 /* there is a drawback here: the length is internally limited to 1024 bytes */
817 for(i=0; argv[i] != 0; i++) {
818 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
819 quoted_arg = protect_arg(argv[i]);
820 g_string_append(args, quoted_arg);
821 g_free(quoted_arg);
824 /* call dumpcap */
825 if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
826 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
827 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
828 args->str, win32strerror(GetLastError()));
829 CloseHandle(data_pipe[PIPE_READ]);
830 CloseHandle(data_pipe[PIPE_WRITE]);
831 CloseHandle(sync_pipe[PIPE_READ]);
832 CloseHandle(sync_pipe[PIPE_WRITE]);
833 for (i = 0; argv[i] != NULL; i++) {
834 g_free( (gpointer) argv[i]);
836 g_free( (gpointer) argv);
837 return -1;
839 *fork_child = (int) pi.hProcess;
840 g_string_free(args, TRUE);
842 /* associate the operating system filehandles to C run-time file handles */
843 /* (good file handle infos at: http://www.flounder.com/handles.htm) */
844 *data_read_fd = _open_osfhandle( (long) data_pipe[PIPE_READ], _O_BINARY);
845 *message_read_fd = _open_osfhandle( (long) sync_pipe[PIPE_READ], _O_BINARY);
846 #else /* _WIN32 */
847 /* Create a pipe for the child process to send us messages */
848 if (pipe(sync_pipe) < 0) {
849 /* Couldn't create the message pipe between parent and child. */
850 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
851 for (i = 0; argv[i] != NULL; i++) {
852 g_free( (gpointer) argv[i]);
854 g_free(argv);
855 return -1;
858 /* Create a pipe for the child process to send us data */
859 if (pipe(data_pipe) < 0) {
860 /* Couldn't create the data pipe between parent and child. */
861 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
862 ws_close(sync_pipe[PIPE_READ]);
863 ws_close(sync_pipe[PIPE_WRITE]);
864 for (i = 0; argv[i] != NULL; i++) {
865 g_free( (gpointer) argv[i]);
867 g_free(argv);
868 return -1;
871 if ((*fork_child = fork()) == 0) {
873 * Child process - run dumpcap with the right arguments to make
874 * it just capture with the specified capture parameters
876 dup2(data_pipe[PIPE_WRITE], 1);
877 ws_close(data_pipe[PIPE_READ]);
878 ws_close(data_pipe[PIPE_WRITE]);
879 dup2(sync_pipe[PIPE_WRITE], 2);
880 ws_close(sync_pipe[PIPE_READ]);
881 ws_close(sync_pipe[PIPE_WRITE]);
882 execv(argv[0], argv);
883 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
884 argv[0], g_strerror(errno));
885 sync_pipe_errmsg_to_parent(2, errmsg, "");
887 /* Exit with "_exit()", so that we don't close the connection
888 to the X server (and cause stuff buffered up by our parent but
889 not yet sent to be sent, as that stuff should only be sent by
890 our parent). We've sent an error message to the parent, so
891 we exit with an exit status of 1 (any exit status other than
892 0 or 1 will cause an additional message to report that exit
893 status, over and above the error message we sent to the parent). */
894 _exit(1);
897 if (fetch_dumpcap_pid && *fork_child > 0)
898 fetch_dumpcap_pid(*fork_child);
900 *data_read_fd = data_pipe[PIPE_READ];
901 *message_read_fd = sync_pipe[PIPE_READ];
902 #endif
904 for (i = 0; argv[i] != NULL; i++) {
905 g_free( (gpointer) argv[i]);
908 /* Parent process - read messages from the child process over the
909 sync pipe. */
910 g_free( (gpointer) argv); /* free up arg array */
912 /* Close the write sides of the pipes, so that only the child has them
913 open, and thus they completely close, and thus return to us
914 an EOF indication, if the child closes them (either deliberately
915 or by exiting abnormally). */
916 #ifdef _WIN32
917 CloseHandle(data_pipe[PIPE_WRITE]);
918 CloseHandle(sync_pipe[PIPE_WRITE]);
919 #else
920 ws_close(data_pipe[PIPE_WRITE]);
921 ws_close(sync_pipe[PIPE_WRITE]);
922 #endif
924 if (*fork_child == -1) {
925 /* We couldn't even create the child process. */
926 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
927 ws_close(*data_read_fd);
928 ws_close(*message_read_fd);
929 return -1;
932 /* we might wait for a moment till child is ready, so update screen now */
933 if (update_cb) update_cb();
934 return 0;
938 * Close the pipes we're using to read from dumpcap, and wait for it
939 * to exit. On success, *msgp is unchanged, and the exit status of
940 * dumpcap is returned. On failure (which includes "dumpcap exited
941 * due to being killed by a signal or an exception"), *msgp points
942 * to an error message for the failure, and -1 is returned. In the
943 * latter case, *msgp must be freed with g_free().
945 static int
946 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
947 int *fork_child, gchar **msgp)
949 ws_close(*data_read_fd);
950 if (message_read_fd != NULL)
951 ws_close(*message_read_fd);
953 #ifdef _WIN32
954 /* XXX - Should we signal the child somehow? */
955 sync_pipe_kill(*fork_child);
956 #endif
958 return sync_pipe_wait_for_child(*fork_child, msgp);
962 * Run dumpcap with the supplied arguments.
964 * On success, *data points to a buffer containing the dumpcap output,
965 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
966 * must be freed with g_free().
968 * On failure, *data is NULL, *primary_msg points to an error message,
969 * *secondary_msg either points to an additional error message or is
970 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
971 * must be freed with g_free().
973 /* XXX - This duplicates a lot of code in sync_pipe_start() */
974 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
975 #define PIPE_BUF_SIZE 5120
976 static int
977 sync_pipe_run_command_actual(char** argv, gchar **data, gchar **primary_msg,
978 gchar **secondary_msg, void(*update_cb)(void))
980 gchar *msg;
981 int data_pipe_read_fd, sync_pipe_read_fd, fork_child, ret;
982 char *wait_msg;
983 gchar buffer[PIPE_BUF_SIZE+1];
984 ssize_t nread;
985 char indicator;
986 int primary_msg_len;
987 char *primary_msg_text;
988 int secondary_msg_len;
989 char *secondary_msg_text;
990 char *combined_msg;
991 GString *data_buf = NULL;
992 ssize_t count;
994 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
995 &fork_child, &msg, update_cb);
996 if (ret == -1) {
997 *primary_msg = msg;
998 *secondary_msg = NULL;
999 *data = NULL;
1000 return -1;
1004 * We were able to set up to read dumpcap's output. Do so.
1006 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1008 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
1009 buffer, primary_msg);
1010 if(nread <= 0) {
1011 /* We got a read error from the sync pipe, or we got no data at
1012 all from the sync pipe, so we're not going to be getting any
1013 data or error message from the child process. Pick up its
1014 exit status, and complain.
1016 We don't have to worry about killing the child, if the sync pipe
1017 returned an error. Usually this error is caused as the child killed
1018 itself while going down. Even in the rare cases that this isn't the
1019 case, the child will get an error when writing to the broken pipe
1020 the next time, cleaning itself up then. */
1021 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
1022 if(nread == 0) {
1023 /* We got an EOF from the sync pipe. That means that it exited
1024 before giving us any data to read. If ret is -1, we report
1025 that as a bad exit (e.g., exiting due to a signal); otherwise,
1026 we report it as a premature exit. */
1027 if (ret == -1)
1028 *primary_msg = wait_msg;
1029 else
1030 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1031 } else {
1032 /* We got an error from the sync pipe. If ret is -1, report
1033 both the sync pipe I/O error and the wait error. */
1034 if (ret == -1) {
1035 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
1036 g_free(*primary_msg);
1037 g_free(wait_msg);
1038 *primary_msg = combined_msg;
1041 *secondary_msg = NULL;
1043 return -1;
1046 /* we got a valid message block from the child, process it */
1047 switch(indicator) {
1049 case SP_ERROR_MSG:
1051 * Error from dumpcap; there will be a primary message and a
1052 * secondary message.
1055 /* convert primary message */
1056 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1057 primary_msg_text = buffer+4;
1058 /* convert secondary message */
1059 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1060 &secondary_msg_len);
1061 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1062 /* the capture child will close the sync_pipe, nothing to do */
1065 * Pick up the child status.
1067 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1068 &fork_child, &msg);
1069 if (ret == -1) {
1071 * Child process failed unexpectedly, or wait failed; msg is the
1072 * error message.
1074 *primary_msg = msg;
1075 *secondary_msg = NULL;
1076 } else {
1078 * Child process failed, but returned the expected exit status.
1079 * Return the messages it gave us, and indicate failure.
1081 *primary_msg = g_strdup(primary_msg_text);
1082 *secondary_msg = g_strdup(secondary_msg_text);
1083 ret = -1;
1085 *data = NULL;
1086 break;
1088 case SP_SUCCESS:
1089 /* read the output from the command */
1090 data_buf = g_string_new("");
1091 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1092 buffer[count] = '\0';
1093 g_string_append(data_buf, buffer);
1097 * Pick up the child status.
1099 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1100 &fork_child, &msg);
1101 if (ret == -1) {
1103 * Child process failed unexpectedly, or wait failed; msg is the
1104 * error message.
1106 *primary_msg = msg;
1107 *secondary_msg = NULL;
1108 g_string_free(data_buf, TRUE);
1109 *data = NULL;
1110 } else {
1112 * Child process succeeded.
1114 *primary_msg = NULL;
1115 *secondary_msg = NULL;
1116 *data = data_buf->str;
1117 g_string_free(data_buf, FALSE);
1119 break;
1121 default:
1123 * Pick up the child status.
1125 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1126 &fork_child, &msg);
1127 if (ret == -1) {
1129 * Child process failed unexpectedly, or wait failed; msg is the
1130 * error message.
1132 *primary_msg = msg;
1133 *secondary_msg = NULL;
1134 } else {
1136 * Child process returned an unknown status.
1138 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1139 indicator);
1140 *secondary_msg = NULL;
1141 ret = -1;
1143 *data = NULL;
1144 break;
1146 return ret;
1149 /* centralised logging and timing for sync_pipe_run_command_actual(),
1150 * redirects to sync_pipe_run_command_actual()
1152 static int
1153 sync_pipe_run_command(char** argv, gchar **data, gchar **primary_msg,
1154 gchar **secondary_msg, void (*update_cb)(void))
1156 int ret, i;
1157 GTimeVal start_time;
1158 GTimeVal end_time;
1159 float elapsed;
1160 int logging_enabled;
1162 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1163 logging_enabled=( (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO) & G_LOG_LEVEL_MASK & prefs.console_log_level);
1164 if(logging_enabled){
1165 g_get_current_time(&start_time);
1166 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() starts");
1167 for(i=0; argv[i] != 0; i++) {
1168 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, " argv[%d]: %s", i, argv[i]);
1171 /* do the actual sync pipe run command */
1172 ret=sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1174 if(logging_enabled){
1175 g_get_current_time(&end_time);
1176 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1177 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1179 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_INFO, "sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1182 return ret;
1187 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1188 gchar **data, gchar **primary_msg,
1189 gchar **secondary_msg, void (*update_cb)(void))
1191 int argc, ret;
1192 char **argv;
1193 gchar *opt;
1195 argv = init_pipe_args(&argc);
1197 if (!argv) {
1198 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1199 *secondary_msg = NULL;
1200 *data = NULL;
1201 return -1;
1204 argv = sync_pipe_add_arg(argv, &argc, "-i");
1205 argv = sync_pipe_add_arg(argv, &argc, iface);
1207 if (type)
1208 opt = g_strdup_printf("%s,%s", freq, type);
1209 else
1210 opt = g_strdup_printf("%s", freq);
1212 if (!opt) {
1213 *primary_msg = g_strdup("Out of mem.");
1214 *secondary_msg = NULL;
1215 *data = NULL;
1216 return -1;
1219 argv = sync_pipe_add_arg(argv, &argc, "-k");
1220 argv = sync_pipe_add_arg(argv, &argc, opt);
1222 #ifndef DEBUG_CHILD
1223 /* Run dumpcap in capture child mode */
1224 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1225 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1226 #endif
1228 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1229 g_free(opt);
1230 return ret;
1234 * Get the list of interfaces using dumpcap.
1236 * On success, *data points to a buffer containing the dumpcap output,
1237 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1238 * must be freed with g_free().
1240 * On failure, *data is NULL, *primary_msg points to an error message,
1241 * *secondary_msg either points to an additional error message or is
1242 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1243 * must be freed with g_free().
1246 sync_interface_list_open(gchar **data, gchar **primary_msg,
1247 gchar **secondary_msg, void (*update_cb)(void))
1249 int argc;
1250 char **argv;
1252 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
1254 argv = init_pipe_args(&argc);
1256 if (!argv) {
1257 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1258 *secondary_msg = NULL;
1259 *data = NULL;
1260 return -1;
1263 /* Ask for the interface list */
1264 argv = sync_pipe_add_arg(argv, &argc, "-D");
1266 #ifndef DEBUG_CHILD
1267 /* Run dumpcap in capture child mode */
1268 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1269 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1270 #endif
1271 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1275 * Get the capabilities of an interface using dumpcap.
1277 * On success, *data points to a buffer containing the dumpcap output,
1278 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1279 * must be freed with g_free().
1281 * On failure, *data is NULL, *primary_msg points to an error message,
1282 * *secondary_msg either points to an additional error message or is
1283 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1284 * must be freed with g_free().
1287 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode,
1288 gchar **data, gchar **primary_msg,
1289 gchar **secondary_msg, void (*update_cb)(void))
1291 int argc;
1292 char **argv;
1294 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_if_capabilities_open");
1296 argv = init_pipe_args(&argc);
1298 if (!argv) {
1299 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1300 *secondary_msg = NULL;
1301 *data = NULL;
1302 return -1;
1305 /* Ask for the interface capabilities */
1306 argv = sync_pipe_add_arg(argv, &argc, "-i");
1307 argv = sync_pipe_add_arg(argv, &argc, ifname);
1308 argv = sync_pipe_add_arg(argv, &argc, "-L");
1309 if (monitor_mode)
1310 argv = sync_pipe_add_arg(argv, &argc, "-I");
1312 #ifndef DEBUG_CHILD
1313 /* Run dumpcap in capture child mode */
1314 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1315 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1316 #endif
1317 return sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1321 * Start getting interface statistics using dumpcap. On success, read_fd
1322 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1323 * and zero is returned. On failure, *msg will point to an error message
1324 * that must be g_free()d, and -1 will be returned.
1327 sync_interface_stats_open(int *data_read_fd, int *fork_child, gchar **msg, void (*update_cb)(void))
1329 int argc;
1330 char **argv;
1331 int message_read_fd, ret;
1332 char *wait_msg;
1333 gchar buffer[PIPE_BUF_SIZE+1];
1334 ssize_t nread;
1335 char indicator;
1336 int primary_msg_len;
1337 char *primary_msg_text;
1338 int secondary_msg_len;
1339 /*char *secondary_msg_text;*/
1340 char *combined_msg;
1342 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
1344 argv = init_pipe_args(&argc);
1346 if (!argv) {
1347 *msg = g_strdup("We don't know where to find dumpcap.");
1348 return -1;
1351 /* Ask for the interface statistics */
1352 argv = sync_pipe_add_arg(argv, &argc, "-S");
1354 #ifndef DEBUG_CHILD
1355 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1356 #ifdef _WIN32
1357 create_dummy_signal_pipe();
1358 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1359 #else
1360 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1361 #endif
1362 #endif
1363 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1364 fork_child, msg, update_cb);
1365 if (ret == -1)
1366 return -1;
1369 * We were able to set up to read dumpcap's output. Do so.
1371 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1373 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1374 buffer, msg);
1375 if(nread <= 0) {
1376 /* We got a read error from the sync pipe, or we got no data at
1377 all from the sync pipe, so we're not going to be getting any
1378 data or error message from the child process. Pick up its
1379 exit status, and complain.
1381 We don't have to worry about killing the child, if the sync pipe
1382 returned an error. Usually this error is caused as the child killed
1383 itself while going down. Even in the rare cases that this isn't the
1384 case, the child will get an error when writing to the broken pipe
1385 the next time, cleaning itself up then. */
1386 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1387 if(nread == 0) {
1388 /* We got an EOF from the sync pipe. That means that it exited
1389 before giving us any data to read. If ret is -1, we report
1390 that as a bad exit (e.g., exiting due to a signal); otherwise,
1391 we report it as a premature exit. */
1392 if (ret == -1)
1393 *msg = wait_msg;
1394 else
1395 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1396 } else {
1397 /* We got an error from the sync pipe. If ret is -1, report
1398 both the sync pipe I/O error and the wait error. */
1399 if (ret == -1) {
1400 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1401 g_free(*msg);
1402 g_free(wait_msg);
1403 *msg = combined_msg;
1407 return -1;
1410 /* we got a valid message block from the child, process it */
1411 switch(indicator) {
1413 case SP_ERROR_MSG:
1415 * Error from dumpcap; there will be a primary message and a
1416 * secondary message.
1419 /* convert primary message */
1420 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1421 primary_msg_text = buffer+4;
1422 /* convert secondary message */
1423 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1424 &secondary_msg_len);
1425 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1426 /* the capture child will close the sync_pipe, nothing to do */
1429 * Pick up the child status.
1431 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1432 fork_child, msg);
1433 if (ret == -1) {
1435 * Child process failed unexpectedly, or wait failed; msg is the
1436 * error message.
1438 } else {
1440 * Child process failed, but returned the expected exit status.
1441 * Return the messages it gave us, and indicate failure.
1443 *msg = g_strdup(primary_msg_text);
1444 ret = -1;
1446 break;
1448 case SP_SUCCESS:
1449 /* Close the message pipe. */
1450 ws_close(message_read_fd);
1451 break;
1453 default:
1455 * Pick up the child status.
1457 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1458 fork_child, msg);
1459 if (ret == -1) {
1461 * Child process failed unexpectedly, or wait failed; msg is the
1462 * error message.
1464 } else {
1466 * Child process returned an unknown status.
1468 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1469 indicator);
1470 ret = -1;
1472 break;
1474 return ret;
1477 /* Close down the stats process */
1479 sync_interface_stats_close(int *read_fd, int *fork_child, gchar **msg)
1481 #ifndef _WIN32
1483 * Don't bother waiting for the child. sync_pipe_close_command
1484 * does this for us on Windows.
1486 sync_pipe_kill(*fork_child);
1487 #endif
1488 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1491 /* read a number of bytes from a pipe */
1492 /* (blocks until enough bytes read or an error occurs) */
1493 static ssize_t
1494 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1496 ssize_t newly;
1497 ssize_t offset = 0;
1498 int error;
1500 while(required) {
1501 newly = read(pipe_fd, &bytes[offset], required);
1502 if (newly == 0) {
1503 /* EOF */
1504 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1505 "read from pipe %d: EOF (capture closed?)", pipe_fd);
1506 *msg = 0;
1507 return offset;
1509 if (newly < 0) {
1510 /* error */
1511 error = errno;
1512 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1513 "read from pipe %d: error(%u): %s", pipe_fd, error,
1514 g_strerror(error));
1515 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1516 g_strerror(error));
1517 return newly;
1520 required -= (int)newly;
1521 offset += newly;
1524 *msg = NULL;
1525 return offset;
1528 static gboolean pipe_data_available(int pipe_fd) {
1529 #ifdef _WIN32 /* PeekNamedPipe */
1530 HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1531 DWORD bytes_avail;
1533 if (hPipe == INVALID_HANDLE_VALUE)
1534 return FALSE;
1536 if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1537 return FALSE;
1539 if (bytes_avail > 0)
1540 return TRUE;
1541 return FALSE;
1542 #else /* select */
1543 fd_set rfds;
1544 struct timeval timeout;
1546 FD_ZERO(&rfds);
1547 FD_SET(pipe_fd, &rfds);
1548 timeout.tv_sec = 0;
1549 timeout.tv_usec = 0;
1551 if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1552 return TRUE;
1554 return FALSE;
1555 #endif
1558 /* Read a line from a pipe, similar to fgets */
1560 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1561 ssize_t newly;
1562 int offset = -1;
1564 while(offset < max - 1) {
1565 offset++;
1566 if (! pipe_data_available(pipe_fd))
1567 break;
1568 newly = read(pipe_fd, &bytes[offset], 1);
1569 if (newly == 0) {
1570 /* EOF - not necessarily an error */
1571 break;
1572 } else if (newly == -1) {
1573 /* error */
1574 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1575 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1576 return -1;
1577 } else if (bytes[offset] == '\n') {
1578 break;
1582 if (offset >= 0)
1583 bytes[offset] = '\0';
1585 return offset;
1589 /* convert header values (indicator and 3-byte length) */
1590 static void
1591 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1593 g_assert(header_len == 4);
1595 /* convert header values */
1596 *indicator = header[0];
1597 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1600 /* read a message from the sending pipe in the standard format
1601 (1-byte message indicator, 3-byte message length (excluding length
1602 and indicator field), and the rest is the message) */
1603 static ssize_t
1604 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1605 char **err_msg)
1607 int required;
1608 ssize_t newly;
1609 gchar header[4];
1611 /* read header (indicator and 3-byte length) */
1612 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1613 if(newly != 4) {
1614 if (newly == 0) {
1616 * Immediate EOF; if the capture child exits normally, this
1617 * is an "I'm done" indication, so don't report it as an
1618 * error.
1620 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1621 "read %d got an EOF", pipe_fd);
1622 return 0;
1624 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1625 "read %d failed to read header: %lu", pipe_fd, (long)newly);
1626 if (newly != -1) {
1628 * Short read, but not an immediate EOF.
1630 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1631 (long)newly);
1633 return -1;
1636 /* convert header values */
1637 pipe_convert_header((guchar*)header, 4, indicator, &required);
1639 /* only indicator with no value? */
1640 if(required == 0) {
1641 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1642 "read %d indicator: %c empty value", pipe_fd, *indicator);
1643 return 4;
1646 /* does the data fit into the given buffer? */
1647 if(required > len) {
1648 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1649 "read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1650 pipe_fd, required, len,
1651 header[0], header[1], header[2], header[3]);
1653 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1654 memcpy(msg, header, sizeof(header));
1655 newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1656 if (newly < 0) { /* error */
1657 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1658 "read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1660 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1661 msg);
1662 return -1;
1664 len = required;
1666 /* read the actual block data */
1667 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1668 if(newly != required) {
1669 if (newly != -1) {
1670 *err_msg = g_strdup_printf("Unknown message from dumpcap, try to show it as a string: %s",
1671 msg);
1673 return -1;
1676 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1677 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1678 "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1679 len, msg);
1680 *err_msg = NULL;
1681 return newly + 4;
1685 /* There's stuff to read from the sync pipe, meaning the child has sent
1686 us a message, or the sync pipe has closed, meaning the child has
1687 closed it (perhaps because it exited). */
1688 static gboolean
1689 sync_pipe_input_cb(gint source, gpointer user_data)
1691 capture_session *cap_session = (capture_session *)user_data;
1692 int ret;
1693 char buffer[SP_MAX_MSG_LEN+1];
1694 ssize_t nread;
1695 char indicator;
1696 int primary_len;
1697 char *primary_msg;
1698 int secondary_len;
1699 char *secondary_msg;
1700 char *wait_msg, *combined_msg;
1701 int npackets;
1703 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1704 &primary_msg);
1705 if(nread <= 0) {
1706 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1708 If we got a read error or a bad message, nread is -1 and
1709 primary_msg is set to point to an error message. We don't
1710 have to worry about killing the child; usually this error
1711 is caused as the child killed itself while going down.
1712 Even in the rare cases that this isn't the case, the child
1713 will get an error when writing to the broken pipe the next time,
1714 cleaning itself up then.
1716 If we got an EOF, nread is 0 and primary_msg isn't set. This
1717 is an indication that the capture is finished. */
1718 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1719 if(nread == 0) {
1720 /* We got an EOF from the sync pipe. That means that the capture
1721 child exited, and not in the middle of a message; we treat
1722 that as an indication that it's done, and only report an
1723 error if ret is -1, in which case wait_msg is the error
1724 message. */
1725 if (ret == -1)
1726 primary_msg = wait_msg;
1727 } else {
1728 /* We got an error from the sync pipe. If ret is -1, report
1729 both the sync pipe I/O error and the wait error. */
1730 if (ret == -1) {
1731 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1732 g_free(primary_msg);
1733 g_free(wait_msg);
1734 primary_msg = combined_msg;
1738 /* No more child process. */
1739 cap_session->fork_child = -1;
1740 cap_session->fork_child_status = ret;
1742 #ifdef _WIN32
1743 ws_close(cap_session->signal_pipe_write_fd);
1744 #endif
1745 capture_input_closed(cap_session, primary_msg);
1746 g_free(primary_msg);
1747 return FALSE;
1750 /* we got a valid message block from the child, process it */
1751 switch(indicator) {
1752 case SP_FILE:
1753 if(!capture_input_new_file(cap_session, buffer)) {
1754 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1756 /* We weren't able to open the new capture file; user has been
1757 alerted. Close the sync pipe. */
1758 ws_close(source);
1760 /* The child has sent us a filename which we couldn't open.
1762 This could mean that the child is creating and deleting files
1763 (ring buffer mode) faster than we can handle it.
1765 That should only be the case for very fast file switches;
1766 We can't do much more than telling the child to stop.
1767 (This is the "emergency brake" if the user e.g. wants to
1768 switch files every second).
1770 This can also happen if the user specified "-", meaning
1771 "standard output", as the capture file. */
1772 sync_pipe_stop(cap_session);
1773 capture_input_closed(cap_session, NULL);
1774 return FALSE;
1776 break;
1777 case SP_PACKET_COUNT:
1778 npackets = atoi(buffer);
1779 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", npackets);
1780 capture_input_new_packets(cap_session, npackets);
1781 break;
1782 case SP_ERROR_MSG:
1783 /* convert primary message */
1784 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1785 primary_msg = buffer+4;
1786 /* convert secondary message */
1787 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1788 secondary_msg = primary_msg + primary_len + 4;
1789 /* message output */
1790 capture_input_error_message(cap_session, primary_msg, secondary_msg);
1791 /* the capture child will close the sync_pipe, nothing to do for now */
1792 /* (an error message doesn't mean we have to stop capturing) */
1793 break;
1794 case SP_BAD_FILTER: {
1795 char *ch;
1796 int indx;
1798 ch = strtok(buffer, ":");
1799 indx = (int)strtol(ch, NULL, 10);
1800 ch = strtok(NULL, ":");
1801 capture_input_cfilter_error_message(cap_session, indx, ch);
1802 /* the capture child will close the sync_pipe, nothing to do for now */
1803 break;
1805 case SP_DROPS:
1806 capture_input_drops(cap_session, (guint32)strtoul(buffer, NULL, 10));
1807 break;
1808 default:
1809 g_assert_not_reached();
1812 return TRUE;
1818 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1819 * unchanged, and the exit status of dumpcap is returned. On
1820 * failure (which includes "dumpcap exited due to being killed by
1821 * a signal or an exception"), *msgp points to an error message
1822 * for the failure, and -1 is returned. In the latter case, *msgp
1823 * must be freed with g_free().
1825 static int
1826 sync_pipe_wait_for_child(int fork_child, gchar **msgp)
1828 int fork_child_status;
1829 int ret;
1830 GTimeVal start_time;
1831 GTimeVal end_time;
1832 float elapsed;
1835 * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
1836 * replace this
1838 g_get_current_time(&start_time);
1840 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1841 g_assert(fork_child != -1);
1843 *msgp = NULL; /* assume no error */
1844 #ifdef _WIN32
1845 if (_cwait(&fork_child_status, fork_child, _WAIT_CHILD) == -1) {
1846 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1847 ret = -1;
1848 } else {
1850 * The child exited; return its exit status. Do not treat this as
1851 * an error.
1853 ret = fork_child_status;
1854 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1855 /* Probably an exception code */
1856 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1857 win32strexception(fork_child_status));
1858 ret = -1;
1861 #else
1862 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1863 if (WIFEXITED(fork_child_status)) {
1865 * The child exited; return its exit status. Do not treat this as
1866 * an error.
1868 ret = WEXITSTATUS(fork_child_status);
1869 } else if (WIFSTOPPED(fork_child_status)) {
1870 /* It stopped, rather than exiting. "Should not happen." */
1871 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1872 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1873 ret = -1;
1874 } else if (WIFSIGNALED(fork_child_status)) {
1875 /* It died with a signal. */
1876 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1877 sync_pipe_signame(WTERMSIG(fork_child_status)),
1878 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1879 ret = -1;
1880 } else {
1881 /* What? It had to either have exited, or stopped, or died with
1882 a signal; what happened here? */
1883 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1884 fork_child_status);
1885 ret = -1;
1887 } else if (errno != ECHILD) {
1888 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1889 ret = -1;
1890 } else {
1891 /* errno == ECHILD ; echld might have already reaped the child */
1892 ret = fetch_dumpcap_pid ? 0 : -1;
1894 #endif
1896 g_get_current_time(&end_time);
1897 elapsed = (float) ((end_time.tv_sec - start_time.tv_sec) +
1898 ((end_time.tv_usec - start_time.tv_usec) / 1e6));
1899 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed after %.3fs", elapsed);
1900 return ret;
1904 #ifndef _WIN32
1905 /* convert signal to corresponding name */
1906 static const char *
1907 sync_pipe_signame(int sig)
1909 const char *sigmsg;
1910 static char sigmsg_buf[6+1+3+1];
1912 switch (sig) {
1914 case SIGHUP:
1915 sigmsg = "Hangup";
1916 break;
1918 case SIGINT:
1919 sigmsg = "Interrupted";
1920 break;
1922 case SIGQUIT:
1923 sigmsg = "Quit";
1924 break;
1926 case SIGILL:
1927 sigmsg = "Illegal instruction";
1928 break;
1930 case SIGTRAP:
1931 sigmsg = "Trace trap";
1932 break;
1934 case SIGABRT:
1935 sigmsg = "Abort";
1936 break;
1938 case SIGFPE:
1939 sigmsg = "Arithmetic exception";
1940 break;
1942 case SIGKILL:
1943 sigmsg = "Killed";
1944 break;
1946 case SIGBUS:
1947 sigmsg = "Bus error";
1948 break;
1950 case SIGSEGV:
1951 sigmsg = "Segmentation violation";
1952 break;
1954 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1955 Linux is POSIX compliant. These are not POSIX-defined signals ---
1956 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1958 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1959 were omitted from POSIX.1 because their behavior is
1960 implementation dependent and could not be adequately catego-
1961 rized. Conforming implementations may deliver these sig-
1962 nals, but must document the circumstances under which they
1963 are delivered and note any restrictions concerning their
1964 delivery.''
1966 So we only check for SIGSYS on those systems that happen to
1967 implement them (a system can be POSIX-compliant and implement
1968 them, it's just that POSIX doesn't *require* a POSIX-compliant
1969 system to implement them).
1972 #ifdef SIGSYS
1973 case SIGSYS:
1974 sigmsg = "Bad system call";
1975 break;
1976 #endif
1978 case SIGPIPE:
1979 sigmsg = "Broken pipe";
1980 break;
1982 case SIGALRM:
1983 sigmsg = "Alarm clock";
1984 break;
1986 case SIGTERM:
1987 sigmsg = "Terminated";
1988 break;
1990 default:
1991 /* Returning a static buffer is ok in the context we use it here */
1992 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1993 sigmsg = sigmsg_buf;
1994 break;
1996 return sigmsg;
1998 #endif
2001 #ifdef _WIN32
2003 static void create_dummy_signal_pipe() {
2004 gchar *dummy_signal_pipe_name;
2006 if (dummy_signal_pipe != NULL) return;
2008 if (!dummy_control_id) {
2009 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
2012 /* Create the signal pipe */
2013 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
2014 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
2015 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
2016 g_free(dummy_signal_pipe_name);
2019 /* tell the child through the signal pipe that we want to quit the capture */
2020 static void
2021 signal_pipe_capquit_to_child(capture_session *cap_session)
2023 const char quit_msg[] = "QUIT";
2024 int ret;
2026 g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
2028 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2029 /* simply sending a "QUIT" string */
2030 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2031 ret = write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2032 if(ret == -1) {
2033 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2034 "signal_pipe_capquit_to_child: %d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2037 #endif
2040 /* user wants to stop the capture run */
2041 void
2042 sync_pipe_stop(capture_session *cap_session)
2044 #ifdef _WIN32
2045 int count;
2046 DWORD childstatus;
2047 gboolean terminate = TRUE;
2048 #endif
2050 if (cap_session->fork_child != -1) {
2051 #ifndef _WIN32
2052 /* send the SIGINT signal to close the capture child gracefully. */
2053 int sts = kill(cap_session->fork_child, SIGINT);
2054 if (sts != 0) {
2055 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2056 "Sending SIGINT to child failed: %s\n", g_strerror(errno));
2058 #else
2059 #define STOP_SLEEP_TIME 500 /* ms */
2060 #define STOP_CHECK_TIME 50
2061 /* First, use the special signal pipe to try to close the capture child
2062 * gracefully.
2064 signal_pipe_capquit_to_child(cap_session);
2066 /* Next, wait for the process to exit on its own */
2067 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2068 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2069 childstatus != STILL_ACTIVE) {
2070 terminate = FALSE;
2071 break;
2073 Sleep(STOP_CHECK_TIME);
2076 /* Force the issue. */
2077 if (terminate) {
2078 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2079 "sync_pipe_stop: forcing child to exit");
2080 sync_pipe_kill(cap_session->fork_child);
2082 #endif
2087 /* Wireshark has to exit, force the capture child to close */
2088 void
2089 sync_pipe_kill(int fork_child)
2091 if (fork_child != -1) {
2092 #ifndef _WIN32
2093 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2094 if (sts != 0) {
2095 g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
2096 "Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2098 #else
2099 /* Remark: This is not the preferred method of closing a process!
2100 * the clean way would be getting the process id of the child process,
2101 * then getting window handle hWnd of that process (using EnumChildWindows),
2102 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2104 * Unfortunately, I don't know how to get the process id from the
2105 * handle. OpenProcess will get an handle (not a window handle)
2106 * from the process ID; it will not get a window handle from the
2107 * process ID. (How could it? A process can have more than one
2108 * window. For that matter, a process might have *no* windows,
2109 * as a process running dumpcap, the normal child process program,
2110 * probably does.)
2112 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2113 * running in the same console; that's not necessarily the case for
2114 * us, as we might not be running in a console.
2115 * And this also will require to have the process id.
2117 TerminateProcess((HANDLE) (fork_child), 0);
2118 #endif
2122 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(int pid)) {
2123 fetch_dumpcap_pid = cb;
2126 #endif /* HAVE_LIBPCAP */