- fix potential buffer overflow problems.
[obnox/wireshark/wip.git] / capture.c
1 /* capture.c
2  * Routines for packet capture windows
3  *
4  * $Id: capture.c,v 1.119 2000/08/14 08:36:39 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
54 #ifdef HAVE_FCNTL_H
55 #include <fcntl.h>
56 #endif
57
58 #ifdef HAVE_UNISTD_H
59 #include <unistd.h>
60 #endif
61
62 #include <time.h>
63
64 #ifdef HAVE_SYS_SOCKET_H
65 #include <sys/socket.h>
66 #endif
67
68 #ifdef HAVE_SYS_IOCTL_H
69 #include <sys/ioctl.h>
70 #endif
71
72 #ifdef HAVE_NET_IF_H
73 #include <net/if.h>
74 #endif
75
76 #include <signal.h>
77 #include <errno.h>
78
79 #ifdef NEED_SNPRINTF_H
80 # include "snprintf.h"
81 #endif
82
83 #ifndef lib_pcap_h
84 #include <pcap.h>
85 #endif
86
87 #ifdef _WIN32
88 #include <process.h>    /* For spawning child process */
89 #endif
90
91 #include "gtk/main.h"
92 #include "gtk/gtkglobals.h"
93 #include "packet.h"
94 #include "file.h"
95 #include "capture.h"
96 #include "util.h"
97 #include "simple_dialog.h"
98 #include "prefs.h"
99 #include "globals.h"
100
101 #include "wiretap/libpcap.h"
102 #include "wiretap/wtap-int.h"
103
104 #include "packet-clip.h"
105 #include "packet-eth.h"
106 #include "packet-fddi.h"
107 #include "packet-null.h"
108 #include "packet-ppp.h"
109 #include "packet-raw.h"
110 #include "packet-tr.h"
111
112 int sync_mode;  /* fork a child to do the capture, and sync between them */
113 static int sync_pipe[2]; /* used to sync father */
114 enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */
115 int quit_after_cap; /* Makes a "capture only mode". Implies -k */
116 gboolean capture_child; /* if this is the child for "-S" */
117 static int fork_child;  /* In parent, process ID of child */
118 static guint cap_input_id;
119
120 #ifdef _WIN32
121 static guint cap_timer_id;
122 static int cap_timer_cb(gpointer); /* Win32 kludge to check for pipe input */
123 #endif
124
125 static void cap_file_input_cb(gpointer, gint, GdkInputCondition);
126 static void capture_delete_cb(GtkWidget *, GdkEvent *, gpointer);
127 static void capture_stop_cb(GtkWidget *, gpointer);
128 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
129   const u_char *);
130 static void send_errmsg_to_parent(const char *);
131 static float pct(gint, gint);
132
133 typedef struct _loop_data {
134   gint           go;
135   gint           max;
136   gint           linktype;
137   gint           sync_packets;
138   gboolean       from_pipe;    /* TRUE if we are capturing data from a pipe */
139   gboolean       modified;     /* TRUE if data in the pipe uses modified pcap headers */
140   gboolean       byte_swapped; /* TRUE if data in the pipe is byte swapped */
141   packet_counts  counts;
142   wtap_dumper   *pdh;
143 } loop_data;
144
145 #ifndef _WIN32
146 static void adjust_header(loop_data *, struct pcap_hdr *, struct pcaprec_hdr *);
147 static int pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *);
148 static int pipe_dispatch(int, loop_data *, struct pcap_hdr *);
149 #endif
150
151 /* Win32 needs the O_BINARY flag for open() */
152 #ifndef O_BINARY
153 #define O_BINARY        0
154 #endif
155
156 #ifdef _WIN32
157 /* Win32 needs a handle to the child capture process */
158 int child_process;
159 #endif
160
161 /* Open a specified file, or create a temporary file, and start a capture
162    to the file in question. */
163 void
164 do_capture(char *capfile_name)
165 {
166   char tmpname[128+1];
167   gboolean is_tempfile;
168   u_char c;
169   int i;
170   guint byte_count;
171   char *msg;
172   int err;
173   int capture_succeeded;
174
175   if (capfile_name != NULL) {
176     /* Try to open/create the specified file for use as a capture buffer. */
177     cfile.save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, 0600);
178     is_tempfile = FALSE;
179   } else {
180     /* Choose a random name for the capture buffer */
181     cfile.save_file_fd = create_tempfile(tmpname, sizeof tmpname, "ether");
182     capfile_name = g_strdup(tmpname);
183     is_tempfile = TRUE;
184   }
185   if (cfile.save_file_fd == -1) {
186     if (is_tempfile) {
187       simple_dialog(ESD_TYPE_CRIT, NULL,
188         "The temporary file to which the capture would be saved (\"%s\")"
189         "could not be opened: %s.", capfile_name, strerror(errno));
190     } else {
191       simple_dialog(ESD_TYPE_CRIT, NULL,
192         file_open_error_message(errno, TRUE), capfile_name);
193     }
194     return;
195   }
196   close_cap_file(&cfile, info_bar);
197   g_assert(cfile.save_file == NULL);
198   cfile.save_file = capfile_name;
199
200   if (sync_mode) {      /* do the capture in a child process */
201     char ssnap[24];
202     char scount[24];    /* need a constant for len of numbers */
203     char save_file_fd[24];
204     char errmsg[1024+1];
205     int error;
206 #ifdef _WIN32
207     char sync_pipe_fd[24];
208     char *filterstring;
209 #endif
210
211     sprintf(ssnap,"%d",cfile.snap); /* in lieu of itoa */
212     sprintf(scount,"%d",cfile.count);
213     sprintf(save_file_fd,"%d",cfile.save_file_fd);
214
215 #ifdef _WIN32
216     /* Create a pipe for the child process */
217
218     if(_pipe(sync_pipe, 512, O_BINARY) < 0) {
219       /* Couldn't create the pipe between parent and child. */
220       error = errno;
221       unlink(cfile.save_file);
222       g_free(cfile.save_file);
223       cfile.save_file = NULL;
224       simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
225                         strerror(error));
226       return;
227     }
228
229     /* Convert pipe write handle to a string and pass to child */
230     itoa(sync_pipe[WRITE], sync_pipe_fd, 10);
231     /* Convert filter string to a quote delimited string */
232     filterstring = g_new(char, strlen(cfile.cfilter) + 3);
233     sprintf(filterstring, "\"%s\"", cfile.cfilter);
234     filterstring[strlen(cfile.cfilter) + 2] = 0;
235     /* Spawn process */
236     fork_child = spawnlp(_P_NOWAIT, ethereal_path, CHILD_NAME, "-i", cfile.iface,
237                          "-w", cfile.save_file, "-W", save_file_fd,
238                          "-c", scount, "-s", ssnap,
239                          "-Z", sync_pipe_fd,
240                          strlen(cfile.cfilter) == 0 ? (const char *)NULL : "-f",
241                          strlen(cfile.cfilter) == 0 ? (const char *)NULL : filterstring,
242                          (const char *)NULL);
243     g_free(filterstring);
244     /* Keep a copy for later evaluation by _cwait() */
245     child_process = fork_child;
246 #else
247     signal(SIGCHLD, SIG_IGN);
248     if (pipe(sync_pipe) < 0) {
249       /* Couldn't create the pipe between parent and child. */
250       error = errno;
251       unlink(cfile.save_file);
252       g_free(cfile.save_file);
253       cfile.save_file = NULL;
254       simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create sync pipe: %s",
255                         strerror(error));
256       return;
257     }
258     if ((fork_child = fork()) == 0) {
259       /*
260        * Child process - run Ethereal with the right arguments to make
261        * it just pop up the live capture dialog box and capture with
262        * the specified capture parameters, writing to the specified file.
263        *
264        * args: -i interface specification
265        * -w file to write
266        * -W file descriptor to write
267        * -c count to capture
268        * -s snaplen
269        * -m / -b fonts
270        * -f "filter expression"
271        */
272       close(1);
273       dup(sync_pipe[WRITE]);
274       close(sync_pipe[READ]);
275       execlp(ethereal_path, CHILD_NAME, "-i", cfile.iface,
276                 "-w", cfile.save_file, "-W", save_file_fd,
277                 "-c", scount, "-s", ssnap, 
278                 "-m", medium_font, "-b", bold_font,
279                 (cfile.cfilter == NULL)? 0 : "-f",
280                 (cfile.cfilter == NULL)? 0 : cfile.cfilter,
281                 (const char *)NULL);    
282       snprintf(errmsg, sizeof errmsg, "Couldn't run %s in child process: %s",
283                 ethereal_path, strerror(errno));
284       send_errmsg_to_parent(errmsg);
285
286       /* Exit with "_exit()", so that we don't close the connection
287          to the X server (and cause stuff buffered up by our parent but
288          not yet sent to be sent, as that stuff should only be sent by
289          our parent). */
290       _exit(2);
291     }
292 #endif
293
294     /* Parent process - read messages from the child process over the
295        sync pipe. */
296
297     /* Close the write side of the pipe, so that only the child has it
298        open, and thus it completely closes, and thus returns to us
299        an EOF indication, if the child closes it (either deliberately
300        or by exiting abnormally). */
301     close(sync_pipe[WRITE]);
302
303     /* Close the save file FD, as we won't be using it - we'll be opening
304        it and reading the save file through Wiretap. */
305     close(cfile.save_file_fd);
306
307     if (fork_child == -1) {
308       /* We couldn't even create the child process. */
309       error = errno;
310       close(sync_pipe[READ]);
311       unlink(cfile.save_file);
312       g_free(cfile.save_file);
313       cfile.save_file = NULL;
314       simple_dialog(ESD_TYPE_CRIT, NULL, "Couldn't create child process: %s",
315                         strerror(error));
316       return;
317     }
318
319     /* Read a byte count from "sync_pipe[READ]", terminated with a
320        colon; if the count is 0, the child process created the
321        capture file and we should start reading from it, otherwise
322        the capture couldn't start and the count is a count of bytes
323        of error message, and we should display the message. */
324     byte_count = 0;
325     for (;;) {
326       i = read(sync_pipe[READ], &c, 1);
327       if (i == 0) {
328         /* EOF - the child process died.
329            Close the read side of the sync pipe, remove the capture file,
330            and report the failure.
331            XXX - reap the child process and report the status in detail. */
332         close(sync_pipe[READ]);
333         unlink(cfile.save_file);
334         g_free(cfile.save_file);
335         cfile.save_file = NULL;
336         simple_dialog(ESD_TYPE_WARN, NULL, "Capture child process died");
337         return;
338       }
339       if (c == ';')
340         break;
341       if (!isdigit(c)) {
342         /* Child process handed us crap.
343            Close the read side of the sync pipe, remove the capture file,
344            and report the failure. */
345         close(sync_pipe[READ]);
346         unlink(cfile.save_file);
347         g_free(cfile.save_file);
348         cfile.save_file = NULL;
349         simple_dialog(ESD_TYPE_WARN, NULL,
350                         "Capture child process sent us a bad message");
351         return;
352       }
353       byte_count = byte_count*10 + c - '0';
354     }
355     if (byte_count == 0) {
356       /* Success.  Open the capture file, and set up to read it. */
357       err = start_tail_cap_file(cfile.save_file, is_tempfile, &cfile);
358       if (err == 0) {
359         /* We were able to open and set up to read the capture file;
360            arrange that our callback be called whenever it's possible
361            to read from the sync pipe, so that it's called when
362            the child process wants to tell us something. */
363 #ifdef _WIN32
364         /* Tricky to use pipes in win9x, as no concept of wait.  NT can
365            do this but that doesn't cover all win32 platforms.  GTK can do
366            this but doesn't seem to work over processes.  Attempt to do
367            something similar here, start a timer and check for data on every
368            timeout. */
369         cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
370 #else
371         cap_input_id = gtk_input_add_full(sync_pipe[READ],
372                                        GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
373                                        cap_file_input_cb,
374                                        NULL,
375                                        (gpointer) &cfile,
376                                        NULL);
377 #endif
378       } else {
379         /* We weren't able to open the capture file; complain, and
380            close the sync pipe. */
381         simple_dialog(ESD_TYPE_CRIT, NULL,
382                         file_open_error_message(err, FALSE), cfile.save_file);
383
384         /* Close the sync pipe. */
385         close(sync_pipe[READ]);
386
387         /* Don't unlink the save file - leave it around, for debugging
388            purposes. */
389         g_free(cfile.save_file);
390         cfile.save_file = NULL;
391       }
392     } else {
393       /* Failure - the child process sent us a message indicating
394          what the problem was. */
395       msg = g_malloc(byte_count + 1);
396       if (msg == NULL) {
397         simple_dialog(ESD_TYPE_WARN, NULL,
398                 "Capture child process failed, but its error message was too big.");
399       } else {
400         i = read(sync_pipe[READ], msg, byte_count);
401         if (i < 0) {
402           simple_dialog(ESD_TYPE_WARN, NULL,
403                   "Capture child process failed: Error %s reading its error message.",
404                   strerror(errno));
405         } else if (i == 0) {
406           simple_dialog(ESD_TYPE_WARN, NULL,
407                   "Capture child process failed: EOF reading its error message.");
408         } else
409           simple_dialog(ESD_TYPE_WARN, NULL, msg);
410         g_free(msg);
411
412         /* Close the sync pipe. */
413         close(sync_pipe[READ]);
414
415         /* Get rid of the save file - the capture never started. */
416         unlink(cfile.save_file);
417         g_free(cfile.save_file);
418         cfile.save_file = NULL;
419       }
420     }
421   } else {
422     /* Not sync mode. */
423     capture_succeeded = capture();
424     if (quit_after_cap) {
425       /* DON'T unlink the save file.  Presumably someone wants it. */
426       gtk_exit(0);
427     }
428     if (capture_succeeded) {
429       /* Capture succeeded; read in the capture file. */
430       if ((err = open_cap_file(cfile.save_file, is_tempfile, &cfile)) == 0) {
431         /* Set the read filter to NULL. */
432         cfile.rfcode = NULL;
433         switch (read_cap_file(&cfile, &err)) {
434
435         case READ_SUCCESS:
436         case READ_ERROR:
437           /* Just because we got an error, that doesn't mean we were unable
438              to read any of the file; we handle what we could get from the
439              file. */
440           break;
441
442         case READ_ABORTED:
443           /* Exit by leaving the main loop, so that any quit functions
444              we registered get called. */
445           gtk_main_quit();
446           return;
447         }
448       }
449     }
450     /* We're not doing a capture any more, so we don't have a save
451        file. */
452     g_free(cfile.save_file);
453     cfile.save_file = NULL;
454   }
455 }
456
457 #ifdef _WIN32
458 /* The timer has expired, see if there's stuff to read from the pipe,
459    if so call the cap_file_input_cb */
460 static gint
461 cap_timer_cb(gpointer data)
462 {
463   HANDLE handle;
464   DWORD avail = 0;
465   gboolean result, result1;
466   DWORD childstatus;
467
468   /* Oddly enough although Named pipes don't work on win9x,
469      PeekNamedPipe does !!! */
470   handle = (HANDLE) _get_osfhandle (sync_pipe[READ]);
471   result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
472
473   /* Get the child process exit status */
474   result1 = GetExitCodeProcess((HANDLE)child_process, &childstatus);
475
476   /* If the Peek returned an error, or there are bytes to be read
477      or the childwatcher thread has terminated then call the normal
478      callback */
479   if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
480
481     /* avoid reentrancy problems and stack overflow */
482     gtk_timeout_remove(cap_timer_id);
483
484     /* And call the real handler */
485     cap_file_input_cb((gpointer) &cfile, 0, 0);
486
487     /* Return false so that the timer is not run again */
488     return FALSE;
489   }
490   else {
491     /* No data so let timer run again */
492     return TRUE;
493   }
494 }
495 #endif
496
497 /* There's stuff to read from the sync pipe, meaning the child has sent
498    us a message, or the sync pipe has closed, meaning the child has
499    closed it (perhaps because it exited). */
500 static void 
501 cap_file_input_cb(gpointer data, gint source, GdkInputCondition condition)
502 {
503   capture_file *cf = (capture_file *)data;
504   char buffer[256+1], *p = buffer, *q = buffer;
505   int  nread;
506   int  to_read = 0;
507   gboolean exit_loop = FALSE;
508   int  err;
509   int  wstatus;
510   int  wsignal;
511   char *msg;
512   char *sigmsg;
513   char sigmsg_buf[6+1+3+1];
514   char *coredumped;
515
516 #ifndef _WIN32
517   /* avoid reentrancy problems and stack overflow */
518   gtk_input_remove(cap_input_id);
519 #endif
520
521   if ((nread = read(sync_pipe[READ], buffer, 256)) <= 0) {
522     /* The child has closed the sync pipe, meaning it's not going to be
523        capturing any more packets.  Pick up its exit status, and
524        complain if it died of a signal. */
525 #ifdef _WIN32
526     /* XXX - analyze the wait stuatus and display more information
527        in the dialog box? */
528     if (_cwait(&wstatus, child_process, _WAIT_CHILD) == -1) {
529       simple_dialog(ESD_TYPE_WARN, NULL, "Child capture process stopped unexpectedly");
530     }
531 #else
532     if (wait(&wstatus) != -1) {
533       /* XXX - are there any platforms on which we can run that *don't*
534          support POSIX.1's <sys/wait.h> and macros therein? */
535       wsignal = wstatus & 0177;
536       coredumped = "";
537       if (wstatus == 0177) {
538         /* It stopped, rather than exiting.  "Should not happen." */
539         msg = "stopped";
540         wsignal = (wstatus >> 8) & 0xFF;
541       } else {
542         msg = "terminated";
543         if (wstatus & 0200)
544           coredumped = " - core dumped";
545       }
546       if (wsignal != 0) {
547         switch (wsignal) {
548
549         case SIGHUP:
550           sigmsg = "Hangup";
551           break;
552
553         case SIGINT:
554           sigmsg = "Interrupted";
555           break;
556
557         case SIGQUIT:
558           sigmsg = "Quit";
559           break;
560
561         case SIGILL:
562           sigmsg = "Illegal instruction";
563           break;
564
565         case SIGTRAP:
566           sigmsg = "Trace trap";
567           break;
568
569         case SIGABRT:
570           sigmsg = "Abort";
571           break;
572
573         case SIGFPE:
574           sigmsg = "Arithmetic exception";
575           break;
576
577         case SIGKILL:
578           sigmsg = "Killed";
579           break;
580
581         case SIGBUS:
582           sigmsg = "Bus error";
583           break;
584
585         case SIGSEGV:
586           sigmsg = "Segmentation violation";
587           break;
588
589         /* http://metalab.unc.edu/pub/Linux/docs/HOWTO/GCC-HOWTO 
590                 Linux is POSIX compliant.  These are not POSIX-defined signals ---
591                   ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
592
593                ``The signals SIGBUS, SIGEMT, SIGIOT, SIGTRAP, and SIGSYS
594                 were omitted from POSIX.1 because their behavior is
595                 implementation dependent and could not be adequately catego-
596                 rized.  Conforming implementations may deliver these sig-
597                 nals, but must document the circumstances under which they
598                 are delivered and note any restrictions concerning their
599                 delivery.''
600         */
601
602         #ifdef SIGSYS
603         case SIGSYS:
604           sigmsg = "Bad system call";
605           break;
606         #endif
607
608         case SIGPIPE:
609           sigmsg = "Broken pipe";
610           break;
611
612         case SIGALRM:
613           sigmsg = "Alarm clock";
614           break;
615
616         case SIGTERM:
617           sigmsg = "Terminated";
618           break;
619
620         default:
621           sprintf(sigmsg_buf, "Signal %d", wsignal);
622           sigmsg = sigmsg_buf;
623           break;
624         }
625         simple_dialog(ESD_TYPE_WARN, NULL,
626                 "Child capture process %s: %s%s", msg, sigmsg, coredumped);
627       }
628     }
629 #endif
630       
631     /* Read what remains of the capture file, and finish the capture.
632        XXX - do something if this fails? */
633     switch (finish_tail_cap_file(cf, &err)) {
634
635     case READ_SUCCESS:
636     case READ_ERROR:
637       /* Just because we got an error, that doesn't mean we were unable
638          to read any of the file; we handle what we could get from the
639          file. */
640       break;
641
642     case READ_ABORTED:
643       /* Exit by leaving the main loop, so that any quit functions
644          we registered get called. */
645       gtk_main_quit();
646       return;
647     }
648
649     /* We're not doing a capture any more, so we don't have a save
650        file. */
651     g_free(cf->save_file);
652     cf->save_file = NULL;
653
654     return;
655   }
656
657   buffer[nread] = '\0';
658
659   while(!exit_loop) {
660     /* look for (possibly multiple) '*' */
661     switch (*q) {
662     case '*' :
663       to_read += atoi(p);
664       p = q + 1; 
665       q++;
666       break;
667     case '\0' :
668       /* XXX should handle the case of a pipe full (i.e. no star found) */
669       exit_loop = TRUE;
670       break;
671     default :
672       q++;
673       break;
674     } 
675   }
676
677   /* Read from the capture file the number of records the child told us
678      it added.
679      XXX - do something if this fails? */
680   switch (continue_tail_cap_file(cf, to_read, &err)) {
681
682   case READ_SUCCESS:
683   case READ_ERROR:
684     /* Just because we got an error, that doesn't mean we were unable
685        to read any of the file; we handle what we could get from the
686        file.
687
688        XXX - abort on a read error? */
689     break;
690
691   case READ_ABORTED:
692     /* Kill the child capture process; the user wants to exit, and we
693        shouldn't just leave it running. */
694 #ifdef _WIN32
695     /* XXX - kill it. */
696 #else
697     kill(fork_child, SIGTERM);  /* SIGTERM so it can clean up if necessary */
698 #endif
699     break;
700   }
701
702   /* restore pipe handler */
703 #ifdef _WIN32
704   cap_timer_id = gtk_timeout_add(1000, cap_timer_cb, NULL);
705 #else
706   cap_input_id = gtk_input_add_full (sync_pipe[READ],
707                                      GDK_INPUT_READ|GDK_INPUT_EXCEPTION,
708                                      cap_file_input_cb,
709                                      NULL,
710                                      (gpointer) cf,
711                                      NULL);
712 #endif
713 }
714
715 /*
716  * Timeout, in milliseconds, for reads from the stream of captured packets.
717  */
718 #define CAP_READ_TIMEOUT        250
719
720 #ifndef _WIN32
721 /* Take carre of byte order in the libpcap headers read from pipes.
722  * (function taken from wiretap/libpcap.c) */
723 static void
724 adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
725 {
726   if (ld->byte_swapped) {
727     /* Byte-swap the record header fields. */
728     rechdr->ts_sec = BSWAP32(rechdr->ts_sec);
729     rechdr->ts_usec = BSWAP32(rechdr->ts_usec);
730     rechdr->incl_len = BSWAP32(rechdr->incl_len);
731     rechdr->orig_len = BSWAP32(rechdr->orig_len);
732   }
733
734   /* In file format version 2.3, the "incl_len" and "orig_len" fields were
735      swapped, in order to match the BPF header layout.
736
737      Unfortunately, some files were, according to a comment in the "libpcap"
738      source, written with version 2.3 in their headers but without the
739      interchanged fields, so if "incl_len" is greater than "orig_len" - which
740      would make no sense - we assume that we need to swap them.  */
741   if (hdr->version_major == 2 &&
742       (hdr->version_minor < 3 ||
743        (hdr->version_minor == 3 && rechdr->incl_len > rechdr->orig_len))) {
744     guint32 temp;
745
746     temp = rechdr->orig_len;
747     rechdr->orig_len = rechdr->incl_len;
748     rechdr->incl_len = temp;
749   }
750 }
751
752 /* Mimic pcap_open_live() for pipe captures 
753  * We check if "pipename" is "-" (stdin) or a FIFO, open it, and read the
754  * header.
755  * N.B. : we can't read the libpcap formats used in RedHat 6.1 or SuSE 6.3
756  * because we can't seek on pipes (see wiretap/libpcap.c for details) */
757 static int
758 pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld, char *ebuf)
759 {
760   struct stat pipe_stat;
761   int         fd;
762   guint32     magic;
763   int         bytes_read, b;
764
765   if (strcmp(pipename, "-") == 0) fd = 0; /* read from stdin */
766   else if (stat(pipename, &pipe_stat) == 0 && S_ISFIFO(pipe_stat.st_mode)) {
767     if ((fd = open(pipename, O_RDONLY)) == -1) return -1;
768   } else return -1;
769
770   ld->from_pipe = TRUE;
771   /* read the pcap header */
772   if (read(fd, &magic, sizeof magic) != sizeof magic) {
773     close(fd);
774     return -1;
775   }
776
777   switch (magic) {
778   case PCAP_MAGIC:
779     /* Host that wrote it has our byte order, and was running
780        a program using either standard or ss990417 libpcap. */
781     ld->byte_swapped = FALSE;
782     ld->modified = FALSE;
783     break;
784   case PCAP_MODIFIED_MAGIC:
785     /* Host that wrote it has our byte order, but was running
786        a program using either ss990915 or ss991029 libpcap. */
787     ld->byte_swapped = FALSE;
788     ld->modified = TRUE;
789     break;
790   case PCAP_SWAPPED_MAGIC:
791     /* Host that wrote it has a byte order opposite to ours,
792        and was running a program using either standard or
793        ss990417 libpcap. */
794     ld->byte_swapped = TRUE;
795     ld->modified = FALSE;
796     break;
797   case PCAP_SWAPPED_MODIFIED_MAGIC:
798     /* Host that wrote it out has a byte order opposite to
799        ours, and was running a program using either ss990915
800        or ss991029 libpcap. */
801     ld->byte_swapped = TRUE;
802     ld->modified = TRUE;
803     break;
804   default:
805     /* Not a "libpcap" type we know about. */
806     close(fd);
807     return -1;
808   }
809
810   /* Read the rest of the header */
811   bytes_read = read(fd, hdr, sizeof(struct pcap_hdr));
812   if (bytes_read <= 0) {
813     close(fd);
814     return -1;
815   }
816   while (bytes_read < sizeof(struct pcap_hdr))
817   {
818     b = read(fd, ((char *)&hdr)+bytes_read, sizeof(struct pcap_hdr) - bytes_read);
819     if (b <= 0) {
820       close(fd);
821       return -1;
822     }
823     bytes_read += b;
824   }
825   if (ld->byte_swapped) {
826     /* Byte-swap the header fields about which we care. */
827     hdr->version_major = BSWAP16(hdr->version_major);
828     hdr->version_minor = BSWAP16(hdr->version_minor);
829     hdr->snaplen = BSWAP32(hdr->snaplen);
830     hdr->network = BSWAP32(hdr->network);
831   }
832   if (hdr->version_major < 2) {
833     close(fd);
834     return -1;
835   }
836
837   return fd;
838 }
839
840 /* We read one record from the pipe, take care of byte order in the record
841  * header, write the record in the capture file, and update capture statistics. */
842 static int
843 pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr)
844 {
845   struct wtap_pkthdr whdr;
846   struct pcaprec_modified_hdr rechdr;
847   int bytes_to_read, bytes_read, b;
848   u_char pd[WTAP_MAX_PACKET_SIZE];
849   int err;
850
851   /* read the record header */
852   bytes_to_read = ld->modified ? sizeof rechdr : sizeof rechdr.hdr;
853   bytes_read = read(fd, &rechdr, bytes_to_read);
854   if (bytes_read <= 0) {
855     close(fd);
856     ld->go = FALSE;
857     return 0;
858   }
859   while (bytes_read < bytes_to_read)
860   {
861     b = read(fd, ((char *)&rechdr)+bytes_read, bytes_to_read - bytes_read);
862     if (b <= 0) {
863       close(fd);
864       ld->go = FALSE;
865       return 0;
866     }
867     bytes_read += b;
868   }
869   /* take care of byte order */
870   adjust_header(ld, hdr, &rechdr.hdr);
871   if (rechdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
872     close(fd);
873     ld->go = FALSE;
874     return 0;
875   }
876   /* read the packet data */
877   bytes_read = read(fd, pd, rechdr.hdr.incl_len);
878   if (bytes_read <= 0) {
879     close(fd);
880     ld->go = FALSE;
881     return 0;
882   }
883   while (bytes_read < rechdr.hdr.incl_len)
884   {
885     b = read(fd, pd+bytes_read, rechdr.hdr.incl_len - bytes_read);
886     if (b <= 0) {
887       close(fd);
888       ld->go = FALSE;
889       return 0;
890     }
891     bytes_read += b;
892   }
893   /* dump the packet data to the capture file */
894   whdr.ts.tv_sec = rechdr.hdr.ts_sec;
895   whdr.ts.tv_usec = rechdr.hdr.ts_usec;
896   whdr.caplen = rechdr.hdr.incl_len;
897   whdr.len = rechdr.hdr.orig_len;
898   whdr.pkt_encap = ld->linktype;
899   wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
900
901   /* Set the initial payload to the packet length, and the initial
902      captured payload to the capture length (other protocols may
903      reduce them if their headers say they're less). */
904   pi.len = whdr.len;
905   pi.captured_len = whdr.caplen;
906     
907   /* update capture statistics */
908   switch (ld->linktype) {
909     case WTAP_ENCAP_ETHERNET:
910       capture_eth(pd, 0, &ld->counts);
911       break;
912     case WTAP_ENCAP_FDDI:
913     case WTAP_ENCAP_FDDI_BITSWAPPED:
914       capture_fddi(pd, &ld->counts);
915       break;
916     case WTAP_ENCAP_TR:
917       capture_tr(pd, 0, &ld->counts);
918       break;
919     case WTAP_ENCAP_NULL:
920       capture_null(pd, &ld->counts);
921       break;
922     case WTAP_ENCAP_PPP:
923       capture_ppp(pd, 0, &ld->counts);
924       break;
925     case WTAP_ENCAP_RAW_IP:
926       capture_raw(pd, &ld->counts);
927       break;
928     case WTAP_ENCAP_LINUX_ATM_CLIP:
929       capture_clip(pd, &ld->counts);
930       break;
931     /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
932        with LLC header following; we should implement it at some
933        point. */
934   }
935
936   return 1;
937 }
938 #endif
939
940 /* Do the low-level work of a capture.
941    Returns TRUE if it succeeds, FALSE otherwise. */
942 int
943 capture(void)
944 {
945   GtkWidget  *cap_w, *main_vb, *count_lb, *sctp_lb, *tcp_lb, *udp_lb, *icmp_lb,
946              *ospf_lb, *gre_lb, *netbios_lb, *ipx_lb, *vines_lb, *other_lb, *stop_bt;
947   pcap_t     *pch;
948   int         pcap_encap;
949   int         snaplen;
950   gchar       err_str[PCAP_ERRBUF_SIZE], label_str[32];
951   loop_data   ld;
952   bpf_u_int32 netnum, netmask;
953   time_t      upd_time, cur_time;
954   int         err, inpkts;
955   char        errmsg[4096+1];
956 #ifndef _WIN32
957   static const char ppamsg[] = "can't find PPA for ";
958   char       *libpcap_warn;
959 #endif
960   fd_set      set1;
961   struct timeval timeout;
962 #ifdef linux
963   int         pcap_fd = 0;
964 #endif
965 #ifdef _WIN32 
966   WORD wVersionRequested; 
967   WSADATA wsaData; 
968 #endif
969 #ifndef _WIN32
970   int         pipe_fd = -1;
971   struct pcap_hdr hdr;
972 #endif
973
974   /* Initialize Windows Socket if we are in a WIN32 OS 
975      This needs to be done before querying the interface for network/netmask */
976 #ifdef _WIN32 
977   wVersionRequested = MAKEWORD( 1, 1 ); 
978   err = WSAStartup( wVersionRequested, &wsaData ); 
979   if (err!=0) { 
980     snprintf(errmsg, sizeof errmsg, 
981       "Couldn't initialize Windows Sockets."); 
982         pch=NULL; 
983     goto error; 
984   } 
985 #endif 
986
987   ld.go             = TRUE;
988   ld.counts.total   = 0;
989   ld.max            = cfile.count;
990   ld.linktype       = WTAP_ENCAP_UNKNOWN;
991   ld.from_pipe      = FALSE;
992   ld.sync_packets   = 0;
993   ld.counts.sctp    = 0;
994   ld.counts.tcp     = 0;
995   ld.counts.udp     = 0;
996   ld.counts.icmp    = 0;
997   ld.counts.ospf    = 0;
998   ld.counts.gre     = 0;
999   ld.counts.ipx     = 0;
1000   ld.counts.netbios = 0;
1001   ld.counts.vines   = 0;
1002   ld.counts.other   = 0;
1003   ld.pdh            = NULL;
1004
1005   /* Open the network interface to capture from it. */
1006   pch = pcap_open_live(cfile.iface, cfile.snap, 1, CAP_READ_TIMEOUT, err_str);
1007
1008   if (pch == NULL) {
1009 #ifdef _WIN32
1010     /* Well, we couldn't start the capture.
1011        If this is a child process that does the capturing in sync
1012        mode or fork mode, it shouldn't do any UI stuff until we pop up the
1013        capture-progress window, and, since we couldn't start the
1014        capture, we haven't popped it up. */
1015     if (!capture_child) {
1016       while (gtk_events_pending()) gtk_main_iteration();
1017     }
1018
1019     /* On Win32 OSes, the capture devices are probably available to all
1020        users; don't warn about permissions problems.
1021
1022        Do, however, warn that Token Ring and PPP devices aren't supported. */
1023     snprintf(errmsg, sizeof errmsg,
1024         "The capture session could not be initiated (%s).\n"
1025         "Please check that you have the proper interface specified.\n"
1026         "\n"
1027         "Note that the driver Ethereal uses for packet capture on Windows\n"
1028         "doesn't support capturing on Token Ring interfaces, and doesn't\n"
1029         "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
1030         err_str);
1031     goto error;
1032 #else
1033     /* try to open cfile.iface as a pipe */
1034     pipe_fd = pipe_open_live(cfile.iface, &hdr, &ld, err_str);
1035
1036     if (pipe_fd == -1) {
1037       /* Well, we couldn't start the capture.
1038          If this is a child process that does the capturing in sync
1039          mode or fork mode, it shouldn't do any UI stuff until we pop up the
1040          capture-progress window, and, since we couldn't start the
1041          capture, we haven't popped it up. */
1042       if (!capture_child) {
1043         while (gtk_events_pending()) gtk_main_iteration();
1044       }
1045
1046       /* If we got a "can't find PPA for XXX" message, warn the user (who
1047          is running Ethereal on HP-UX) that they don't have a version
1048          of libpcap patched to properly handle HP-UX (the patched version
1049          says "can't find /dev/dlpi PPA for XXX" rather than "can't find
1050          PPA for XXX"). */
1051       if (strncmp(err_str, ppamsg, sizeof ppamsg - 1) == 0)
1052         libpcap_warn =
1053           "\n\n"
1054           "You are running Ethereal with a version of the libpcap library\n"
1055           "that doesn't handle HP-UX network devices well; this means that\n"
1056           "Ethereal may not be able to capture packets.\n"
1057           "\n"
1058           "To fix this, you will need to download the source to Ethereal\n"
1059           "from ethereal.zing.org if you have not already done so, read\n"
1060           "the instructions in the \"README.hpux\" file in the source\n"
1061           "distribution, download the source to libpcap if you have not\n"
1062           "already done so, patch libpcap as per the instructions, rebuild\n"
1063           "and install libpcap, and then build Ethereal (if you have already\n"
1064           "built Ethereal from source, do a \"make distclean\" and re-run\n"
1065           "configure before building).";
1066       else
1067         libpcap_warn = "";
1068       snprintf(errmsg, sizeof errmsg,
1069           "The capture session could not be initiated (%s).\n"
1070           "Please check to make sure you have sufficient permissions, and that\n"
1071           "you have the proper interface or pipe specified.%s", err_str,
1072           libpcap_warn);
1073       goto error;
1074     }
1075 #endif
1076   }
1077
1078   /* capture filters only work on real interfaces */
1079   if (cfile.cfilter && !ld.from_pipe) {
1080     /* A capture filter was specified; set it up. */
1081     if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
1082       snprintf(errmsg, sizeof errmsg,
1083         "Can't use filter:  Couldn't obtain netmask info (%s).", err_str);
1084       goto error;
1085     }
1086     if (pcap_compile(pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
1087       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
1088         pcap_geterr(pch));
1089       goto error;
1090     }
1091     if (pcap_setfilter(pch, &cfile.fcode) < 0) {
1092       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
1093         pcap_geterr(pch));
1094       goto error;
1095     }
1096   }
1097
1098   /* Set up to write to the capture file. */
1099 #ifndef _WIN32
1100   if (ld.from_pipe) {
1101     pcap_encap = hdr.network;
1102     snaplen = hdr.snaplen;
1103   } else
1104 #endif
1105   {
1106     pcap_encap = pcap_datalink(pch);
1107     snaplen = pcap_snapshot(pch);
1108   }
1109   ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_encap);
1110   if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
1111     strcpy(errmsg, "The network you're capturing from is of a type"
1112              " that Ethereal doesn't support.");
1113     goto error;
1114   }
1115   ld.pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP,
1116       ld.linktype, snaplen, &err);
1117
1118   if (ld.pdh == NULL) {
1119     /* We couldn't set up to write to the capture file. */
1120     switch (err) {
1121
1122     case WTAP_ERR_CANT_OPEN:
1123       strcpy(errmsg, "The file to which the capture would be saved"
1124                " couldn't be created for some unknown reason.");
1125       break;
1126
1127     case WTAP_ERR_SHORT_WRITE:
1128       strcpy(errmsg, "A full header couldn't be written to the file"
1129                " to which the capture would be saved.");
1130       break;
1131
1132     default:
1133       if (err < 0) {
1134         sprintf(errmsg, "The file to which the capture would be"
1135                      " saved (\"%s\") could not be opened: Error %d.",
1136                         cfile.save_file, err);
1137       } else {
1138         sprintf(errmsg, "The file to which the capture would be"
1139                      " saved (\"%s\") could not be opened: %s.",
1140                         cfile.save_file, strerror(err));
1141       }
1142       break;
1143     }
1144     goto error;
1145   }
1146
1147   /* XXX - capture SIGTERM and close the capture, in case we're on a
1148      Linux 2.0[.x] system and you have to explicitly close the capture
1149      stream in order to turn promiscuous mode off?  We need to do that
1150      in other places as well - and I don't think that works all the
1151      time in any case, due to libpcap bugs. */
1152
1153   if (capture_child) {
1154     /* Well, we should be able to start capturing.
1155
1156        This is the child process for a sync mode capture, so sync out
1157        the capture file, so the header makes it to the file system,
1158        and send a "capture started successfully and capture file created"
1159        message to our parent so that they'll open the capture file and
1160        update its windows to indicate that we have a live capture in
1161        progress. */
1162     fflush(wtap_dump_file(ld.pdh));
1163     write(1, "0;", 2);
1164   }
1165
1166   cap_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1167   gtk_window_set_title(GTK_WINDOW(cap_w), "Ethereal: Capture");
1168   gtk_window_set_modal(GTK_WINDOW(cap_w), TRUE);
1169
1170   /* Container for capture display widgets */
1171   main_vb = gtk_vbox_new(FALSE, 1);
1172   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
1173   gtk_container_add(GTK_CONTAINER(cap_w), main_vb);
1174   gtk_widget_show(main_vb);
1175
1176   count_lb = gtk_label_new("Count: 0");
1177   gtk_box_pack_start(GTK_BOX(main_vb), count_lb, FALSE, FALSE, 3);
1178   gtk_widget_show(count_lb);
1179
1180   sctp_lb = gtk_label_new("SCTP: 0 (0.0%)");
1181   gtk_box_pack_start(GTK_BOX(main_vb), sctp_lb, FALSE, FALSE, 3);
1182   gtk_widget_show(sctp_lb);
1183
1184   tcp_lb = gtk_label_new("TCP: 0 (0.0%)");
1185   gtk_box_pack_start(GTK_BOX(main_vb), tcp_lb, FALSE, FALSE, 3);
1186   gtk_widget_show(tcp_lb);
1187
1188   udp_lb = gtk_label_new("UDP: 0 (0.0%)");
1189   gtk_box_pack_start(GTK_BOX(main_vb), udp_lb, FALSE, FALSE, 3);
1190   gtk_widget_show(udp_lb);
1191
1192   icmp_lb = gtk_label_new("ICMP: 0 (0.0%)");
1193   gtk_box_pack_start(GTK_BOX(main_vb), icmp_lb, FALSE, FALSE, 3);
1194   gtk_widget_show(icmp_lb);
1195
1196   ospf_lb = gtk_label_new("OSPF: 0 (0.0%)");
1197   gtk_box_pack_start(GTK_BOX(main_vb), ospf_lb, FALSE, FALSE, 3);
1198   gtk_widget_show(ospf_lb);
1199
1200   gre_lb = gtk_label_new("GRE: 0 (0.0%)");
1201   gtk_box_pack_start(GTK_BOX(main_vb), gre_lb, FALSE, FALSE, 3);
1202   gtk_widget_show(gre_lb);
1203
1204   netbios_lb = gtk_label_new("NetBIOS: 0 (0.0%)");
1205   gtk_box_pack_start(GTK_BOX(main_vb), netbios_lb, FALSE, FALSE, 3);
1206   gtk_widget_show(netbios_lb);
1207
1208   ipx_lb = gtk_label_new("IPX: 0 (0.0%)");
1209   gtk_box_pack_start(GTK_BOX(main_vb), ipx_lb, FALSE, FALSE, 3);
1210   gtk_widget_show(ipx_lb);
1211
1212   vines_lb = gtk_label_new("VINES: 0 (0.0%)");
1213   gtk_box_pack_start(GTK_BOX(main_vb), vines_lb, FALSE, FALSE, 3);
1214   gtk_widget_show(vines_lb);
1215
1216   other_lb = gtk_label_new("Other: 0 (0.0%)");
1217   gtk_box_pack_start(GTK_BOX(main_vb), other_lb, FALSE, FALSE, 3);
1218   gtk_widget_show(other_lb);
1219
1220   /* allow user to either click a stop button, or the close button on
1221         the window to stop a capture in progress. */
1222   stop_bt = gtk_button_new_with_label ("Stop");
1223   gtk_signal_connect(GTK_OBJECT(stop_bt), "clicked",
1224     GTK_SIGNAL_FUNC(capture_stop_cb), (gpointer) &ld);
1225   gtk_signal_connect(GTK_OBJECT(cap_w), "delete_event",
1226         GTK_SIGNAL_FUNC(capture_delete_cb), (gpointer) &ld);
1227   gtk_box_pack_end(GTK_BOX(main_vb), stop_bt, FALSE, FALSE, 3);
1228   GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1229   gtk_widget_grab_default(stop_bt);
1230   GTK_WIDGET_SET_FLAGS(stop_bt, GTK_CAN_DEFAULT);
1231   gtk_widget_grab_default(stop_bt);
1232   gtk_widget_show(stop_bt);
1233
1234   gtk_widget_show(cap_w);
1235
1236   upd_time = time(NULL);
1237 #ifdef linux
1238   if (!ld.from_pipe) pcap_fd = pcap_fileno(pch);
1239 #endif
1240   while (ld.go) {
1241     while (gtk_events_pending()) gtk_main_iteration();
1242
1243 #ifndef _WIN32
1244     if (ld.from_pipe) {
1245       FD_ZERO(&set1);
1246       FD_SET(pipe_fd, &set1);
1247       timeout.tv_sec = 0;
1248       timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1249       if (select(pipe_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1250         /*
1251          * "select()" says we can read from the pipe without blocking; go for
1252          * it. We are not sure we can read a whole record, but at least the
1253          * begninning of one. pipe_dispatch() will block reading the whole
1254          * record.
1255          */
1256         inpkts = pipe_dispatch(pipe_fd, &ld, &hdr);
1257       } else
1258         inpkts = 0;
1259     }
1260     else
1261 #endif
1262     {
1263 #ifdef linux
1264       /*
1265        * Sigh.  The semantics of the read timeout argument to
1266        * "pcap_open_live()" aren't particularly well specified by
1267        * the "pcap" man page - at least with the BSD BPF code, the
1268        * intent appears to be, at least in part, a way of cutting
1269        * down the number of reads done on a capture, by blocking
1270        * until the buffer fills or a timer expires - and the Linux
1271        * libpcap doesn't actually support it, so we can't use it
1272        * to break out of the "pcap_dispatch()" every 1/4 of a second
1273        * or so.
1274        *
1275        * Thus, on Linux, we do a "select()" on the file descriptor for the
1276        * capture, with a timeout of CAP_READ_TIMEOUT milliseconds, or
1277        * CAP_READ_TIMEOUT*1000 microseconds.
1278        */
1279       FD_ZERO(&set1);
1280       FD_SET(pcap_fd, &set1);
1281       timeout.tv_sec = 0;
1282       timeout.tv_usec = CAP_READ_TIMEOUT*1000;
1283       if (select(pcap_fd+1, &set1, NULL, NULL, &timeout) != 0) {
1284         /*
1285          * "select()" says we can read from it without blocking; go for
1286          * it.
1287          */
1288         inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1289       } else
1290         inpkts = 0;
1291 #else
1292       inpkts = pcap_dispatch(pch, 1, capture_pcap_cb, (u_char *) &ld);
1293 #endif
1294     }
1295     if (inpkts > 0)
1296       ld.sync_packets += inpkts;
1297     /* Only update once a second so as not to overload slow displays */
1298     cur_time = time(NULL);
1299     if (cur_time > upd_time) {
1300       upd_time = cur_time;
1301
1302       sprintf(label_str, "Count: %d", ld.counts.total);
1303       gtk_label_set(GTK_LABEL(count_lb), label_str);
1304
1305       sprintf(label_str, "SCTP: %d (%.1f%%)", ld.counts.sctp,
1306                 pct(ld.counts.sctp, ld.counts.total));
1307       gtk_label_set(GTK_LABEL(sctp_lb), label_str);
1308
1309       sprintf(label_str, "TCP: %d (%.1f%%)", ld.counts.tcp,
1310                 pct(ld.counts.tcp, ld.counts.total));
1311       gtk_label_set(GTK_LABEL(tcp_lb), label_str);
1312
1313       sprintf(label_str, "UDP: %d (%.1f%%)", ld.counts.udp,
1314                 pct(ld.counts.udp, ld.counts.total));
1315       gtk_label_set(GTK_LABEL(udp_lb), label_str);
1316
1317       sprintf(label_str, "ICMP: %d (%.1f%%)", ld.counts.icmp,
1318                 pct(ld.counts.icmp, ld.counts.total));
1319       gtk_label_set(GTK_LABEL(icmp_lb), label_str);
1320
1321       sprintf(label_str, "OSPF: %d (%.1f%%)", ld.counts.ospf,
1322                 pct(ld.counts.ospf, ld.counts.total));
1323       gtk_label_set(GTK_LABEL(ospf_lb), label_str);
1324
1325       sprintf(label_str, "GRE: %d (%.1f%%)", ld.counts.gre,
1326                 pct(ld.counts.gre, ld.counts.total));
1327       gtk_label_set(GTK_LABEL(gre_lb), label_str);
1328
1329       sprintf(label_str, "NetBIOS: %d (%.1f%%)", ld.counts.netbios,
1330                 pct(ld.counts.netbios, ld.counts.total));
1331       gtk_label_set(GTK_LABEL(netbios_lb), label_str);
1332
1333       sprintf(label_str, "IPX: %d (%.1f%%)", ld.counts.ipx,
1334                 pct(ld.counts.ipx, ld.counts.total));
1335       gtk_label_set(GTK_LABEL(ipx_lb), label_str);
1336
1337       sprintf(label_str, "VINES: %d (%.1f%%)", ld.counts.vines,
1338                 pct(ld.counts.vines, ld.counts.total));
1339       gtk_label_set(GTK_LABEL(vines_lb), label_str);
1340
1341       sprintf(label_str, "Other: %d (%.1f%%)", ld.counts.other,
1342                 pct(ld.counts.other, ld.counts.total));
1343       gtk_label_set(GTK_LABEL(other_lb), label_str);
1344
1345       /* do sync here, too */
1346       fflush(wtap_dump_file(ld.pdh));
1347       if (capture_child && ld.sync_packets) {
1348         /* This is the child process for a sync mode capture, so send
1349            our parent a message saying we've written out "ld.sync_packets"
1350            packets to the capture file. */
1351         char tmp[20];
1352         sprintf(tmp, "%d*", ld.sync_packets);
1353         write(1, tmp, strlen(tmp));
1354         ld.sync_packets = 0;
1355       }
1356     }
1357   }
1358     
1359   if (!wtap_dump_close(ld.pdh, &err)) {
1360     /* XXX - in fork mode, this may not pop up, or, if it does,
1361        it may disappear as soon as we exit.
1362
1363        We should have the parent process, while it's reading
1364        the packet count update messages, catch error messages
1365        and pop up a message box if it sees one. */
1366     switch (err) {
1367
1368     case WTAP_ERR_CANT_CLOSE:
1369       simple_dialog(ESD_TYPE_WARN, NULL,
1370                 "The file to which the capture was being saved"
1371                 " couldn't be closed for some unknown reason.");
1372       break;
1373
1374     case WTAP_ERR_SHORT_WRITE:
1375       simple_dialog(ESD_TYPE_WARN, NULL,
1376                 "Not all the data could be written to the file"
1377                 " to which the capture was being saved.");
1378       break;
1379
1380     default:
1381       simple_dialog(ESD_TYPE_WARN, NULL,
1382                 "The file to which the capture was being"
1383                 " saved (\"%s\") could not be closed: %s.",
1384                 cfile.save_file, wtap_strerror(err));
1385       break;
1386     }
1387   }
1388 #ifndef _WIN32
1389   if (ld.from_pipe)
1390     close(pipe_fd);
1391   else
1392 #endif
1393     pcap_close(pch);
1394
1395   gtk_grab_remove(GTK_WIDGET(cap_w));
1396   gtk_widget_destroy(GTK_WIDGET(cap_w));
1397
1398   return TRUE;
1399
1400 error:
1401   /* We can't use the save file, and we have no wtap_dump stream
1402      to close in order to close it, so close the FD directly. */
1403   close(cfile.save_file_fd);
1404
1405   /* We couldn't even start the capture, so get rid of the capture
1406      file. */
1407   unlink(cfile.save_file); /* silently ignore error */
1408   g_free(cfile.save_file);
1409   cfile.save_file = NULL;
1410   if (capture_child) {
1411     /* This is the child process for a sync mode capture.
1412        Send the error message to our parent, so they can display a
1413        dialog box containing it. */
1414     send_errmsg_to_parent(errmsg);
1415   } else {
1416     /* Display the dialog box ourselves; there's no parent. */
1417     simple_dialog(ESD_TYPE_CRIT, NULL, errmsg);
1418   }
1419   if (pch != NULL && !ld.from_pipe)
1420     pcap_close(pch);
1421
1422   return FALSE;
1423 }
1424
1425 static void
1426 send_errmsg_to_parent(const char *errmsg)
1427 {
1428     int msglen = strlen(errmsg);
1429     char lenbuf[10+1+1];
1430
1431     sprintf(lenbuf, "%u;", msglen);
1432     write(1, lenbuf, strlen(lenbuf));
1433     write(1, errmsg, msglen);
1434 }
1435
1436 static float
1437 pct(gint num, gint denom) {
1438   if (denom) {
1439     return (float) num * 100.0 / (float) denom;
1440   } else {
1441     return 0.0;
1442   }
1443 }
1444
1445 static void
1446 capture_delete_cb(GtkWidget *w, GdkEvent *event, gpointer data) {
1447   capture_stop_cb(NULL, data);
1448 }
1449
1450 static void
1451 capture_stop_cb(GtkWidget *w, gpointer data) {
1452   loop_data *ld = (loop_data *) data;
1453   
1454   ld->go = FALSE;
1455 }
1456
1457 static void
1458 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1459   const u_char *pd) {
1460   struct wtap_pkthdr whdr;
1461   loop_data *ld = (loop_data *) user;
1462   int err;
1463
1464   if ((++ld->counts.total >= ld->max) && (ld->max > 0)) 
1465   {
1466      ld->go = FALSE;
1467   }
1468   if (ld->pdh) {
1469      /* "phdr->ts" may not necessarily be a "struct timeval" - it may
1470         be a "struct bpf_timeval", with member sizes wired to 32
1471         bits - and we may go that way ourselves in the future, so
1472         copy the members individually. */
1473      whdr.ts.tv_sec = phdr->ts.tv_sec;
1474      whdr.ts.tv_usec = phdr->ts.tv_usec;
1475      whdr.caplen = phdr->caplen;
1476      whdr.len = phdr->len;
1477      whdr.pkt_encap = ld->linktype;
1478
1479      /* XXX - do something if this fails */
1480      wtap_dump(ld->pdh, &whdr, NULL, pd, &err);
1481   }
1482
1483   /* Set the initial payload to the packet length, and the initial
1484      captured payload to the capture length (other protocols may
1485      reduce them if their headers say they're less). */
1486   pi.len = phdr->len;
1487   pi.captured_len = phdr->caplen;
1488     
1489   switch (ld->linktype) {
1490     case WTAP_ENCAP_ETHERNET:
1491       capture_eth(pd, 0, &ld->counts);
1492       break;
1493     case WTAP_ENCAP_FDDI:
1494     case WTAP_ENCAP_FDDI_BITSWAPPED:
1495       capture_fddi(pd, &ld->counts);
1496       break;
1497     case WTAP_ENCAP_TR:
1498       capture_tr(pd, 0, &ld->counts);
1499       break;
1500     case WTAP_ENCAP_NULL:
1501       capture_null(pd, &ld->counts);
1502       break;
1503     case WTAP_ENCAP_PPP:
1504       capture_ppp(pd, 0, &ld->counts);
1505       break;
1506     case WTAP_ENCAP_RAW_IP:
1507       capture_raw(pd, &ld->counts);
1508       break;
1509     case WTAP_ENCAP_LINUX_ATM_CLIP:
1510       capture_clip(pd, &ld->counts);
1511       break;
1512     /* XXX - FreeBSD may append 4-byte ATM pseudo-header to DLT_ATM_RFC1483,
1513        with LLC header following; we should implement it at some
1514        point. */
1515   }
1516 }
1517
1518 #endif /* HAVE_LIBPCAP */