Patch from Ben Fowler to rename the global variable "cf" to "cfile", to
[obnox/wireshark/wip.git] / capture.c
1 /* capture.c
2  * Routines for packet capture windows
3  *
4  * $Id: capture.c,v 1.109 2000/06/27 04:35:42 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_LIBPCAP
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #ifdef HAVE_SYS_STAT_H
38 # include <sys/stat.h>
39 #endif
40
41 #ifdef HAVE_SYS_WAIT_H
42 # include <sys/wait.h>
43 #endif
44 #ifdef HAVE_IO_H
45 #include <io.h>
46 #endif
47
48 #include <gtk/gtk.h>
49 #include <stdlib.h>
50 #include <stdio.h>
51 #include <ctype.h>
52 #include <string.h>
53 #include <fcntl.h>
54
55 #ifdef HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58
59 #include <time.h>
60
61 #ifdef HAVE_SYS_SOCKET_H
62 #include <sys/socket.h>
63 #endif
64
65 #ifdef HAVE_SYS_IOCTL_H
66 #include <sys/ioctl.h>
67 #endif
68
69 #ifdef HAVE_NET_IF_H
70 #include <net/if.h>
71 #endif
72
73 #include <signal.h>
74 #include <errno.h>
75
76 #ifdef NEED_SNPRINTF_H
77 # ifdef HAVE_STDARG_H
78 #  include <stdarg.h>
79 # else
80 #  include <varargs.h>
81 # endif
82 # include "snprintf.h"
83 #endif
84
85 #ifndef lib_pcap_h
86 #include <pcap.h>
87 #endif
88
89 #ifdef _WIN32
90 #include <process.h>    /* For spawning child process */
91 #endif
92
93 #include "gtk/main.h"
94 #include "gtk/gtkglobals.h"
95 #include "packet.h"
96 #include "file.h"
97 #include "capture.h"
98 #include "util.h"
99 #include "simple_dialog.h"
100 #include "prefs.h"
101 #include "globals.h"
102
103 #include "packet-clip.h"
104 #include "packet-eth.h"
105 #include "packet-fddi.h"
106 #include "packet-null.h"
107 #include "packet-ppp.h"
108 #include "packet-raw.h"
109 #include "packet-tr.h"
110
111 int sync_mode;  /* fork a child to do the capture, and sync between them */
112 static int sync_pipe[2]; /* used to sync father */
113 enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
114 int quit_after_cap; /* Makes a "capture only mode". Implies -k */
115 gboolean capture_child; /* if this is the child for "-S" */
116 static guint cap_input_id;
117
118 #ifdef _WIN32
119 static guint cap_timer_id;
120 static int cap_timer_cb(gpointer); /* Win32 kludge to check for pipe input */
121 #endif
122
123 static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
124 static void capture_delete_cb(GtkWidget *, GdkEvent *, gpointer);
125 static void capture_stop_cb(GtkWidget *, gpointer);
126 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
127   const u_char *);
128 static void send_errmsg_to_parent(const char *);
129 static float pct(gint, gint);
130
131 typedef struct _loop_data {
132   gint           go;
133   gint           max;
134   gint           linktype;
135   gint           sync_packets;
136   packet_counts  counts;
137   wtap_dumper   *pdh;
138 } loop_data;
139
140 /* Win32 needs the O_BINARY flag for open() */
141 #ifndef O_BINARY
142 #define O_BINARY        0
143 #endif
144
145 #ifdef _WIN32
146 /* Win32 needs a handle to the child capture process */
147 int child_process;
148 #endif
149
150 /* Open a specified file, or create a temporary file, and start a capture
151    to the file in question. */
152 void
153 do_capture(char *capfile_name)
154 {
155   char tmpname[128+1];
156   gboolean is_tempfile;
157   u_char c;
158   int i;
159   guint byte_count;
160   char *msg;
161   int err;
162   int capture_succeeded;
163
164   if (capfile_name != NULL) {
165     /* Try to open/create the specified file for use as a capture buffer. */
166     cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600);
167     is_tempfile = FALSE;
168   } else {
169     /* Choose a random name for the capture buffer */
170     cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
171     capfile_name = g_strdup(tmpname);
172     is_tempfile = TRUE;
173   }
174   if (cfile.save_file_fd == -1) {
175     simple_dialog(ESD_TYPE_WARN, NULL,
176         "The file to which the capture would be saved (\"%s\")"
177         "could not be opened: %s.", capfile_name, strerror(errno));
178     return;
179   }
180   close_cap_file(&cfile, info_bar);
181   g_assert(cfile.save_file == NULL);
182   cfile.save_file = capfile_name;
183
184   if (sync_mode) {      /* do the capture in a child process */
185     int  fork_child;
186     char ssnap[24];
187     char scount[24];    /* need a constant for len of numbers */
188     char save_file_fd[24];
189     char errmsg[1024+1];
190     int error;
191 #ifdef _WIN32
192     char sync_pipe_fd[24];
193     char *filterstring;
194 #endif
195
196     sprintf(ssnap,"%d",cfile.snap); /* in lieu of itoa */
197     sprintf(scount,"%d",cfile.count);
198     sprintf(save_file_fd,"%d",cfile.save_file_fd);
199
200 #ifdef _WIN32
201     /* Create a pipe for the child process */
202
203     if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
204       /* Couldn't create the pipe between parent and child. */
205       error = errno;
206       unlink(cfile.save_file);
207       g_free(cfile.save_file);
208       cfile.save_file = NULL;
209       simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't create sync pipe: %s",
210                         strerror(error));
211       return;
212     }
213
214     /* Convert pipe write handle to a string and pass to child */
215     itoa(sync_pipe[WRITE], sync_pipe_fd, 10);
216     /* Convert filter string to a quote delimited string */
217     filterstring = g_new(char, strlen(cfile.cfilter) + 3);
218     sprintf(filterstring, "\"%s\"", cfile.cfilter);
219     filterstring[strlen(cfile.cfilter) + 2] = 0;
220     /* Spawn process */
221     fork_child = spawnlp(_P_NOWAIT, ethereal_path, CHILD_NAME, "-i", cfile.iface,
222                          "-w", cfile.save_file, "-W", save_file_fd,
223                          "-c", scount, "-s", ssnap,
224                          "-Z", sync_pipe_fd,
225                          strlen(cfile.cfilter) == 0 ? (const char *)NULL : "-f",
226                          strlen(cfile.cfilter) == 0 ? (const char *)NULL : filterstring,
227                          (const char *)NULL);
228     g_free(filterstring);
229     /* Keep a copy for later evaluation by _cwait() */
230     child_process = fork_child;
231 #else
232     signal(SIGCHLD, SIG_IGN);
233     if (pipe(sync_pipe) < 0) {
234       /* Couldn't create the pipe between parent and child. */
235       error = errno;
236       unlink(cfile.save_file);
237       g_free(cfile.save_file);
238       cfile.save_file = NULL;
239       simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't create sync pipe: %s",
240                         strerror(error));
241       return;
242     }
243     if ((fork_child = fork()) == 0) {
244       /*
245        * Child process - run Ethereal with the right arguments to make
246        * it just pop up the live capture dialog box and capture with
247        * the specified capture parameters, writing to the specified file.
248        *
249        * args: -i interface specification
250        * -w file to write
251        * -W file descriptor to write
252        * -c count to capture
253        * -s snaplen
254        * -m / -b fonts
255        * -f "filter expression"
256        */
257       close(1);
258       dup(sync_pipe[WRITE]);
259       close(sync_pipe[READ]);
260       execlp(ethereal_path, CHILD_NAME, "-i", cfile.iface,
261                 "-w", cfile.save_file, "-W", save_file_fd,
262                 "-c", scount, "-s", ssnap, 
263                 "-m", medium_font, "-b", bold_font,
264                 (cfile.cfilter == NULL)? 0 : "-f",
265                 (cfile.cfilter == NULL)? 0 : cfile.cfilter,
266                 (const char *)NULL);    
267       snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
268                 ethereal_path, strerror(errno));
269       send_errmsg_to_parent(errmsg);
270
271       /* Exit with "_exit()", so that we don't close the connection
272          to the X server (and cause stuff buffered up by our parent but
273          not yet sent to be sent, as that stuff should only be sent by
274          our parent). */
275       _exit(2);
276     }
277 #endif
278
279     /* Parent process - read messages from the child process over the
280        sync pipe. */
281
282     /* Close the write side of the pipe, so that only the child has it
283        open, and thus it completely closes, and thus returns to us
284        an EOF indication, if the child closes it (either deliberately
285        or by exiting abnormally). */
286     close(sync_pipe[WRITE]);
287
288     /* Close the save file FD, as we won't be using it - we'll be opening
289        it and reading the save file through Wiretap. */
290     close(cfile.save_file_fd);
291
292     if (fork_child == -1) {
293       /* We couldn't even create the child process. */
294       error = errno;
295       close(sync_pipe[READ]);
296       unlink(cfile.save_file);
297       g_free(cfile.save_file);
298       cfile.save_file = NULL;
299       simple_dialog(ESD_TYPE_WARN, NULL, "Couldn't create child process: %s",
300                         strerror(error));
301       return;
302     }
303
304     /* Read a byte count from "sync_pipe[READ]", terminated with a
305        colon; if the count is 0, the child process created the
306        capture file and we should start reading from it, otherwise
307        the capture couldn't start and the count is a count of bytes
308        of error message, and we should display the message. */
309     byte_count = 0;
310     for (;;) {
311       i = read(sync_pipe[READ], &c, 1);
312       if (i == 0) {
313         /* EOF - the child process died.
314            Close the read side of the sync pipe, remove the capture file,
315            and report the failure.
316            XXX - reap the child process and report the status in detail. */
317         close(sync_pipe[READ]);
318         unlink(cfile.save_file);
319         g_free(cfile.save_file);
320         cfile.save_file = NULL;
321         simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
322         return;
323       }
324       if (c == ';')
325         break;
326       if (!isdigit(c)) {
327         /* Child process handed us crap.
328            Close the read side of the sync pipe, remove the capture file,
329            and report the failure. */
330         close(sync_pipe[READ]);
331         unlink(cfile.save_file);
332         g_free(cfile.save_file);
333         cfile.save_file = NULL;
334         simple_dialog(ESD_TYPE_WARN, NULL,
335                         "Capture child process sent us a bad message");
336         return;
337       }
338       byte_count = byte_count*10 + c - '0';
339     }
340     if (byte_count == 0) {
341       /* Success.  Open the capture file, and set up to read it. */
342       err = start_tail_cap_file(cfile.save_file, is_tempfile, &cfile);
343       if (err == 0) {
344         /* We were able to open and set up to read the capture file;
345            arrange that our callback be called whenever it's possible
346            to read from the sync pipe, so that it's called when
347            the child process wants to tell us something. */
348 #ifdef _WIN32
349         /* Tricky to use pipes in win9x, as no concept of wait.  NT can
350            do this but that doesn't cover all win32 platforms.  GTK can do
351            this but doesn't seem to work over processes.  Attempt to do
352            something similar here, start a timer and check for data on every
353            timeout. */
354         cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
355 #else
356         cap_input_id = gtk_input_add_full(sync_pipe[READ],
357                                        GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
358                                        cap_file_input_cb,
359                                        NULL,
360                                        (gpointer) &cfile,
361                                        NULL);
362 #endif
363       } else {
364         /* We weren't able to open the capture file; complain, and
365            close the sync pipe. */
366         simple_dialog(ESD_TYPE_WARN, NULL,
367                         file_open_error_message(err, FALSE), cfile.save_file);
368
369         /* Close the sync pipe. */
370         close(sync_pipe[READ]);
371
372         /* Don't unlink the save file - leave it around, for debugging
373            purposes. */
374         g_free(cfile.save_file);
375         cfile.save_file = NULL;
376       }
377     } else {
378       /* Failure - the child process sent us a message indicating
379          what the problem was. */
380       msg = g_malloc(byte_count + 1);
381       if (msg == NULL) {
382         simple_dialog(ESD_TYPE_WARN, NULL,
383                 "Capture child process failed, but its error message was too big.");
384       } else {
385         i = read(sync_pipe[READ], msg, byte_count);
386         if (i < 0) {
387           simple_dialog(ESD_TYPE_WARN, NULL,
388                   "Capture child process failed: Error %s reading its error message.",
389                   strerror(errno));
390         } else if (i == 0) {
391           simple_dialog(ESD_TYPE_WARN, NULL,
392                   "Capture child process failed: EOF reading its error message.");
393         } else
394           simple_dialog(ESD_TYPE_WARN, NULL, msg);
395         g_free(msg);
396
397         /* Close the sync pipe. */
398         close(sync_pipe[READ]);
399
400         /* Get rid of the save file - the capture never started. */
401         unlink(cfile.save_file);
402         g_free(cfile.save_file);
403         cfile.save_file = NULL;
404       }
405     }
406   } else {
407     /* Not sync mode. */
408     capture_succeeded = capture();
409     if (quit_after_cap) {
410       /* DON'T unlink the save file.  Presumably someone wants it. */
411       gtk_exit(0);
412     }
413     if (capture_succeeded) {
414       /* Capture succeeded; read in the capture file. */
415       if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
416         /* Set the read filter to NULL. */
417         cfile.rfcode = NULL;
418         err = read_cap_file(&cfile);
419       }
420     }
421     /* We're not doing a capture any more, so we don't have a save
422        file. */
423     g_free(cfile.save_file);
424     cfile.save_file = NULL;
425   }
426 }
427
428 #ifdef _WIN32
429 /* The timer has expired, see if there's stuff to read from the pipe,
430    if so call the cap_file_input_cb */
431 static gint
432 cap_timer_cb(gpointer data)
433 {
434   HANDLE handle;
435   DWORD avail = 0;
436   gboolean result, result1;
437   DWORD childstatus;
438
439   /* Oddly enough although Named pipes don't work on win9x,
440      PeekNamedPipe does !!! */
441   handle = (HANDLE) _get_osfhandle (sync_pipe[READ]);
442   result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
443
444   /* Get the child process exit status */
445   result1 = GetExitCodeProcess((HANDLE)child_process, &childstatus);
446
447   /* If the Peek returned an error, or there are bytes to be read
448      or the childwatcher thread has terminated then call the normal
449      callback */
450   if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
451
452     /* avoid reentrancy problems and stack overflow */
453     gtk_timeout_remove(cap_timer_id);
454
455     /* And call the real handler */
456     cap_file_input_cb((gpointer) &cfile, 0, 0);
457
458     /* Return false so that the timer is not run again */
459     return FALSE;
460   }
461   else {
462     /* No data so let timer run again */
463     return TRUE;
464   }
465 }
466 #endif
467
468 /* There's stuff to read from the sync pipe, meaning the child has sent
469    us a message, or the sync pipe has closed, meaning the child has
470    closed it (perhaps because it exited). */
471 static void 
472 cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
473 {
474   capture_file *cf = (capture_file *)data;
475   char buffer[256+1], *p = buffer, *q = buffer;
476   int  nread;
477   int  to_read = 0;
478   gboolean exit_loop = FALSE;
479   int  err;
480   int  wstatus;
481   int  wsignal;
482   char *msg;
483   char *sigmsg;
484   char sigmsg_buf[6+1+3+1];
485   char *coredumped;
486
487 #ifndef _WIN32
488   /* avoid reentrancy problems and stack overflow */
489   gtk_input_remove(cap_input_id);
490 #endif
491
492   if ((nread = read(sync_pipe[READ], buffer, 256)) <= 0) {
493     /* The child has closed the sync pipe, meaning it's not going to be
494        capturing any more packets.  Pick up its exit status, and
495        complain if it died of a signal. */
496 #ifdef _WIN32
497     /* XXX - analyze the wait stuatus and display more information
498        in the dialog box? */
499     if (_cwait(&wstatus, child_process, _WAIT_CHILD) == -1) {
500       simple_dialog(ESD_TYPE_WARN, NULL, "Child capture process stopped unexpectedly");
501     }
502 #else
503     if (wait(&wstatus) != -1) {
504       /* XXX - are there any platforms on which we can run that *don't*
505          support POSIX.1's <sys/wait.h> and macros therein? */
506       wsignal = wstatus & 0177;
507       coredumped = "";
508       if (wstatus == 0177) {
509         /* It stopped, rather than exiting.  "Should not happen." */
510         msg = "stopped";
511         wsignal = (wstatus >> 8) & 0xFF;
512       } else {
513         msg = "terminated";
514         if (wstatus & 0200)
515           coredumped = " - core dumped";
516       }
517       if (wsignal != 0) {
518         switch (wsignal) {
519
520         case SIGHUP:
521           sigmsg = "Hangup";
522           break;
523
524         case SIGINT:
525           sigmsg = "Interrupted";
526           break;
527
528         case SIGQUIT:
529           sigmsg = "Quit";
530           break;
531
532         case SIGILL:
533           sigmsg = "Illegal instruction";
534           break;
535
536         case SIGTRAP:
537           sigmsg = "Trace trap";
538           break;
539
540         case SIGABRT:
541           sigmsg = "Abort";
542           break;
543
544         case SIGFPE:
545           sigmsg = "Arithmetic exception";
546           break;
547
548         case SIGKILL:
549           sigmsg = "Killed";
550           break;
551
552         case SIGBUS:
553           sigmsg = "Bus error";
554           break;
555
556         case SIGSEGV:
557           sigmsg = "Segmentation violation";
558           break;
559
560         /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO 
561                 Linux is POSIX compliant.  These are not POSIX-defined signals ---
562                   ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
563
564                ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
565                 were omitted from POSIX.1 because their behavior is
566                 implementation dependent and could not be adequately catego-
567                 rized.  Conforming implementations may deliver these sig-
568                 nals, but must document the circumstances under which they
569                 are delivered and note any restrictions concerning their
570                 delivery.''
571         */
572
573         #ifdef SIGSYS
574         case SIGSYS:
575           sigmsg = "Bad system call";
576           break;
577         #endif
578
579         case SIGPIPE:
580           sigmsg = "Broken pipe";
581           break;
582
583         case SIGALRM:
584           sigmsg = "Alarm clock";
585           break;
586
587         case SIGTERM:
588           sigmsg = "Terminated";
589           break;
590
591         default:
592           sprintf(sigmsg_buf, "Signal %d", wsignal);
593           sigmsg = sigmsg_buf;
594           break;
595         }
596         simple_dialog(ESD_TYPE_WARN, NULL,
597                 "Child capture process %s: %s%s", msg, sigmsg, coredumped);
598       }
599     }
600 #endif
601       
602     /* Read what remains of the capture file, and finish the capture.
603        XXX - do something if this fails? */
604     err = finish_tail_cap_file(cf);
605
606     /* We're not doing a capture any more, so we don't have a save
607        file. */
608     g_free(cf->save_file);
609     cf->save_file = NULL;
610
611     return;
612   }
613
614   buffer[nread] = '\0';
615
616   while(!exit_loop) {
617     /* look for (possibly multiple) '*' */
618     switch (*q) {
619     case '*' :
620       to_read += atoi(p);
621       p = q + 1; 
622       q++;
623       break;
624     case '\0' :
625       /* XXX should handle the case of a pipe full (i.e. no star found) */
626       exit_loop = TRUE;
627       break;
628     default :
629       q++;
630       break;
631     } 
632   }
633
634   /* Read from the capture file the number of records the child told us
635      it added.
636      XXX - do something if this fails? */
637   err = continue_tail_cap_file(cf, to_read);
638
639   /* restore pipe handler */
640 #ifdef _WIN32
641   cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
642 #else
643   cap_input_id = gtk_input_add_full (sync_pipe[READ],
644                                      GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
645                                      cap_file_input_cb,
646                                      NULL,
647                                      (gpointer) cf,
648                                      NULL);
649 #endif
650 }
651
652 /*
653  * Timeout, in milliseconds, for reads from the stream of captured packets.
654  */
655 #define CAP_READ_TIMEOUT        250
656
657 /* Do the low-level work of a capture.
658    Returns TRUE if it succeeds, FALSE otherwise. */
659 int
660 capture(void)
661 {
662   GtkWidget  *cap_w, *main_vb, *count_lb, *sctp_lb, *tcp_lb, *udp_lb, *icmp_lb,
663              *ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
664   pcap_t     *pch;
665   gchar       err_str[PCAP_ERRBUF_SIZE], label_str[32];
666   loop_data   ld;
667   bpf_u_int32 netnum, netmask;
668   time_t      upd_time, cur_time;
669   int         err, inpkts;
670   char        errmsg[1024+1];
671 #ifdef linux
672   fd_set      set1;
673   struct timeval timeout;
674   int         pcap_fd;
675 #endif
676 #ifdef _WIN32 
677   WORD wVersionRequested; 
678   WSADATA wsaData; 
679 #endif
680
681   /* Initialize Windows Socket if we are in a WIN32 OS 
682      This needs to be done before querying the interface for network/netmask */
683 #ifdef _WIN32 
684   wVersionRequested = MAKEWORD( 1, 1 ); 
685   err = WSAStartup( wVersionRequested, &wsaData ); 
686   if (err!=0) { 
687     snprintf(errmsg, sizeof errmsg, 
688       "Couldn't initialize Windows Sockets."); 
689         pch=NULL; 
690     goto error; 
691   } 
692 #endif 
693
694   ld.go             = TRUE;
695   ld.counts.total   = 0;
696   ld.max            = cfile.count;
697   ld.linktype       = WTAP_ENCAP_UNKNOWN;
698   ld.sync_packets   = 0;
699   ld.counts.sctp    = 0;
700   ld.counts.tcp     = 0;
701   ld.counts.udp     = 0;
702   ld.counts.icmp    = 0;
703   ld.counts.ospf    = 0;
704   ld.counts.gre     = 0;
705   ld.counts.ipx     = 0;
706   ld.counts.netbios = 0;
707   ld.counts.vines   = 0;
708   ld.counts.other   = 0;
709   ld.pdh            = NULL;
710
711   /* Open the network interface to capture from it. */
712   pch = pcap_open_live(cfile.iface, cfile.snap, 1, CAP_READ_TIMEOUT, err_str);
713
714   if (pch == NULL) {
715     /* Well, we couldn't start the capture.
716        If this is a child process that does the capturing in sync
717        mode or fork mode, it shouldn't do any UI stuff until we pop up the
718        capture-progress window, and, since we couldn't start the
719        capture, we haven't popped it up. */
720     if (!capture_child) {
721       while (gtk_events_pending()) gtk_main_iteration();
722     }
723     snprintf(errmsg, sizeof errmsg,
724       "The capture session could not be initiated (%s).\n"
725       "Please check to make sure you have sufficient permissions, and that\n"
726       "you have the proper interface specified.", err_str);
727     goto error;
728   }
729
730   if (cfile.cfilter) {
731     /* A capture filter was specified; set it up. */
732     if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
733       snprintf(errmsg, sizeof errmsg,
734         "Can't use filter:  Couldn't obtain netmask info (%s).", err_str);
735       goto error;
736     }
737     if (pcap_compile(pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
738       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
739         pcap_geterr(pch));
740       goto error;
741     }
742     if (pcap_setfilter(pch, &cfile.fcode) < 0) {
743       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
744         pcap_geterr(pch));
745       goto error;
746     }
747   }
748
749   /* Set up to write to the capture file. */
750   ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(pch));
751   if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
752     strcpy(errmsg, "The network you're capturing from is of a type"
753              " that Ethereal doesn't support.");
754     goto error;
755   }
756   ld.pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP,
757                 ld.linktype, pcap_snapshot(pch), &err);
758
759   if (ld.pdh == NULL) {
760     /* We couldn't set up to write to the capture file. */
761     switch (err) {
762
763     case WTAP_ERR_CANT_OPEN:
764       strcpy(errmsg, "The file to which the capture would be saved"
765                " couldn't be created for some unknown reason.");
766       break;
767
768     case WTAP_ERR_SHORT_WRITE:
769       strcpy(errmsg, "A full header couldn't be written to the file"
770                " to which the capture would be saved.");
771       break;
772
773     default:
774       if (err < 0) {
775         sprintf(errmsg, "The file to which the capture would be"
776                      " saved (\"%s\") could not be opened: Error %d.",
777                         cfile.save_file, err);
778       } else {
779         sprintf(errmsg, "The file to which the capture would be"
780                      " saved (\"%s\") could not be opened: %s.",
781                         cfile.save_file, strerror(err));
782       }
783       break;
784     }
785     goto error;
786   }
787
788   if (capture_child) {
789     /* Well, we should be able to start capturing.
790
791        This is the child process for a sync mode capture, so sync out
792        the capture file, so the header makes it to the file system,
793        and send a "capture started successfully and capture file created"
794        message to our parent so that they'll open the capture file and
795        update its windows to indicate that we have a live capture in
796        progress. */
797     fflush(wtap_dump_file(ld.pdh));
798     write(1, "0;", 2);
799   }
800
801   cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
802   gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture / Playback");
803
804   /* Container for capture display widgets */
805   main_vb = gtk_vbox_new(FALSE, 1);
806   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
807   gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
808   gtk_widget_show(main_vb);
809
810   count_lb = gtk_label_new("Count: 0");
811   gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
812   gtk_widget_show(count_lb);
813
814   sctp_lb = gtk_label_new("SCTP: 0 (0.0%)");
815   gtk_box_pack_start(GTK_BOX(main_vb), sctp_lb, FALSE, FALSE, 3);
816   gtk_widget_show(sctp_lb);
817
818   tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
819   gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
820   gtk_widget_show(tcp_lb);
821
822   udp_lb = gtk_label_new("UDP: 0 (0.0%)");
823   gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
824   gtk_widget_show(udp_lb);
825
826   icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
827   gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
828   gtk_widget_show(icmp_lb);
829
830   ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
831   gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
832   gtk_widget_show(ospf_lb);
833
834   gre_lb = gtk_label_new("GRE: 0 (0.0%)");
835   gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
836   gtk_widget_show(gre_lb);
837
838   netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
839   gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
840   gtk_widget_show(netbios_lb);
841
842   ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
843   gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
844   gtk_widget_show(ipx_lb);
845
846   vines_lb = gtk_label_new("VINES: 0 (0.0%)");
847   gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
848   gtk_widget_show(vines_lb);
849
850   other_lb = gtk_label_new("Other: 0 (0.0%)");
851   gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
852   gtk_widget_show(other_lb);
853
854   /* allow user to either click a stop button, or the close button on
855         the window to stop a capture in progress. */
856   stop_bt = gtk_button_new_with_label ("Stop");
857   gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
858     GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
859   gtk_signal_connect(GTK_OBJECT(cap_w), "delete_event",
860         GTK_SIGNAL_FUNC(capture_delete_cb), (gpointer) &ld);
861   gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
862   GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
863   gtk_widget_grab_default(stop_bt);
864   GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
865   gtk_widget_grab_default(stop_bt);
866   gtk_widget_show(stop_bt);
867
868   gtk_widget_show(cap_w);
869   gtk_grab_add(cap_w);
870
871   upd_time = time(NULL);
872 #ifdef linux
873   pcap_fd = pcap_fileno(pch);
874 #endif
875   while (ld.go) {
876     while (gtk_events_pending()) gtk_main_iteration();
877 #ifdef linux
878     /*
879      * Sigh.  The semantics of the read timeout argument to
880      * "pcap_open_live()" aren't particularly well specified by
881      * the "pcap" man page - at least with the BSD BPF code, the
882      * intent appears to be, at least in part, a way of cutting
883      * down the number of reads done on a capture, by blocking
884      * until the buffer fills or a timer expires - and the Linux
885      * libpcap doesn't actually support it, so we can't use it
886      * to break out of the "pcap_dispatch()" every 1/4 of a second
887      * or so.
888      *
889      * Thus, on Linux, we do a "select()" on the file descriptor for the
890      * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or
891      * CAP_READ_TIMEOUT*1000 microseconds.
892      */
893     FD_ZERO(&set1);
894     FD_SET(pcap_fd, &set1);
895     timeout.tv_sec = 0;
896     timeout.tv_usec = CAP_READ_TIMEOUT*1000;
897     if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
898       /*
899        * "select()" says we can read from it without blocking; go for
900        * it.
901        */
902       inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
903     } else
904       inpkts = 0;
905 #else
906     inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
907 #endif
908     if (inpkts > 0)
909       ld.sync_packets += inpkts;
910     /* Only update once a second so as not to overload slow displays */
911     cur_time = time(NULL);
912     if (cur_time > upd_time) {
913       upd_time = cur_time;
914
915       sprintf(label_str, "Count: %d", ld.counts.total);
916       gtk_label_set(GTK_LABEL(count_lb), label_str);
917
918       sprintf(label_str, "SCTP: %d (%.1f%%)", ld.counts.sctp,
919                 pct(ld.counts.sctp, ld.counts.total));
920       gtk_label_set(GTK_LABEL(sctp_lb), label_str);
921
922       sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
923                 pct(ld.counts.tcp, ld.counts.total));
924       gtk_label_set(GTK_LABEL(tcp_lb), label_str);
925
926       sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
927                 pct(ld.counts.udp, ld.counts.total));
928       gtk_label_set(GTK_LABEL(udp_lb), label_str);
929
930       sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
931                 pct(ld.counts.icmp, ld.counts.total));
932       gtk_label_set(GTK_LABEL(icmp_lb), label_str);
933
934       sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
935                 pct(ld.counts.ospf, ld.counts.total));
936       gtk_label_set(GTK_LABEL(ospf_lb), label_str);
937
938       sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
939                 pct(ld.counts.gre, ld.counts.total));
940       gtk_label_set(GTK_LABEL(gre_lb), label_str);
941
942       sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
943                 pct(ld.counts.netbios, ld.counts.total));
944       gtk_label_set(GTK_LABEL(netbios_lb), label_str);
945
946       sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
947                 pct(ld.counts.ipx, ld.counts.total));
948       gtk_label_set(GTK_LABEL(ipx_lb), label_str);
949
950       sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
951                 pct(ld.counts.vines, ld.counts.total));
952       gtk_label_set(GTK_LABEL(vines_lb), label_str);
953
954       sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
955                 pct(ld.counts.other, ld.counts.total));
956       gtk_label_set(GTK_LABEL(other_lb), label_str);
957
958       /* do sync here, too */
959       fflush(wtap_dump_file(ld.pdh));
960       if (capture_child && ld.sync_packets) {
961         /* This is the child process for a sync mode capture, so send
962            our parent a message saying we've written out "ld.sync_packets"
963            packets to the capture file. */
964         char tmp[20];
965         sprintf(tmp, "%d*", ld.sync_packets);
966         write(1, tmp, strlen(tmp));
967         ld.sync_packets = 0;
968       }
969     }
970   }
971     
972   if (!wtap_dump_close(ld.pdh, &err)) {
973     /* XXX - in fork mode, this may not pop up, or, if it does,
974        it may disappear as soon as we exit.
975
976        We should have the parent process, while it's reading
977        the packet count update messages, catch error messages
978        and pop up a message box if it sees one. */
979     switch (err) {
980
981     case WTAP_ERR_CANT_CLOSE:
982       simple_dialog(ESD_TYPE_WARN, NULL,
983                 "The file to which the capture was being saved"
984                 " couldn't be closed for some unknown reason.");
985       break;
986
987     case WTAP_ERR_SHORT_WRITE:
988       simple_dialog(ESD_TYPE_WARN, NULL,
989                 "Not all the data could be written to the file"
990                 " to which the capture was being saved.");
991       break;
992
993     default:
994       simple_dialog(ESD_TYPE_WARN, NULL,
995                 "The file to which the capture was being"
996                 " saved (\"%s\") could not be closed: %s.",
997                 cfile.save_file, wtap_strerror(err));
998       break;
999     }
1000   }
1001   pcap_close(pch);
1002
1003   gtk_grab_remove(GTK_WIDGET(cap_w));
1004   gtk_widget_destroy(GTK_WIDGET(cap_w));
1005
1006   return TRUE;
1007
1008 error:
1009   /* We can't use the save file, and we have no wtap_dump stream
1010      to close in order to close it, so close the FD directly. */
1011   close(cfile.save_file_fd);
1012
1013   /* We couldn't even start the capture, so get rid of the capture
1014      file. */
1015   unlink(cfile.save_file); /* silently ignore error */
1016   g_free(cfile.save_file);
1017   cfile.save_file = NULL;
1018   if (capture_child) {
1019     /* This is the child process for a sync mode capture.
1020        Send the error message to our parent, so they can display a
1021        dialog box containing it. */
1022     send_errmsg_to_parent(errmsg);
1023   } else {
1024     /* Display the dialog box ourselves; there's no parent. */
1025     simple_dialog(ESD_TYPE_WARN, NULL, errmsg);
1026   }
1027   if (pch != NULL)
1028     pcap_close(pch);
1029
1030   return FALSE;
1031 }
1032
1033 static void
1034 send_errmsg_to_parent(const char *errmsg)
1035 {
1036     int msglen = strlen(errmsg);
1037     char lenbuf[10+1+1];
1038
1039     sprintf(lenbuf, "%u;", msglen);
1040     write(1, lenbuf, strlen(lenbuf));
1041     write(1, errmsg, msglen);
1042 }
1043
1044 static float
1045 pct(gint num, gint denom) {
1046   if (denom) {
1047     return (float) num * 100.0 / (float) denom;
1048   } else {
1049     return 0.0;
1050   }
1051 }
1052
1053 static void
1054 capture_delete_cb(GtkWidget *w, GdkEvent *event, gpointer data) {
1055   capture_stop_cb(NULL, data);
1056 }
1057
1058 static void
1059 capture_stop_cb(GtkWidget *w, gpointer data) {
1060   loop_data *ld = (loop_data *) data;
1061   
1062   ld->go = FALSE;
1063 }
1064
1065 static void
1066 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1067   const u_char *pd) {
1068   struct wtap_pkthdr whdr;
1069   loop_data *ld = (loop_data *) user;
1070   int err;
1071
1072   if ((++ld->counts.total >= ld->max) && (ld->max > 0)) 
1073   {
1074      ld->go = FALSE;
1075   }
1076   if (ld->pdh) {
1077      /* "phdr->ts" may not necessarily be a "struct timeval" - it may
1078         be a "struct bpf_timeval", with member sizes wired to 32
1079         bits - and we may go that way ourselves in the future, so
1080         copy the members individually. */
1081      whdr.ts.tv_sec = phdr->ts.tv_sec;
1082      whdr.ts.tv_usec = phdr->ts.tv_usec;
1083      whdr.caplen = phdr->caplen;
1084      whdr.len = phdr->len;
1085      whdr.pkt_encap = ld->linktype;
1086
1087      /* XXX - do something if this fails */
1088      wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
1089   }
1090
1091   /* Set the initial payload to the packet length, and the initial
1092      captured payload to the capture length (other protocols may
1093      reduce them if their headers say they're less). */
1094   pi.len = phdr->len;
1095   pi.captured_len = phdr->caplen;
1096     
1097   switch (ld->linktype) {
1098     case WTAP_ENCAP_ETHERNET:
1099       capture_eth(pd, 0, &ld->counts);
1100       break;
1101     case WTAP_ENCAP_FDDI:
1102     case WTAP_ENCAP_FDDI_BITSWAPPED:
1103       capture_fddi(pd, &ld->counts);
1104       break;
1105     case WTAP_ENCAP_TR:
1106       capture_tr(pd, 0, &ld->counts);
1107       break;
1108     case WTAP_ENCAP_NULL:
1109       capture_null(pd, &ld->counts);
1110       break;
1111     case WTAP_ENCAP_PPP:
1112       capture_ppp(pd, 0, &ld->counts);
1113       break;
1114     case WTAP_ENCAP_RAW_IP:
1115       capture_raw(pd, &ld->counts);
1116       break;
1117     case WTAP_ENCAP_LINUX_ATM_CLIP:
1118       capture_clip(pd, &ld->counts);
1119       break;
1120     /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
1121        with LLC header following; we should implement it at some
1122        point. */
1123   }
1124 }
1125
1126 #endif /* HAVE_LIBPCAP */