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