Add a preferences page for capture preferences, so that the user can
[obnox/wireshark/wip.git] / tethereal.c
1 /* tethereal.c
2  *
3  * $Id: tethereal.c,v 1.114 2002/01/10 07:43:37 guy Exp $
4  *
5  * Ethereal - Network traffic analyzer
6  * By Gerald Combs <gerald@ethereal.com>
7  * Copyright 1998 Gerald Combs
8  *
9  * Text-mode variant, by Gilbert Ramirez <gram@alumni.rice.edu>
10  * and Guy Harris <guy@alum.mit.edu>.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <locale.h>
36 #include <limits.h>
37
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 #include <errno.h>
43
44 #ifdef HAVE_SYS_TYPES_H
45 #include <sys/types.h>
46 #endif
47
48 #ifdef HAVE_SYS_STAT_H
49 #include <sys/stat.h>
50 #endif
51
52 #ifdef HAVE_FCNTL_H
53 #include <fcntl.h>
54 #endif
55
56 #include <signal.h>
57
58 #ifdef HAVE_LIBPCAP
59 #include <pcap.h>
60 #include <setjmp.h>
61 #endif
62
63 #ifdef HAVE_LIBZ
64 #include <zlib.h>       /* to get the libz version number */
65 #endif
66
67 #ifdef NEED_SNPRINTF_H
68 # include "snprintf.h"
69 #endif
70
71 #if defined(HAVE_UCD_SNMP_SNMP_H)
72 #ifdef HAVE_UCD_SNMP_VERSION_H
73 #include <ucd-snmp/version.h>
74 #endif /* HAVE_UCD_SNMP_VERSION_H */
75 #elif defined(HAVE_SNMP_SNMP_H)
76 #ifdef HAVE_SNMP_VERSION_H
77 #include <snmp/version.h>
78 #endif /* HAVE_SNMP_VERSION_H */
79 #endif /* SNMP */
80
81 #ifdef NEED_STRERROR_H
82 #include "strerror.h"
83 #endif
84
85 #ifdef NEED_GETOPT_H
86 #include "getopt.h"
87 #endif
88
89 #include <glib.h>
90 #include <epan.h>
91
92 #include "globals.h"
93 #include "timestamp.h"
94 #include "packet.h"
95 #include "file.h"
96 #include "prefs.h"
97 #include "column.h"
98 #include "print.h"
99 #include "resolv.h"
100 #include "util.h"
101 #ifdef HAVE_LIBPCAP
102 #include "pcap-util.h"
103 #endif
104 #include "conversation.h"
105 #include "reassemble.h"
106 #include "plugins.h"
107 #include "register.h"
108 #include "conditions.h"
109 #include "capture_stop_conditions.h"
110 #include "ringbuffer.h"
111 #include "epan_dissect.h"
112
113 #ifdef WIN32
114 #include "capture-wpcap.h"
115 #endif
116
117 static guint32 firstsec, firstusec;
118 static guint32 prevsec, prevusec;
119 static GString *comp_info_str;
120 static gboolean verbose;
121 static gboolean print_hex;
122 static gboolean line_buffered;
123
124 #ifdef HAVE_LIBPCAP
125 typedef struct _loop_data {
126   gboolean       go;           /* TRUE as long as we're supposed to keep capturing */
127   gint           linktype;
128   pcap_t        *pch;
129   wtap_dumper   *pdh;
130   jmp_buf        stopenv;
131 } loop_data;
132
133 static loop_data ld;
134
135 static int capture(int, int);
136 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
137   const u_char *);
138 static void capture_cleanup(int);
139 #endif
140
141 typedef struct {
142   capture_file *cf;
143   wtap_dumper *pdh;
144 } cb_args_t;
145
146 static int load_cap_file(capture_file *, int);
147 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, long,
148     union wtap_pseudo_header *, const u_char *);
149 static void show_capture_file_io_error(const char *, int, gboolean);
150 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, long,
151     union wtap_pseudo_header *, const u_char *);
152
153 capture_file cfile;
154 FILE        *data_out_file = NULL;
155 ts_type timestamp_type = RELATIVE;
156 #ifdef HAVE_LIBPCAP
157 static int promisc_mode = TRUE;
158 #endif
159
160 static void 
161 print_usage(void)
162 {
163   int i;
164
165   fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
166         comp_info_str->str);
167 #ifdef HAVE_LIBPCAP
168   fprintf(stderr, "t%s [ -DvVhlp ] [ -a <capture autostop condition> ] ...\n",
169           PACKAGE);
170   fprintf(stderr, "\t[ -b <number of ring buffer files> ] [ -c <count> ]\n");
171   fprintf(stderr, "\t[ -f <capture filter> ] [ -F <capture file type> ]\n");
172   fprintf(stderr, "\t[ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
173   fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
174   fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
175 #else
176   fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
177   fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
178   fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
179 #endif
180   fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
181   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
182     if (wtap_dump_can_open(i))
183       fprintf(stderr, "\t%s - %s\n",
184         wtap_file_type_short_string(i), wtap_file_type_string(i));
185   }
186   fprintf(stderr, "\tdefault is libpcap\n");
187 }
188
189 static int
190 get_positive_int(const char *string, const char *name)
191 {
192   long number;
193   char *p;
194
195   number = strtol(string, &p, 10);
196   if (p == string || *p != '\0') {
197     fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
198             name, string);
199     exit(1);
200   }
201   if (number < 0) {
202     fprintf(stderr, "tethereal: The specified %s \"%s\" is a negative number\n",
203             name, string);
204     exit(1);
205   }
206   if (number > INT_MAX) {
207     fprintf(stderr, "tethereal: The specified %s \"%s\" is too large (greater than %d)\n",
208             name, string, INT_MAX);
209     exit(1);
210   }
211   return number;
212 }
213
214 /*
215  * Given a string of the form "<autostop criterion>:<value>", as might appear
216  * as an argument to a "-a" option, parse it and set the criterion in
217  * question.  Return an indication of whether it succeeded or failed
218  * in some fashion.
219  */
220 static gboolean
221 set_autostop_criterion(const char *autostoparg)
222 {
223   u_char *p, *colonp;
224
225   colonp = strchr(autostoparg, ':');
226   if (colonp == NULL)
227     return FALSE;
228
229   p = colonp;
230   *p++ = '\0';
231
232   /*
233    * Skip over any white space (there probably won't be any, but
234    * as we allow it in the preferences file, we might as well
235    * allow it here).
236    */
237   while (isspace(*p))
238     p++;
239   if (*p == '\0') {
240     /*
241      * Put the colon back, so if our caller uses, in an
242      * error message, the string they passed us, the message
243      * looks correct.
244      */
245     *colonp = ':';
246     return FALSE;
247   }
248   if (strcmp(autostoparg,"duration") == 0) {
249     cfile.autostop_duration = get_positive_int(p,"autostop duration");
250   } else if (strcmp(autostoparg,"filesize") == 0) {
251     cfile.autostop_filesize = get_positive_int(p,"autostop filesize");
252   } else {
253     return FALSE;
254   }
255   *colonp = ':';        /* put the colon back */
256   return TRUE;
257 }
258
259 int
260 main(int argc, char *argv[])
261 {
262   int                  opt, i;
263   extern char         *optarg;
264   gboolean             arg_error = FALSE;
265 #ifdef HAVE_LIBPCAP
266 #ifdef HAVE_PCAP_VERSION
267   extern char          pcap_version[];
268 #endif /* HAVE_PCAP_VERSION */
269 #endif /* HAVE_LIBPCAP */
270
271 #ifdef WIN32
272   WSADATA               wsaData;
273 #endif
274
275   char                *gpf_path;
276   const char          *pf_path;
277   int                  gpf_open_errno, pf_open_errno;
278   int                  err;
279 #ifdef HAVE_LIBPCAP
280   gboolean             capture_filter_specified = FALSE;
281   guint                packet_count = 0;
282   GList               *if_list, *if_entry;
283   gchar                err_str[PCAP_ERRBUF_SIZE];
284 #else
285   gboolean             capture_option_specified = FALSE;
286 #endif
287   int                  out_file_type = WTAP_FILE_PCAP;
288   gchar               *cf_name = NULL, *rfilter = NULL;
289   dfilter_t           *rfcode = NULL;
290   e_prefs             *prefs;
291   char                 badopt;
292
293   /* Register all dissectors; we must do this before checking for the
294      "-G" flag, as the "-G" flag dumps a list of fields registered
295      by the dissectors, and we must do it before we read the preferences,
296      in case any dissectors register preferences. */
297   epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
298
299   /* Now register the preferences for any non-dissector modules.
300      We must do that before we read the preferences as well. */
301   prefs_register_modules();
302
303   /* If invoked with the "-G" flag, we dump out a glossary of
304      display filter symbols.
305
306      We do this here to mirror what happens in the GTK+ version, although
307      it's not necessary here. */
308   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
309     proto_registrar_dump();
310     exit(0);
311   }
312
313   /* Set the C-language locale to the native environment. */
314   setlocale(LC_ALL, "");
315
316   prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
317   if (gpf_path != NULL) {
318     fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
319         strerror(gpf_open_errno));
320   }
321   if (pf_path != NULL) {
322     fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
323         strerror(pf_open_errno));
324   }
325
326 #ifdef WIN32
327   /* Load Wpcap, if possible */
328   load_wpcap();
329 #endif
330     
331   /* Initialize the capture file struct */
332   cfile.plist           = NULL;
333   cfile.plist_end       = NULL;
334   cfile.wth             = NULL;
335   cfile.filename        = NULL;
336   cfile.user_saved      = FALSE;
337   cfile.is_tempfile     = FALSE;
338   cfile.rfcode          = NULL;
339   cfile.dfilter         = NULL;
340   cfile.dfcode          = NULL;
341 #ifdef HAVE_LIBPCAP
342   cfile.cfilter         = g_strdup("");
343 #endif
344   cfile.iface           = NULL;
345   cfile.save_file       = NULL;
346   cfile.save_file_fd    = -1;
347   cfile.snap            = WTAP_MAX_PACKET_SIZE;
348   cfile.count           = 0;
349 #ifdef HAVE_LIBPCAP
350   cfile.autostop_duration = 0;
351   cfile.autostop_filesize = 0;
352   cfile.ringbuffer_on = FALSE;
353   cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
354 #endif
355   col_init(&cfile.cinfo, prefs->num_cols);
356
357   /* Assemble the compile-time options */
358   comp_info_str = g_string_new("");
359
360   g_string_append(comp_info_str, "with ");
361   g_string_sprintfa(comp_info_str,
362 #ifdef GLIB_MAJOR_VERSION
363     "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
364     GLIB_MICRO_VERSION);
365 #else
366     "GLib (version unknown)");
367 #endif
368
369 #ifdef HAVE_LIBPCAP
370   g_string_append(comp_info_str, ", with libpcap ");
371 #ifdef HAVE_PCAP_VERSION
372   g_string_append(comp_info_str, pcap_version);
373 #else /* HAVE_PCAP_VERSION */
374   g_string_append(comp_info_str, "(version unknown)");
375 #endif /* HAVE_PCAP_VERSION */
376 #else /* HAVE_LIBPCAP */
377   g_string_append(comp_info_str, ", without libpcap");
378 #endif /* HAVE_LIBPCAP */
379
380 #ifdef HAVE_LIBZ
381   g_string_append(comp_info_str, ", with libz ");
382 #ifdef ZLIB_VERSION
383   g_string_append(comp_info_str, ZLIB_VERSION);
384 #else /* ZLIB_VERSION */
385   g_string_append(comp_info_str, "(version unknown)");
386 #endif /* ZLIB_VERSION */
387 #else /* HAVE_LIBZ */
388   g_string_append(comp_info_str, ", without libz");
389 #endif /* HAVE_LIBZ */
390
391 /* Oh, this is pretty */
392 #if defined(HAVE_UCD_SNMP_SNMP_H)
393   g_string_append(comp_info_str, ", with UCD SNMP ");
394 #ifdef HAVE_UCD_SNMP_VERSION_H
395   g_string_append(comp_info_str, VersionInfo);
396 #else /* HAVE_UCD_SNMP_VERSION_H */
397   g_string_append(comp_info_str, "(version unknown)");
398 #endif /* HAVE_UCD_SNMP_VERSION_H */
399 #elif defined(HAVE_SNMP_SNMP_H)
400   g_string_append(comp_info_str, ", with CMU SNMP ");
401 #ifdef HAVE_SNMP_VERSION_H
402   g_string_append(comp_info_str, snmp_Version());
403 #else /* HAVE_SNMP_VERSION_H */
404   g_string_append(comp_info_str, "(version unknown)");
405 #endif /* HAVE_SNMP_VERSION_H */
406 #else /* no SNMP */
407   g_string_append(comp_info_str, ", without SNMP");
408 #endif
409     
410   /* Now get our args */
411   while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != EOF) {
412     switch (opt) {
413       case 'a':        /* autostop criteria */
414 #ifdef HAVE_LIBPCAP
415         if (set_autostop_criterion(optarg) == FALSE) {
416           fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
417           exit(1);          
418         }
419 #else
420         capture_option_specified = TRUE;
421         arg_error = TRUE;
422 #endif
423         break;
424       case 'b':        /* Ringbuffer option */
425 #ifdef HAVE_LIBPCAP
426         cfile.ringbuffer_on = TRUE;
427         cfile.ringbuffer_num_files = get_positive_int(optarg, "number of ring buffer files");
428 #else
429         capture_option_specified = TRUE;
430         arg_error = TRUE;
431 #endif
432         break;
433       case 'c':        /* Capture xxx packets */
434 #ifdef HAVE_LIBPCAP
435         packet_count = get_positive_int(optarg, "packet count");
436 #else
437         capture_option_specified = TRUE;
438         arg_error = TRUE;
439 #endif
440         break;
441       case 'D':        /* Print a list of capture devices */
442 #ifdef HAVE_LIBPCAP
443         if_list = get_interface_list(&err, err_str);
444         if (if_list == NULL) {
445             switch (err) {
446
447             case CANT_GET_INTERFACE_LIST:
448                 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
449                         err_str);
450                 break;
451
452             case NO_INTERFACES_FOUND:
453                 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
454                 break;
455             }
456             exit(2);
457         }
458         for (if_entry = g_list_first(if_list); if_entry != NULL;
459                 if_entry = g_list_next(if_entry))
460           printf("%s\n", (char *)if_entry->data);
461         free_interface_list(if_list);
462         exit(0);
463 #else
464         capture_option_specified = TRUE;
465         arg_error = TRUE;
466 #endif
467         break;
468       case 'f':
469 #ifdef HAVE_LIBPCAP
470         capture_filter_specified = TRUE;
471         cfile.cfilter = g_strdup(optarg);
472 #else
473         capture_option_specified = TRUE;
474         arg_error = TRUE;
475 #endif
476         break;
477       case 'F':
478         out_file_type = wtap_short_string_to_file_type(optarg);
479         if (out_file_type < 0) {
480           fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
481                         optarg);
482           exit(1);
483         }
484         break;
485       case 'h':        /* Print help and exit */
486         print_usage();
487         exit(0);
488         break;
489       case 'i':        /* Use interface xxx */
490 #ifdef HAVE_LIBPCAP
491         cfile.iface = g_strdup(optarg);
492 #else
493         capture_option_specified = TRUE;
494         arg_error = TRUE;
495 #endif
496         break;
497       case 'l':        /* "Line-buffer" standard output */
498         /* This isn't line-buffering, strictly speaking, it's just
499            flushing the standard output after the information for
500            each packet is printed; however, that should be good
501            enough for all the purposes to which "-l" is put.
502
503            See the comment in "wtap_dispatch_cb_print()" for an
504            explanation of why we do that, and why we don't just
505            use "setvbuf()" to make the standard output line-buffered
506            (short version: in Windows, "line-buffered" is the same
507            as "fully-buffered", and the output buffer is only flushed
508            when it fills up). */
509         line_buffered = TRUE;
510         break;
511       case 'n':        /* No name resolution */
512         prefs->name_resolve = PREFS_RESOLV_NONE;
513         break;
514       case 'N':        /* Select what types of addresses/port #s to resolve */
515         if (prefs->name_resolve == PREFS_RESOLV_ALL)
516           prefs->name_resolve = PREFS_RESOLV_NONE;
517         badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
518         if (badopt != '\0') {
519           fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
520                         badopt);
521           exit(1);
522         }
523         break;
524       case 'o':        /* Override preference from command line */
525         switch (prefs_set_pref(optarg)) {
526
527         case PREFS_SET_SYNTAX_ERR:
528           fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
529           exit(1);
530           break;
531
532         case PREFS_SET_NO_SUCH_PREF:
533         case PREFS_SET_OBSOLETE:
534           fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
535                         optarg);
536           exit(1);
537           break;
538         }
539         break;
540       case 'p':        /* Don't capture in promiscuous mode */
541 #ifdef HAVE_LIBPCAP
542         promisc_mode = 0;
543 #else
544         capture_option_specified = TRUE;
545         arg_error = TRUE;
546 #endif
547         break;
548       case 'r':        /* Read capture file xxx */
549         cf_name = g_strdup(optarg);
550         break;
551       case 'R':        /* Read file filter */
552         rfilter = optarg;
553         break;
554       case 's':        /* Set the snapshot (capture) length */
555 #ifdef HAVE_LIBPCAP
556         cfile.snap = get_positive_int(optarg, "snapshot length");
557 #else
558         capture_option_specified = TRUE;
559         arg_error = TRUE;
560 #endif
561         break;
562       case 't':        /* Time stamp type */
563         if (strcmp(optarg, "r") == 0)
564           timestamp_type = RELATIVE;
565         else if (strcmp(optarg, "a") == 0)
566           timestamp_type = ABSOLUTE;
567         else if (strcmp(optarg, "ad") == 0)
568           timestamp_type = ABSOLUTE_WITH_DATE;
569         else if (strcmp(optarg, "d") == 0)
570           timestamp_type = DELTA;
571         else {
572           fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
573             optarg);
574           fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
575           fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
576           exit(1);
577         }
578         break;
579       case 'v':        /* Show version and exit */
580         printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
581         exit(0);
582         break;
583       case 'w':        /* Write to capture file xxx */
584         cfile.save_file = g_strdup(optarg);
585         break;
586       case 'V':        /* Verbose */
587         verbose = TRUE;
588         break;
589       case 'x':        /* Print packet data in hex (and ASCII) */
590         print_hex = TRUE;
591         break;
592     }
593   }
594   
595   /* If no capture filter or read filter has been specified, and there are
596      still command-line arguments, treat them as the tokens of a capture
597      filter (if no "-r" flag was specified) or a read filter (if a "-r"
598      flag was specified. */
599   if (optind < argc) {
600     if (cf_name != NULL) {
601       if (rfilter != NULL) {
602         fprintf(stderr,
603 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
604         exit(2);
605       }
606       rfilter = get_args_as_string(argc, argv, optind);
607     } else {
608 #ifdef HAVE_LIBPCAP
609       if (capture_filter_specified) {
610         fprintf(stderr,
611 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
612         exit(2);
613       }
614       cfile.cfilter = get_args_as_string(argc, argv, optind);
615 #else
616       capture_option_specified = TRUE;
617 #endif
618     }
619   }
620
621   /* If they didn't specify a "-w" flag, but specified a maximum capture
622      file size, tell them that this doesn't work, and exit. */
623   if (cfile.autostop_filesize != 0 && cfile.save_file == NULL) {
624     fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
625     exit(2);
626   }
627
628   if (cfile.ringbuffer_on) {
629     /* Ring buffer works only under certain conditions:
630        a) ring buffer does not work if you're not saving the capture to
631           a file;
632        b) it makes no sense to enable the ring buffer if the maximum
633           file size is set to "infinite". */
634     if (cfile.save_file == NULL) {
635       fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved to a file.\n");
636       exit(2);
637     }
638     if (cfile.autostop_filesize == 0) {
639       fprintf(stderr, "tethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
640       exit(2);
641     }
642   }
643
644 #ifdef WIN32
645   /* Start windows sockets */
646   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
647 #endif
648
649   /* Notify all registered modules that have had any of their preferences
650      changed either from one of the preferences file or from the command
651      line that its preferences have changed. */
652   prefs_apply_all();
653
654 #ifndef HAVE_LIBPCAP
655   if (capture_option_specified)
656     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
657 #endif
658   if (arg_error)
659     print_usage();
660
661   /* Build the column format array */  
662   for (i = 0; i < cfile.cinfo.num_cols; i++) {
663     cfile.cinfo.col_fmt[i] = get_column_format(i);
664     cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
665     cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
666       NUM_COL_FMTS);
667     get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
668     cfile.cinfo.col_data[i] = NULL;
669     if (cfile.cinfo.col_fmt[i] == COL_INFO)
670       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
671     else
672       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
673   }
674
675   if (cfile.snap < 1)
676     cfile.snap = WTAP_MAX_PACKET_SIZE;
677   else if (cfile.snap < MIN_PACKET_SIZE)
678     cfile.snap = MIN_PACKET_SIZE;
679   
680   /* Check the value range of the ringbuffer_num_files parameter */
681   if (cfile.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
682     cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
683   else if (cfile.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
684     cfile.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
685   
686   if (rfilter != NULL) {
687     if (!dfilter_compile(rfilter, &rfcode)) {
688       fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
689       epan_cleanup();
690       exit(2);
691     }
692   }
693   cfile.rfcode = rfcode;
694   if (cf_name) {
695     err = open_cap_file(cf_name, FALSE, &cfile);
696     if (err != 0) {
697       epan_cleanup();
698       exit(2);
699     }
700     err = load_cap_file(&cfile, out_file_type);
701     if (err != 0) {
702       epan_cleanup();
703       exit(2);
704     }
705     cf_name[0] = '\0';
706   } else {
707     /* No capture file specified, so we're supposed to do a live capture;
708        do we have support for live captures? */
709 #ifdef HAVE_LIBPCAP
710
711 #ifdef _WIN32
712     if (!has_wpcap) {
713         fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
714         exit(2);
715     }
716 #endif
717
718     /* Yes; did the user specify an interface to use? */
719     if (cfile.iface == NULL) {
720         /* No - is a default specified in the preferences file? */
721         if (prefs->capture_device != NULL) {
722             /* Yes - use it. */
723             cfile.iface = g_strdup(prefs->capture_device);
724         } else {
725             /* No - pick the first one from the list of interfaces. */
726             if_list = get_interface_list(&err, err_str);
727             if (if_list == NULL) {
728                 switch (err) {
729
730                 case CANT_GET_INTERFACE_LIST:
731                     fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
732                             err_str);
733                     break;
734
735                 case NO_INTERFACES_FOUND:
736                     fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
737                     break;
738                 }
739                 exit(2);
740             }
741             cfile.iface = g_strdup(if_list->data);      /* first interface */
742             free_interface_list(if_list);
743         }
744     }
745     capture(packet_count, out_file_type);
746
747     if (cfile.ringbuffer_on) {
748       ringbuf_free();
749     }
750 #else
751     /* No - complain. */
752     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
753     exit(2);
754 #endif
755   }
756
757   epan_cleanup();
758
759   return 0;
760 }
761
762 #ifdef HAVE_LIBPCAP
763 /* Do the low-level work of a capture.
764    Returns TRUE if it succeeds, FALSE otherwise. */
765 static int
766 capture(volatile int packet_count, int out_file_type)
767 {
768   gchar       open_err_str[PCAP_ERRBUF_SIZE];
769   gchar       lookup_net_err_str[PCAP_ERRBUF_SIZE];
770   bpf_u_int32 netnum, netmask;
771   struct bpf_program fcode;
772   void        (*oldhandler)(int);
773   int         err;
774   volatile int inpkts = 0;
775   char        errmsg[1024+1];
776   condition *cnd_stop_capturesize;
777   condition *cnd_stop_timeout;
778 #ifndef _WIN32
779   static const char ppamsg[] = "can't find PPA for ";
780   char       *libpcap_warn;
781 #endif
782   struct pcap_stat stats;
783   gboolean    dump_ok;
784
785   /* Initialize the table of conversations. */
786   epan_conversation_init();
787
788   /* Initialize protocol-specific variables */
789   init_all_protocols();
790
791   /* Initialize the common data structures for fragment reassembly.
792      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
793      may free up space for fragments, which it finds by using the
794      data structures that "reassemble_init()" frees. */
795   reassemble_init();
796
797   ld.linktype       = WTAP_ENCAP_UNKNOWN;
798   ld.pdh            = NULL;
799
800   /* Open the network interface to capture from it.
801      Some versions of libpcap may put warnings into the error buffer
802      if they succeed; to tell if that's happened, we have to clear
803      the error buffer, and check if it's still a null string.  */
804   open_err_str[0] = '\0';
805   ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000,
806                           open_err_str);
807
808   if (ld.pch == NULL) {
809     /* Well, we couldn't start the capture. */
810 #ifdef _WIN32
811     /* On Win32 OSes, the capture devices are probably available to all
812        users; don't warn about permissions problems.
813
814        Do, however, warn that Token Ring and PPP devices aren't supported. */
815     snprintf(errmsg, sizeof errmsg,
816         "The capture session could not be initiated (%s).\n"
817         "Please check that you have the proper interface specified.\n"
818         "\n"
819         "Note that the driver Tethereal uses for packet capture on Windows\n"
820         "doesn't support capturing on Token Ring interfaces, and doesn't\n"
821         "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
822         open_err_str);
823 #else
824       /* If we got a "can't find PPA for XXX" message, warn the user (who
825          is running Ethereal on HP-UX) that they don't have a version
826          of libpcap that properly handles HP-UX (libpcap 0.6.x and later
827          versions, which properly handle HP-UX, say "can't find /dev/dlpi
828          PPA for XXX" rather than "can't find PPA for XXX"). */
829       if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
830         libpcap_warn =
831           "\n\n"
832           "You are running Tethereal with a version of the libpcap library\n"
833           "that doesn't handle HP-UX network devices well; this means that\n"
834           "Tethereal may not be able to capture packets.\n"
835           "\n"
836           "To fix this, you should install libpcap 0.6.2, or a later version\n"
837           "of libpcap, rather than libpcap 0.4 or 0.5.x.  It is available in\n"
838           "packaged binary form from the Software Porting And Archive Centre\n"
839           "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
840           "at the URL lists a number of mirror sites.";
841       else
842         libpcap_warn = "";
843     snprintf(errmsg, sizeof errmsg,
844       "The capture session could not be initiated (%s).\n"
845       "Please check to make sure you have sufficient permissions, and that\n"
846       "you have the proper interface specified.%s", open_err_str, libpcap_warn);
847 #endif
848     goto error;
849   }
850
851   if (cfile.cfilter) {
852     /* A capture filter was specified; set it up. */
853     if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
854       /*
855        * Well, we can't get the netmask for this interface; it's used
856        * only for filters that check for broadcast IP addresses, so
857        * we just warn the user, and punt and use 0.
858        */
859       fprintf(stderr, 
860         "Warning:  Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
861       netmask = 0;
862     }
863     if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
864       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
865         pcap_geterr(ld.pch));
866       goto error;
867     }
868     if (pcap_setfilter(ld.pch, &fcode) < 0) {
869       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
870         pcap_geterr(ld.pch));
871       goto error;
872     }
873   }
874
875   ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
876         cfile.iface));
877   if (cfile.save_file != NULL) {
878     /* Set up to write to the capture file. */
879     if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
880       strcpy(errmsg, "The network you're capturing from is of a type"
881                " that Tethereal doesn't support.");
882       goto error;
883     }
884     if (cfile.ringbuffer_on) {
885       cfile.save_file_fd = ringbuf_init(cfile.save_file,
886         cfile.ringbuffer_num_files);
887       if (cfile.save_file_fd != -1) {
888         ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
889           pcap_snapshot(ld.pch), &err);
890       } else {
891         ld.pdh = NULL;
892       }
893     } else {
894       ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
895                  ld.linktype, pcap_snapshot(ld.pch), &err);
896     }
897
898     if (ld.pdh == NULL) {
899       snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
900                 cfile.save_file);
901       goto error;
902     }
903   }
904
905   /* Does "open_err_str" contain a non-empty string?  If so, "pcap_open_live()"
906      returned a warning; print it, but keep capturing. */
907   if (open_err_str[0] != '\0')
908     fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
909
910   /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
911      and exit.
912      XXX - deal with signal semantics on various platforms.  Or just
913      use "sigaction()" and be done with it? */
914   signal(SIGTERM, capture_cleanup);
915   signal(SIGINT, capture_cleanup);
916 #if !defined(WIN32)
917   if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
918     signal(SIGHUP, oldhandler);
919 #endif
920
921   /* Let the user know what interface was chosen. */
922   fprintf(stderr, "Capturing on %s\n", cfile.iface);
923   fflush(stderr);
924
925   /* initialize capture stop conditions */ 
926   init_capture_stop_conditions();
927   /* create stop conditions */
928   cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
929                                  (long)cfile.autostop_filesize * 1000);
930   cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
931                              (gint32)cfile.autostop_duration);
932
933   if (packet_count == 0)
934     packet_count = -1; /* infinite capturng */
935   if (!setjmp(ld.stopenv))
936     ld.go = TRUE;
937   else
938     ld.go = FALSE;
939   while (ld.go) {
940     if (packet_count > 0)
941       packet_count--;
942     inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
943     if (packet_count == 0 || inpkts < 0) {
944       ld.go = FALSE;
945     } else if (cnd_eval(cnd_stop_timeout) == TRUE) {
946       /* The specified capture time has elapsed; stop the capture. */
947       ld.go = FALSE;
948     } else if (ld.pdh != NULL && (cnd_eval(cnd_stop_capturesize, 
949                   (guint32)wtap_get_bytes_dumped(ld.pdh))) == TRUE){
950       /* We're saving the capture to a file, and the capture file reached
951          its maximum size. */
952       if (cfile.ringbuffer_on) {
953         /* Switch to the next ringbuffer file */
954         if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
955           /* File switch failed: reset the condition */
956           cnd_reset(cnd_stop_capturesize);
957         } else {
958           /* File switch failed: stop here */
959           ld.go = FALSE;
960           continue;
961         }
962       } else {
963         /* No ringbuffer - just stop. */
964         ld.go = FALSE;
965       }
966     }
967   }
968   
969   /* delete stop conditions */
970   cnd_delete(cnd_stop_capturesize);
971   cnd_delete(cnd_stop_timeout);
972
973   if (cfile.save_file != NULL) {
974     /* We're saving to a file, which means we're printing packet counts
975        to the standard output.  Send a newline so that we move to the
976        line after the packet count. */
977     fprintf(stderr, "\n");
978   }
979
980   /* If we got an error while capturing, report it. */
981   if (inpkts < 0) {
982     fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
983         pcap_geterr(ld.pch));
984   }
985
986   /* Get the capture statistics, and, if any packets were dropped, report
987      that. */
988   if (pcap_stats(ld.pch, &stats) >= 0) {
989     if (stats.ps_drop != 0) {
990       fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
991     }
992   } else {
993     fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
994         pcap_geterr(ld.pch));
995   }
996
997   pcap_close(ld.pch);
998
999   if (cfile.save_file != NULL) {
1000     /* We're saving to a file or files; close all files. */
1001     if (cfile.ringbuffer_on) {
1002       dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
1003     } else {
1004       dump_ok = wtap_dump_close(ld.pdh, &err);
1005     }
1006     if (!dump_ok)
1007       show_capture_file_io_error(cfile.save_file, err, TRUE);
1008   }
1009
1010   return TRUE;
1011
1012 error:
1013   if (cfile.ringbuffer_on) {
1014     ringbuf_error_cleanup();
1015   }
1016   g_free(cfile.save_file);
1017   cfile.save_file = NULL;
1018   fprintf(stderr, "tethereal: %s\n", errmsg);
1019   if (ld.pch != NULL)
1020     pcap_close(ld.pch);
1021
1022   return FALSE;
1023 }
1024
1025 static void
1026 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1027   const u_char *pd)
1028 {
1029   struct wtap_pkthdr whdr;
1030   loop_data *ld = (loop_data *) user;
1031   cb_args_t args;
1032
1033   whdr.ts.tv_sec = phdr->ts.tv_sec;
1034   whdr.ts.tv_usec = phdr->ts.tv_usec;
1035   whdr.caplen = phdr->caplen;
1036   whdr.len = phdr->len;
1037   whdr.pkt_encap = ld->linktype;
1038
1039   args.cf = &cfile;
1040   args.pdh = ld->pdh;
1041   if (ld->pdh) {
1042     wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1043     fprintf(stderr, "\r%u ", cfile.count);
1044     fflush(stdout);
1045   } else {
1046     wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1047   }
1048 }
1049
1050 static void
1051 capture_cleanup(int signum)
1052 {
1053   /* Longjmp back to the starting point; "pcap_dispatch()", on many
1054      platforms, just keeps looping if it gets EINTR, so if we set
1055      "ld.go" to FALSE and return, we won't break out of it and quit
1056      capturing. */
1057   longjmp(ld.stopenv, 1);
1058 }
1059 #endif /* HAVE_LIBPCAP */
1060
1061 static int
1062 load_cap_file(capture_file *cf, int out_file_type)
1063 {
1064   gint         linktype;
1065   wtap_dumper *pdh;
1066   int          err;
1067   int          success;
1068   cb_args_t    args;
1069
1070   linktype = wtap_file_encap(cf->wth);
1071   if (cf->save_file != NULL) {
1072     /* Set up to write to the capture file. */
1073     pdh = wtap_dump_open(cf->save_file, out_file_type,
1074                 linktype, wtap_snapshot_length(cf->wth), &err);
1075
1076     if (pdh == NULL) {
1077       /* We couldn't set up to write to the capture file. */
1078       switch (err) {
1079
1080       case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1081         fprintf(stderr,
1082                 "tethereal: Capture files can't be written in that format.\n");
1083         break;
1084
1085       case WTAP_ERR_UNSUPPORTED_ENCAP:
1086       case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1087         fprintf(stderr,
1088 "tethereal: The capture file being read cannot be written in that format.\n");
1089         break;
1090
1091       case WTAP_ERR_CANT_OPEN:
1092         fprintf(stderr,
1093 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1094                  cf->save_file);
1095         break;
1096
1097       case WTAP_ERR_SHORT_WRITE:
1098         fprintf(stderr,
1099 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1100                 cf->save_file);
1101         break;
1102
1103       default:
1104         if (err < 0) {
1105           fprintf(stderr,
1106                 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1107                 cf->save_file, err);
1108         } else {
1109           fprintf(stderr,
1110                 "tethereal: The file \"%s\" could not be opened: %s\n.",
1111                 cf->save_file, strerror(err));
1112         }
1113         break;
1114       }
1115       goto out;
1116     }
1117     args.cf = cf;
1118     args.pdh = pdh;
1119     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1120                         &err);
1121
1122     /* Now close the capture file. */
1123     if (!wtap_dump_close(pdh, &err))
1124       show_capture_file_io_error(cfile.save_file, err, TRUE);
1125   } else {
1126     args.cf = cf;
1127     args.pdh = NULL;
1128     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1129                         &err);
1130   }
1131   if (!success) {
1132     /* Print up a message box noting that the read failed somewhere along
1133        the line. */
1134     switch (err) {
1135
1136     case WTAP_ERR_UNSUPPORTED_ENCAP:
1137       fprintf(stderr,
1138 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1139         cf->filename);
1140       break;
1141
1142     case WTAP_ERR_CANT_READ:
1143       fprintf(stderr,
1144 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1145         cf->filename);
1146       break;
1147
1148     case WTAP_ERR_SHORT_READ:
1149       fprintf(stderr,
1150 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1151         cf->filename);
1152       break;
1153
1154     case WTAP_ERR_BAD_RECORD:
1155       fprintf(stderr,
1156 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1157         cf->filename);
1158       break;
1159
1160     default:
1161       fprintf(stderr,
1162 "tethereal: An error occurred while reading \"%s\": %s.\n",
1163         cf->filename, wtap_strerror(err));
1164       break;
1165     }
1166   }
1167
1168 out:
1169   wtap_close(cf->wth);
1170   cf->wth = NULL;
1171
1172   return err;
1173 }
1174
1175 static void
1176 fill_in_fdata(frame_data *fdata, capture_file *cf,
1177         const struct wtap_pkthdr *phdr,
1178         const union wtap_pseudo_header *pseudo_header, long offset)
1179 {
1180   int i;
1181
1182   fdata->next = NULL;
1183   fdata->prev = NULL;
1184   fdata->pfd = NULL;
1185   fdata->data_src = NULL;
1186   fdata->num = cf->count;
1187   fdata->pkt_len = phdr->len;
1188   fdata->cap_len = phdr->caplen;
1189   fdata->file_off = offset;
1190   fdata->lnk_t = phdr->pkt_encap;
1191   fdata->abs_secs  = phdr->ts.tv_sec;
1192   fdata->abs_usecs = phdr->ts.tv_usec;
1193   fdata->flags.passed_dfilter = 0;
1194   fdata->flags.encoding = CHAR_ASCII;
1195   fdata->flags.visited = 0;
1196   fdata->flags.marked = 0;
1197
1198   /* If we don't have the time stamp of the first packet in the
1199      capture, it's because this is the first packet.  Save the time
1200      stamp of this packet as the time stamp of the first packet. */
1201   if (!firstsec && !firstusec) {
1202     firstsec  = fdata->abs_secs;
1203     firstusec = fdata->abs_usecs;
1204   }
1205
1206   /* If we don't have the time stamp of the previous displayed packet,
1207      it's because this is the first displayed packet.  Save the time
1208      stamp of this packet as the time stamp of the previous displayed
1209      packet. */
1210   if (!prevsec && !prevusec) {
1211     prevsec  = fdata->abs_secs;
1212     prevusec = fdata->abs_usecs;
1213   }
1214
1215   /* Get the time elapsed between the first packet and this packet. */
1216   compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1217                 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1218
1219   /* If it's greater than the current elapsed time, set the elapsed time
1220      to it (we check for "greater than" so as not to be confused by
1221      time moving backwards). */
1222   if ((gint32)cf->esec < fdata->rel_secs
1223         || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1224     cf->esec = fdata->rel_secs;
1225     cf->eusec = fdata->rel_usecs;
1226   }
1227   
1228   /* Get the time elapsed between the previous displayed packet and
1229      this packet. */
1230   compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1231                 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1232   prevsec = fdata->abs_secs;
1233   prevusec = fdata->abs_usecs;
1234 }
1235
1236 /* Free up all data attached to a "frame_data" structure. */
1237 static void
1238 clear_fdata(frame_data *fdata)
1239 {
1240   if (fdata->pfd)
1241     g_slist_free(fdata->pfd);
1242   if (fdata->data_src)
1243     g_slist_free(fdata->data_src);
1244 }
1245
1246 static void
1247 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1248   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1249 {
1250   cb_args_t    *args = (cb_args_t *) user;
1251   capture_file *cf = args->cf;
1252   wtap_dumper  *pdh = args->pdh;
1253   frame_data    fdata;
1254   int           err;
1255   gboolean      passed;
1256   epan_dissect_t *edt;
1257
1258   cf->count++;
1259   if (cf->rfcode) {
1260     fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1261     edt = epan_dissect_new(TRUE, FALSE);
1262     epan_dissect_prime_dfilter(edt, cf->rfcode);
1263     epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1264     passed = dfilter_apply_edt(cf->rfcode, edt);
1265   } else {
1266     passed = TRUE;
1267     edt = NULL;
1268   }
1269   if (passed) {
1270     if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1271 #ifdef HAVE_LIBPCAP
1272       if (ld.pch != NULL) {
1273         /* We're capturing packets, so we're printing a count of packets
1274            captured; move to the line after the count. */
1275         fprintf(stderr, "\n");
1276       }
1277 #endif
1278       show_capture_file_io_error(cf->save_file, err, FALSE);
1279 #ifdef HAVE_LIBPCAP
1280       if (ld.pch != NULL)
1281         pcap_close(ld.pch);
1282 #endif
1283       wtap_dump_close(pdh, &err);
1284       exit(2);
1285     }
1286   }
1287   if (edt != NULL)
1288     epan_dissect_free(edt);
1289   if (cf->rfcode)
1290     clear_fdata(&fdata);
1291 }
1292
1293 static void
1294 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1295 {
1296   switch (err) {
1297
1298   case ENOSPC:
1299     fprintf(stderr,
1300 "tethereal: Not all the packets could be written to \"%s\" because there is "
1301 "no space left on the file system.\n",
1302         fname);
1303     break;
1304
1305 #ifdef EDQUOT
1306   case EDQUOT:
1307     fprintf(stderr,
1308 "tethereal: Not all the packets could be written to \"%s\" because you are "
1309 "too close to, or over your disk quota.\n",
1310         fname);
1311   break;
1312 #endif
1313
1314   case WTAP_ERR_CANT_CLOSE:
1315     fprintf(stderr,
1316 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1317         fname);
1318     break;
1319
1320   case WTAP_ERR_SHORT_WRITE:
1321     fprintf(stderr,
1322 "tethereal: Not all the packets could be written to \"%s\".\n",
1323         fname);
1324     break;
1325
1326   default:
1327     if (is_close) {
1328       fprintf(stderr,
1329 "tethereal: \"%s\" could not be closed: %s.\n",
1330         fname, wtap_strerror(err));
1331     } else {
1332       fprintf(stderr,
1333 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1334         fname, wtap_strerror(err));
1335     }
1336     break;
1337   }
1338 }
1339
1340 static void
1341 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1342   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1343 {
1344   cb_args_t    *args = (cb_args_t *) user;
1345   capture_file *cf = args->cf;
1346   frame_data    fdata;
1347   gboolean      passed;
1348   print_args_t  print_args;
1349   epan_dissect_t *edt;
1350   gboolean      create_proto_tree;
1351   int           i;
1352
1353   cf->count++;
1354
1355   fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1356
1357   passed = TRUE;
1358   if (cf->rfcode || verbose)
1359     create_proto_tree = TRUE;
1360   else
1361     create_proto_tree = FALSE;
1362   /* The protocol tree will be "visible", i.e., printed, only if we're
1363      not printing a summary.
1364
1365      We only need the columns if we're *not* verbose; in verbose mode,
1366      we print the protocol tree, not the protocol summary. */
1367   edt = epan_dissect_new(create_proto_tree, verbose);
1368   if (cf->rfcode) {
1369     epan_dissect_prime_dfilter(edt, cf->rfcode);
1370   }
1371   epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1372   if (cf->rfcode) {
1373     passed = dfilter_apply_edt(cf->rfcode, edt);
1374   }
1375   if (passed) {
1376     /* The packet passed the read filter. */
1377     if (verbose) {
1378       /* Print the information in the protocol tree. */
1379       print_args.to_file = TRUE;
1380       print_args.format = PR_FMT_TEXT;
1381       print_args.print_summary = FALSE;
1382       print_args.print_hex = print_hex;
1383       print_args.expand_all = TRUE;
1384       print_args.suppress_unmarked = FALSE;
1385       proto_tree_print(FALSE, &print_args, (GNode *)edt->tree,
1386                         &fdata, stdout);
1387       if (!print_hex) {
1388         /* "print_hex_data()" will put out a leading blank line, as well
1389            as a trailing one; print one here, to separate the packets,
1390            only if "print_hex_data()" won't be called. */
1391         printf("\n");
1392       }
1393     } else {
1394       /* Just fill in the columns. */
1395       epan_dissect_fill_in_columns(edt);
1396
1397       /* Now print them. */
1398       for (i = 0; i < cf->cinfo.num_cols; i++) {
1399         switch (cf->cinfo.col_fmt[i]) {
1400         case COL_NUMBER:
1401           /*
1402            * Don't print this if we're doing a live capture from a network
1403            * interface - if we're doing a live capture, you won't be
1404            * able to look at the capture in the future (it's not being
1405            * saved anywhere), so the frame numbers are unlikely to be
1406            * useful.
1407            *
1408            * (XXX - it might be nice to be able to save and print at
1409            * the same time, sort of like an "Update list of packets
1410            * in real time" capture in Ethereal.)
1411            */
1412           if (cf->iface != NULL)
1413             continue;
1414           printf("%3s", cf->cinfo.col_data[i]);
1415           break;
1416
1417         case COL_CLS_TIME:
1418         case COL_REL_TIME:
1419         case COL_ABS_TIME:
1420         case COL_ABS_DATE_TIME: /* XXX - wider */
1421           printf("%10s", cf->cinfo.col_data[i]);
1422           break;
1423
1424         case COL_DEF_SRC:
1425         case COL_RES_SRC:
1426         case COL_UNRES_SRC:
1427         case COL_DEF_DL_SRC:
1428         case COL_RES_DL_SRC:
1429         case COL_UNRES_DL_SRC:
1430         case COL_DEF_NET_SRC:
1431         case COL_RES_NET_SRC:
1432         case COL_UNRES_NET_SRC:
1433           printf("%12s", cf->cinfo.col_data[i]);
1434           break;
1435
1436         case COL_DEF_DST:
1437         case COL_RES_DST:
1438         case COL_UNRES_DST:
1439         case COL_DEF_DL_DST:
1440         case COL_RES_DL_DST:
1441         case COL_UNRES_DL_DST:
1442         case COL_DEF_NET_DST:
1443         case COL_RES_NET_DST:
1444         case COL_UNRES_NET_DST:
1445           printf("%-12s", cf->cinfo.col_data[i]);
1446           break;
1447
1448         default:
1449           printf("%s", cf->cinfo.col_data[i]);
1450           break;
1451         }
1452         if (i != cf->cinfo.num_cols - 1) {
1453           /*
1454            * This isn't the last column, so we need to print a
1455            * separator between this column and the next.
1456            *
1457            * If we printed a network source and are printing a
1458            * network destination of the same type next, separate
1459            * them with "->"; if we printed a network destination
1460            * and are printing a network source of the same type
1461            * next, separate them with "<-"; otherwise separate them
1462            * with a space.
1463            */
1464           switch (cf->cinfo.col_fmt[i]) {
1465
1466           case COL_DEF_SRC:
1467           case COL_RES_SRC:
1468           case COL_UNRES_SRC:
1469             switch (cf->cinfo.col_fmt[i + 1]) {
1470
1471             case COL_DEF_DST:
1472             case COL_RES_DST:
1473             case COL_UNRES_DST:
1474               printf(" -> ");
1475               break;
1476
1477             default:
1478               putchar(' ');
1479               break;
1480             }
1481             break;
1482
1483           case COL_DEF_DL_SRC:
1484           case COL_RES_DL_SRC:
1485           case COL_UNRES_DL_SRC:
1486             switch (cf->cinfo.col_fmt[i + 1]) {
1487
1488             case COL_DEF_DL_DST:
1489             case COL_RES_DL_DST:
1490             case COL_UNRES_DL_DST:
1491               printf(" -> ");
1492               break;
1493
1494             default:
1495               putchar(' ');
1496               break;
1497             }
1498             break;
1499
1500           case COL_DEF_NET_SRC:
1501           case COL_RES_NET_SRC:
1502           case COL_UNRES_NET_SRC:
1503             switch (cf->cinfo.col_fmt[i + 1]) {
1504
1505             case COL_DEF_NET_DST:
1506             case COL_RES_NET_DST:
1507             case COL_UNRES_NET_DST:
1508               printf(" -> ");
1509               break;
1510
1511             default:
1512               putchar(' ');
1513               break;
1514             }
1515             break;
1516
1517           case COL_DEF_DST:
1518           case COL_RES_DST:
1519           case COL_UNRES_DST:
1520             switch (cf->cinfo.col_fmt[i + 1]) {
1521
1522             case COL_DEF_SRC:
1523             case COL_RES_SRC:
1524             case COL_UNRES_SRC:
1525               printf(" <- ");
1526               break;
1527
1528             default:
1529               putchar(' ');
1530               break;
1531             }
1532             break;
1533
1534           case COL_DEF_DL_DST:
1535           case COL_RES_DL_DST:
1536           case COL_UNRES_DL_DST:
1537             switch (cf->cinfo.col_fmt[i + 1]) {
1538
1539             case COL_DEF_DL_SRC:
1540             case COL_RES_DL_SRC:
1541             case COL_UNRES_DL_SRC:
1542               printf(" <- ");
1543               break;
1544
1545             default:
1546               putchar(' ');
1547               break;
1548             }
1549             break;
1550
1551           case COL_DEF_NET_DST:
1552           case COL_RES_NET_DST:
1553           case COL_UNRES_NET_DST:
1554             switch (cf->cinfo.col_fmt[i + 1]) {
1555
1556             case COL_DEF_NET_SRC:
1557             case COL_RES_NET_SRC:
1558             case COL_UNRES_NET_SRC:
1559               printf(" <- ");
1560               break;
1561
1562             default:
1563               putchar(' ');
1564               break;
1565             }
1566             break;
1567
1568           default:
1569             putchar(' ');
1570             break;
1571           }
1572         }
1573       }
1574       putchar('\n');
1575     }
1576     if (print_hex) {
1577       print_hex_data(stdout, print_args.format, &fdata);
1578       putchar('\n');
1579     }
1580   }
1581
1582   /* The ANSI C standard does not appear to *require* that a line-buffered
1583      stream be flushed to the host environment whenever a newline is
1584      written, it just says that, on such a stream, characters "are
1585      intended to be transmitted to or from the host environment as a
1586      block when a new-line character is encountered".
1587
1588      The Visual C++ 6.0 C implementation doesn't do what is intended;
1589      even if you set a stream to be line-buffered, it still doesn't
1590      flush the buffer at the end of every line.
1591
1592      So, if the "-l" flag was specified, we flush the standard output
1593      at the end of a packet.  This will do the right thing if we're
1594      printing packet summary lines, and, as we print the entire protocol
1595      tree for a single packet without waiting for anything to happen,
1596      it should be as good as line-buffered mode if we're printing
1597      protocol trees.  (The whole reason for the "-l" flag in either
1598      tcpdump or Tethereal is to allow the output of a live capture to
1599      be piped to a program or script and to have that script see the
1600      information for the packet as soon as it's printed, rather than
1601      having to wait until a standard I/O buffer fills up. */
1602   if (line_buffered)
1603     fflush(stdout);
1604
1605   epan_dissect_free(edt);
1606
1607   clear_fdata(&fdata);
1608 }
1609
1610 char *
1611 file_open_error_message(int err, gboolean for_writing)
1612 {
1613   char *errmsg;
1614   static char errmsg_errno[1024+1];
1615
1616   switch (err) {
1617
1618   case WTAP_ERR_NOT_REGULAR_FILE:
1619     errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1620     break;
1621
1622   case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1623   case WTAP_ERR_UNSUPPORTED:
1624     /* Seen only when opening a capture file for reading. */
1625     errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1626     break;
1627
1628   case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1629     /* Seen only when opening a capture file for writing. */
1630     errmsg = "Tethereal does not support writing capture files in that format.";
1631     break;
1632
1633   case WTAP_ERR_UNSUPPORTED_ENCAP:
1634   case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1635     if (for_writing)
1636       errmsg = "Tethereal cannot save this capture in that format.";
1637     else
1638       errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1639     break;
1640
1641   case WTAP_ERR_BAD_RECORD:
1642     errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1643     break;
1644
1645   case WTAP_ERR_CANT_OPEN:
1646     if (for_writing)
1647       errmsg = "The file \"%s\" could not be created for some unknown reason.";
1648     else
1649       errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1650     break;
1651
1652   case WTAP_ERR_SHORT_READ:
1653     errmsg = "The file \"%s\" appears to have been cut short"
1654              " in the middle of a packet or other data.";
1655     break;
1656
1657   case WTAP_ERR_SHORT_WRITE:
1658     errmsg = "A full header couldn't be written to the file \"%s\".";
1659     break;
1660
1661   case ENOENT:
1662     if (for_writing)
1663       errmsg = "The path to the file \"%s\" does not exist.";
1664     else
1665       errmsg = "The file \"%s\" does not exist.";
1666     break;
1667
1668   case EACCES:
1669     if (for_writing)
1670       errmsg = "You do not have permission to create or write to the file \"%s\".";
1671     else
1672       errmsg = "You do not have permission to read the file \"%s\".";
1673     break;
1674
1675   case EISDIR:
1676     errmsg = "\"%s\" is a directory (folder), not a file.";
1677     break;
1678
1679   default:
1680     snprintf(errmsg_errno, sizeof(errmsg_errno),
1681              "The file \"%%s\" could not be opened: %s.",
1682              wtap_strerror(err));
1683     errmsg = errmsg_errno;
1684     break;
1685   }
1686   return errmsg;
1687 }
1688
1689 int
1690 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1691 {
1692   wtap       *wth;
1693   int         err;
1694   int         fd;
1695   struct stat cf_stat;
1696   char        err_msg[2048+1];
1697
1698   wth = wtap_open_offline(fname, &err, FALSE);
1699   if (wth == NULL)
1700     goto fail;
1701
1702   /* Find the size of the file. */
1703   fd = wtap_fd(wth);
1704   if (fstat(fd, &cf_stat) < 0) {
1705     err = errno;
1706     wtap_close(wth);
1707     goto fail;
1708   }
1709
1710   /* The open succeeded.  Fill in the information for this file. */
1711
1712   /* Initialize the table of conversations. */
1713   epan_conversation_init();
1714
1715   /* Initialize protocol-specific variables */
1716   init_all_protocols();
1717
1718   /* Initialize the common data structures for fragment reassembly.
1719      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
1720      may free up space for fragments, which it finds by using the
1721      data structures that "reassemble_init()" frees. */
1722   reassemble_init();
1723
1724   cf->wth = wth;
1725   cf->filed = fd;
1726   cf->f_len = cf_stat.st_size;
1727
1728   /* Set the file name because we need it to set the follow stream filter.
1729      XXX - is that still true?  We need it for other reasons, though,
1730      in any case. */
1731   cf->filename = g_strdup(fname);
1732
1733   /* Indicate whether it's a permanent or temporary file. */
1734   cf->is_tempfile = is_tempfile;
1735
1736   /* If it's a temporary capture buffer file, mark it as not saved. */
1737   cf->user_saved = !is_tempfile;
1738
1739   cf->cd_t      = wtap_file_type(cf->wth);
1740   cf->count     = 0;
1741   cf->drops_known = FALSE;
1742   cf->drops     = 0;
1743   cf->esec      = 0;
1744   cf->eusec     = 0;
1745   cf->snap      = wtap_snapshot_length(cf->wth);
1746   cf->progbar_quantum = 0;
1747   cf->progbar_nextstep = 0;
1748   firstsec = 0, firstusec = 0;
1749   prevsec = 0, prevusec = 0;
1750  
1751   return (0);
1752
1753 fail:
1754   snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1755   fprintf(stderr, "tethereal: %s\n", err_msg);
1756   return (err);
1757 }