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