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