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