Update value strings.
[metze/wireshark/wip.git] / capture_sync.c
1 /* capture_sync.c
2  * Synchronisation between Wireshark capture parent and child instances
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <glib.h>
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <string.h>
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #ifdef HAVE_FCNTL_H
41 #include <fcntl.h>
42 #endif
43
44 #include <signal.h>
45
46 #ifdef _WIN32
47 #include <wsutil/unicode-utils.h>
48 #endif
49
50 #ifdef HAVE_SYS_WAIT_H
51 # include <sys/wait.h>
52 #endif
53
54 #include "capture-pcap-util.h"
55
56 #ifndef _WIN32
57 /*
58  * Define various POSIX macros (and, in the case of WCOREDUMP, non-POSIX
59  * macros) on UNIX systems that don't have them.
60  */
61 #ifndef WIFEXITED
62 # define WIFEXITED(status)      (((status) & 0177) == 0)
63 #endif
64 #ifndef WIFSTOPPED
65 # define WIFSTOPPED(status)     (((status) & 0177) == 0177)
66 #endif
67 #ifndef WIFSIGNALED
68 # define WIFSIGNALED(status)    (!WIFSTOPPED(status) && !WIFEXITED(status))
69 #endif
70 #ifndef WEXITSTATUS
71 # define WEXITSTATUS(status)    ((status) >> 8)
72 #endif
73 #ifndef WTERMSIG
74 # define WTERMSIG(status)       ((status) & 0177)
75 #endif
76 #ifndef WCOREDUMP
77 # define WCOREDUMP(status)      ((status) & 0200)
78 #endif
79 #ifndef WSTOPSIG
80 # define WSTOPSIG(status)       ((status) >> 8)
81 #endif
82 #endif /* _WIN32 */
83
84 #include <epan/packet.h>
85 #include <epan/prefs.h>
86
87 #include "globals.h"
88 #include "file.h"
89 #include <epan/filesystem.h>
90 #include <epan/report_err.h>
91
92 #include "capture.h"
93 #include "capture_sync.h"
94
95 #include "sync_pipe.h"
96
97 #ifdef _WIN32
98 #include "capture-wpcap.h"
99 #endif
100 #include "ui_util.h"
101 #include <wsutil/file_util.h>
102 #include "log.h"
103
104 #ifdef _WIN32
105 #include <process.h>    /* For spawning child process */
106 #endif
107
108
109
110 #ifndef _WIN32
111 static const char *sync_pipe_signame(int);
112 #endif
113
114
115 static gboolean sync_pipe_input_cb(gint source, gpointer user_data);
116 static void sync_pipe_wait_for_child(capture_options *capture_opts);
117
118
119
120 /* Append an arg (realloc) to an argc/argv array */
121 /* (add a string pointer to a NULL-terminated array of string pointers) */
122 static const char **
123 sync_pipe_add_arg(const char **args, int *argc, const char *arg)
124 {
125   /* Grow the array; "*argc" currently contains the number of string
126      pointers, *not* counting the NULL pointer at the end, so we have
127      to add 2 in order to get the new size of the array, including the
128      new pointer and the terminating NULL pointer. */
129   args = g_realloc( (gpointer) args, (*argc + 2) * sizeof (char *));
130
131   /* Stuff the pointer into the penultimate element of the array, which
132      is the one at the index specified by "*argc". */
133   args[*argc] = arg;
134
135   /* Now bump the count. */
136   (*argc)++;
137
138   /* We overwrite the NULL pointer; put it back right after the
139      element we added. */
140   args[*argc] = NULL;
141
142   return args;
143 }
144
145
146
147 #ifdef _WIN32
148 /* Quote the argument element if necessary, so that it will get
149  * reconstructed correctly in the C runtime startup code.  Note that
150  * the unquoting algorithm in the C runtime is really weird, and
151  * rather different than what Unix shells do. See stdargv.c in the C
152  * runtime sources (in the Platform SDK, in src/crt).
153  *
154  * Stolen from GLib's protect_argv(), an internal routine that quotes
155  * string in an argument list so that they arguments will be handled
156  * correctly in the command-line string passed to CreateProcess()
157  * if that string is constructed by gluing those strings together.
158  */
159 static gchar *
160 protect_arg (const gchar *argv)
161 {
162     gchar *new_arg;
163     const gchar *p = argv;
164     gchar *q;
165     gint len = 0;
166     gboolean need_dblquotes = FALSE;
167
168     while (*p) {
169         if (*p == ' ' || *p == '\t')
170             need_dblquotes = TRUE;
171         else if (*p == '"')
172             len++;
173         else if (*p == '\\') {
174             const gchar *pp = p;
175
176             while (*pp && *pp == '\\')
177                 pp++;
178             if (*pp == '"')
179                 len++;
180         }
181         len++;
182         p++;
183     }
184
185     q = new_arg = g_malloc (len + need_dblquotes*2 + 1);
186     p = argv;
187
188     if (need_dblquotes)
189         *q++ = '"';
190
191     while (*p) {
192         if (*p == '"')
193             *q++ = '\\';
194         else if (*p == '\\') {
195             const gchar *pp = p;
196
197             while (*pp && *pp == '\\')
198                 pp++;
199             if (*pp == '"')
200                 *q++ = '\\';
201         }
202         *q++ = *p;
203         p++;
204     }
205
206     if (need_dblquotes)
207         *q++ = '"';
208     *q++ = '\0';
209
210     return new_arg;
211 }
212 #endif
213
214 /* Initialize an argument list and add dumpcap to it. */
215 static const char **
216 init_pipe_args(int *argc) {
217     const char **argv;
218     const char *progfile_dir;
219     char *exename;
220
221     progfile_dir = get_progfile_dir();
222     if (progfile_dir == NULL) {
223       return NULL;
224     }
225
226     /* Allocate the string pointer array with enough space for the
227        terminating NULL pointer. */
228     *argc = 0;
229     argv = g_malloc(sizeof (char *));
230     *argv = NULL;
231
232     /* take Wireshark's absolute program path and replace "Wireshark" with "dumpcap" */
233     exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
234
235     /* Make that the first argument in the argument list (argv[0]). */
236     argv = sync_pipe_add_arg(argv, argc, exename);
237
238     return argv;
239 }
240
241 #define ARGV_NUMBER_LEN 24
242 /* a new capture run: start a new dumpcap task and hand over parameters through command line */
243 gboolean
244 sync_pipe_start(capture_options *capture_opts) {
245     char ssnap[ARGV_NUMBER_LEN];
246     char sdlt[ARGV_NUMBER_LEN];
247     char scount[ARGV_NUMBER_LEN];
248     char sfilesize[ARGV_NUMBER_LEN];
249     char sfile_duration[ARGV_NUMBER_LEN];
250     char sring_num_files[ARGV_NUMBER_LEN];
251     char sautostop_files[ARGV_NUMBER_LEN];
252     char sautostop_filesize[ARGV_NUMBER_LEN];
253     char sautostop_duration[ARGV_NUMBER_LEN];
254 #ifdef HAVE_PCAP_REMOTE
255     char sauth[256];
256 #endif
257 #ifdef HAVE_PCAP_SETSAMPLING
258     char ssampling[ARGV_NUMBER_LEN];
259 #endif
260 #ifdef _WIN32
261     char buffer_size[ARGV_NUMBER_LEN];
262     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
263     HANDLE sync_pipe_write;                 /* pipe used to send messages from child to parent */
264     HANDLE signal_pipe;                     /* named pipe used to send messages from parent to child (currently only stop) */
265     GString *args = g_string_sized_new(200);
266     gchar *quoted_arg;
267     SECURITY_ATTRIBUTES sa;
268     STARTUPINFO si;
269     PROCESS_INFORMATION pi;
270     int i;
271     char control_id[ARGV_NUMBER_LEN];
272     gchar *signal_pipe_name;
273 #else
274     char errmsg[1024+1];
275     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
276     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
277 #endif
278     int sync_pipe_read_fd;
279     int argc;
280     const char **argv;
281
282
283     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_start");
284     capture_opts_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, capture_opts);
285
286     capture_opts->fork_child = -1;
287
288     argv = init_pipe_args(&argc);
289     if (!argv) {
290         /* We don't know where to find dumpcap. */
291         report_failure("We don't know where to find dumpcap.");
292         return FALSE;
293     }
294
295     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "argv[0]: %s", argv[0]);
296
297     argv = sync_pipe_add_arg(argv, &argc, "-i");
298     argv = sync_pipe_add_arg(argv, &argc, capture_opts->iface);
299
300     if (capture_opts->has_snaplen) {
301       argv = sync_pipe_add_arg(argv, &argc, "-s");
302       g_snprintf(ssnap, ARGV_NUMBER_LEN, "%d",capture_opts->snaplen);
303       argv = sync_pipe_add_arg(argv, &argc, ssnap);
304     }
305
306     if (capture_opts->linktype != -1) {
307       argv = sync_pipe_add_arg(argv, &argc, "-y");
308       g_snprintf(sdlt, ARGV_NUMBER_LEN, "%s",linktype_val_to_name(capture_opts->linktype));
309       argv = sync_pipe_add_arg(argv, &argc, sdlt);
310     }
311
312     if(capture_opts->multi_files_on) {
313       if (capture_opts->has_autostop_filesize) {
314         argv = sync_pipe_add_arg(argv, &argc, "-b");
315         g_snprintf(sfilesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
316         argv = sync_pipe_add_arg(argv, &argc, sfilesize);
317       }
318
319       if (capture_opts->has_file_duration) {
320         argv = sync_pipe_add_arg(argv, &argc, "-b");
321         g_snprintf(sfile_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->file_duration);
322         argv = sync_pipe_add_arg(argv, &argc, sfile_duration);
323       }
324
325       if (capture_opts->has_ring_num_files) {
326         argv = sync_pipe_add_arg(argv, &argc, "-b");
327         g_snprintf(sring_num_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->ring_num_files);
328         argv = sync_pipe_add_arg(argv, &argc, sring_num_files);
329       }
330
331       if (capture_opts->has_autostop_files) {
332         argv = sync_pipe_add_arg(argv, &argc, "-a");
333         g_snprintf(sautostop_files, ARGV_NUMBER_LEN, "files:%d",capture_opts->autostop_files);
334         argv = sync_pipe_add_arg(argv, &argc, sautostop_files);
335       }
336     } else {
337         if (capture_opts->has_autostop_filesize) {
338           argv = sync_pipe_add_arg(argv, &argc, "-a");
339           g_snprintf(sautostop_filesize, ARGV_NUMBER_LEN, "filesize:%d",capture_opts->autostop_filesize);
340           argv = sync_pipe_add_arg(argv, &argc, sautostop_filesize);
341         }
342     }
343
344     if (capture_opts->has_autostop_packets) {
345       argv = sync_pipe_add_arg(argv, &argc, "-c");
346       g_snprintf(scount, ARGV_NUMBER_LEN, "%d",capture_opts->autostop_packets);
347       argv = sync_pipe_add_arg(argv, &argc, scount);
348     }
349
350     if (capture_opts->has_autostop_duration) {
351       argv = sync_pipe_add_arg(argv, &argc, "-a");
352       g_snprintf(sautostop_duration, ARGV_NUMBER_LEN, "duration:%d",capture_opts->autostop_duration);
353       argv = sync_pipe_add_arg(argv, &argc, sautostop_duration);
354     }
355
356     if (!capture_opts->promisc_mode)
357       argv = sync_pipe_add_arg(argv, &argc, "-p");
358 #ifdef HAVE_PCAP_REMOTE
359     if (capture_opts->datatx_udp)
360       argv = sync_pipe_add_arg(argv, &argc, "-u");
361
362     if (!capture_opts->nocap_rpcap)
363       argv = sync_pipe_add_arg(argv, &argc, "-r");
364
365     if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
366     {
367         argv = sync_pipe_add_arg(argv, &argc, "-A");
368         g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
369                    capture_opts->auth_password);
370         argv = sync_pipe_add_arg(argv, &argc, sauth);
371     }
372 #endif
373 #ifdef HAVE_PCAP_SETSAMPLING
374     if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
375     {
376         argv = sync_pipe_add_arg(argv, &argc, "-m");
377         g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
378              capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
379              capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
380              "undef",
381              capture_opts->sampling_param);
382         argv = sync_pipe_add_arg(argv, &argc, ssampling);
383     }
384 #endif
385
386     /* dumpcap should be running in capture child mode (hidden feature) */
387 #ifndef DEBUG_CHILD
388     argv = sync_pipe_add_arg(argv, &argc, "-Z");
389 #ifdef _WIN32
390     g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
391     argv = sync_pipe_add_arg(argv, &argc, control_id);
392 #else
393     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
394 #endif
395 #endif
396
397 #ifdef _WIN32
398     argv = sync_pipe_add_arg(argv, &argc, "-B");
399 #ifdef HAVE_PCAP_REMOTE
400     if (capture_opts->src_type == CAPTURE_IFREMOTE)
401       /* No buffer size when using remote interfaces */
402       g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
403     else
404 #endif
405     g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
406     argv = sync_pipe_add_arg(argv, &argc, buffer_size);
407 #endif
408
409     if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
410       argv = sync_pipe_add_arg(argv, &argc, "-f");
411       argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
412     }
413
414     if(capture_opts->save_file) {
415       argv = sync_pipe_add_arg(argv, &argc, "-w");
416       argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
417     }
418
419 #ifdef _WIN32
420     /* init SECURITY_ATTRIBUTES */
421     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
422     sa.bInheritHandle = TRUE;
423     sa.lpSecurityDescriptor = NULL;
424
425     /* Create a pipe for the child process */
426     /* (increase this value if you have trouble while fast capture file switches) */
427     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
428       /* Couldn't create the pipe between parent and child. */
429       report_failure("Couldn't create sync pipe: %s", strerror(errno));
430       g_free( (gpointer) argv[0]);
431       g_free( (gpointer) argv);
432       return FALSE;
433     }
434
435     /* Create the signal pipe */
436     signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
437     signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
438       PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
439     g_free(signal_pipe_name);
440
441     if (signal_pipe == INVALID_HANDLE_VALUE) {
442       /* Couldn't create the signal pipe between parent and child. */
443       report_failure("Couldn't create signal pipe: %s", strerror(errno));
444       g_free( (gpointer) argv[0]);
445       g_free( (gpointer) argv);
446       return FALSE;
447     }
448
449     /* init STARTUPINFO */
450     memset(&si, 0, sizeof(si));
451     si.cb           = sizeof(si);
452 #ifdef DEBUG_CHILD
453     si.dwFlags = STARTF_USESHOWWINDOW;
454     si.wShowWindow  = SW_SHOW;
455 #else
456     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
457     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
458     si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
459     si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
460     si.hStdError = sync_pipe_write;
461     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
462 #endif
463
464     /* convert args array into a single string */
465     /* XXX - could change sync_pipe_add_arg() instead */
466     /* there is a drawback here: the length is internally limited to 1024 bytes */
467     for(i=0; argv[i] != 0; i++) {
468         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
469         quoted_arg = protect_arg(argv[i]);
470         g_string_append(args, quoted_arg);
471         g_free(quoted_arg);
472     }
473
474     /* call dumpcap */
475     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
476                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
477       report_failure("Couldn't run %s in child process: error %u",
478                      args->str, GetLastError());
479       CloseHandle(sync_pipe_read);
480       CloseHandle(sync_pipe_write);
481       g_free( (gpointer) argv[0]);
482       g_free( (gpointer) argv);
483       return FALSE;
484     }
485     capture_opts->fork_child = (int) pi.hProcess;
486     g_string_free(args, TRUE);
487
488     /* associate the operating system filehandle to a C run-time file handle */
489     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
490     sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
491
492     /* associate the operating system filehandle to a C run-time file handle */
493     capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
494
495 #else /* _WIN32 */
496     if (pipe(sync_pipe) < 0) {
497       /* Couldn't create the pipe between parent and child. */
498       report_failure("Couldn't create sync pipe: %s", strerror(errno));
499       g_free( (gpointer) argv[0]);
500       g_free(argv);
501       return FALSE;
502     }
503
504     if ((capture_opts->fork_child = fork()) == 0) {
505       /*
506        * Child process - run dumpcap with the right arguments to make
507        * it just capture with the specified capture parameters
508        */
509       dup2(sync_pipe[PIPE_WRITE], 2);
510       ws_close(sync_pipe[PIPE_READ]);
511       execv(argv[0], (gpointer)argv);
512       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
513                 argv[0], strerror(errno));
514       sync_pipe_errmsg_to_parent(2, errmsg, "");
515
516       /* Exit with "_exit()", so that we don't close the connection
517          to the X server (and cause stuff buffered up by our parent but
518          not yet sent to be sent, as that stuff should only be sent by
519          our parent).  We've sent an error message to the parent, so
520          we exit with an exit status of 1 (any exit status other than
521          0 or 1 will cause an additional message to report that exit
522          status, over and above the error message we sent to the parent). */
523       _exit(1);
524     }
525
526     sync_pipe_read_fd = sync_pipe[PIPE_READ];
527 #endif
528
529     g_free( (gpointer) argv[0]);  /* exename */
530
531     /* Parent process - read messages from the child process over the
532        sync pipe. */
533     g_free( (gpointer) argv);   /* free up arg array */
534
535     /* Close the write side of the pipe, so that only the child has it
536        open, and thus it completely closes, and thus returns to us
537        an EOF indication, if the child closes it (either deliberately
538        or by exiting abnormally). */
539 #ifdef _WIN32
540     CloseHandle(sync_pipe_write);
541 #else
542     ws_close(sync_pipe[PIPE_WRITE]);
543 #endif
544
545     if (capture_opts->fork_child == -1) {
546       /* We couldn't even create the child process. */
547       report_failure("Couldn't create child process: %s", strerror(errno));
548       ws_close(sync_pipe_read_fd);
549 #ifdef _WIN32
550       ws_close(capture_opts->signal_pipe_write_fd);
551 #endif
552       return FALSE;
553     }
554
555     /* we might wait for a moment till child is ready, so update screen now */
556     main_window_update();
557
558     /* We were able to set up to read the capture file;
559        arrange that our callback be called whenever it's possible
560        to read from the sync pipe, so that it's called when
561        the child process wants to tell us something. */
562
563     /* we have a running capture, now wait for the real capture filename */
564     pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
565         &capture_opts->fork_child, sync_pipe_input_cb);
566
567     return TRUE;
568 }
569
570 /*
571  * Open dumpcap with the supplied arguments.  On success, msg points to
572  * a buffer containing the dumpcap output and returns 0.  read_fd and
573  * fork_child point to the pipe's file descriptor and child PID/handle,
574  * respectively.  On failure, msg points to the error message returned by
575  * dumpcap, and returns dumpcap's exit value.  In either case, msg must be
576  * freed with g_free().
577  */
578 /* XXX - This duplicates a lot of code in sync_pipe_start() */
579 #define PIPE_BUF_SIZE 5120
580 static int
581 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
582 #ifdef _WIN32
583     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
584     HANDLE sync_pipe_write;                 /* pipe used to send messages from parent to child */
585     GString *args = g_string_sized_new(200);
586     gchar *quoted_arg;
587     SECURITY_ATTRIBUTES sa;
588     STARTUPINFO si;
589     PROCESS_INFORMATION pi;
590     int i;
591 #else
592     char errmsg[1024+1];
593     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
594     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
595 #endif
596
597     *fork_child = -1;
598     *read_fd = -1;
599     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
600
601     if (!msg) {
602         /* We can't return anything */
603 #ifdef _WIN32
604         g_string_free(args, TRUE);
605 #endif
606         return -1;
607     }
608
609 #ifdef _WIN32
610     /* init SECURITY_ATTRIBUTES */
611     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
612     sa.bInheritHandle = TRUE;
613     sa.lpSecurityDescriptor = NULL;
614
615     /* Create a pipe for the child process */
616     /* (inrease this value if you have trouble while fast capture file switches) */
617     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
618         /* Couldn't create the pipe between parent and child. */
619         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
620         g_free( (gpointer) argv[0]);
621         g_free( (gpointer) argv);
622         return CANT_RUN_DUMPCAP;
623     }
624
625     /* init STARTUPINFO */
626     memset(&si, 0, sizeof(si));
627     si.cb           = sizeof(si);
628 #ifdef DEBUG_CHILD
629     si.dwFlags = STARTF_USESHOWWINDOW;
630     si.wShowWindow  = SW_SHOW;
631 #else
632     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
633     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
634     si.hStdInput = NULL;
635     si.hStdOutput = sync_pipe_write;
636     si.hStdError = sync_pipe_write;
637     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
638 #endif
639
640     /* convert args array into a single string */
641     /* XXX - could change sync_pipe_add_arg() instead */
642     /* there is a drawback here: the length is internally limited to 1024 bytes */
643     for(i=0; argv[i] != 0; i++) {
644         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
645         quoted_arg = protect_arg(argv[i]);
646         g_string_append(args, quoted_arg);
647         g_free(quoted_arg);
648     }
649
650     /* call dumpcap */
651     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
652                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
653         *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
654                         args->str, GetLastError());
655         CloseHandle(sync_pipe_read);
656         CloseHandle(sync_pipe_write);
657         g_free( (gpointer) argv[0]);
658         g_free( (gpointer) argv);
659         return CANT_RUN_DUMPCAP;
660     }
661     *fork_child = (int) pi.hProcess;
662     g_string_free(args, TRUE);
663
664     /* associate the operating system filehandle to a C run-time file handle */
665     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
666     *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
667
668 #else /* _WIN32 */
669     if (pipe(sync_pipe) < 0) {
670         /* Couldn't create the pipe between parent and child. */
671         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
672         g_free( (gpointer) argv[0]);
673         g_free(argv);
674         return CANT_RUN_DUMPCAP;
675     }
676
677     if ((*fork_child = fork()) == 0) {
678         /*
679          * Child process - run dumpcap with the right arguments to make
680          * it just capture with the specified capture parameters
681          */
682         dup2(sync_pipe[PIPE_WRITE], 1);
683         ws_close(sync_pipe[PIPE_READ]);
684         execv(argv[0], (gpointer)argv);
685         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
686                    argv[0], strerror(errno));
687         sync_pipe_errmsg_to_parent(1, errmsg, "");
688
689         /* Exit with "_exit()", so that we don't close the connection
690            to the X server (and cause stuff buffered up by our parent but
691            not yet sent to be sent, as that stuff should only be sent by
692            our parent).  We've sent an error message to the parent, so
693            we exit with an exit status of 1 (any exit status other than
694            0 or 1 will cause an additional message to report that exit
695            status, over and above the error message we sent to the parent). */
696         _exit(1);
697     }
698
699     *read_fd = sync_pipe[PIPE_READ];
700 #endif
701
702     g_free( (gpointer) argv[0]);  /* exename */
703
704     /* Parent process - read messages from the child process over the
705        sync pipe. */
706     g_free( (gpointer) argv);   /* free up arg array */
707
708     /* Close the write side of the pipe, so that only the child has it
709        open, and thus it completely closes, and thus returns to us
710        an EOF indication, if the child closes it (either deliberately
711        or by exiting abnormally). */
712 #ifdef _WIN32
713     CloseHandle(sync_pipe_write);
714 #else
715     ws_close(sync_pipe[PIPE_WRITE]);
716 #endif
717
718     if (*fork_child == -1) {
719         /* We couldn't even create the child process. */
720         *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
721         ws_close(*read_fd);
722         return CANT_RUN_DUMPCAP;
723     }
724
725     /* we might wait for a moment till child is ready, so update screen now */
726     main_window_update();
727     return 0;
728 }
729
730 static int
731 #ifdef _WIN32
732 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
733 #else
734 sync_pipe_close_command(int *read_fd, gchar **msg) {
735 #endif
736     int fork_child_status;
737
738     ws_close(*read_fd);
739
740     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
741
742 #ifdef _WIN32
743     /* XXX - Should we signal the child somehow? */
744     sync_pipe_kill(*fork_child);
745     if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
746         *msg = g_strdup_printf("Child capture process stopped unexpectedly "
747             "(errno:%u)", errno);
748         return CANT_RUN_DUMPCAP;
749     }
750 #else
751     if (wait(&fork_child_status) != -1) {
752         if (WIFEXITED(fork_child_status)) {
753             /* The child exited. */
754             fork_child_status = WEXITSTATUS(fork_child_status);
755         } else {
756             if (WIFSTOPPED(fork_child_status)) {
757                 /* It stopped, rather than exiting.  "Should not happen." */
758                 *msg = g_strdup_printf("Child capture process stopped: %s",
759                     sync_pipe_signame(WSTOPSIG(fork_child_status)));
760             } else if (WIFSIGNALED(fork_child_status)) {
761                 /* It died with a signal. */
762                 *msg = g_strdup_printf("Child capture process died: %s%s",
763                     sync_pipe_signame(WTERMSIG(fork_child_status)),
764                     WCOREDUMP(fork_child_status) ? " - core dumped" : "");
765             } else {
766                 /* What?  It had to either have exited, or stopped, or died with
767                    a signal; what happened here? */
768                 *msg = g_strdup_printf("Child capture process died: wait status %#o",
769                     fork_child_status);
770             }
771             return CANT_RUN_DUMPCAP;
772         }
773     } else {
774       *msg = g_strdup_printf("Child capture process stopped unexpectedly "
775         "(errno:%u)", errno);
776       return CANT_RUN_DUMPCAP;
777     }
778 #endif
779     return 0;
780 }
781
782 /*
783  * Run dumpcap with the supplied arguments.  On success, msg points to
784  * a buffer containing the dumpcap output and returns 0.  On failure, msg
785  * points to the error message returned by dumpcap, and returns dumpcap's
786  * exit value.  In either case, msg must be freed with g_free().
787  */
788 /* XXX - This duplicates a lot of code in sync_pipe_start() */
789 #define PIPE_BUF_SIZE 5120
790 static int
791 sync_pipe_run_command(const char** argv, gchar **msg) {
792     int sync_pipe_read_fd, fork_child, ret;
793     gchar buf[PIPE_BUF_SIZE+1];
794     GString *msg_buf = NULL;
795     int count;
796
797     ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
798
799     if (ret)
800         return ret;
801
802     /* We were able to set up to read dumpcap's output.  Do so and
803        return its exit value. */
804     msg_buf = g_string_new("");
805     while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
806         buf[count] = '\0';
807         g_string_append(msg_buf, buf);
808     }
809
810 #ifdef _WIN32
811     ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
812 #else
813     ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
814 #endif
815
816     if (ret) {
817         g_string_free(msg_buf, TRUE);
818         return ret;
819     }
820
821     *msg = msg_buf->str;
822     g_string_free(msg_buf, FALSE);
823     return 0;
824 }
825
826 /*
827  * Get an interface list using dumpcap.  On success, msg points to
828  * a buffer containing the dumpcap output and returns 0.  On failure, msg
829  * points to the error message returned by dumpcap, and returns dumpcap's
830  * exit value.  In either case, msg must be freed with g_free().
831  */
832 int
833 sync_interface_list_open(gchar **msg) {
834     int argc;
835     const char **argv;
836
837     if (!msg) {
838         /* We can't return anything */
839         return -1;
840     }
841
842     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
843
844     argv = init_pipe_args(&argc);
845
846     if (!argv) {
847         *msg = g_strdup_printf("We don't know where to find dumpcap.");
848         return CANT_RUN_DUMPCAP;
849     }
850
851     /* Ask for the interface list */
852     argv = sync_pipe_add_arg(argv, &argc, "-D");
853     argv = sync_pipe_add_arg(argv, &argc, "-M");
854
855 #if 0
856     /* dumpcap should be running in capture child mode (hidden feature)                   */
857     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
858     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
859     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
860     /*     Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
861     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
862     /*           msgs to stderr in a special type/len/string format which would then      */
863     /*           currently be sent as is to stderr resulting in garbled output.           */
864     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
865     /*     special format error messages to stderr are captured and returned to caller    */
866     /*     (eg: so can be processed and displayed in a pop-up box).                       */
867 #ifndef DEBUG_CHILD
868     argv = sync_pipe_add_arg(argv, &argc, "-Z");
869     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
870 #endif
871 #endif
872
873     return sync_pipe_run_command(argv, msg);
874 }
875
876 /*
877  * Get an linktype list using dumpcap.  On success, msg points to
878  * a buffer containing the dumpcap output and returns 0.  On failure, msg
879  * points to the error message returned by dumpcap, and returns dumpcap's
880  * exit value.  In either case, msg must be freed with g_free().
881  */
882 int
883 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
884     int argc;
885     const char **argv;
886
887     if (!msg) {
888         /* We can't return anything */
889         return -1;
890     }
891
892     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
893
894     argv = init_pipe_args(&argc);
895
896     if (!argv) {
897         *msg = g_strdup_printf("We don't know where to find dumpcap.");
898         return CANT_RUN_DUMPCAP;
899     }
900
901     /* Ask for the linktype list */
902     argv = sync_pipe_add_arg(argv, &argc, "-i");
903     argv = sync_pipe_add_arg(argv, &argc, ifname);
904     argv = sync_pipe_add_arg(argv, &argc, "-L");
905     argv = sync_pipe_add_arg(argv, &argc, "-M");
906
907 #if 0
908     /* dumpcap should be running in capture child mode (hidden feature)                   */
909     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
910     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
911     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
912     /*     Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
913     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
914     /*           msgs to stderr in a special type/len/string format which would then      */
915     /*           currently be sent as is to stderr resulting in garbled output.           */
916     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
917     /*     special format error messages to stderr are captured and returned to caller    */
918     /*     (eg: so can be processed and displayed in a pop-up box).                       */
919 #ifndef DEBUG_CHILD
920     argv = sync_pipe_add_arg(argv, &argc, "-Z");
921     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
922 #endif
923 #endif
924     return sync_pipe_run_command(argv, msg);
925 }
926
927 /*
928  * Start getting interface statistics using dumpcap.  On success, read_fd
929  * contains the file descriptor for the pipe's stdout, msg is unchanged,
930  * and zero is returned.  On failure, msg will point to an error message
931  * that must be g_free()d and a nonzero error value will be returned.
932  */
933 int
934 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
935     int argc;
936     const char **argv;
937
938     if (!msg) {
939         /* We can't return anything */
940         return -1;
941     }
942
943     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
944
945     argv = init_pipe_args(&argc);
946
947     if (!argv) {
948         *msg = g_strdup_printf("We don't know where to find dumpcap.");
949         return CANT_RUN_DUMPCAP;
950     }
951
952     /* Ask for the interface statistics */
953     argv = sync_pipe_add_arg(argv, &argc, "-S");
954     argv = sync_pipe_add_arg(argv, &argc, "-M");
955
956 #if 0
957     /* dumpcap should be running in capture child mode (hidden feature)                   */
958     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
959     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
960     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
961     /*     Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
962     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
963     /*           msgs to stderr in a special type/len/string format which would then      */
964     /*           currently be sent as is to stderr resulting in garbled output.           */
965     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
966     /*     special format error messages to stderr are captured and returned to caller    */
967     /*     (eg: so can be processed and displayed in a pop-up box).                       */
968 #ifndef DEBUG_CHILD
969     argv = sync_pipe_add_arg(argv, &argc, "-Z");
970     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
971 #endif
972 #endif
973     return sync_pipe_open_command(argv, read_fd, fork_child, msg);
974 }
975
976 /* Close down the stats process */
977 int
978 sync_interface_stats_close(int *read_fd, int *fork_child
979 #ifndef _WIN32
980 _U_
981 #endif
982 , gchar **msg) {
983 #ifdef _WIN32
984     return sync_pipe_close_command(read_fd, fork_child, msg);
985 #else
986     return sync_pipe_close_command(read_fd, msg);
987 #endif
988 }
989
990 /* read a number of bytes from a pipe */
991 /* (blocks until enough bytes read or an error occurs) */
992 static int
993 pipe_read_bytes(int pipe, char *bytes, int required) {
994     int newly;
995     int offset = 0;
996
997     while(required) {
998         newly = read(pipe, &bytes[offset], required);
999         if (newly == 0) {
1000             /* EOF */
1001             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1002                   "read from pipe %d: EOF (capture closed?)", pipe);
1003             return offset;
1004         }
1005         if (newly < 0) {
1006             /* error */
1007             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1008                   "read from pipe %d: error(%u): %s", pipe, errno, strerror(errno));
1009             return newly;
1010         }
1011
1012         required -= newly;
1013         offset += newly;
1014     }
1015
1016     return offset;
1017 }
1018
1019 static gboolean pipe_data_available(int pipe) {
1020 #ifdef _WIN32 /* PeekNamedPipe */
1021     HANDLE hPipe = (HANDLE) _get_osfhandle(pipe);
1022     DWORD bytes_avail;
1023
1024     if (hPipe == INVALID_HANDLE_VALUE)
1025         return FALSE;
1026
1027     if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1028         return FALSE;
1029
1030     if (bytes_avail > 0)
1031         return TRUE;
1032     return FALSE;
1033 #else /* select */
1034     fd_set rfds;
1035     struct timeval timeout;
1036
1037     FD_ZERO(&rfds);
1038     FD_SET(pipe, &rfds);
1039     timeout.tv_sec = 0;
1040     timeout.tv_usec = 0;
1041
1042     if (select(pipe+1, &rfds, NULL, NULL, &timeout) > 0)
1043         return TRUE;
1044
1045     return FALSE;
1046 #endif
1047 }
1048
1049 /* Read a line from a pipe, similar to fgets */
1050 int
1051 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1052     int newly;
1053     int offset = -1;
1054
1055     while(offset < max - 1) {
1056         offset++;
1057         if (! pipe_data_available(pipe_fd))
1058             break;
1059         newly = read(pipe_fd, &bytes[offset], 1);
1060         if (newly == 0) {
1061             /* EOF - not necessarily an error */
1062             break;
1063         } else if (newly < 0) {
1064             /* error */
1065             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1066                   "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1067             return newly;
1068         } else if (bytes[offset] == '\n') {
1069             break;
1070         }
1071     }
1072
1073     if (offset >= 0)
1074         bytes[offset] = '\0';
1075
1076     return offset;
1077 }
1078
1079
1080 /* convert header values (indicator and 4-byte length) */
1081 static void
1082 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1083
1084     g_assert(header_len == 4);
1085
1086     /* convert header values */
1087     *indicator = header[0];
1088     *block_len = header[1]<<16 | header[2]<<8 | header[3];
1089 }
1090
1091 /* read a message from the sending pipe in the standard format
1092    (1-byte message indicator, 3-byte message length (excluding length
1093    and indicator field), and the rest is the message) */
1094 static int
1095 pipe_read_block(int pipe, char *indicator, int len, char *msg) {
1096     int required;
1097     int newly;
1098     guchar header[4];
1099
1100
1101     /* read header (indicator and 3-byte length) */
1102     newly = pipe_read_bytes(pipe, header, 4);
1103     if(newly != 4) {
1104         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1105               "read %d failed to read header: %u", pipe, newly);
1106         return -1;
1107     }
1108
1109     /* convert header values */
1110     pipe_convert_header(header, 4, indicator, &required);
1111
1112     /* only indicator with no value? */
1113     if(required == 0) {
1114         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1115               "read %d indicator: %c empty value", pipe, *indicator);
1116         return 4;
1117     }
1118
1119     /* does the data fit into the given buffer? */
1120     if(required > len) {
1121         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1122               "read %d length error, required %d > len %d, indicator: %u",
1123               pipe, required, len, *indicator);
1124
1125         /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1126         memcpy(msg, header, sizeof(header));
1127         newly = read(pipe, &msg[sizeof(header)], len-sizeof(header));
1128         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1129         return -1;
1130     }
1131     len = required;
1132
1133     /* read the actual block data */
1134     newly = pipe_read_bytes(pipe, msg, required);
1135     if(newly != required) {
1136         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1137         return -1;
1138     }
1139
1140     /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1141     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1142           "read %d ok indicator: %c len: %u msg: %s", pipe, *indicator,
1143           len, msg);
1144     return newly + 4;
1145 }
1146
1147
1148 /* There's stuff to read from the sync pipe, meaning the child has sent
1149    us a message, or the sync pipe has closed, meaning the child has
1150    closed it (perhaps because it exited). */
1151 static gboolean
1152 sync_pipe_input_cb(gint source, gpointer user_data)
1153 {
1154   capture_options *capture_opts = (capture_options *)user_data;
1155   char buffer[SP_MAX_MSG_LEN+1];
1156   int  nread;
1157   char indicator;
1158   int  primary_len;
1159   char * primary_msg;
1160   int  secondary_len;
1161   char * secondary_msg;
1162
1163
1164   nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1165   if(nread <= 0) {
1166     if (nread == 0)
1167       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1168             "sync_pipe_input_cb: child has closed sync_pipe");
1169     else
1170       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1171             "sync_pipe_input_cb: error reading from sync pipe");
1172
1173     /* The child has closed the sync pipe, meaning it's not going to be
1174        capturing any more packets.  Pick up its exit status, and
1175        complain if it did anything other than exit with status 0.
1176
1177        We don't have to worry about killing the child, if the sync pipe
1178        returned an error. Usually this error is caused as the child killed itself
1179        while going down. Even in the rare cases that this isn't the case,
1180        the child will get an error when writing to the broken pipe the next time,
1181        cleaning itself up then. */
1182     sync_pipe_wait_for_child(capture_opts);
1183
1184 #ifdef _WIN32
1185     ws_close(capture_opts->signal_pipe_write_fd);
1186 #endif
1187     capture_input_closed(capture_opts);
1188     return FALSE;
1189   }
1190
1191   /* we got a valid message block from the child, process it */
1192   switch(indicator) {
1193   case SP_FILE:
1194     if(!capture_input_new_file(capture_opts, buffer)) {
1195       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1196
1197       /* We weren't able to open the new capture file; user has been
1198          alerted. Close the sync pipe. */
1199       ws_close(source);
1200
1201       /* the child has send us a filename which we couldn't open.
1202          this probably means, the child is creating files faster than we can handle it.
1203          this should only be the case for very fast file switches
1204          we can't do much more than telling the child to stop
1205          (this is the "emergency brake" if user e.g. wants to switch files every second) */
1206       sync_pipe_stop(capture_opts);
1207     }
1208     break;
1209   case SP_PACKET_COUNT:
1210     nread = atoi(buffer);
1211     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1212     capture_input_new_packets(capture_opts, nread);
1213     break;
1214   case SP_ERROR_MSG:
1215     /* convert primary message */
1216     pipe_convert_header(buffer, 4, &indicator, &primary_len);
1217     primary_msg = buffer+4;
1218     /* convert secondary message */
1219     pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1220     secondary_msg = primary_msg + primary_len + 4;
1221     /* message output */
1222     capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1223     /* the capture child will close the sync_pipe, nothing to do for now */
1224     /* (an error message doesn't mean we have to stop capturing) */
1225     break;
1226   case SP_BAD_FILTER:
1227     capture_input_cfilter_error_message(capture_opts, buffer);
1228     /* the capture child will close the sync_pipe, nothing to do for now */
1229     break;
1230   case SP_DROPS:
1231     capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1232     break;
1233   default:
1234     g_assert_not_reached();
1235   }
1236
1237   return TRUE;
1238 }
1239
1240
1241
1242 /* the child process is going down, wait until it's completely terminated */
1243 static void
1244 sync_pipe_wait_for_child(capture_options *capture_opts)
1245 {
1246   int  wstatus;
1247
1248
1249   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1250   g_assert(capture_opts->fork_child != -1);
1251
1252 #ifdef _WIN32
1253   if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1254     report_failure("Child capture process stopped unexpectedly (errno:%u)",
1255                    errno);
1256   }
1257 #else
1258   if (wait(&wstatus) != -1) {
1259     if (WIFEXITED(wstatus)) {
1260       /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1261       /* the child will inform us about errors through the sync_pipe, which will popup */
1262       /* an error message, so don't popup another one */
1263
1264       /* If there are situations where the child won't send us such an error message, */
1265       /* this should be fixed in the child and not here! */
1266       if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1267         report_failure("Child capture process exited: exit status %d",
1268                        WEXITSTATUS(wstatus));
1269       }
1270     } else if (WIFSTOPPED(wstatus)) {
1271       /* It stopped, rather than exiting.  "Should not happen." */
1272       report_failure("Child capture process stopped: %s",
1273                      sync_pipe_signame(WSTOPSIG(wstatus)));
1274     } else if (WIFSIGNALED(wstatus)) {
1275       /* It died with a signal. */
1276       report_failure("Child capture process died: %s%s",
1277                      sync_pipe_signame(WTERMSIG(wstatus)),
1278                      WCOREDUMP(wstatus) ? " - core dumped" : "");
1279     } else {
1280       /* What?  It had to either have exited, or stopped, or died with
1281          a signal; what happened here? */
1282       report_failure("Child capture process died: wait status %#o", wstatus);
1283     }
1284   }
1285 #endif
1286
1287   /* No more child process. */
1288   capture_opts->fork_child = -1;
1289
1290   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1291 }
1292
1293
1294 #ifndef _WIN32
1295 /* convert signal to corresponding name */
1296 static const char *
1297 sync_pipe_signame(int sig)
1298 {
1299   const char *sigmsg;
1300   static char sigmsg_buf[6+1+3+1];
1301
1302   switch (sig) {
1303
1304   case SIGHUP:
1305     sigmsg = "Hangup";
1306     break;
1307
1308   case SIGINT:
1309     sigmsg = "Interrupted";
1310     break;
1311
1312   case SIGQUIT:
1313     sigmsg = "Quit";
1314     break;
1315
1316   case SIGILL:
1317     sigmsg = "Illegal instruction";
1318     break;
1319
1320   case SIGTRAP:
1321     sigmsg = "Trace trap";
1322     break;
1323
1324   case SIGABRT:
1325     sigmsg = "Abort";
1326     break;
1327
1328   case SIGFPE:
1329     sigmsg = "Arithmetic exception";
1330     break;
1331
1332   case SIGKILL:
1333     sigmsg = "Killed";
1334     break;
1335
1336   case SIGBUS:
1337     sigmsg = "Bus error";
1338     break;
1339
1340   case SIGSEGV:
1341     sigmsg = "Segmentation violation";
1342     break;
1343
1344   /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1345      Linux is POSIX compliant.  These are not POSIX-defined signals ---
1346      ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1347
1348         ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1349         were omitted from POSIX.1 because their behavior is
1350         implementation dependent and could not be adequately catego-
1351         rized.  Conforming implementations may deliver these sig-
1352         nals, but must document the circumstances under which they
1353         are delivered and note any restrictions concerning their
1354         delivery.''
1355
1356      So we only check for SIGSYS on those systems that happen to
1357      implement them (a system can be POSIX-compliant and implement
1358      them, it's just that POSIX doesn't *require* a POSIX-compliant
1359      system to implement them).
1360    */
1361
1362 #ifdef SIGSYS
1363   case SIGSYS:
1364     sigmsg = "Bad system call";
1365     break;
1366 #endif
1367
1368   case SIGPIPE:
1369     sigmsg = "Broken pipe";
1370     break;
1371
1372   case SIGALRM:
1373     sigmsg = "Alarm clock";
1374     break;
1375
1376   case SIGTERM:
1377     sigmsg = "Terminated";
1378     break;
1379
1380   default:
1381         /* Returning a static buffer is ok in the context we use it here */
1382     g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1383     sigmsg = sigmsg_buf;
1384     break;
1385   }
1386   return sigmsg;
1387 }
1388 #endif
1389
1390
1391 #ifdef _WIN32
1392 /* tell the child through the signal pipe that we want to quit the capture */
1393 static void
1394 signal_pipe_capquit_to_child(capture_options *capture_opts)
1395 {
1396     const char quit_msg[] = "QUIT";
1397     int ret;
1398
1399
1400     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1401
1402     /* it doesn't matter *what* we send here, the first byte will stop the capture */
1403     /* simply sending a "QUIT" string */
1404     /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1405     ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1406     if(ret == -1) {
1407         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1408               "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1409     }
1410 }
1411 #endif
1412
1413
1414 /* user wants to stop the capture run */
1415 void
1416 sync_pipe_stop(capture_options *capture_opts)
1417 {
1418 #ifdef _WIN32
1419   int count;
1420   DWORD childstatus;
1421   gboolean terminate = TRUE;
1422 #endif
1423
1424   if (capture_opts->fork_child != -1) {
1425 #ifndef _WIN32
1426     /* send the SIGUSR1 signal to close the capture child gracefully. */
1427     int sts = kill(capture_opts->fork_child, SIGUSR1);
1428     if (sts != 0) {
1429         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1430               "Sending SIGUSR1 to child failed: %s\n", strerror(errno));
1431     }
1432 #else
1433 #define STOP_SLEEP_TIME 500 /* ms */
1434 #define STOP_CHECK_TIME 50
1435     /* First, use the special signal pipe to try to close the capture child
1436      * gracefully.
1437      */
1438     signal_pipe_capquit_to_child(capture_opts);
1439
1440     /* Next, wait for the process to exit on its own */
1441     for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1442       if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1443               childstatus != STILL_ACTIVE) {
1444         terminate = FALSE;
1445         break;
1446       }
1447       Sleep(STOP_CHECK_TIME);
1448     }
1449
1450     /* Force the issue. */
1451     if (terminate) {
1452       g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1453             "sync_pipe_stop: forcing child to exit");
1454       sync_pipe_kill(capture_opts->fork_child);
1455     }
1456 #endif
1457   }
1458 }
1459
1460
1461 /* Wireshark has to exit, force the capture child to close */
1462 void
1463 sync_pipe_kill(int fork_child)
1464 {
1465     if (fork_child != -1) {
1466 #ifndef _WIN32
1467         int sts = kill(fork_child, SIGTERM);    /* SIGTERM so it can clean up if necessary */
1468         if (sts != 0) {
1469             g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1470                   "Sending SIGTERM to child failed: %s\n", strerror(errno));
1471         }
1472 #else
1473       /* Remark: This is not the preferred method of closing a process!
1474        * the clean way would be getting the process id of the child process,
1475        * then getting window handle hWnd of that process (using EnumChildWindows),
1476        * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1477        *
1478        * Unfortunately, I don't know how to get the process id from the
1479        * handle.  OpenProcess will get an handle (not a window handle)
1480        * from the process ID; it will not get a window handle from the
1481        * process ID.  (How could it?  A process can have more than one
1482        * window.  For that matter, a process might have *no* windows,
1483        * as a process running dumpcap, the normal child process program,
1484        * probably does.)
1485        *
1486        * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1487        * running in the same console; that's not necessarily the case for
1488        * us, as we might not be running in a console.
1489        * And this also will require to have the process id.
1490        */
1491         TerminateProcess((HANDLE) (fork_child), 0);
1492 #endif
1493     }
1494 }
1495
1496 #endif /* HAVE_LIBPCAP */