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