Turn on memory scrubbing when fuzz testing.
[obnox/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     if (capture_opts->use_pcapng)
359       argv = sync_pipe_add_arg(argv, &argc, "-n");
360 #ifdef HAVE_PCAP_REMOTE
361     if (capture_opts->datatx_udp)
362       argv = sync_pipe_add_arg(argv, &argc, "-u");
363
364     if (!capture_opts->nocap_rpcap)
365       argv = sync_pipe_add_arg(argv, &argc, "-r");
366
367     if (capture_opts->auth_type == CAPTURE_AUTH_PWD)
368     {
369         argv = sync_pipe_add_arg(argv, &argc, "-A");
370         g_snprintf(sauth, sizeof(sauth), "%s:%s", capture_opts->auth_username,
371                    capture_opts->auth_password);
372         argv = sync_pipe_add_arg(argv, &argc, sauth);
373     }
374 #endif
375 #ifdef HAVE_PCAP_SETSAMPLING
376     if (capture_opts->sampling_method != CAPTURE_SAMP_NONE)
377     {
378         argv = sync_pipe_add_arg(argv, &argc, "-m");
379         g_snprintf(ssampling, ARGV_NUMBER_LEN, "%s:%d",
380              capture_opts->sampling_method == CAPTURE_SAMP_BY_COUNT ? "count" :
381              capture_opts->sampling_method == CAPTURE_SAMP_BY_TIMER ? "timer" :
382              "undef",
383              capture_opts->sampling_param);
384         argv = sync_pipe_add_arg(argv, &argc, ssampling);
385     }
386 #endif
387
388     /* dumpcap should be running in capture child mode (hidden feature) */
389 #ifndef DEBUG_CHILD
390     argv = sync_pipe_add_arg(argv, &argc, "-Z");
391 #ifdef _WIN32
392     g_snprintf(control_id, ARGV_NUMBER_LEN, "%d", GetCurrentProcessId());
393     argv = sync_pipe_add_arg(argv, &argc, control_id);
394 #else
395     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
396 #endif
397 #endif
398
399 #ifdef _WIN32
400     argv = sync_pipe_add_arg(argv, &argc, "-B");
401 #ifdef HAVE_PCAP_REMOTE
402     if (capture_opts->src_type == CAPTURE_IFREMOTE)
403       /* No buffer size when using remote interfaces */
404       g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d", 1);
405     else
406 #endif
407     g_snprintf(buffer_size, ARGV_NUMBER_LEN, "%d",capture_opts->buffer_size);
408     argv = sync_pipe_add_arg(argv, &argc, buffer_size);
409 #endif
410
411     if (capture_opts->cfilter != NULL && strlen(capture_opts->cfilter) != 0) {
412       argv = sync_pipe_add_arg(argv, &argc, "-f");
413       argv = sync_pipe_add_arg(argv, &argc, capture_opts->cfilter);
414     }
415
416     if(capture_opts->save_file) {
417       argv = sync_pipe_add_arg(argv, &argc, "-w");
418       argv = sync_pipe_add_arg(argv, &argc, capture_opts->save_file);
419     }
420
421 #ifdef _WIN32
422     /* init SECURITY_ATTRIBUTES */
423     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
424     sa.bInheritHandle = TRUE;
425     sa.lpSecurityDescriptor = NULL;
426
427     /* Create a pipe for the child process */
428     /* (increase this value if you have trouble while fast capture file switches) */
429     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
430       /* Couldn't create the pipe between parent and child. */
431       report_failure("Couldn't create sync pipe: %s", strerror(errno));
432       g_free( (gpointer) argv[0]);
433       g_free( (gpointer) argv);
434       return FALSE;
435     }
436
437     /* Create the signal pipe */
438     signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id);
439     signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name),
440       PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE, 1, 65535, 65535, 0, NULL);
441     g_free(signal_pipe_name);
442
443     if (signal_pipe == INVALID_HANDLE_VALUE) {
444       /* Couldn't create the signal pipe between parent and child. */
445       report_failure("Couldn't create signal pipe: %s", strerror(errno));
446       g_free( (gpointer) argv[0]);
447       g_free( (gpointer) argv);
448       return FALSE;
449     }
450
451     /* init STARTUPINFO */
452     memset(&si, 0, sizeof(si));
453     si.cb           = sizeof(si);
454 #ifdef DEBUG_CHILD
455     si.dwFlags = STARTF_USESHOWWINDOW;
456     si.wShowWindow  = SW_SHOW;
457 #else
458     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
459     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
460     si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
461     si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
462     si.hStdError = sync_pipe_write;
463     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
464 #endif
465
466     /* convert args array into a single string */
467     /* XXX - could change sync_pipe_add_arg() instead */
468     /* there is a drawback here: the length is internally limited to 1024 bytes */
469     for(i=0; argv[i] != 0; i++) {
470         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
471         quoted_arg = protect_arg(argv[i]);
472         g_string_append(args, quoted_arg);
473         g_free(quoted_arg);
474     }
475
476     /* call dumpcap */
477     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
478                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
479       report_failure("Couldn't run %s in child process: error %u",
480                      args->str, GetLastError());
481       CloseHandle(sync_pipe_read);
482       CloseHandle(sync_pipe_write);
483       g_free( (gpointer) argv[0]);
484       g_free( (gpointer) argv);
485       return FALSE;
486     }
487     capture_opts->fork_child = (int) pi.hProcess;
488     g_string_free(args, TRUE);
489
490     /* associate the operating system filehandle to a C run-time file handle */
491     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
492     sync_pipe_read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
493
494     /* associate the operating system filehandle to a C run-time file handle */
495     capture_opts->signal_pipe_write_fd = _open_osfhandle( (long) signal_pipe, _O_BINARY);
496
497 #else /* _WIN32 */
498     if (pipe(sync_pipe) < 0) {
499       /* Couldn't create the pipe between parent and child. */
500       report_failure("Couldn't create sync pipe: %s", strerror(errno));
501       g_free( (gpointer) argv[0]);
502       g_free(argv);
503       return FALSE;
504     }
505
506     if ((capture_opts->fork_child = fork()) == 0) {
507       /*
508        * Child process - run dumpcap with the right arguments to make
509        * it just capture with the specified capture parameters
510        */
511       dup2(sync_pipe[PIPE_WRITE], 2);
512       ws_close(sync_pipe[PIPE_READ]);
513       execv(argv[0], (gpointer)argv);
514       g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
515                 argv[0], strerror(errno));
516       sync_pipe_errmsg_to_parent(2, errmsg, "");
517
518       /* Exit with "_exit()", so that we don't close the connection
519          to the X server (and cause stuff buffered up by our parent but
520          not yet sent to be sent, as that stuff should only be sent by
521          our parent).  We've sent an error message to the parent, so
522          we exit with an exit status of 1 (any exit status other than
523          0 or 1 will cause an additional message to report that exit
524          status, over and above the error message we sent to the parent). */
525       _exit(1);
526     }
527
528     sync_pipe_read_fd = sync_pipe[PIPE_READ];
529 #endif
530
531     g_free( (gpointer) argv[0]);  /* exename */
532
533     /* Parent process - read messages from the child process over the
534        sync pipe. */
535     g_free( (gpointer) argv);   /* free up arg array */
536
537     /* Close the write side of the pipe, so that only the child has it
538        open, and thus it completely closes, and thus returns to us
539        an EOF indication, if the child closes it (either deliberately
540        or by exiting abnormally). */
541 #ifdef _WIN32
542     CloseHandle(sync_pipe_write);
543 #else
544     ws_close(sync_pipe[PIPE_WRITE]);
545 #endif
546
547     if (capture_opts->fork_child == -1) {
548       /* We couldn't even create the child process. */
549       report_failure("Couldn't create child process: %s", strerror(errno));
550       ws_close(sync_pipe_read_fd);
551 #ifdef _WIN32
552       ws_close(capture_opts->signal_pipe_write_fd);
553 #endif
554       return FALSE;
555     }
556
557     /* we might wait for a moment till child is ready, so update screen now */
558     main_window_update();
559
560     /* We were able to set up to read the capture file;
561        arrange that our callback be called whenever it's possible
562        to read from the sync pipe, so that it's called when
563        the child process wants to tell us something. */
564
565     /* we have a running capture, now wait for the real capture filename */
566     pipe_input_set_handler(sync_pipe_read_fd, (gpointer) capture_opts,
567         &capture_opts->fork_child, sync_pipe_input_cb);
568
569     return TRUE;
570 }
571
572 /*
573  * Open a pipe to dumpcap with the supplied arguments.  On success, *msg
574  * is unchanged and 0 is returned; read_fd and fork_child point to the
575  * pipe's file descriptor and child PID/handle, respectively.  On failure,
576  * *msg points to an error message for the failure, and -1 is returned.
577  * In the latter case, *msg must be freed with g_free().
578  */
579 /* XXX - This duplicates a lot of code in sync_pipe_start() */
580 #define PIPE_BUF_SIZE 5120
581 static int
582 sync_pipe_open_command(const char** argv, int *read_fd, int *fork_child, gchar **msg) {
583 #ifdef _WIN32
584     HANDLE sync_pipe_read;                  /* pipe used to send messages from child to parent */
585     HANDLE sync_pipe_write;                 /* pipe used to send messages from parent to child */
586     GString *args = g_string_sized_new(200);
587     gchar *quoted_arg;
588     SECURITY_ATTRIBUTES sa;
589     STARTUPINFO si;
590     PROCESS_INFORMATION pi;
591     int i;
592 #else
593     char errmsg[1024+1];
594     int sync_pipe[2];                       /* pipe used to send messages from child to parent */
595     enum PIPES { PIPE_READ, PIPE_WRITE };   /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
596 #endif
597
598     *fork_child = -1;
599     *read_fd = -1;
600     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_run_command");
601
602     if (!msg) {
603         /* We can't return anything */
604 #ifdef _WIN32
605         g_string_free(args, TRUE);
606 #endif
607         return -1;
608     }
609
610 #ifdef _WIN32
611     /* init SECURITY_ATTRIBUTES */
612     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
613     sa.bInheritHandle = TRUE;
614     sa.lpSecurityDescriptor = NULL;
615
616     /* Create a pipe for the child process */
617     /* (increase this value if you have trouble while fast capture file switches) */
618     if (! CreatePipe(&sync_pipe_read, &sync_pipe_write, &sa, 5120)) {
619         /* Couldn't create the pipe between parent and child. */
620         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
621         g_free( (gpointer) argv[0]);
622         g_free( (gpointer) argv);
623         return -1;
624     }
625
626     /* init STARTUPINFO */
627     memset(&si, 0, sizeof(si));
628     si.cb           = sizeof(si);
629 #ifdef DEBUG_CHILD
630     si.dwFlags = STARTF_USESHOWWINDOW;
631     si.wShowWindow  = SW_SHOW;
632 #else
633     si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
634     si.wShowWindow  = SW_HIDE;  /* this hides the console window */
635     si.hStdInput = NULL;
636     si.hStdOutput = sync_pipe_write;
637     si.hStdError = sync_pipe_write;
638     /*si.hStdError = (HANDLE) _get_osfhandle(2);*/
639 #endif
640
641     /* convert args array into a single string */
642     /* XXX - could change sync_pipe_add_arg() instead */
643     /* there is a drawback here: the length is internally limited to 1024 bytes */
644     for(i=0; argv[i] != 0; i++) {
645         if(i != 0) g_string_append_c(args, ' ');    /* don't prepend a space before the path!!! */
646         quoted_arg = protect_arg(argv[i]);
647         g_string_append(args, quoted_arg);
648         g_free(quoted_arg);
649     }
650
651     /* call dumpcap */
652     if(!CreateProcess(NULL, utf_8to16(args->str), NULL, NULL, TRUE,
653                       CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
654         *msg = g_strdup_printf("Couldn't run %s in child process: error %u",
655                         args->str, GetLastError());
656         CloseHandle(sync_pipe_read);
657         CloseHandle(sync_pipe_write);
658         g_free( (gpointer) argv[0]);
659         g_free( (gpointer) argv);
660         return -1;
661     }
662     *fork_child = (int) pi.hProcess;
663     g_string_free(args, TRUE);
664
665     /* associate the operating system filehandle to a C run-time file handle */
666     /* (good file handle infos at: http://www.flounder.com/handles.htm) */
667     *read_fd = _open_osfhandle( (long) sync_pipe_read, _O_BINARY);
668
669 #else /* _WIN32 */
670     if (pipe(sync_pipe) < 0) {
671         /* Couldn't create the pipe between parent and child. */
672         *msg = g_strdup_printf("Couldn't create sync pipe: %s", strerror(errno));
673         g_free( (gpointer) argv[0]);
674         g_free(argv);
675         return -1;
676     }
677
678     if ((*fork_child = fork()) == 0) {
679         /*
680          * Child process - run dumpcap with the right arguments to make
681          * it just capture with the specified capture parameters
682          */
683         dup2(sync_pipe[PIPE_WRITE], 1);
684         ws_close(sync_pipe[PIPE_READ]);
685         execv(argv[0], (gpointer)argv);
686         g_snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
687                    argv[0], strerror(errno));
688         sync_pipe_errmsg_to_parent(1, errmsg, "");
689
690         /* Exit with "_exit()", so that we don't close the connection
691            to the X server (and cause stuff buffered up by our parent but
692            not yet sent to be sent, as that stuff should only be sent by
693            our parent).  We've sent an error message to the parent, so
694            we exit with an exit status of 1 (any exit status other than
695            0 or 1 will cause an additional message to report that exit
696            status, over and above the error message we sent to the parent). */
697         _exit(1);
698     }
699
700     *read_fd = sync_pipe[PIPE_READ];
701 #endif
702
703     g_free( (gpointer) argv[0]);  /* exename */
704
705     /* Parent process - read messages from the child process over the
706        sync pipe. */
707     g_free( (gpointer) argv);   /* free up arg array */
708
709     /* Close the write side of the pipe, so that only the child has it
710        open, and thus it completely closes, and thus returns to us
711        an EOF indication, if the child closes it (either deliberately
712        or by exiting abnormally). */
713 #ifdef _WIN32
714     CloseHandle(sync_pipe_write);
715 #else
716     ws_close(sync_pipe[PIPE_WRITE]);
717 #endif
718
719     if (*fork_child == -1) {
720         /* We couldn't even create the child process. */
721         *msg = g_strdup_printf("Couldn't create child process: %s", strerror(errno));
722         ws_close(*read_fd);
723         return -1;
724     }
725
726     /* we might wait for a moment till child is ready, so update screen now */
727     main_window_update();
728     return 0;
729 }
730
731 /*
732  * Wait for dumpcap to finish.  On success, *msg is unchanged, and 0 is
733  * returned.  On failure, *msg points to an error message for the
734  * failure, and -1 is returned.  In the latter case, *msg must be
735  * freed with g_free().
736  */
737 static int
738 #ifdef _WIN32
739 sync_pipe_close_command(int *read_fd, int *fork_child, gchar **msg) {
740 #else
741 sync_pipe_close_command(int *read_fd, gchar **msg) {
742 #endif
743     int fork_child_status;
744
745     ws_close(*read_fd);
746
747     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_close_command: wait till child closed");
748
749 #ifdef _WIN32
750     /* XXX - Should we signal the child somehow? */
751     sync_pipe_kill(*fork_child);
752     if (_cwait(&fork_child_status, *fork_child, _WAIT_CHILD) == -1) {
753         *msg = g_strdup_printf("Child capture process stopped unexpectedly "
754             "(errno:%u)", errno);
755         return -1;
756     }
757 #else
758     if (wait(&fork_child_status) != -1) {
759         if (WIFEXITED(fork_child_status)) {
760             /* The child exited. */
761             fork_child_status = WEXITSTATUS(fork_child_status);
762         } else {
763             if (WIFSTOPPED(fork_child_status)) {
764                 /* It stopped, rather than exiting.  "Should not happen." */
765                 *msg = g_strdup_printf("Child capture process stopped: %s",
766                     sync_pipe_signame(WSTOPSIG(fork_child_status)));
767             } else if (WIFSIGNALED(fork_child_status)) {
768                 /* It died with a signal. */
769                 *msg = g_strdup_printf("Child capture process died: %s%s",
770                     sync_pipe_signame(WTERMSIG(fork_child_status)),
771                     WCOREDUMP(fork_child_status) ? " - core dumped" : "");
772             } else {
773                 /* What?  It had to either have exited, or stopped, or died with
774                    a signal; what happened here? */
775                 *msg = g_strdup_printf("Child capture process died: wait status %#o",
776                     fork_child_status);
777             }
778             return -1;
779         }
780     } else {
781       *msg = g_strdup_printf("Child capture process stopped unexpectedly "
782         "(errno:%u)", errno);
783       return -1;
784     }
785 #endif
786     return 0;
787 }
788
789 /*
790  * Run dumpcap with the supplied arguments.  On success, *msg points to
791  * a buffer containing the dumpcap output, and 0 is returned.  On failure,
792  * *msg points to an error message, and -1 is returned.  In either case,
793  * *msg must be freed with g_free().
794  *
795  * XXX - this doesn't check the exit status of dumpcap if it can be
796  * started and its return status could be fetched.
797  */
798 /* XXX - This duplicates a lot of code in sync_pipe_start() */
799 #define PIPE_BUF_SIZE 5120
800 static int
801 sync_pipe_run_command(const char** argv, gchar **msg) {
802     int sync_pipe_read_fd, fork_child, ret;
803     gchar buf[PIPE_BUF_SIZE+1];
804     GString *msg_buf = NULL;
805     int count;
806
807     ret = sync_pipe_open_command(argv, &sync_pipe_read_fd, &fork_child, msg);
808
809     if (ret)
810         return ret;
811
812     /* We were able to set up to read dumpcap's output.  Do so. */
813     msg_buf = g_string_new("");
814     while ((count = ws_read(sync_pipe_read_fd, buf, PIPE_BUF_SIZE)) > 0) {
815         buf[count] = '\0';
816         g_string_append(msg_buf, buf);
817     }
818
819 #ifdef _WIN32
820     ret = sync_pipe_close_command(&sync_pipe_read_fd, &fork_child, msg);
821 #else
822     ret = sync_pipe_close_command(&sync_pipe_read_fd, msg);
823 #endif
824
825     if (ret) {
826         g_string_free(msg_buf, TRUE);
827         return ret;
828     }
829
830     *msg = msg_buf->str;
831     g_string_free(msg_buf, FALSE);
832     return 0;
833 }
834
835 /*
836  * Get an interface list using dumpcap.  On success, *msg points to
837  * a buffer containing the dumpcap output, and 0 is returned.  On failure,
838  * *msg points to an error message, and -1 is returned.  In either case,
839  * msg must be freed with g_free().
840  */
841 int
842 sync_interface_list_open(gchar **msg) {
843     int argc;
844     const char **argv;
845
846     if (!msg) {
847         /* We can't return anything */
848         return -1;
849     }
850
851     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_list_open");
852
853     argv = init_pipe_args(&argc);
854
855     if (!argv) {
856         *msg = g_strdup_printf("We don't know where to find dumpcap.");
857         return -1;
858     }
859
860     /* Ask for the interface list */
861     argv = sync_pipe_add_arg(argv, &argc, "-D");
862     argv = sync_pipe_add_arg(argv, &argc, "-M");
863
864 #if 0
865     /* dumpcap should be running in capture child mode (hidden feature)                   */
866     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
867     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
868     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
869     /*     Note: Using 'dumpcap -D -M -Z' (capture_child mode) changes only the format of */
870     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
871     /*           msgs to stderr in a special type/len/string format which would then      */
872     /*           currently be sent as is to stderr resulting in garbled output.           */
873     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
874     /*     special format error messages to stderr are captured and returned to caller    */
875     /*     (eg: so can be processed and displayed in a pop-up box).                       */
876 #ifndef DEBUG_CHILD
877     argv = sync_pipe_add_arg(argv, &argc, "-Z");
878     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
879 #endif
880 #endif
881
882     return sync_pipe_run_command(argv, msg);
883 }
884
885 /*
886  * Get an linktype list using dumpcap.  On success, *msg points to
887  * a buffer containing the dumpcap output, and 0 is returned.  On failure,
888  * *msg points to an error message, and -1 is returned.  In either case,
889  * *msg must be freed with g_free().
890  */
891 int
892 sync_linktype_list_open(const gchar *ifname, gchar **msg) {
893     int argc;
894     const char **argv;
895
896     if (!msg) {
897         /* We can't return anything */
898         return -1;
899     }
900
901     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_linktype_list_open");
902
903     argv = init_pipe_args(&argc);
904
905     if (!argv) {
906         *msg = g_strdup_printf("We don't know where to find dumpcap.");
907         return -1;
908     }
909
910     /* Ask for the linktype list */
911     argv = sync_pipe_add_arg(argv, &argc, "-i");
912     argv = sync_pipe_add_arg(argv, &argc, ifname);
913     argv = sync_pipe_add_arg(argv, &argc, "-L");
914     argv = sync_pipe_add_arg(argv, &argc, "-M");
915
916 #if 0
917     /* dumpcap should be running in capture child mode (hidden feature)                   */
918     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
919     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
920     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
921     /*     Note: Using 'dumpcap -L -M -Z' (capture_child mode) changes only the format of */
922     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
923     /*           msgs to stderr in a special type/len/string format which would then      */
924     /*           currently be sent as is to stderr resulting in garbled output.           */
925     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
926     /*     special format error messages to stderr are captured and returned to caller    */
927     /*     (eg: so can be processed and displayed in a pop-up box).                       */
928 #ifndef DEBUG_CHILD
929     argv = sync_pipe_add_arg(argv, &argc, "-Z");
930     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
931 #endif
932 #endif
933     return sync_pipe_run_command(argv, msg);
934 }
935
936 /*
937  * Start getting interface statistics using dumpcap.  On success, read_fd
938  * contains the file descriptor for the pipe's stdout, *msg is unchanged,
939  * and zero is returned.  On failure, *msg will point to an error message
940  * that must be g_free()d, and -1 will be returned.
941  */
942 int
943 sync_interface_stats_open(int *read_fd, int *fork_child, gchar **msg) {
944     int argc;
945     const char **argv;
946
947     if (!msg) {
948         /* We can't return anything */
949         return -1;
950     }
951
952     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_interface_stats_open");
953
954     argv = init_pipe_args(&argc);
955
956     if (!argv) {
957         *msg = g_strdup_printf("We don't know where to find dumpcap.");
958         return -1;
959     }
960
961     /* Ask for the interface statistics */
962     argv = sync_pipe_add_arg(argv, &argc, "-S");
963     argv = sync_pipe_add_arg(argv, &argc, "-M");
964
965 #if 0
966     /* dumpcap should be running in capture child mode (hidden feature)                   */
967     /* XXX: Actually: don't run dumpcap in capture_child_mode.                            */
968     /*     Instead run dumpcap in 'normal' mode so that dumpcap err msgs are sent to      */
969     /*     stderr in normal format and are then sent to whereever our stderr goes.        */
970     /*     Note: Using 'dumpcap -S -M -Z' (capture_child mode) changes only the format of */
971     /*           dumpcap err msgs. That is: dumpcap in capture_child mode outputs err     */
972     /*           msgs to stderr in a special type/len/string format which would then      */
973     /*           currently be sent as is to stderr resulting in garbled output.           */
974     /*     ToDo: Revise this code to be similar to sync_pipe_start so that 'dumpcap -Z'   */
975     /*     special format error messages to stderr are captured and returned to caller    */
976     /*     (eg: so can be processed and displayed in a pop-up box).                       */
977 #ifndef DEBUG_CHILD
978     argv = sync_pipe_add_arg(argv, &argc, "-Z");
979     argv = sync_pipe_add_arg(argv, &argc, SIGNAL_PIPE_CTRL_ID_NONE);
980 #endif
981 #endif
982     return sync_pipe_open_command(argv, read_fd, fork_child, msg);
983 }
984
985 /* Close down the stats process */
986 int
987 sync_interface_stats_close(int *read_fd, int *fork_child
988 #ifndef _WIN32
989 _U_
990 #endif
991 , gchar **msg) {
992 #ifdef _WIN32
993     return sync_pipe_close_command(read_fd, fork_child, msg);
994 #else
995     return sync_pipe_close_command(read_fd, msg);
996 #endif
997 }
998
999 /* read a number of bytes from a pipe */
1000 /* (blocks until enough bytes read or an error occurs) */
1001 static int
1002 pipe_read_bytes(int pipe_fd, char *bytes, int required) {
1003     int newly;
1004     int offset = 0;
1005
1006     while(required) {
1007         newly = read(pipe_fd, &bytes[offset], required);
1008         if (newly == 0) {
1009             /* EOF */
1010             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1011                   "read from pipe %d: EOF (capture closed?)", pipe_fd);
1012             return offset;
1013         }
1014         if (newly < 0) {
1015             /* error */
1016             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1017                   "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1018             return newly;
1019         }
1020
1021         required -= newly;
1022         offset += newly;
1023     }
1024
1025     return offset;
1026 }
1027
1028 static gboolean pipe_data_available(int pipe_fd) {
1029 #ifdef _WIN32 /* PeekNamedPipe */
1030     HANDLE hPipe = (HANDLE) _get_osfhandle(pipe_fd);
1031     DWORD bytes_avail;
1032
1033     if (hPipe == INVALID_HANDLE_VALUE)
1034         return FALSE;
1035
1036     if (! PeekNamedPipe(hPipe, NULL, 0, NULL, &bytes_avail, NULL))
1037         return FALSE;
1038
1039     if (bytes_avail > 0)
1040         return TRUE;
1041     return FALSE;
1042 #else /* select */
1043     fd_set rfds;
1044     struct timeval timeout;
1045
1046     FD_ZERO(&rfds);
1047     FD_SET(pipe_fd, &rfds);
1048     timeout.tv_sec = 0;
1049     timeout.tv_usec = 0;
1050
1051     if (select(pipe_fd+1, &rfds, NULL, NULL, &timeout) > 0)
1052         return TRUE;
1053
1054     return FALSE;
1055 #endif
1056 }
1057
1058 /* Read a line from a pipe, similar to fgets */
1059 int
1060 sync_pipe_gets_nonblock(int pipe_fd, char *bytes, int max) {
1061     int newly;
1062     int offset = -1;
1063
1064     while(offset < max - 1) {
1065         offset++;
1066         if (! pipe_data_available(pipe_fd))
1067             break;
1068         newly = read(pipe_fd, &bytes[offset], 1);
1069         if (newly == 0) {
1070             /* EOF - not necessarily an error */
1071             break;
1072         } else if (newly < 0) {
1073             /* error */
1074             g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1075                   "read from pipe %d: error(%u): %s", pipe_fd, errno, strerror(errno));
1076             return newly;
1077         } else if (bytes[offset] == '\n') {
1078             break;
1079         }
1080     }
1081
1082     if (offset >= 0)
1083         bytes[offset] = '\0';
1084
1085     return offset;
1086 }
1087
1088
1089 /* convert header values (indicator and 4-byte length) */
1090 static void
1091 pipe_convert_header(const guchar *header, int header_len, char *indicator, int *block_len) {
1092
1093     g_assert(header_len == 4);
1094
1095     /* convert header values */
1096     *indicator = header[0];
1097     *block_len = header[1]<<16 | header[2]<<8 | header[3];
1098 }
1099
1100 /* read a message from the sending pipe in the standard format
1101    (1-byte message indicator, 3-byte message length (excluding length
1102    and indicator field), and the rest is the message) */
1103 static int
1104 pipe_read_block(int pipe_fd, char *indicator, int len, char *msg) {
1105     int required;
1106     int newly;
1107     guchar header[4];
1108
1109
1110     /* read header (indicator and 3-byte length) */
1111     newly = pipe_read_bytes(pipe_fd, header, 4);
1112     if(newly != 4) {
1113         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1114               "read %d failed to read header: %u", pipe_fd, newly);
1115         return -1;
1116     }
1117
1118     /* convert header values */
1119     pipe_convert_header(header, 4, indicator, &required);
1120
1121     /* only indicator with no value? */
1122     if(required == 0) {
1123         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1124               "read %d indicator: %c empty value", pipe_fd, *indicator);
1125         return 4;
1126     }
1127
1128     /* does the data fit into the given buffer? */
1129     if(required > len) {
1130         g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1131               "read %d length error, required %d > len %d, indicator: %u",
1132               pipe_fd, required, len, *indicator);
1133
1134         /* we have a problem here, try to read some more bytes from the pipe to debug where the problem really is */
1135         memcpy(msg, header, sizeof(header));
1136         newly = read(pipe_fd, &msg[sizeof(header)], len-sizeof(header));
1137         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1138         return -1;
1139     }
1140     len = required;
1141
1142     /* read the actual block data */
1143     newly = pipe_read_bytes(pipe_fd, msg, required);
1144     if(newly != required) {
1145         g_warning("Unknown message from dumpcap, try to show it as a string: %s", msg);
1146         return -1;
1147     }
1148
1149     /* XXX If message is "2part", the msg probably won't be sent to debug log correctly */
1150     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1151           "read %d ok indicator: %c len: %u msg: %s", pipe_fd, *indicator,
1152           len, msg);
1153     return newly + 4;
1154 }
1155
1156
1157 /* There's stuff to read from the sync pipe, meaning the child has sent
1158    us a message, or the sync pipe has closed, meaning the child has
1159    closed it (perhaps because it exited). */
1160 static gboolean
1161 sync_pipe_input_cb(gint source, gpointer user_data)
1162 {
1163   capture_options *capture_opts = (capture_options *)user_data;
1164   char buffer[SP_MAX_MSG_LEN+1];
1165   int  nread;
1166   char indicator;
1167   int  primary_len;
1168   char * primary_msg;
1169   int  secondary_len;
1170   char * secondary_msg;
1171
1172
1173   nread = pipe_read_block(source, &indicator, SP_MAX_MSG_LEN, buffer);
1174   if(nread <= 0) {
1175     if (nread == 0)
1176       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1177             "sync_pipe_input_cb: child has closed sync_pipe");
1178     else
1179       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG,
1180             "sync_pipe_input_cb: error reading from sync pipe");
1181
1182     /* The child has closed the sync pipe, meaning it's not going to be
1183        capturing any more packets.  Pick up its exit status, and
1184        complain if it did anything other than exit with status 0.
1185
1186        We don't have to worry about killing the child, if the sync pipe
1187        returned an error. Usually this error is caused as the child killed itself
1188        while going down. Even in the rare cases that this isn't the case,
1189        the child will get an error when writing to the broken pipe the next time,
1190        cleaning itself up then. */
1191     sync_pipe_wait_for_child(capture_opts);
1192
1193 #ifdef _WIN32
1194     ws_close(capture_opts->signal_pipe_write_fd);
1195 #endif
1196     capture_input_closed(capture_opts);
1197     return FALSE;
1198   }
1199
1200   /* we got a valid message block from the child, process it */
1201   switch(indicator) {
1202   case SP_FILE:
1203     if(!capture_input_new_file(capture_opts, buffer)) {
1204       g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: file failed, closing capture");
1205
1206       /* We weren't able to open the new capture file; user has been
1207          alerted. Close the sync pipe. */
1208       ws_close(source);
1209
1210       /* the child has send us a filename which we couldn't open.
1211          this probably means, the child is creating files faster than we can handle it.
1212          this should only be the case for very fast file switches
1213          we can't do much more than telling the child to stop
1214          (this is the "emergency brake" if user e.g. wants to switch files every second) */
1215       sync_pipe_stop(capture_opts);
1216     }
1217     break;
1218   case SP_PACKET_COUNT:
1219     nread = atoi(buffer);
1220     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_input_cb: new packets %u", nread);
1221     capture_input_new_packets(capture_opts, nread);
1222     break;
1223   case SP_ERROR_MSG:
1224     /* convert primary message */
1225     pipe_convert_header(buffer, 4, &indicator, &primary_len);
1226     primary_msg = buffer+4;
1227     /* convert secondary message */
1228     pipe_convert_header(primary_msg + primary_len, 4, &indicator, &secondary_len);
1229     secondary_msg = primary_msg + primary_len + 4;
1230     /* message output */
1231     capture_input_error_message(capture_opts, primary_msg, secondary_msg);
1232     /* the capture child will close the sync_pipe, nothing to do for now */
1233     /* (an error message doesn't mean we have to stop capturing) */
1234     break;
1235   case SP_BAD_FILTER:
1236     capture_input_cfilter_error_message(capture_opts, buffer);
1237     /* the capture child will close the sync_pipe, nothing to do for now */
1238     break;
1239   case SP_DROPS:
1240     capture_input_drops(capture_opts, (guint32)strtoul(buffer, NULL, 10));
1241     break;
1242   default:
1243     g_assert_not_reached();
1244   }
1245
1246   return TRUE;
1247 }
1248
1249
1250
1251 /* the child process is going down, wait until it's completely terminated */
1252 static void
1253 sync_pipe_wait_for_child(capture_options *capture_opts)
1254 {
1255   int  wstatus;
1256
1257
1258   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: wait till child closed");
1259   g_assert(capture_opts->fork_child != -1);
1260
1261 #ifdef _WIN32
1262   if (_cwait(&wstatus, capture_opts->fork_child, _WAIT_CHILD) == -1) {
1263     report_failure("Child capture process stopped unexpectedly (errno:%u)",
1264                    errno);
1265   }
1266 #else
1267   if (wait(&wstatus) != -1) {
1268     if (WIFEXITED(wstatus)) {
1269       /* The child exited; display its exit status, if it seems uncommon (0=ok, 1=error) */
1270       /* the child will inform us about errors through the sync_pipe, which will popup */
1271       /* an error message, so don't popup another one */
1272
1273       /* If there are situations where the child won't send us such an error message, */
1274       /* this should be fixed in the child and not here! */
1275       if (WEXITSTATUS(wstatus) != 0 && WEXITSTATUS(wstatus) != 1) {
1276         report_failure("Child capture process exited: exit status %d",
1277                        WEXITSTATUS(wstatus));
1278       }
1279     } else if (WIFSTOPPED(wstatus)) {
1280       /* It stopped, rather than exiting.  "Should not happen." */
1281       report_failure("Child capture process stopped: %s",
1282                      sync_pipe_signame(WSTOPSIG(wstatus)));
1283     } else if (WIFSIGNALED(wstatus)) {
1284       /* It died with a signal. */
1285       report_failure("Child capture process died: %s%s",
1286                      sync_pipe_signame(WTERMSIG(wstatus)),
1287                      WCOREDUMP(wstatus) ? " - core dumped" : "");
1288     } else {
1289       /* What?  It had to either have exited, or stopped, or died with
1290          a signal; what happened here? */
1291       report_failure("Child capture process died: wait status %#o", wstatus);
1292     }
1293   }
1294 #endif
1295
1296   /* No more child process. */
1297   capture_opts->fork_child = -1;
1298
1299   g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "sync_pipe_wait_for_child: capture child closed");
1300 }
1301
1302
1303 #ifndef _WIN32
1304 /* convert signal to corresponding name */
1305 static const char *
1306 sync_pipe_signame(int sig)
1307 {
1308   const char *sigmsg;
1309   static char sigmsg_buf[6+1+3+1];
1310
1311   switch (sig) {
1312
1313   case SIGHUP:
1314     sigmsg = "Hangup";
1315     break;
1316
1317   case SIGINT:
1318     sigmsg = "Interrupted";
1319     break;
1320
1321   case SIGQUIT:
1322     sigmsg = "Quit";
1323     break;
1324
1325   case SIGILL:
1326     sigmsg = "Illegal instruction";
1327     break;
1328
1329   case SIGTRAP:
1330     sigmsg = "Trace trap";
1331     break;
1332
1333   case SIGABRT:
1334     sigmsg = "Abort";
1335     break;
1336
1337   case SIGFPE:
1338     sigmsg = "Arithmetic exception";
1339     break;
1340
1341   case SIGKILL:
1342     sigmsg = "Killed";
1343     break;
1344
1345   case SIGBUS:
1346     sigmsg = "Bus error";
1347     break;
1348
1349   case SIGSEGV:
1350     sigmsg = "Segmentation violation";
1351     break;
1352
1353   /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO
1354      Linux is POSIX compliant.  These are not POSIX-defined signals ---
1355      ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
1356
1357         ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
1358         were omitted from POSIX.1 because their behavior is
1359         implementation dependent and could not be adequately catego-
1360         rized.  Conforming implementations may deliver these sig-
1361         nals, but must document the circumstances under which they
1362         are delivered and note any restrictions concerning their
1363         delivery.''
1364
1365      So we only check for SIGSYS on those systems that happen to
1366      implement them (a system can be POSIX-compliant and implement
1367      them, it's just that POSIX doesn't *require* a POSIX-compliant
1368      system to implement them).
1369    */
1370
1371 #ifdef SIGSYS
1372   case SIGSYS:
1373     sigmsg = "Bad system call";
1374     break;
1375 #endif
1376
1377   case SIGPIPE:
1378     sigmsg = "Broken pipe";
1379     break;
1380
1381   case SIGALRM:
1382     sigmsg = "Alarm clock";
1383     break;
1384
1385   case SIGTERM:
1386     sigmsg = "Terminated";
1387     break;
1388
1389   default:
1390         /* Returning a static buffer is ok in the context we use it here */
1391     g_snprintf(sigmsg_buf, sizeof sigmsg_buf, "Signal %d", sig);
1392     sigmsg = sigmsg_buf;
1393     break;
1394   }
1395   return sigmsg;
1396 }
1397 #endif
1398
1399
1400 #ifdef _WIN32
1401 /* tell the child through the signal pipe that we want to quit the capture */
1402 static void
1403 signal_pipe_capquit_to_child(capture_options *capture_opts)
1404 {
1405     const char quit_msg[] = "QUIT";
1406     int ret;
1407
1408
1409     g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "signal_pipe_capquit_to_child");
1410
1411     /* it doesn't matter *what* we send here, the first byte will stop the capture */
1412     /* simply sending a "QUIT" string */
1413     /*pipe_write_block(capture_opts->signal_pipe_write_fd, SP_QUIT, quit_msg);*/
1414     ret = write(capture_opts->signal_pipe_write_fd, quit_msg, sizeof quit_msg);
1415     if(ret == -1) {
1416         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1417               "signal_pipe_capquit_to_child: %d header: error %s", capture_opts->signal_pipe_write_fd, strerror(errno));
1418     }
1419 }
1420 #endif
1421
1422
1423 /* user wants to stop the capture run */
1424 void
1425 sync_pipe_stop(capture_options *capture_opts)
1426 {
1427 #ifdef _WIN32
1428   int count;
1429   DWORD childstatus;
1430   gboolean terminate = TRUE;
1431 #endif
1432
1433   if (capture_opts->fork_child != -1) {
1434 #ifndef _WIN32
1435     /* send the SIGINT signal to close the capture child gracefully. */
1436     int sts = kill(capture_opts->fork_child, SIGINT);
1437     if (sts != 0) {
1438         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1439               "Sending SIGINT to child failed: %s\n", strerror(errno));
1440     }
1441 #else
1442 #define STOP_SLEEP_TIME 500 /* ms */
1443 #define STOP_CHECK_TIME 50
1444     /* First, use the special signal pipe to try to close the capture child
1445      * gracefully.
1446      */
1447     signal_pipe_capquit_to_child(capture_opts);
1448
1449     /* Next, wait for the process to exit on its own */
1450     for (count = 0; count < STOP_SLEEP_TIME / STOP_CHECK_TIME; count++) {
1451       if (GetExitCodeProcess((HANDLE) capture_opts->fork_child, &childstatus) &&
1452               childstatus != STILL_ACTIVE) {
1453         terminate = FALSE;
1454         break;
1455       }
1456       Sleep(STOP_CHECK_TIME);
1457     }
1458
1459     /* Force the issue. */
1460     if (terminate) {
1461       g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1462             "sync_pipe_stop: forcing child to exit");
1463       sync_pipe_kill(capture_opts->fork_child);
1464     }
1465 #endif
1466   }
1467 }
1468
1469
1470 /* Wireshark has to exit, force the capture child to close */
1471 void
1472 sync_pipe_kill(int fork_child)
1473 {
1474     if (fork_child != -1) {
1475 #ifndef _WIN32
1476         int sts = kill(fork_child, SIGTERM);    /* SIGTERM so it can clean up if necessary */
1477         if (sts != 0) {
1478             g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_WARNING,
1479                   "Sending SIGTERM to child failed: %s\n", strerror(errno));
1480         }
1481 #else
1482       /* Remark: This is not the preferred method of closing a process!
1483        * the clean way would be getting the process id of the child process,
1484        * then getting window handle hWnd of that process (using EnumChildWindows),
1485        * and then do a SendMessage(hWnd, WM_CLOSE, 0, 0)
1486        *
1487        * Unfortunately, I don't know how to get the process id from the
1488        * handle.  OpenProcess will get an handle (not a window handle)
1489        * from the process ID; it will not get a window handle from the
1490        * process ID.  (How could it?  A process can have more than one
1491        * window.  For that matter, a process might have *no* windows,
1492        * as a process running dumpcap, the normal child process program,
1493        * probably does.)
1494        *
1495        * Hint: GenerateConsoleCtrlEvent() will only work if both processes are
1496        * running in the same console; that's not necessarily the case for
1497        * us, as we might not be running in a console.
1498        * And this also will require to have the process id.
1499        */
1500         TerminateProcess((HANDLE) (fork_child), 0);
1501 #endif
1502     }
1503 }
1504
1505 #endif /* HAVE_LIBPCAP */