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