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