1 /* capture_sync.c
2 * Synchronisation between Wireshark capture parent and child instances
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "config.h"
12 #define WS_LOG_DOMAIN LOG_DOMAIN_CAPTURE
13
14 #ifdef HAVE_LIBPCAP
15
16 #include <glib.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 #include <signal.h>
22
23 #include <wsutil/strtoi.h>
24 #include <wsutil/wslog.h>
25 #include <wsutil/ws_assert.h>
26
27 #ifdef _WIN32
28 #include <wsutil/unicode-utils.h>
29 #include <wsutil/win32-utils.h>
30 #include <wsutil/ws_pipe.h>
31 #endif
32
33 #ifdef HAVE_SYS_WAIT_H
34 # include <sys/wait.h>
35 #endif
36
37 #include "capture/capture-pcap-util.h"
38
39 #ifndef _WIN32
40 /*
41 * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
42 * macros) on UNIX systems that don't have them.
43 */
44 #ifndef WIFEXITED
45 # define WIFEXITED(status) (((status) & 0177) == 0)
46 #endif
47 #ifndef WIFSTOPPED
48 # define WIFSTOPPED(status) (((status) & 0177) == 0177)
49 #endif
50 #ifndef WIFSIGNALED
51 # define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
52 #endif
53 #ifndef WEXITSTATUS
54 # define WEXITSTATUS(status) ((status) >> 8)
55 #endif
56 #ifndef WTERMSIG
57 # define WTERMSIG(status) ((status) & 0177)
58 #endif
59 #ifndef WCOREDUMP
60 # define WCOREDUMP(status) ((status) & 0200)
61 #endif
62 #ifndef WSTOPSIG
63 # define WSTOPSIG(status) ((status) >> 8)
64 #endif
65 #endif /* _WIN32 */
66
67 #include <epan/packet.h>
68 #include <epan/prefs.h>
69
70 #include "file.h"
71
72 #include "ui/capture.h"
73 #include <capture/capture_sync.h>
74
75 #include "sync_pipe.h"
76
77 #ifdef _WIN32
78 #include "capture/capture-wpcap.h"
79 #endif
80
81 #include "ui/ws_ui_util.h"
82
83 #include <wsutil/filesystem.h>
84 #include <wsutil/file_util.h>
85 #include <wsutil/report_message.h>
86 #include "extcap.h"
87
88 #ifdef _WIN32
89 #include <process.h> /* For spawning child process */
90 #endif
91
92 #include <wsutil/ws_pipe.h>
93
94 #ifdef _WIN32
95 static void create_dummy_signal_pipe();
96 static HANDLE dummy_signal_pipe; /* Dummy named pipe which lets the child check for a dropped connection */
97 static gchar *dummy_control_id;
98 #else
99 static const char *sync_pipe_signame(int);
100 #endif
101
102
103 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
104 static int sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp);
105 static void pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len);
106 static ssize_t pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
107 char **err_msg);
108
109 static void (*fetch_dumpcap_pid)(ws_process_id) = NULL;
110
free_argv(char ** argv,int argc)111 static void free_argv(char** argv, int argc)
112 {
113 int i;
114 for (i = 0; i < argc; i++)
115 g_free(argv[i]);
116 g_free(argv);
117 }
118
119 void
capture_session_init(capture_session * cap_session,capture_file * cf,new_file_fn new_file,new_packets_fn new_packets,drops_fn drops,error_fn error,cfilter_error_fn cfilter_error,closed_fn closed)120 capture_session_init(capture_session *cap_session, capture_file *cf,
121 new_file_fn new_file, new_packets_fn new_packets,
122 drops_fn drops, error_fn error,
123 cfilter_error_fn cfilter_error, closed_fn closed)
124 {
125 cap_session->cf = cf;
126 cap_session->fork_child = WS_INVALID_PID; /* invalid process handle */
127 #ifdef _WIN32
128 cap_session->signal_pipe_write_fd = -1;
129 #endif
130 cap_session->state = CAPTURE_STOPPED;
131 #ifndef _WIN32
132 cap_session->owner = getuid();
133 cap_session->group = getgid();
134 #endif
135 cap_session->count = 0;
136 cap_session->session_will_restart = FALSE;
137
138 cap_session->new_file = new_file;
139 cap_session->new_packets = new_packets;
140 cap_session->drops = drops;
141 cap_session->error = error;
142 cap_session->cfilter_error = cfilter_error;
143 cap_session->closed = closed;
144 }
145
146 /* Append an arg (realloc) to an argc/argv array */
147 /* (add a string pointer to a NULL-terminated array of string pointers) */
148 static char **
sync_pipe_add_arg(char ** args,int * argc,const char * arg)149 sync_pipe_add_arg(char **args, int *argc, const char *arg)
150 {
151 /* Grow the array; "*argc" currently contains the number of string
152 pointers, *not* counting the NULL pointer at the end, so we have
153 to add 2 in order to get the new size of the array, including the
154 new pointer and the terminating NULL pointer. */
155 args = (char **)g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
156
157 /* Stuff the pointer into the penultimate element of the array, which
158 is the one at the index specified by "*argc". */
159 args[*argc] = g_strdup(arg);
160 /* Now bump the count. */
161 (*argc)++;
162
163 /* We overwrite the NULL pointer; put it back right after the
164 element we added. */
165 args[*argc] = NULL;
166
167 return args;
168 }
169
170 /* Initialize an argument list and add dumpcap to it. */
171 static char **
init_pipe_args(int * argc)172 init_pipe_args(int *argc) {
173 char **argv;
174 const char *progfile_dir;
175 char *exename;
176
177 progfile_dir = get_progfile_dir();
178 if (progfile_dir == NULL) {
179 return NULL;
180 }
181
182 /* Allocate the string pointer array with enough space for the
183 terminating NULL pointer. */
184 *argc = 0;
185 argv = (char **)g_malloc(sizeof (char *));
186 *argv = NULL;
187
188 /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
189 #ifdef _WIN32
190 exename = g_strdup_printf("%s\\dumpcap.exe", progfile_dir);
191 #else
192 exename = g_strdup_printf("%s/dumpcap", progfile_dir);
193 #endif
194
195 /* Make that the first argument in the argument list (argv[0]). */
196 argv = sync_pipe_add_arg(argv, argc, exename);
197
198 /* sync_pipe_add_arg strdupes exename, so we should free our copy */
199 g_free(exename);
200
201 return argv;
202 }
203
204 #define ARGV_NUMBER_LEN 24
205 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
206 gboolean
sync_pipe_start(capture_options * capture_opts,GPtrArray * capture_comments,capture_session * cap_session,info_data_t * cap_data,void (* update_cb)(void))207 sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
208 capture_session *cap_session, info_data_t* cap_data,
209 void (*update_cb)(void))
210 {
211 #ifdef _WIN32
212 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */
213 HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */
214 int signal_pipe_write_fd;
215 HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */
216 GString *args = g_string_sized_new(200);
217 gchar *quoted_arg;
218 SECURITY_ATTRIBUTES sa;
219 STARTUPINFO si;
220 PROCESS_INFORMATION pi;
221 char control_id[ARGV_NUMBER_LEN];
222 gchar *signal_pipe_name;
223 #else
224 char errmsg[1024+1];
225 int sync_pipe[2]; /* pipe used to send messages from child to parent */
226 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
227 #endif
228 int sync_pipe_read_fd;
229 int argc;
230 char **argv;
231 int i;
232 guint j;
233 interface_options *interface_opts;
234
235 if (capture_opts->ifaces->len > 1)
236 capture_opts->use_pcapng = TRUE;
237 ws_debug("sync_pipe_start");
238 capture_opts_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, capture_opts);
239
240 cap_session->fork_child = WS_INVALID_PID;
241
242 if (!extcap_init_interfaces(capture_opts)) {
243 report_failure("Unable to init extcaps. (tmp fifo already exists?)");
244 return FALSE;
245 }
246
247 argv = init_pipe_args(&argc);
248 if (!argv) {
249 /* We don't know where to find dumpcap. */
250 report_failure("We don't know where to find dumpcap.");
251 return FALSE;
252 }
253
254 if (capture_opts->ifaces->len > 1)
255 argv = sync_pipe_add_arg(argv, &argc, "-t");
256
257 if (capture_opts->use_pcapng)
258 argv = sync_pipe_add_arg(argv, &argc, "-n");
259 else
260 argv = sync_pipe_add_arg(argv, &argc, "-P");
261
262 if (capture_comments != NULL) {
263 for (j = 0; j < capture_comments->len; j++) {
264 argv = sync_pipe_add_arg(argv, &argc, "--capture-comment");
265 argv = sync_pipe_add_arg(argv, &argc, (char*)g_ptr_array_index(capture_comments, j));
266 }
267 }
268
269 if (capture_opts->multi_files_on) {
270 if (capture_opts->has_autostop_filesize) {
271 char sfilesize[ARGV_NUMBER_LEN];
272 argv = sync_pipe_add_arg(argv, &argc, "-b");
273 g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
274 argv = sync_pipe_add_arg(argv, &argc, sfilesize);
275 }
276
277 if (capture_opts->has_file_duration) {
278 char sfile_duration[ARGV_NUMBER_LEN];
279 argv = sync_pipe_add_arg(argv, &argc, "-b");
280 g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->file_duration);
281 argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
282 }
283
284 if (capture_opts->has_file_interval) {
285 char sfile_interval[ARGV_NUMBER_LEN];
286 argv = sync_pipe_add_arg(argv, &argc, "-b");
287 g_snprintf(sfile_interval, ARGV_NUMBER_LEN, "interval:%d",capture_opts->file_interval);
288 argv = sync_pipe_add_arg(argv, &argc, sfile_interval);
289 }
290
291 if (capture_opts->has_file_packets) {
292 char sfile_packets[ARGV_NUMBER_LEN];
293 argv = sync_pipe_add_arg(argv, &argc, "-b");
294 g_snprintf(sfile_packets, ARGV_NUMBER_LEN, "packets:%d",capture_opts->file_packets);
295 argv = sync_pipe_add_arg(argv, &argc, sfile_packets);
296 }
297
298 if (capture_opts->has_ring_num_files) {
299 char sring_num_files[ARGV_NUMBER_LEN];
300 argv = sync_pipe_add_arg(argv, &argc, "-b");
301 g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
302 argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
303 }
304
305 if (capture_opts->has_nametimenum) {
306 char nametimenum[ARGV_NUMBER_LEN];
307 argv = sync_pipe_add_arg(argv, &argc, "-b");
308 g_snprintf(nametimenum, ARGV_NUMBER_LEN, "nametimenum:2");
309 argv = sync_pipe_add_arg(argv, &argc, nametimenum);
310 }
311
312 if (capture_opts->has_autostop_files) {
313 char sautostop_files[ARGV_NUMBER_LEN];
314 argv = sync_pipe_add_arg(argv, &argc, "-a");
315 g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
316 argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
317 }
318 } else {
319 if (capture_opts->has_autostop_filesize) {
320 char sautostop_filesize[ARGV_NUMBER_LEN];
321 argv = sync_pipe_add_arg(argv, &argc, "-a");
322 g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%u",capture_opts->autostop_filesize);
323 argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
324 }
325 }
326
327 if (capture_opts->has_autostop_packets) {
328 char scount[ARGV_NUMBER_LEN];
329 argv = sync_pipe_add_arg(argv, &argc, "-c");
330 g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
331 argv = sync_pipe_add_arg(argv, &argc, scount);
332 }
333
334 if (capture_opts->has_autostop_duration) {
335 char sautostop_duration[ARGV_NUMBER_LEN];
336 argv = sync_pipe_add_arg(argv, &argc, "-a");
337 g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%f",capture_opts->autostop_duration);
338 argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
339 }
340
341 if (capture_opts->group_read_access) {
342 argv = sync_pipe_add_arg(argv, &argc, "-g");
343 }
344
345 for (j = 0; j < capture_opts->ifaces->len; j++) {
346 interface_opts = &g_array_index(capture_opts->ifaces, interface_options, j);
347
348 argv = sync_pipe_add_arg(argv, &argc, "-i");
349 if (interface_opts->extcap_fifo != NULL)
350 {
351 #ifdef _WIN32
352 char *pipe = g_strdup_printf("%s%" G_GUINTPTR_FORMAT, EXTCAP_PIPE_PREFIX, interface_opts->extcap_pipe_h);
353 argv = sync_pipe_add_arg(argv, &argc, pipe);
354 g_free(pipe);
355 #else
356 argv = sync_pipe_add_arg(argv, &argc, interface_opts->extcap_fifo);
357 #endif
358 /* Add a name for the interface, to put into an IDB. */
359 argv = sync_pipe_add_arg(argv, &argc, "--ifname");
360 argv = sync_pipe_add_arg(argv, &argc, interface_opts->name);
361 if (interface_opts->descr != NULL)
362 {
363 /* Add a description for the interface, to put into an IDB. */
364 argv = sync_pipe_add_arg(argv, &argc, "--ifdescr");
365 argv = sync_pipe_add_arg(argv, &argc, interface_opts->descr);
366 }
367 }
368 else
369 argv = sync_pipe_add_arg(argv, &argc, interface_opts->name);
370
371 if (interface_opts->cfilter != NULL && strlen(interface_opts->cfilter) != 0) {
372 argv = sync_pipe_add_arg(argv, &argc, "-f");
373 argv = sync_pipe_add_arg(argv, &argc, interface_opts->cfilter);
374 }
375 if (interface_opts->has_snaplen) {
376 char ssnap[ARGV_NUMBER_LEN];
377 argv = sync_pipe_add_arg(argv, &argc, "-s");
378 g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d", interface_opts->snaplen);
379 argv = sync_pipe_add_arg(argv, &argc, ssnap);
380 }
381
382 if (interface_opts->linktype != -1) {
383 const char *linktype = linktype_val_to_name(interface_opts->linktype);
384 if ( linktype != NULL )
385 {
386 argv = sync_pipe_add_arg(argv, &argc, "-y");
387 argv = sync_pipe_add_arg(argv, &argc, linktype);
388 }
389 }
390
391 if (!interface_opts->promisc_mode) {
392 argv = sync_pipe_add_arg(argv, &argc, "-p");
393 }
394
395 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
396 if (interface_opts->buffer_size != DEFAULT_CAPTURE_BUFFER_SIZE) {
397 char buffer_size[ARGV_NUMBER_LEN];
398 argv = sync_pipe_add_arg(argv, &argc, "-B");
399 if(interface_opts->buffer_size == 0x00)
400 interface_opts->buffer_size = DEFAULT_CAPTURE_BUFFER_SIZE;
401 g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", interface_opts->buffer_size);
402 argv = sync_pipe_add_arg(argv, &argc, buffer_size);
403 }
404 #endif
405
406 #ifdef HAVE_PCAP_CREATE
407 if (interface_opts->monitor_mode) {
408 argv = sync_pipe_add_arg(argv, &argc, "-I");
409 }
410 #endif
411
412 #ifdef HAVE_PCAP_REMOTE
413 if (interface_opts->datatx_udp)
414 argv = sync_pipe_add_arg(argv, &argc, "-u");
415
416 if (!interface_opts->nocap_rpcap)
417 argv = sync_pipe_add_arg(argv, &argc, "-r");
418
419 if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
420 char sauth[256];
421 argv = sync_pipe_add_arg(argv, &argc, "-A");
422 g_snprintf(sauth, sizeof(sauth), "%s:%s",
423 interface_opts->auth_username,
424 interface_opts->auth_password);
425 argv = sync_pipe_add_arg(argv, &argc, sauth);
426 }
427 #endif
428
429 #ifdef HAVE_PCAP_SETSAMPLING
430 if (interface_opts->sampling_method != CAPTURE_SAMP_NONE) {
431 char ssampling[ARGV_NUMBER_LEN];
432 argv = sync_pipe_add_arg(argv, &argc, "-m");
433 g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
434 interface_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
435 interface_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
436 "undef",
437 interface_opts->sampling_param);
438 argv = sync_pipe_add_arg(argv, &argc, ssampling);
439 }
440 #endif
441 if (interface_opts->timestamp_type) {
442 argv = sync_pipe_add_arg(argv, &argc, "--time-stamp-type");
443 argv = sync_pipe_add_arg(argv, &argc, interface_opts->timestamp_type);
444 }
445 }
446
447 /* dumpcap should be running in capture child mode (hidden feature) */
448 #ifndef DEBUG_CHILD
449 argv = sync_pipe_add_arg(argv, &argc, "-Z");
450 #ifdef _WIN32
451 g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
452 argv = sync_pipe_add_arg(argv, &argc, control_id);
453 #else
454 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
455 #endif
456 #endif
457
458 if (capture_opts->save_file) {
459 argv = sync_pipe_add_arg(argv, &argc, "-w");
460 argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
461 }
462 for (i = 0; i < argc; i++) {
463 ws_debug("argv[%d]: %s", i, argv[i]);
464 }
465 if (capture_opts->compress_type) {
466 argv = sync_pipe_add_arg(argv, &argc, "--compress-type");
467 argv = sync_pipe_add_arg(argv, &argc, capture_opts->compress_type);
468 }
469
470 #ifdef _WIN32
471 /* init SECURITY_ATTRIBUTES */
472 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
473 sa.bInheritHandle = TRUE;
474 sa.lpSecurityDescriptor = NULL;
475
476 /* Create a pipe for the child process */
477 /* (increase this value if you have trouble while fast capture file switches) */
478 if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
479 /* Couldn't create the pipe between parent and child. */
480 report_failure("Couldn't create sync pipe: %s",
481 win32strerror(GetLastError()));
482 free_argv(argv, argc);
483 return FALSE;
484 }
485
486 /*
487 * Associate a C run-time file handle with the Windows HANDLE for the
488 * read side of the message pipe.
489 *
490 * (See http://www.flounder.com/handles.htm for information on various
491 * types of file handle in C/C++ on Windows.)
492 */
493 sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY);
494 if (sync_pipe_read_fd == -1) {
495 /* Couldn't create the pipe between parent and child. */
496 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
497 CloseHandle(sync_pipe_read);
498 CloseHandle(sync_pipe_write);
499 free_argv(argv, argc);
500 return FALSE;
501 }
502
503 /* Create the signal pipe */
504 signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
505 signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
506 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
507 g_free(signal_pipe_name);
508
509 if (signal_pipe == INVALID_HANDLE_VALUE) {
510 /* Couldn't create the signal pipe between parent and child. */
511 report_failure("Couldn't create signal pipe: %s",
512 win32strerror(GetLastError()));
513 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
514 CloseHandle(sync_pipe_write);
515 free_argv(argv, argc);
516 return FALSE;
517 }
518
519 /*
520 * Associate a C run-time file handle with the Windows HANDLE for the
521 * read side of the message pipe.
522 *
523 * (See http://www.flounder.com/handles.htm for information on various
524 * types of file handle in C/C++ on Windows.)
525 */
526 signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY);
527 if (sync_pipe_read_fd == -1) {
528 /* Couldn't create the pipe between parent and child. */
529 report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno));
530 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
531 CloseHandle(sync_pipe_write);
532 CloseHandle(signal_pipe);
533 free_argv(argv, argc);
534 return FALSE;
535 }
536
537 /* init STARTUPINFO & PROCESS_INFORMATION */
538 memset(&si, 0, sizeof(si));
539 si.cb = sizeof(si);
540 memset(&pi, 0, sizeof(pi));
541 #ifdef DEBUG_CHILD
542 si.dwFlags = STARTF_USESHOWWINDOW;
543 si.wShowWindow = SW_SHOW;
544 #else
545 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
546 si.wShowWindow = SW_HIDE; /* this hides the console window */
547 si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
548 si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
549 si.hStdError = sync_pipe_write;
550 /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
551 #endif
552
553 /* convert args array into a single string */
554 /* XXX - could change sync_pipe_add_arg() instead */
555 /* there is a drawback here: the length is internally limited to 1024 bytes */
556 for(i=0; argv[i] != 0; i++) {
557 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
558 quoted_arg = protect_arg(argv[i]);
559 g_string_append(args, quoted_arg);
560 g_free(quoted_arg);
561 }
562
563 /* call dumpcap */
564 if(!win32_create_process(argv[0], args->str, NULL, NULL, TRUE,
565 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
566 report_failure("Couldn't run %s in child process: %s",
567 args->str, win32strerror(GetLastError()));
568 ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */
569 CloseHandle(sync_pipe_write);
570 CloseHandle(signal_pipe);
571 free_argv(argv, argc);
572 g_string_free(args, TRUE);
573 return FALSE;
574 }
575 cap_session->fork_child = pi.hProcess;
576 /* We may need to store this and close it later */
577 CloseHandle(pi.hThread);
578 g_string_free(args, TRUE);
579
580 cap_session->signal_pipe_write_fd = signal_pipe_write_fd;
581
582 #else /* _WIN32 */
583 if (pipe(sync_pipe) < 0) {
584 /* Couldn't create the pipe between parent and child. */
585 report_failure("Couldn't create sync pipe: %s", g_strerror(errno));
586 free_argv(argv, argc);
587 return FALSE;
588 }
589
590 if ((cap_session->fork_child = fork()) == 0) {
591 /*
592 * Child process - run dumpcap with the right arguments to make
593 * it just capture with the specified capture parameters
594 */
595 dup2(sync_pipe[PIPE_WRITE], 2);
596 ws_close(sync_pipe[PIPE_READ]);
597 execv(argv[0], argv);
598 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
599 argv[0], g_strerror(errno));
600 sync_pipe_errmsg_to_parent(2, errmsg, "");
601
602 /* Exit with "_exit()", so that we don't close the connection
603 to the X server (and cause stuff buffered up by our parent but
604 not yet sent to be sent, as that stuff should only be sent by
605 our parent). We've sent an error message to the parent, so
606 we exit with an exit status of 1 (any exit status other than
607 0 or 1 will cause an additional message to report that exit
608 status, over and above the error message we sent to the parent). */
609 _exit(1);
610 }
611
612 if (fetch_dumpcap_pid && cap_session->fork_child > 0)
613 fetch_dumpcap_pid(cap_session->fork_child);
614
615 sync_pipe_read_fd = sync_pipe[PIPE_READ];
616 #endif
617
618 /* Parent process - read messages from the child process over the
619 sync pipe. */
620 free_argv(argv, argc);
621
622 /* Close the write side of the pipe, so that only the child has it
623 open, and thus it completely closes, and thus returns to us
624 an EOF indication, if the child closes it (either deliberately
625 or by exiting abnormally). */
626 #ifdef _WIN32
627 CloseHandle(sync_pipe_write);
628 #else
629 ws_close(sync_pipe[PIPE_WRITE]);
630 #endif
631
632 if (cap_session->fork_child == WS_INVALID_PID) {
633 /* We couldn't even create the child process. */
634 report_failure("Couldn't create child process: %s", g_strerror(errno));
635 ws_close(sync_pipe_read_fd);
636 #ifdef _WIN32
637 ws_close(cap_session->signal_pipe_write_fd);
638 #endif
639 return FALSE;
640 }
641
642 cap_session->fork_child_status = 0;
643 cap_session->capture_opts = capture_opts;
644 cap_session->cap_data_info = cap_data;
645
646 /* we might wait for a moment till child is ready, so update screen now */
647 if (update_cb) update_cb();
648
649 /* We were able to set up to read the capture file;
650 arrange that our callback be called whenever it's possible
651 to read from the sync pipe, so that it's called when
652 the child process wants to tell us something. */
653
654 /* we have a running capture, now wait for the real capture filename */
655 pipe_input_set_handler(sync_pipe_read_fd, (gpointer) cap_session,
656 &cap_session->fork_child, sync_pipe_input_cb);
657
658 return TRUE;
659 }
660
661 /*
662 * Open two pipes to dumpcap with the supplied arguments, one for its
663 * standard output and one for its standard error.
664 *
665 * On success, *msg is unchanged and 0 is returned; data_read_fd,
666 * message_read_fd, and fork_child point to the standard output pipe's
667 * file descriptor, the standard error pipe's file descriptor, and
668 * the child's PID/handle, respectively.
669 *
670 * On failure, *msg points to an error message for the failure, and -1 is
671 * returned, in which case *msg must be freed with g_free().
672 */
673 /* XXX - This duplicates a lot of code in sync_pipe_start() */
674 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
675 #define PIPE_BUF_SIZE 5120
676 static int
sync_pipe_open_command(char * const argv[],int * data_read_fd,int * message_read_fd,ws_process_id * fork_child,gchar ** msg,void (* update_cb)(void))677 sync_pipe_open_command(char* const argv[], int *data_read_fd,
678 int *message_read_fd, ws_process_id *fork_child, gchar **msg, void(*update_cb)(void))
679 {
680 enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
681 #ifdef _WIN32
682 HANDLE sync_pipe[2]; /* pipe used to send messages from child to parent */
683 HANDLE data_pipe[2]; /* pipe used to send data from child to parent */
684 GString *args = g_string_sized_new(200);
685 gchar *quoted_arg;
686 SECURITY_ATTRIBUTES sa;
687 STARTUPINFO si;
688 PROCESS_INFORMATION pi;
689 int i;
690 #else
691 char errmsg[1024+1];
692 int sync_pipe[2]; /* pipe used to send messages from child to parent */
693 int data_pipe[2]; /* pipe used to send data from child to parent */
694 #endif
695 *fork_child = WS_INVALID_PID;
696 *data_read_fd = -1;
697 *message_read_fd = -1;
698 ws_debug("sync_pipe_open_command");
699
700 if (!msg) {
701 /* We can't return anything */
702 #ifdef _WIN32
703 g_string_free(args, TRUE);
704 #endif
705 return -1;
706 }
707
708 #ifdef _WIN32
709 /* init SECURITY_ATTRIBUTES */
710 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
711 sa.bInheritHandle = TRUE;
712 sa.lpSecurityDescriptor = NULL;
713
714 /* Create a pipe for the child process to send us messages */
715 /* (increase this value if you have trouble while fast capture file switches) */
716 if (! CreatePipe(&sync_pipe[PIPE_READ], &sync_pipe[PIPE_WRITE], &sa, 5120)) {
717 /* Couldn't create the message pipe between parent and child. */
718 *msg = g_strdup_printf("Couldn't create sync pipe: %s",
719 win32strerror(GetLastError()));
720 return -1;
721 }
722
723 /*
724 * Associate a C run-time file handle with the Windows HANDLE for the
725 * read side of the message pipe.
726 *
727 * (See http://www.flounder.com/handles.htm for information on various
728 * types of file handle in C/C++ on Windows.)
729 */
730 *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY);
731 if (*message_read_fd == -1) {
732 *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno));
733 CloseHandle(sync_pipe[PIPE_READ]);
734 CloseHandle(sync_pipe[PIPE_WRITE]);
735 return -1;
736 }
737
738 /* Create a pipe for the child process to send us data */
739 /* (increase this value if you have trouble while fast capture file switches) */
740 if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) {
741 /* Couldn't create the message pipe between parent and child. */
742 *msg = g_strdup_printf("Couldn't create data pipe: %s",
743 win32strerror(GetLastError()));
744 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
745 CloseHandle(sync_pipe[PIPE_WRITE]);
746 return -1;
747 }
748
749 /*
750 * Associate a C run-time file handle with the Windows HANDLE for the
751 * read side of the data pipe.
752 *
753 * (See http://www.flounder.com/handles.htm for information on various
754 * types of file handle in C/C++ on Windows.)
755 */
756 *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY);
757 if (*data_read_fd == -1) {
758 *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno));
759 CloseHandle(data_pipe[PIPE_READ]);
760 CloseHandle(data_pipe[PIPE_WRITE]);
761 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
762 CloseHandle(sync_pipe[PIPE_WRITE]);
763 return -1;
764 }
765
766 /* init STARTUPINFO & PROCESS_INFORMATION */
767 memset(&si, 0, sizeof(si));
768 si.cb = sizeof(si);
769 memset(&pi, 0, sizeof(pi));
770 #ifdef DEBUG_CHILD
771 si.dwFlags = STARTF_USESHOWWINDOW;
772 si.wShowWindow = SW_SHOW;
773 #else
774 si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
775 si.wShowWindow = SW_HIDE; /* this hides the console window */
776 si.hStdInput = NULL; /* handle for named pipe*/
777
778 si.hStdOutput = data_pipe[PIPE_WRITE];
779 si.hStdError = sync_pipe[PIPE_WRITE];
780 #endif
781
782 /* convert args array into a single string */
783 /* XXX - could change sync_pipe_add_arg() instead */
784 /* there is a drawback here: the length is internally limited to 1024 bytes */
785 for(i=0; argv[i] != 0; i++) {
786 if(i != 0) g_string_append_c(args, ' '); /* don't prepend a space before the path!!! */
787 quoted_arg = protect_arg(argv[i]);
788 g_string_append(args, quoted_arg);
789 g_free(quoted_arg);
790 }
791
792 /* call dumpcap */
793 if(!win32_create_process(argv[0], args->str, NULL, NULL, TRUE,
794 CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
795 *msg = g_strdup_printf("Couldn't run %s in child process: %s",
796 args->str, win32strerror(GetLastError()));
797 ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */
798 CloseHandle(data_pipe[PIPE_WRITE]);
799 ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */
800 CloseHandle(sync_pipe[PIPE_WRITE]);
801 g_string_free(args, TRUE);
802 return -1;
803 }
804 *fork_child = pi.hProcess;
805 /* We may need to store this and close it later */
806 CloseHandle(pi.hThread);
807 g_string_free(args, TRUE);
808 #else /* _WIN32 */
809 /* Create a pipe for the child process to send us messages */
810 if (pipe(sync_pipe) < 0) {
811 /* Couldn't create the message pipe between parent and child. */
812 *msg = g_strdup_printf("Couldn't create sync pipe: %s", g_strerror(errno));
813 return -1;
814 }
815
816 /* Create a pipe for the child process to send us data */
817 if (pipe(data_pipe) < 0) {
818 /* Couldn't create the data pipe between parent and child. */
819 *msg = g_strdup_printf("Couldn't create data pipe: %s", g_strerror(errno));
820 ws_close(sync_pipe[PIPE_READ]);
821 ws_close(sync_pipe[PIPE_WRITE]);
822 return -1;
823 }
824
825 if ((*fork_child = fork()) == 0) {
826 /*
827 * Child process - run dumpcap with the right arguments to make
828 * it just capture with the specified capture parameters
829 */
830 dup2(data_pipe[PIPE_WRITE], 1);
831 ws_close(data_pipe[PIPE_READ]);
832 ws_close(data_pipe[PIPE_WRITE]);
833 dup2(sync_pipe[PIPE_WRITE], 2);
834 ws_close(sync_pipe[PIPE_READ]);
835 ws_close(sync_pipe[PIPE_WRITE]);
836 execv(argv[0], argv);
837 g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
838 argv[0], g_strerror(errno));
839 sync_pipe_errmsg_to_parent(2, errmsg, "");
840
841 /* Exit with "_exit()", so that we don't close the connection
842 to the X server (and cause stuff buffered up by our parent but
843 not yet sent to be sent, as that stuff should only be sent by
844 our parent). We've sent an error message to the parent, so
845 we exit with an exit status of 1 (any exit status other than
846 0 or 1 will cause an additional message to report that exit
847 status, over and above the error message we sent to the parent). */
848 _exit(1);
849 }
850
851 if (fetch_dumpcap_pid && *fork_child > 0)
852 fetch_dumpcap_pid(*fork_child);
853
854 *data_read_fd = data_pipe[PIPE_READ];
855 *message_read_fd = sync_pipe[PIPE_READ];
856 #endif
857
858 /* Parent process - read messages from the child process over the
859 sync pipe. */
860
861 /* Close the write sides of the pipes, so that only the child has them
862 open, and thus they completely close, and thus return to us
863 an EOF indication, if the child closes them (either deliberately
864 or by exiting abnormally). */
865 #ifdef _WIN32
866 CloseHandle(data_pipe[PIPE_WRITE]);
867 CloseHandle(sync_pipe[PIPE_WRITE]);
868 #else
869 ws_close(data_pipe[PIPE_WRITE]);
870 ws_close(sync_pipe[PIPE_WRITE]);
871 #endif
872
873 if (*fork_child == WS_INVALID_PID) {
874 /* We couldn't even create the child process. */
875 *msg = g_strdup_printf("Couldn't create child process: %s", g_strerror(errno));
876 ws_close(*data_read_fd);
877 ws_close(*message_read_fd);
878 return -1;
879 }
880
881 /* we might wait for a moment till child is ready, so update screen now */
882 if (update_cb) update_cb();
883 return 0;
884 }
885
886 /*
887 * Close the pipes we're using to read from dumpcap, and wait for it
888 * to exit. On success, *msgp is unchanged, and the exit status of
889 * dumpcap is returned. On failure (which includes "dumpcap exited
890 * due to being killed by a signal or an exception"), *msgp points
891 * to an error message for the failure, and -1 is returned. In the
892 * latter case, *msgp must be freed with g_free().
893 */
894 static int
sync_pipe_close_command(int * data_read_fd,int * message_read_fd,ws_process_id * fork_child,gchar ** msgp)895 sync_pipe_close_command(int *data_read_fd, int *message_read_fd,
896 ws_process_id *fork_child, gchar **msgp)
897 {
898 ws_close(*data_read_fd);
899 if (message_read_fd != NULL)
900 ws_close(*message_read_fd);
901
902 #ifdef _WIN32
903 /* XXX - Should we signal the child somehow? */
904 sync_pipe_kill(*fork_child);
905 #endif
906
907 return sync_pipe_wait_for_child(*fork_child, msgp);
908 }
909
910 /*
911 * Run dumpcap with the supplied arguments.
912 *
913 * On success, *data points to a buffer containing the dumpcap output,
914 * *primary_msg and *secondary_message are NULL, and 0 is returned; *data
915 * must be freed with g_free().
916 *
917 * On failure, *data is NULL, *primary_msg points to an error message,
918 * *secondary_msg either points to an additional error message or is
919 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
920 * must be freed with g_free().
921 */
922 /* XXX - This duplicates a lot of code in sync_pipe_start() */
923 /* XXX - assumes PIPE_BUF_SIZE > SP_MAX_MSG_LEN */
924 #define PIPE_BUF_SIZE 5120
925 static int
sync_pipe_run_command_actual(char * const argv[],gchar ** data,gchar ** primary_msg,gchar ** secondary_msg,void (* update_cb)(void))926 sync_pipe_run_command_actual(char* const argv[], gchar **data, gchar **primary_msg,
927 gchar **secondary_msg, void(*update_cb)(void))
928 {
929 gchar *msg;
930 int data_pipe_read_fd, sync_pipe_read_fd, ret;
931 ws_process_id fork_child;
932 char *wait_msg;
933 gchar buffer[PIPE_BUF_SIZE+1] = {0};
934 ssize_t nread;
935 char indicator;
936 int primary_msg_len;
937 char *primary_msg_text;
938 int secondary_msg_len;
939 char *secondary_msg_text;
940 char *combined_msg;
941 GString *data_buf = NULL;
942 ssize_t count;
943
944 ret = sync_pipe_open_command(argv, &data_pipe_read_fd, &sync_pipe_read_fd,
945 &fork_child, &msg, update_cb);
946 if (ret == -1) {
947 *primary_msg = msg;
948 *secondary_msg = NULL;
949 *data = NULL;
950 return -1;
951 }
952
953 /*
954 * We were able to set up to read dumpcap's output. Do so.
955 *
956 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
957 */
958 nread = pipe_read_block(sync_pipe_read_fd, &indicator, SP_MAX_MSG_LEN,
959 buffer, primary_msg);
960 if(nread <= 0) {
961 /* We got a read error from the sync pipe, or we got no data at
962 all from the sync pipe, so we're not going to be getting any
963 data or error message from the child process. Pick up its
964 exit status, and complain.
965
966 We don't have to worry about killing the child, if the sync pipe
967 returned an error. Usually this error is caused as the child killed
968 itself while going down. Even in the rare cases that this isn't the
969 case, the child will get an error when writing to the broken pipe
970 the next time, cleaning itself up then. */
971 ret = sync_pipe_wait_for_child(fork_child, &wait_msg);
972 if(nread == 0) {
973 /* We got an EOF from the sync pipe. That means that it exited
974 before giving us any data to read. If ret is -1, we report
975 that as a bad exit (e.g., exiting due to a signal); otherwise,
976 we report it as a premature exit. */
977 if (ret == -1)
978 *primary_msg = wait_msg;
979 else
980 *primary_msg = g_strdup("Child dumpcap closed sync pipe prematurely");
981 } else {
982 /* We got an error from the sync pipe. If ret is -1, report
983 both the sync pipe I/O error and the wait error. */
984 if (ret == -1) {
985 combined_msg = g_strdup_printf("%s\n\n%s", *primary_msg, wait_msg);
986 g_free(*primary_msg);
987 g_free(wait_msg);
988 *primary_msg = combined_msg;
989 }
990 }
991 *secondary_msg = NULL;
992 *data = NULL;
993
994 return -1;
995 }
996
997 /* we got a valid message block from the child, process it */
998 switch(indicator) {
999
1000 case SP_ERROR_MSG:
1001 /*
1002 * Error from dumpcap; there will be a primary message and a
1003 * secondary message.
1004 */
1005
1006 /* convert primary message */
1007 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1008 primary_msg_text = buffer+4;
1009 /* convert secondary message */
1010 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1011 &secondary_msg_len);
1012 secondary_msg_text = primary_msg_text + primary_msg_len + 4;
1013 /* the capture child will close the sync_pipe, nothing to do */
1014
1015 /*
1016 * Pick up the child status.
1017 */
1018 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1019 &fork_child, &msg);
1020 if (ret == -1) {
1021 /*
1022 * Child process failed unexpectedly, or wait failed; msg is the
1023 * error message.
1024 */
1025 *primary_msg = msg;
1026 *secondary_msg = NULL;
1027 } else {
1028 /*
1029 * Child process failed, but returned the expected exit status.
1030 * Return the messages it gave us, and indicate failure.
1031 */
1032 *primary_msg = g_strdup(primary_msg_text);
1033 *secondary_msg = g_strdup(secondary_msg_text);
1034 ret = -1;
1035 }
1036 *data = NULL;
1037 break;
1038
1039 case SP_SUCCESS:
1040 /* read the output from the command */
1041 data_buf = g_string_new("");
1042 while ((count = ws_read(data_pipe_read_fd, buffer, PIPE_BUF_SIZE)) > 0) {
1043 buffer[count] = '\0';
1044 g_string_append(data_buf, buffer);
1045 }
1046
1047 /*
1048 * Pick up the child status.
1049 */
1050 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1051 &fork_child, &msg);
1052 if (ret == -1) {
1053 /*
1054 * Child process failed unexpectedly, or wait failed; msg is the
1055 * error message.
1056 */
1057 *primary_msg = msg;
1058 *secondary_msg = NULL;
1059 g_string_free(data_buf, TRUE);
1060 *data = NULL;
1061 } else {
1062 /*
1063 * Child process succeeded.
1064 */
1065 *primary_msg = NULL;
1066 *secondary_msg = NULL;
1067 *data = g_string_free(data_buf, FALSE);
1068 }
1069 break;
1070
1071 default:
1072 /*
1073 * Pick up the child status.
1074 */
1075 ret = sync_pipe_close_command(&data_pipe_read_fd, &sync_pipe_read_fd,
1076 &fork_child, &msg);
1077 if (ret == -1) {
1078 /*
1079 * Child process failed unexpectedly, or wait failed; msg is the
1080 * error message.
1081 */
1082 *primary_msg = msg;
1083 *secondary_msg = NULL;
1084 } else {
1085 /*
1086 * Child process returned an unknown status.
1087 */
1088 *primary_msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1089 indicator);
1090 *secondary_msg = NULL;
1091 ret = -1;
1092 }
1093 *data = NULL;
1094 break;
1095 }
1096 return ret;
1097 }
1098
1099 /* centralised logging and timing for sync_pipe_run_command_actual(),
1100 * redirects to sync_pipe_run_command_actual()
1101 */
1102 static int
sync_pipe_run_command(char * const argv[],gchar ** data,gchar ** primary_msg,gchar ** secondary_msg,void (* update_cb)(void))1103 sync_pipe_run_command(char* const argv[], gchar **data, gchar **primary_msg,
1104 gchar **secondary_msg, void (*update_cb)(void))
1105 {
1106 int ret, i;
1107 gint64 start_time;
1108 double elapsed;
1109 int logging_enabled;
1110
1111 /* check if logging is actually enabled, otherwise don't expend the CPU generating logging */
1112 logging_enabled = ws_log_msg_is_active(WS_LOG_DOMAIN, LOG_LEVEL_INFO);
1113 if (logging_enabled) {
1114 start_time = g_get_monotonic_time();
1115 ws_info("sync_pipe_run_command() starts");
1116 for (i=0; argv[i] != 0; i++) {
1117 ws_debug(" argv[%d]: %s", i, argv[i]);
1118 }
1119 }
1120 /* do the actual sync pipe run command */
1121 ret = sync_pipe_run_command_actual(argv, data, primary_msg, secondary_msg, update_cb);
1122
1123 if (logging_enabled) {
1124 elapsed = (g_get_monotonic_time() - start_time) / 1e6;
1125
1126 ws_info("sync_pipe_run_command() ends, taking %.3fs, result=%d", elapsed, ret);
1127
1128 }
1129 return ret;
1130 }
1131
1132
1133 int
sync_interface_set_80211_chan(const gchar * iface,const char * freq,const gchar * type,const gchar * center_freq1,const gchar * center_freq2,gchar ** data,gchar ** primary_msg,gchar ** secondary_msg,void (* update_cb)(void))1134 sync_interface_set_80211_chan(const gchar *iface, const char *freq, const gchar *type,
1135 const gchar *center_freq1, const gchar *center_freq2,
1136 gchar **data, gchar **primary_msg,
1137 gchar **secondary_msg, void (*update_cb)(void))
1138 {
1139 int argc, ret;
1140 char **argv;
1141 gchar *opt;
1142
1143 argv = init_pipe_args(&argc);
1144
1145 if (!argv) {
1146 *primary_msg = g_strdup("We don't know where to find dumpcap.");
1147 *secondary_msg = NULL;
1148 *data = NULL;
1149 return -1;
1150 }
1151
1152 argv = sync_pipe_add_arg(argv, &argc, "-i");
1153 argv = sync_pipe_add_arg(argv, &argc, iface);
1154
1155 if (center_freq2)
1156 opt = g_strdup_printf("%s,%s,%s,%s", freq, type, center_freq1, center_freq2);
1157 else if (center_freq1)
1158 opt = g_strdup_printf("%s,%s,%s", freq, type, center_freq1);
1159 else if (type)
1160 opt = g_strdup_printf("%s,%s", freq, type);
1161 else
1162 opt = g_strdup(freq);
1163
1164 if (!opt) {
1165 *primary_msg = g_strdup("Out of mem.");
1166 *secondary_msg = NULL;
1167 *data = NULL;
1168 free_argv(argv, argc);
1169 return -1;
1170 }
1171
1172 argv = sync_pipe_add_arg(argv, &argc, "-k");
1173 argv = sync_pipe_add_arg(argv, &argc, opt);
1174
1175 #ifndef DEBUG_CHILD
1176 /* Run dumpcap in capture child mode */
1177 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1178 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1179 #endif
1180
1181 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1182 g_free(opt);
1183 free_argv(argv, argc);
1184 return ret;
1185 }
1186
1187 /*
1188 * Get the list of interfaces using dumpcap.
1189 *
1190 * On success, *data points to a buffer containing the dumpcap output,
1191 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1192 * must be freed with g_free().
1193 *
1194 * On failure, *data is NULL, *primary_msg points to an error message,
1195 * *secondary_msg either points to an additional error message or is
1196 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1197 * must be freed with g_free().
1198 */
1199 int
sync_interface_list_open(gchar ** data,gchar ** primary_msg,gchar ** secondary_msg,void (* update_cb)(void))1200 sync_interface_list_open(gchar **data, gchar **primary_msg,
1201 gchar **secondary_msg, void (*update_cb)(void))
1202 {
1203 int argc;
1204 char **argv;
1205 int ret;
1206
1207 ws_debug("sync_interface_list_open");
1208
1209 argv = init_pipe_args(&argc);
1210
1211 if (!argv) {
1212 *primary_msg = g_strdup("We don't know where to find dumpcap..");
1213 *secondary_msg = NULL;
1214 *data = NULL;
1215 return -1;
1216 }
1217
1218 /* Ask for the interface list */
1219 argv = sync_pipe_add_arg(argv, &argc, "-D");
1220
1221 #ifndef DEBUG_CHILD
1222 /* Run dumpcap in capture child mode */
1223 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1224 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1225 #endif
1226 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1227 free_argv(argv, argc);
1228 return ret;
1229 }
1230
1231 /*
1232 * Get the capabilities of an interface using dumpcap.
1233 *
1234 * On success, *data points to a buffer containing the dumpcap output,
1235 * *primary_msg and *secondary_msg are NULL, and 0 is returned. *data
1236 * must be freed with g_free().
1237 *
1238 * On failure, *data is NULL, *primary_msg points to an error message,
1239 * *secondary_msg either points to an additional error message or is
1240 * NULL, and -1 is returned; *primary_msg, and *secondary_msg if not NULL,
1241 * must be freed with g_free().
1242 */
1243 int
sync_if_capabilities_open(const gchar * ifname,gboolean monitor_mode,const gchar * auth,gchar ** data,gchar ** primary_msg,gchar ** secondary_msg,void (* update_cb)(void))1244 sync_if_capabilities_open(const gchar *ifname, gboolean monitor_mode, const gchar* auth,
1245 gchar **data, gchar **primary_msg,
1246 gchar **secondary_msg, void (*update_cb)(void))
1247 {
1248 int argc;
1249 char **argv;
1250 int ret;
1251
1252 ws_debug("sync_if_capabilities_open");
1253
1254 argv = init_pipe_args(&argc);
1255
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;
1261 }
1262
1263 /* Ask for the interface capabilities */
1264 argv = sync_pipe_add_arg(argv, &argc, "-i");
1265 argv = sync_pipe_add_arg(argv, &argc, ifname);
1266 argv = sync_pipe_add_arg(argv, &argc, "-L");
1267 argv = sync_pipe_add_arg(argv, &argc, "--list-time-stamp-types");
1268 if (monitor_mode)
1269 argv = sync_pipe_add_arg(argv, &argc, "-I");
1270 if (auth) {
1271 argv = sync_pipe_add_arg(argv, &argc, "-A");
1272 argv = sync_pipe_add_arg(argv, &argc, auth);
1273 }
1274
1275 #ifndef DEBUG_CHILD
1276 /* Run dumpcap in capture child mode */
1277 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1278 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1279 #endif
1280 ret = sync_pipe_run_command(argv, data, primary_msg, secondary_msg, update_cb);
1281 free_argv(argv, argc);
1282 return ret;
1283 }
1284
1285 /*
1286 * Start getting interface statistics using dumpcap. On success, read_fd
1287 * contains the file descriptor for the pipe's stdout, *msg is unchanged,
1288 * and zero is returned. On failure, *msg will point to an error message
1289 * that must be g_free()d, and -1 will be returned.
1290 */
1291 int
sync_interface_stats_open(int * data_read_fd,ws_process_id * fork_child,gchar ** msg,void (* update_cb)(void))1292 sync_interface_stats_open(int *data_read_fd, ws_process_id *fork_child, gchar **msg, void (*update_cb)(void))
1293 {
1294 int argc;
1295 char **argv;
1296 int message_read_fd, ret;
1297 char *wait_msg;
1298 gchar buffer[PIPE_BUF_SIZE+1] = {0};
1299 ssize_t nread;
1300 char indicator;
1301 int primary_msg_len;
1302 char *primary_msg_text;
1303 int secondary_msg_len;
1304 /*char *secondary_msg_text;*/
1305 char *combined_msg;
1306
1307 ws_debug("sync_interface_stats_open");
1308
1309 argv = init_pipe_args(&argc);
1310
1311 if (!argv) {
1312 *msg = g_strdup("We don't know where to find dumpcap.");
1313 return -1;
1314 }
1315
1316 /* Ask for the interface statistics */
1317 argv = sync_pipe_add_arg(argv, &argc, "-S");
1318
1319 #ifndef DEBUG_CHILD
1320 argv = sync_pipe_add_arg(argv, &argc, "-Z");
1321 #ifdef _WIN32
1322 create_dummy_signal_pipe();
1323 argv = sync_pipe_add_arg(argv, &argc, dummy_control_id);
1324 #else
1325 argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
1326 #endif
1327 #endif
1328 ret = sync_pipe_open_command(argv, data_read_fd, &message_read_fd,
1329 fork_child, msg, update_cb);
1330 free_argv(argv, argc);
1331 if (ret == -1) {
1332 return -1;
1333 }
1334
1335 /*
1336 * We were able to set up to read dumpcap's output. Do so.
1337 *
1338 * First, wait for an SP_ERROR_MSG message or SP_SUCCESS message.
1339 */
1340 nread = pipe_read_block(message_read_fd, &indicator, SP_MAX_MSG_LEN,
1341 buffer, msg);
1342 if(nread <= 0) {
1343 /* We got a read error from the sync pipe, or we got no data at
1344 all from the sync pipe, so we're not going to be getting any
1345 data or error message from the child process. Pick up its
1346 exit status, and complain.
1347
1348 We don't have to worry about killing the child, if the sync pipe
1349 returned an error. Usually this error is caused as the child killed
1350 itself while going down. Even in the rare cases that this isn't the
1351 case, the child will get an error when writing to the broken pipe
1352 the next time, cleaning itself up then. */
1353 ret = sync_pipe_wait_for_child(*fork_child, &wait_msg);
1354 ws_close(message_read_fd);
1355 ws_close(*data_read_fd);
1356 if(nread == 0) {
1357 /* We got an EOF from the sync pipe. That means that it exited
1358 before giving us any data to read. If ret is -1, we report
1359 that as a bad exit (e.g., exiting due to a signal); otherwise,
1360 we report it as a premature exit. */
1361 if (ret == -1)
1362 *msg = wait_msg;
1363 else
1364 *msg = g_strdup("Child dumpcap closed sync pipe prematurely");
1365 } else {
1366 /* We got an error from the sync pipe. If ret is -1, report
1367 both the sync pipe I/O error and the wait error. */
1368 if (ret == -1) {
1369 combined_msg = g_strdup_printf("%s\n\n%s", *msg, wait_msg);
1370 g_free(*msg);
1371 g_free(wait_msg);
1372 *msg = combined_msg;
1373 }
1374 }
1375 return -1;
1376 }
1377
1378 /* we got a valid message block from the child, process it */
1379 switch(indicator) {
1380
1381 case SP_ERROR_MSG:
1382 /*
1383 * Error from dumpcap; there will be a primary message and a
1384 * secondary message.
1385 */
1386
1387 /* convert primary message */
1388 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_msg_len);
1389 primary_msg_text = buffer+4;
1390 /* convert secondary message */
1391 pipe_convert_header((guchar*)primary_msg_text + primary_msg_len, 4, &indicator,
1392 &secondary_msg_len);
1393 /*secondary_msg_text = primary_msg_text + primary_msg_len + 4;*/
1394 /* the capture child will close the sync_pipe, nothing to do */
1395
1396 /*
1397 * Pick up the child status.
1398 */
1399 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1400 fork_child, msg);
1401 if (ret == -1) {
1402 /*
1403 * Child process failed unexpectedly, or wait failed; msg is the
1404 * error message.
1405 */
1406 } else {
1407 /*
1408 * Child process failed, but returned the expected exit status.
1409 * Return the messages it gave us, and indicate failure.
1410 */
1411 *msg = g_strdup(primary_msg_text);
1412 ret = -1;
1413 }
1414 break;
1415
1416 case SP_SUCCESS:
1417 /* Close the message pipe. */
1418 ws_close(message_read_fd);
1419 break;
1420
1421 default:
1422 /*
1423 * Pick up the child status.
1424 */
1425 ret = sync_pipe_close_command(data_read_fd, &message_read_fd,
1426 fork_child, msg);
1427 if (ret == -1) {
1428 /*
1429 * Child process failed unexpectedly, or wait failed; msg is the
1430 * error message.
1431 */
1432 } else {
1433 /*
1434 * Child process returned an unknown status.
1435 */
1436 *msg = g_strdup_printf("dumpcap process gave an unexpected message type: 0x%02x",
1437 indicator);
1438 ret = -1;
1439 }
1440 break;
1441 }
1442 return ret;
1443 }
1444
1445 /* Close down the stats process */
1446 int
sync_interface_stats_close(int * read_fd,ws_process_id * fork_child,gchar ** msg)1447 sync_interface_stats_close(int *read_fd, ws_process_id *fork_child, gchar **msg)
1448 {
1449 #ifndef _WIN32
1450 /*
1451 * Don't bother waiting for the child. sync_pipe_close_command
1452 * does this for us on Windows.
1453 */
1454 sync_pipe_kill(*fork_child);
1455 #endif
1456 return sync_pipe_close_command(read_fd, NULL, fork_child, msg);
1457 }
1458
1459 /* read a number of bytes from a pipe */
1460 /* (blocks until enough bytes read or an error occurs) */
1461 static ssize_t
pipe_read_bytes(int pipe_fd,char * bytes,int required,char ** msg)1462 pipe_read_bytes(int pipe_fd, char *bytes, int required, char **msg)
1463 {
1464 ssize_t newly;
1465 ssize_t offset = 0;
1466 int error;
1467
1468 while(required) {
1469 newly = ws_read(pipe_fd, &bytes[offset], required);
1470 if (newly == 0) {
1471 /* EOF */
1472 ws_debug("read from pipe %d: EOF (capture closed?)", pipe_fd);
1473 *msg = 0;
1474 return offset;
1475 }
1476 if (newly < 0) {
1477 /* error */
1478 error = errno;
1479 ws_debug("read from pipe %d: error(%u): %s", pipe_fd, error, g_strerror(error));
1480 *msg = g_strdup_printf("Error reading from sync pipe: %s",
1481 g_strerror(error));
1482 return newly;
1483 }
1484
1485 required -= (int)newly;
1486 offset += newly;
1487 }
1488
1489 *msg = NULL;
1490 return offset;
1491 }
1492
1493 /*
1494 * Read a line from a pipe; similar to fgets, but doesn't block.
1495 *
1496 * XXX - just stops reading if there's nothing to be read right now;
1497 * that could conceivably mean that you don't get a complete line.
1498 */
1499 int
sync_pipe_gets_nonblock(int pipe_fd,char * bytes,int max)1500 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1501 ssize_t newly;
1502 int offset = -1;
1503
1504 while(offset < max - 1) {
1505 offset++;
1506 if (! ws_pipe_data_available(pipe_fd))
1507 break;
1508 newly = ws_read(pipe_fd, &bytes[offset], 1);
1509 if (newly == 0) {
1510 /* EOF - not necessarily an error */
1511 break;
1512 } else if (newly == -1) {
1513 /* error */
1514 ws_debug("read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1515 return -1;
1516 } else if (bytes[offset] == '\n') {
1517 break;
1518 }
1519 }
1520
1521 if (offset >= 0)
1522 bytes[offset] = '\0';
1523
1524 return offset;
1525 }
1526
1527
1528 /* convert header values (indicator and 3-byte length) */
1529 static void
pipe_convert_header(const guchar * header,int header_len _U_,char * indicator,int * block_len)1530 pipe_convert_header(const guchar *header, int header_len _U_, char *indicator, int *block_len) {
1531
1532 ws_assert(header_len == 4);
1533
1534 /* convert header values */
1535 *indicator = header[0];
1536 *block_len = (header[1]&0xFF)<<16 | (header[2]&0xFF)<<8 | (header[3]&0xFF);
1537 }
1538
1539 /* read a message from the sending pipe in the standard format
1540 (1-byte message indicator, 3-byte message length (excluding length
1541 and indicator field), and the rest is the message) */
1542 static ssize_t
pipe_read_block(int pipe_fd,char * indicator,int len,char * msg,char ** err_msg)1543 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg,
1544 char **err_msg)
1545 {
1546 int required;
1547 ssize_t newly;
1548 gchar header[4];
1549
1550 /* read header (indicator and 3-byte length) */
1551 newly = pipe_read_bytes(pipe_fd, header, 4, err_msg);
1552 if(newly != 4) {
1553 if (newly == 0) {
1554 /*
1555 * Immediate EOF; if the capture child exits normally, this
1556 * is an "I'm done" indication, so don't report it as an
1557 * error.
1558 */
1559 ws_debug("read %d got an EOF", pipe_fd);
1560 return 0;
1561 }
1562 ws_debug("read %d failed to read header: %lu", pipe_fd, (long)newly);
1563 if (newly != -1) {
1564 /*
1565 * Short read, but not an immediate EOF.
1566 */
1567 *err_msg = g_strdup_printf("Premature EOF reading from sync pipe: got only %ld bytes",
1568 (long)newly);
1569 }
1570 return -1;
1571 }
1572
1573 /* convert header values */
1574 pipe_convert_header((guchar*)header, 4, indicator, &required);
1575
1576 /* only indicator with no value? */
1577 if(required == 0) {
1578 ws_debug("read %d indicator: %c empty value", pipe_fd, *indicator);
1579 return 4;
1580 }
1581
1582 /* does the data fit into the given buffer? */
1583 if(required > len) {
1584 ws_debug("read %d length error, required %d > len %d, header: 0x%02x 0x%02x 0x%02x 0x%02x",
1585 pipe_fd, required, len,
1586 header[0], header[1], header[2], header[3]);
1587
1588 /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1589 memcpy(msg, header, sizeof(header));
1590 newly = ws_read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1591 if (newly < 0) { /* error */
1592 ws_debug("read from pipe %d: error(%u): %s", pipe_fd, errno, g_strerror(errno));
1593 }
1594 *err_msg = g_strdup_printf("Unknown message from dumpcap reading header, try to show it as a string: %s",
1595 msg);
1596 return -1;
1597 }
1598 len = required;
1599
1600 /* read the actual block data */
1601 newly = pipe_read_bytes(pipe_fd, msg, required, err_msg);
1602 if(newly != required) {
1603 if (newly != -1) {
1604 *err_msg = g_strdup_printf("Unknown message from dumpcap reading data, try to show it as a string: %s",
1605 msg);
1606 }
1607 return -1;
1608 }
1609
1610 /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1611 ws_debug("read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator, len, msg);
1612 *err_msg = NULL;
1613 return newly + 4;
1614 }
1615
1616
1617 /* There's stuff to read from the sync pipe, meaning the child has sent
1618 us a message, or the sync pipe has closed, meaning the child has
1619 closed it (perhaps because it exited). */
1620 static gboolean
sync_pipe_input_cb(gint source,gpointer user_data)1621 sync_pipe_input_cb(gint source, gpointer user_data)
1622 {
1623 capture_session *cap_session = (capture_session *)user_data;
1624 int ret;
1625 char buffer[SP_MAX_MSG_LEN+1] = {0};
1626 ssize_t nread;
1627 char indicator;
1628 int primary_len;
1629 char *primary_msg;
1630 int secondary_len;
1631 char *secondary_msg;
1632 char *wait_msg, *combined_msg;
1633 guint32 npackets = 0;
1634
1635 nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer,
1636 &primary_msg);
1637 if(nread <= 0) {
1638 /* We got a read error, or a bad message, or an EOF, from the sync pipe.
1639
1640 If we got a read error or a bad message, nread is -1 and
1641 primary_msg is set to point to an error message. We don't
1642 have to worry about killing the child; usually this error
1643 is caused as the child killed itself while going down.
1644 Even in the rare cases that this isn't the case, the child
1645 will get an error when writing to the broken pipe the next time,
1646 cleaning itself up then.
1647
1648 If we got an EOF, nread is 0 and primary_msg isn't set. This
1649 is an indication that the capture is finished. */
1650 ret = sync_pipe_wait_for_child(cap_session->fork_child, &wait_msg);
1651 if(nread == 0) {
1652 /* We got an EOF from the sync pipe. That means that the capture
1653 child exited, and not in the middle of a message; we treat
1654 that as an indication that it's done, and only report an
1655 error if ret is -1, in which case wait_msg is the error
1656 message. */
1657 if (ret == -1)
1658 primary_msg = wait_msg;
1659 } else {
1660 /* We got an error from the sync pipe. If ret is -1, report
1661 both the sync pipe I/O error and the wait error. */
1662 if (ret == -1) {
1663 combined_msg = g_strdup_printf("%s\n\n%s", primary_msg, wait_msg);
1664 g_free(primary_msg);
1665 g_free(wait_msg);
1666 primary_msg = combined_msg;
1667 }
1668 }
1669
1670 /* No more child process. */
1671 cap_session->fork_child = WS_INVALID_PID;
1672 cap_session->fork_child_status = ret;
1673
1674 #ifdef _WIN32
1675 ws_close(cap_session->signal_pipe_write_fd);
1676 #endif
1677 ws_debug("cleaning extcap pipe");
1678 extcap_if_cleanup(cap_session->capture_opts, &primary_msg);
1679 cap_session->closed(cap_session, primary_msg);
1680 g_free(primary_msg);
1681 return FALSE;
1682 }
1683
1684 /* we got a valid message block from the child, process it */
1685 switch(indicator) {
1686 case SP_FILE:
1687 if(!cap_session->new_file(cap_session, buffer)) {
1688 ws_debug("file failed, closing capture");
1689
1690 /* We weren't able to open the new capture file; user has been
1691 alerted. Close the sync pipe. */
1692 ws_close(source);
1693
1694 /* The child has sent us a filename which we couldn't open.
1695
1696 This could mean that the child is creating and deleting files
1697 (ring buffer mode) faster than we can handle it.
1698
1699 That should only be the case for very fast file switches;
1700 We can't do much more than telling the child to stop.
1701 (This is the "emergency brake" if the user e.g. wants to
1702 switch files every second).
1703
1704 This can also happen if the user specified "-", meaning
1705 "standard output", as the capture file. */
1706 sync_pipe_stop(cap_session);
1707 cap_session->closed(cap_session, NULL);
1708 return FALSE;
1709 }
1710 break;
1711 case SP_PACKET_COUNT:
1712 if (!ws_strtou32(buffer, NULL, &npackets)) {
1713 ws_warning("Invalid packets number: %s", buffer);
1714 }
1715 ws_debug("new packets %u", npackets);
1716 cap_session->count += npackets;
1717 cap_session->new_packets(cap_session, npackets);
1718 break;
1719 case SP_ERROR_MSG:
1720 /* convert primary message */
1721 pipe_convert_header((guchar*)buffer, 4, &indicator, &primary_len);
1722 primary_msg = buffer+4;
1723 /* convert secondary message */
1724 pipe_convert_header((guchar*)primary_msg + primary_len, 4, &indicator, &secondary_len);
1725 secondary_msg = primary_msg + primary_len + 4;
1726 /* message output */
1727 cap_session->error(cap_session, primary_msg, secondary_msg);
1728 /* the capture child will close the sync_pipe, nothing to do for now */
1729 /* (an error message doesn't mean we have to stop capturing) */
1730 break;
1731 case SP_BAD_FILTER: {
1732 const char *message=NULL;
1733 guint32 indx = 0;
1734 const gchar* end;
1735
1736 if (ws_strtou32(buffer, &end, &indx) && end[0] == ':') {
1737 message = end + 1;
1738 }
1739
1740 cap_session->cfilter_error(cap_session, indx, message);
1741 /* the capture child will close the sync_pipe, nothing to do for now */
1742 break;
1743 }
1744 case SP_DROPS: {
1745 const char *name = NULL;
1746 const gchar* end;
1747 guint32 num = 0;
1748
1749 if (ws_strtou32(buffer, &end, &num) && end[0] == ':') {
1750 name = end + 1;
1751 }
1752
1753 cap_session->drops(cap_session, num, name);
1754 break;
1755 }
1756 default:
1757 ws_assert_not_reached();
1758 }
1759
1760 return TRUE;
1761 }
1762
1763
1764
1765 /*
1766 * dumpcap is exiting; wait for it to exit. On success, *msgp is
1767 * unchanged, and the exit status of dumpcap is returned. On
1768 * failure (which includes "dumpcap exited due to being killed by
1769 * a signal or an exception"), *msgp points to an error message
1770 * for the failure, and -1 is returned. In the latter case, *msgp
1771 * must be freed with g_free().
1772 */
1773 static int
sync_pipe_wait_for_child(ws_process_id fork_child,gchar ** msgp)1774 sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
1775 {
1776 int fork_child_status;
1777 #ifndef _WIN32
1778 int retry_waitpid = 3;
1779 #endif
1780 int ret = -1;
1781 gint64 start_time;
1782 double elapsed;
1783
1784 start_time = g_get_monotonic_time();
1785
1786 ws_debug("wait till child closed");
1787 ws_assert(fork_child != WS_INVALID_PID);
1788
1789 *msgp = NULL; /* assume no error */
1790 #ifdef _WIN32
1791 if (_cwait(&fork_child_status, (intptr_t) fork_child, _WAIT_CHILD) == -1) {
1792 *msgp = g_strdup_printf("Error from cwait(): %s", g_strerror(errno));
1793 ret = -1;
1794 } else {
1795 /*
1796 * The child exited; return its exit status. Do not treat this as
1797 * an error.
1798 */
1799 ret = fork_child_status;
1800 if ((fork_child_status & 0xC0000000) == ERROR_SEVERITY_ERROR) {
1801 /* Probably an exception code */
1802 *msgp = g_strdup_printf("Child dumpcap process died: %s",
1803 win32strexception(fork_child_status));
1804 ret = -1;
1805 }
1806 }
1807 #else
1808 while (--retry_waitpid >= 0) {
1809 if (waitpid(fork_child, &fork_child_status, 0) != -1) {
1810 /* waitpid() succeeded */
1811 if (WIFEXITED(fork_child_status)) {
1812 /*
1813 * The child exited; return its exit status. Do not treat this as
1814 * an error.
1815 */
1816 ret = WEXITSTATUS(fork_child_status);
1817 } else if (WIFSTOPPED(fork_child_status)) {
1818 /* It stopped, rather than exiting. "Should not happen." */
1819 *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
1820 sync_pipe_signame(WSTOPSIG(fork_child_status)));
1821 ret = -1;
1822 } else if (WIFSIGNALED(fork_child_status)) {
1823 /* It died with a signal. */
1824 *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
1825 sync_pipe_signame(WTERMSIG(fork_child_status)),
1826 WCOREDUMP(fork_child_status) ? " - core dumped" : "");
1827 ret = -1;
1828 } else {
1829 /* What? It had to either have exited, or stopped, or died with
1830 a signal; what happened here? */
1831 *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
1832 fork_child_status);
1833 ret = -1;
1834 }
1835 } else {
1836 /* waitpid() failed */
1837 if (errno == EINTR) {
1838 /*
1839 * Signal interrupted waitpid().
1840 *
1841 * If it's SIGALRM, we just want to keep waiting, in case
1842 * there's some timer using it (e.g., in a GUI toolkit).
1843 *
1844 * If you ^C TShark (or Wireshark), that should deliver
1845 * SIGINT to dumpcap as well. dumpcap catches SIGINT,
1846 * and should clean up and exit, so we should eventually
1847 * see that and clean up and terminate.
1848 *
1849 * If we're sent a SIGTERM, we should (and do) catch it,
1850 * and TShark, at least, calls sync_pipe_stop(). which
1851 * kills dumpcap, so we should eventually see that and
1852 * clean up and terminate.
1853 */
1854 ws_warning("waitpid returned EINTR. retrying.");
1855 continue;
1856 } else if (errno == ECHILD) {
1857 /*
1858 * The process identified by fork_child either doesn't
1859 * exist any more or isn't our child process (anymore?).
1860 *
1861 * echld might have already reaped the child.
1862 */
1863 ret = fetch_dumpcap_pid ? 0 : -1;
1864 } else {
1865 /* Unknown error. */
1866 *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
1867 ret = -1;
1868 }
1869 }
1870 break;
1871 }
1872 #endif
1873
1874 elapsed = (g_get_monotonic_time() - start_time) / 1e6;
1875 ws_debug("capture child closed after %.3fs", elapsed);
1876 return ret;
1877 }
1878
1879
1880 #ifndef _WIN32
1881 /* convert signal to corresponding name */
1882 static const char *
sync_pipe_signame(int sig)1883 sync_pipe_signame(int sig)
1884 {
1885 const char *sigmsg;
1886 static char sigmsg_buf[6+1+3+1];
1887
1888 switch (sig) {
1889
1890 case SIGHUP:
1891 sigmsg = "Hangup";
1892 break;
1893
1894 case SIGINT:
1895 sigmsg = "Interrupted";
1896 break;
1897
1898 case SIGQUIT:
1899 sigmsg = "Quit";
1900 break;
1901
1902 case SIGILL:
1903 sigmsg = "Illegal instruction";
1904 break;
1905
1906 case SIGTRAP:
1907 sigmsg = "Trace trap";
1908 break;
1909
1910 case SIGABRT:
1911 sigmsg = "Abort";
1912 break;
1913
1914 case SIGFPE:
1915 sigmsg = "Arithmetic exception";
1916 break;
1917
1918 case SIGKILL:
1919 sigmsg = "Killed";
1920 break;
1921
1922 case SIGBUS:
1923 sigmsg = "Bus error";
1924 break;
1925
1926 case SIGSEGV:
1927 sigmsg = "Segmentation violation";
1928 break;
1929
1930 /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1931 Linux is POSIX compliant. These are not POSIX-defined signals ---
1932 ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1933
1934 ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1935 were omitted from POSIX.1 because their behavior is
1936 implementation dependent and could not be adequately catego-
1937 rized. Conforming implementations may deliver these sig-
1938 nals, but must document the circumstances under which they
1939 are delivered and note any restrictions concerning their
1940 delivery.''
1941
1942 So we only check for SIGSYS on those systems that happen to
1943 implement them (a system can be POSIX-compliant and implement
1944 them, it's just that POSIX doesn't *require* a POSIX-compliant
1945 system to implement them).
1946 */
1947
1948 #ifdef SIGSYS
1949 case SIGSYS:
1950 sigmsg = "Bad system call";
1951 break;
1952 #endif
1953
1954 case SIGPIPE:
1955 sigmsg = "Broken pipe";
1956 break;
1957
1958 case SIGALRM:
1959 sigmsg = "Alarm clock";
1960 break;
1961
1962 case SIGTERM:
1963 sigmsg = "Terminated";
1964 break;
1965
1966 default:
1967 /* Returning a static buffer is ok in the context we use it here */
1968 g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1969 sigmsg = sigmsg_buf;
1970 break;
1971 }
1972 return sigmsg;
1973 }
1974 #endif
1975
1976
1977 #ifdef _WIN32
1978
create_dummy_signal_pipe()1979 static void create_dummy_signal_pipe() {
1980 gchar *dummy_signal_pipe_name;
1981
1982 if (dummy_signal_pipe != NULL) return;
1983
1984 if (!dummy_control_id) {
1985 dummy_control_id = g_strdup_printf("%d.dummy", GetCurrentProcessId());
1986 }
1987
1988 /* Create the signal pipe */
1989 dummy_signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, dummy_control_id);
1990 dummy_signal_pipe = CreateNamedPipe(utf_8to16(dummy_signal_pipe_name),
1991 PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
1992 g_free(dummy_signal_pipe_name);
1993 }
1994
1995 /* tell the child through the signal pipe that we want to quit the capture */
1996 static void
signal_pipe_capquit_to_child(capture_session * cap_session)1997 signal_pipe_capquit_to_child(capture_session *cap_session)
1998 {
1999 const char quit_msg[] = "QUIT";
2000 int ret;
2001
2002 ws_debug("signal_pipe_capquit_to_child");
2003
2004 /* it doesn't matter *what* we send here, the first byte will stop the capture */
2005 /* simply sending a "QUIT" string */
2006 /*pipe_write_block(cap_session->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
2007 ret = ws_write(cap_session->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
2008 if(ret == -1) {
2009 ws_warning("%d header: error %s", cap_session->signal_pipe_write_fd, g_strerror(errno));
2010 }
2011 }
2012 #endif
2013
2014
2015 /* user wants to stop the capture run */
2016 void
sync_pipe_stop(capture_session * cap_session)2017 sync_pipe_stop(capture_session *cap_session)
2018 {
2019 #ifdef _WIN32
2020 int count;
2021 DWORD childstatus;
2022 gboolean terminate = TRUE;
2023 #endif
2024 if (cap_session->fork_child != WS_INVALID_PID) {
2025 #ifndef _WIN32
2026 /* send the SIGINT signal to close the capture child gracefully. */
2027 int sts = kill(cap_session->fork_child, SIGINT);
2028 if (sts != 0) {
2029 ws_warning("Sending SIGINT to child failed: %s\n", g_strerror(errno));
2030 }
2031 #else
2032 #define STOP_SLEEP_TIME 500 /* ms */
2033 #define STOP_CHECK_TIME 50
2034 /* First, use the special signal pipe to try to close the capture child
2035 * gracefully.
2036 */
2037 signal_pipe_capquit_to_child(cap_session);
2038
2039 /* Next, wait for the process to exit on its own */
2040 for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
2041 if (GetExitCodeProcess((HANDLE) cap_session->fork_child, &childstatus) &&
2042 childstatus != STILL_ACTIVE) {
2043 terminate = FALSE;
2044 break;
2045 }
2046 Sleep(STOP_CHECK_TIME);
2047 }
2048
2049 /* Force the issue. */
2050 if (terminate) {
2051 ws_warning("sync_pipe_stop: forcing child to exit");
2052 sync_pipe_kill(cap_session->fork_child);
2053 }
2054 #endif
2055 }
2056 }
2057
2058
2059 /* Wireshark has to exit, force the capture child to close */
2060 void
sync_pipe_kill(ws_process_id fork_child)2061 sync_pipe_kill(ws_process_id fork_child)
2062 {
2063 if (fork_child != WS_INVALID_PID) {
2064 #ifndef _WIN32
2065 int sts = kill(fork_child, SIGTERM); /* SIGTERM so it can clean up if necessary */
2066 if (sts != 0) {
2067 ws_warning("Sending SIGTERM to child failed: %s\n", g_strerror(errno));
2068 }
2069 #else
2070 /* Remark: This is not the preferred method of closing a process!
2071 * the clean way would be getting the process id of the child process,
2072 * then getting window handle hWnd of that process (using EnumChildWindows),
2073 * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
2074 *
2075 * Unfortunately, I don't know how to get the process id from the
2076 * handle. OpenProcess will get an handle (not a window handle)
2077 * from the process ID; it will not get a window handle from the
2078 * process ID. (How could it? A process can have more than one
2079 * window. For that matter, a process might have *no* windows,
2080 * as a process running dumpcap, the normal child process program,
2081 * probably does.)
2082 *
2083 * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
2084 * running in the same console; that's not necessarily the case for
2085 * us, as we might not be running in a console.
2086 * And this also will require to have the process id.
2087 */
2088 TerminateProcess((HANDLE) (fork_child), 0);
2089
2090 #endif
2091 }
2092 }
2093
capture_sync_set_fetch_dumpcap_pid_cb(void (* cb)(ws_process_id pid))2094 void capture_sync_set_fetch_dumpcap_pid_cb(void(*cb)(ws_process_id pid)) {
2095 fetch_dumpcap_pid = cb;
2096 }
2097
2098 #endif /* HAVE_LIBPCAP */
2099