Don't let the user specify a maximum capture file size if they're not
[obnox/wireshark/wip.git] / tethereal.c
1 /* tethereal.c
2  *
3  * $Id: tethereal.c,v 1.109 2001/12/21 19:58:30 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   /* If they didn't specify a "-w" flag, but specified a maximum capture
626      file size, tell them that this doesn't work, and exit. */
627   if (cfile.autostop_filesize != 0 && cfile.save_file == NULL) {
628     fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
629     exit(2);
630   }
631
632 #ifdef WIN32
633   /* Start windows sockets */
634   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
635 #endif
636
637   /* Notify all registered modules that have had any of their preferences
638      changed either from one of the preferences file or from the command
639      line that its preferences have changed. */
640   prefs_apply_all();
641
642 #ifndef HAVE_LIBPCAP
643   if (capture_option_specified)
644     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
645 #endif
646   if (arg_error)
647     print_usage();
648
649   /* Build the column format array */  
650   for (i = 0; i < cfile.cinfo.num_cols; i++) {
651     cfile.cinfo.col_fmt[i] = get_column_format(i);
652     cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
653     cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
654       NUM_COL_FMTS);
655     get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
656     cfile.cinfo.col_data[i] = NULL;
657     if (cfile.cinfo.col_fmt[i] == COL_INFO)
658       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
659     else
660       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
661   }
662
663   if (cfile.snap < 1)
664     cfile.snap = WTAP_MAX_PACKET_SIZE;
665   else if (cfile.snap < MIN_PACKET_SIZE)
666     cfile.snap = MIN_PACKET_SIZE;
667   
668   if (cfile.ringbuffer_on) {
669     /* Ringbuffer works just under certain conditions:*/ 
670     if (cfile.save_file == NULL) {
671        /* Ringbuffer does not work with temporary files */
672       fprintf(stderr, "tethereal: Turning ring buffer off (no save file specified).\n");
673       cfile.ringbuffer_on = FALSE;
674     }
675     if (cfile.autostop_filesize == 0) {
676        /* It makes no sense to enable the ring buffer if the maximum
677           file size is set to infinite */
678       fprintf(stderr, "tethereal: Turning ring buffer off (file size = 0).\n");
679       cfile.ringbuffer_on = FALSE;
680     }
681   }
682
683   /* Check the value range of the ringbuffer_num_files parameter */
684   if (cfile.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
685     cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
686   else if (cfile.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
687     cfile.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
688   
689   if (rfilter != NULL) {
690     if (!dfilter_compile(rfilter, &rfcode)) {
691       fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
692       epan_cleanup();
693       exit(2);
694     }
695   }
696   cfile.rfcode = rfcode;
697   if (cf_name) {
698     err = open_cap_file(cf_name, FALSE, &cfile);
699     if (err != 0) {
700       epan_cleanup();
701       exit(2);
702     }
703     err = load_cap_file(&cfile, out_file_type);
704     if (err != 0) {
705       epan_cleanup();
706       exit(2);
707     }
708     cf_name[0] = '\0';
709   } else {
710     /* No capture file specified, so we're supposed to do a live capture;
711        do we have support for live captures? */
712 #ifdef HAVE_LIBPCAP
713
714 #ifdef _WIN32
715     if (!has_wpcap) {
716         fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
717         exit(2);
718     }
719 #endif
720
721     /* Yes; did the user specify an interface to use? */
722     if (cfile.iface == NULL) {
723         /* No - pick the first one from the list of interfaces. */
724         if_list = get_interface_list(&err, err_str);
725         if (if_list == NULL) {
726             switch (err) {
727
728             case CANT_GET_INTERFACE_LIST:
729                 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
730                         err_str);
731                 break;
732
733             case NO_INTERFACES_FOUND:
734                 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
735                 break;
736             }
737             exit(2);
738         }
739         cfile.iface = g_strdup(if_list->data);  /* first interface */
740         free_interface_list(if_list);
741     }
742     capture(packet_count, out_file_type);
743
744     if (cfile.ringbuffer_on) {
745       ringbuf_free();
746     }
747 #else
748     /* No - complain. */
749     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
750     exit(2);
751 #endif
752   }
753
754   epan_cleanup();
755
756   return 0;
757 }
758
759 #ifdef HAVE_LIBPCAP
760 /* Do the low-level work of a capture.
761    Returns TRUE if it succeeds, FALSE otherwise. */
762 static int
763 capture(int packet_count, int out_file_type)
764 {
765   gchar       open_err_str[PCAP_ERRBUF_SIZE];
766   gchar       lookup_net_err_str[PCAP_ERRBUF_SIZE];
767   bpf_u_int32 netnum, netmask;
768   struct bpf_program fcode;
769   void        (*oldhandler)(int);
770   int         err, inpkts;
771   char        errmsg[1024+1];
772   condition *cnd_stop_capturesize;
773   condition *cnd_stop_timeout;
774 #ifndef _WIN32
775   static const char ppamsg[] = "can't find PPA for ";
776   char       *libpcap_warn;
777 #endif
778   struct pcap_stat stats;
779   gboolean    dump_ok;
780
781   /* Initialize the table of conversations. */
782   epan_conversation_init();
783
784   /* Initialize protocol-specific variables */
785   init_all_protocols();
786
787   /* Initialize the common data structures for fragment reassembly.
788      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
789      may free up space for fragments, which it finds by using the
790      data structures that "reassemble_init()" frees. */
791   reassemble_init();
792
793   ld.linktype       = WTAP_ENCAP_UNKNOWN;
794   ld.pdh            = NULL;
795
796   /* Open the network interface to capture from it.
797      Some versions of libpcap may put warnings into the error buffer
798      if they succeed; to tell if that's happened, we have to clear
799      the error buffer, and check if it's still a null string.  */
800   open_err_str[0] = '\0';
801   ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000,
802                           open_err_str);
803
804   if (ld.pch == NULL) {
805     /* Well, we couldn't start the capture. */
806 #ifdef _WIN32
807     /* On Win32 OSes, the capture devices are probably available to all
808        users; don't warn about permissions problems.
809
810        Do, however, warn that Token Ring and PPP devices aren't supported. */
811     snprintf(errmsg, sizeof errmsg,
812         "The capture session could not be initiated (%s).\n"
813         "Please check that you have the proper interface specified.\n"
814         "\n"
815         "Note that the driver Tethereal uses for packet capture on Windows\n"
816         "doesn't support capturing on Token Ring interfaces, and doesn't\n"
817         "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
818         open_err_str);
819 #else
820       /* If we got a "can't find PPA for XXX" message, warn the user (who
821          is running Ethereal on HP-UX) that they don't have a version
822          of libpcap that properly handles HP-UX (libpcap 0.6.x and later
823          versions, which properly handle HP-UX, say "can't find /dev/dlpi
824          PPA for XXX" rather than "can't find PPA for XXX"). */
825       if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
826         libpcap_warn =
827           "\n\n"
828           "You are running Tethereal with a version of the libpcap library\n"
829           "that doesn't handle HP-UX network devices well; this means that\n"
830           "Tethereal may not be able to capture packets.\n"
831           "\n"
832           "To fix this, you should install libpcap 0.6.2, or a later version\n"
833           "of libpcap, rather than libpcap 0.4 or 0.5.x.  It is available in\n"
834           "packaged binary form from the Software Porting And Archive Centre\n"
835           "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
836           "at the URL lists a number of mirror sites.";
837       else
838         libpcap_warn = "";
839     snprintf(errmsg, sizeof errmsg,
840       "The capture session could not be initiated (%s).\n"
841       "Please check to make sure you have sufficient permissions, and that\n"
842       "you have the proper interface specified.%s", open_err_str, libpcap_warn);
843 #endif
844     goto error;
845   }
846
847   if (cfile.cfilter) {
848     /* A capture filter was specified; set it up. */
849     if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
850       /*
851        * Well, we can't get the netmask for this interface; it's used
852        * only for filters that check for broadcast IP addresses, so
853        * we just warn the user, and punt and use 0.
854        */
855       fprintf(stderr, 
856         "Warning:  Couldn't obtain netmask info (%s)\n.", lookup_net_err_str);
857       netmask = 0;
858     }
859     if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
860       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
861         pcap_geterr(ld.pch));
862       goto error;
863     }
864     if (pcap_setfilter(ld.pch, &fcode) < 0) {
865       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
866         pcap_geterr(ld.pch));
867       goto error;
868     }
869   }
870
871   ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
872         cfile.iface));
873   if (cfile.save_file != NULL) {
874     /* Set up to write to the capture file. */
875     if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
876       strcpy(errmsg, "The network you're capturing from is of a type"
877                " that Tethereal doesn't support.");
878       goto error;
879     }
880     if (cfile.ringbuffer_on) {
881       cfile.save_file_fd = ringbuf_init(cfile.save_file,
882         cfile.ringbuffer_num_files);
883       if (cfile.save_file_fd != -1) {
884         ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
885           pcap_snapshot(ld.pch), &err);
886       } else {
887         ld.pdh = NULL;
888       }
889     } else {
890       ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
891                  ld.linktype, pcap_snapshot(ld.pch), &err);
892     }
893
894     if (ld.pdh == NULL) {
895       snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
896                 cfile.save_file);
897       goto error;
898     }
899   }
900
901   /* Does "open_err_str" contain a non-empty string?  If so, "pcap_open_live()"
902      returned a warning; print it, but keep capturing. */
903   if (open_err_str[0] != '\0')
904     fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
905
906   /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
907      and exit.
908      XXX - deal with signal semantics on various platforms.  Or just
909      use "sigaction()" and be done with it? */
910   signal(SIGTERM, capture_cleanup);
911   signal(SIGINT, capture_cleanup);
912 #if !defined(WIN32)
913   if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
914     signal(SIGHUP, oldhandler);
915 #endif
916
917   /* Let the user know what interface was chosen. */
918   fprintf(stderr, "Capturing on %s\n", cfile.iface);
919   fflush(stderr);
920
921   /* initialize capture stop conditions */ 
922   init_capture_stop_conditions();
923   /* create stop conditions */
924   cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
925                                  (long)cfile.autostop_filesize * 1000);
926   cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
927                              (gint32)cfile.autostop_duration);
928
929   if (packet_count == 0)
930     packet_count = -1; /* infinite capturng */
931   ld.go = TRUE;
932   while (ld.go) {
933     if (packet_count > 0)
934       packet_count--;
935     inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
936     if (packet_count == 0) {
937       ld.go = FALSE;
938     } else if (cnd_eval(cnd_stop_timeout) == TRUE) {
939       /* The specified capture time has elapsed; stop the capture. */
940       ld.go = FALSE;
941     } else if (ld.pdh != NULL && (cnd_eval(cnd_stop_capturesize, 
942                   (guint32)wtap_get_bytes_dumped(ld.pdh))) == TRUE){
943       /* We're saving the capture to a file, and the capture file reached
944          its maximum size. */
945       if (cfile.ringbuffer_on) {
946         /* Switch to the next ringbuffer file */
947         if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
948           /* File switch failed: reset the condition */
949           cnd_reset(cnd_stop_capturesize);
950         } else {
951           /* File switch failed: stop here */
952           ld.go = FALSE;
953           continue;
954         }
955       } else {
956         /* No ringbuffer - just stop. */
957         ld.go = FALSE;
958       }
959     }
960   }
961   
962   /* delete stop conditions */
963   cnd_delete(cnd_stop_capturesize);
964   cnd_delete(cnd_stop_timeout);
965
966   if (cfile.save_file != NULL) {
967     /* We're saving to a file, which means we're printing packet counts
968        to the standard output.  Send a newline so that we move to the
969        line after the packet count. */
970     fprintf(stderr, "\n");
971   }
972
973   /* If we got an error while capturing, report it. */
974   if (inpkts < 0) {
975     fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
976         pcap_geterr(ld.pch));
977   }
978
979   /* Get the capture statistics, and, if any packets were dropped, report
980      that. */
981   if (pcap_stats(ld.pch, &stats) >= 0) {
982     if (stats.ps_drop != 0) {
983       fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
984     }
985   } else {
986     fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
987         pcap_geterr(ld.pch));
988   }
989
990   pcap_close(ld.pch);
991
992   if (cfile.save_file != NULL) {
993     /* We're saving to a file or files; close all files. */
994     if (cfile.ringbuffer_on) {
995       dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
996     } else {
997       dump_ok = wtap_dump_close(ld.pdh, &err);
998     }
999     if (!dump_ok)
1000       show_capture_file_io_error(cfile.save_file, err, TRUE);
1001   }
1002
1003   return TRUE;
1004
1005 error:
1006   if (cfile.ringbuffer_on) {
1007     ringbuf_error_cleanup();
1008   }
1009   g_free(cfile.save_file);
1010   cfile.save_file = NULL;
1011   fprintf(stderr, "tethereal: %s\n", errmsg);
1012   if (ld.pch != NULL)
1013     pcap_close(ld.pch);
1014
1015   return FALSE;
1016 }
1017
1018 static void
1019 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1020   const u_char *pd)
1021 {
1022   struct wtap_pkthdr whdr;
1023   loop_data *ld = (loop_data *) user;
1024   cb_args_t args;
1025
1026   whdr.ts.tv_sec = phdr->ts.tv_sec;
1027   whdr.ts.tv_usec = phdr->ts.tv_usec;
1028   whdr.caplen = phdr->caplen;
1029   whdr.len = phdr->len;
1030   whdr.pkt_encap = ld->linktype;
1031
1032   args.cf = &cfile;
1033   args.pdh = ld->pdh;
1034   if (ld->pdh) {
1035     wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1036     fprintf(stderr, "\r%u ", cfile.count);
1037     fflush(stdout);
1038   } else {
1039     wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1040   }
1041 }
1042
1043 static void
1044 capture_cleanup(int signum)
1045 {
1046   /* Just set the loop flag to false. This will initiate 
1047      a proper termination. */
1048   ld.go = FALSE;
1049 }
1050 #endif /* HAVE_LIBPCAP */
1051
1052 static int
1053 load_cap_file(capture_file *cf, int out_file_type)
1054 {
1055   gint         linktype;
1056   wtap_dumper *pdh;
1057   int          err;
1058   int          success;
1059   cb_args_t    args;
1060
1061   linktype = wtap_file_encap(cf->wth);
1062   if (cf->save_file != NULL) {
1063     /* Set up to write to the capture file. */
1064     pdh = wtap_dump_open(cf->save_file, out_file_type,
1065                 linktype, wtap_snapshot_length(cf->wth), &err);
1066
1067     if (pdh == NULL) {
1068       /* We couldn't set up to write to the capture file. */
1069       switch (err) {
1070
1071       case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1072         fprintf(stderr,
1073                 "tethereal: Capture files can't be written in that format.\n");
1074         break;
1075
1076       case WTAP_ERR_UNSUPPORTED_ENCAP:
1077       case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1078         fprintf(stderr,
1079 "tethereal: The capture file being read cannot be written in that format.\n");
1080         break;
1081
1082       case WTAP_ERR_CANT_OPEN:
1083         fprintf(stderr,
1084 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1085                  cf->save_file);
1086         break;
1087
1088       case WTAP_ERR_SHORT_WRITE:
1089         fprintf(stderr,
1090 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1091                 cf->save_file);
1092         break;
1093
1094       default:
1095         if (err < 0) {
1096           fprintf(stderr,
1097                 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1098                 cf->save_file, err);
1099         } else {
1100           fprintf(stderr,
1101                 "tethereal: The file \"%s\" could not be opened: %s\n.",
1102                 cf->save_file, strerror(err));
1103         }
1104         break;
1105       }
1106       goto out;
1107     }
1108     args.cf = cf;
1109     args.pdh = pdh;
1110     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1111                         &err);
1112
1113     /* Now close the capture file. */
1114     if (!wtap_dump_close(pdh, &err))
1115       show_capture_file_io_error(cfile.save_file, err, TRUE);
1116   } else {
1117     args.cf = cf;
1118     args.pdh = NULL;
1119     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1120                         &err);
1121   }
1122   if (!success) {
1123     /* Print up a message box noting that the read failed somewhere along
1124        the line. */
1125     switch (err) {
1126
1127     case WTAP_ERR_UNSUPPORTED_ENCAP:
1128       fprintf(stderr,
1129 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1130         cf->filename);
1131       break;
1132
1133     case WTAP_ERR_CANT_READ:
1134       fprintf(stderr,
1135 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1136         cf->filename);
1137       break;
1138
1139     case WTAP_ERR_SHORT_READ:
1140       fprintf(stderr,
1141 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1142         cf->filename);
1143       break;
1144
1145     case WTAP_ERR_BAD_RECORD:
1146       fprintf(stderr,
1147 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1148         cf->filename);
1149       break;
1150
1151     default:
1152       fprintf(stderr,
1153 "tethereal: An error occurred while reading \"%s\": %s.\n",
1154         cf->filename, wtap_strerror(err));
1155       break;
1156     }
1157   }
1158
1159 out:
1160   wtap_close(cf->wth);
1161   cf->wth = NULL;
1162
1163   return err;
1164 }
1165
1166 static void
1167 fill_in_fdata(frame_data *fdata, capture_file *cf,
1168         const struct wtap_pkthdr *phdr,
1169         const union wtap_pseudo_header *pseudo_header, long offset)
1170 {
1171   int i;
1172
1173   fdata->next = NULL;
1174   fdata->prev = NULL;
1175   fdata->pfd = NULL;
1176   fdata->data_src = NULL;
1177   fdata->num = cf->count;
1178   fdata->pkt_len = phdr->len;
1179   fdata->cap_len = phdr->caplen;
1180   fdata->file_off = offset;
1181   fdata->lnk_t = phdr->pkt_encap;
1182   fdata->abs_secs  = phdr->ts.tv_sec;
1183   fdata->abs_usecs = phdr->ts.tv_usec;
1184   fdata->flags.passed_dfilter = 0;
1185   fdata->flags.encoding = CHAR_ASCII;
1186   fdata->flags.visited = 0;
1187   fdata->flags.marked = 0;
1188
1189   /* If we don't have the time stamp of the first packet in the
1190      capture, it's because this is the first packet.  Save the time
1191      stamp of this packet as the time stamp of the first packet. */
1192   if (!firstsec && !firstusec) {
1193     firstsec  = fdata->abs_secs;
1194     firstusec = fdata->abs_usecs;
1195   }
1196
1197   /* If we don't have the time stamp of the previous displayed packet,
1198      it's because this is the first displayed packet.  Save the time
1199      stamp of this packet as the time stamp of the previous displayed
1200      packet. */
1201   if (!prevsec && !prevusec) {
1202     prevsec  = fdata->abs_secs;
1203     prevusec = fdata->abs_usecs;
1204   }
1205
1206   /* Get the time elapsed between the first packet and this packet. */
1207   compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1208                 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1209
1210   /* If it's greater than the current elapsed time, set the elapsed time
1211      to it (we check for "greater than" so as not to be confused by
1212      time moving backwards). */
1213   if ((gint32)cf->esec < fdata->rel_secs
1214         || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1215     cf->esec = fdata->rel_secs;
1216     cf->eusec = fdata->rel_usecs;
1217   }
1218   
1219   /* Get the time elapsed between the previous displayed packet and
1220      this packet. */
1221   compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1222                 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1223   prevsec = fdata->abs_secs;
1224   prevusec = fdata->abs_usecs;
1225 }
1226
1227 /* Free up all data attached to a "frame_data" structure. */
1228 static void
1229 clear_fdata(frame_data *fdata)
1230 {
1231   if (fdata->pfd)
1232     g_slist_free(fdata->pfd);
1233   if (fdata->data_src)
1234     g_slist_free(fdata->data_src);
1235 }
1236
1237 static void
1238 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1239   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1240 {
1241   cb_args_t    *args = (cb_args_t *) user;
1242   capture_file *cf = args->cf;
1243   wtap_dumper  *pdh = args->pdh;
1244   frame_data    fdata;
1245   int           err;
1246   gboolean      passed;
1247   epan_dissect_t *edt;
1248
1249   cf->count++;
1250   if (cf->rfcode) {
1251     fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1252     edt = epan_dissect_new(TRUE, FALSE);
1253     epan_dissect_prime_dfilter(edt, cf->rfcode);
1254     epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1255     passed = dfilter_apply_edt(cf->rfcode, edt);
1256   } else {
1257     passed = TRUE;
1258     edt = NULL;
1259   }
1260   if (passed) {
1261     if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1262 #ifdef HAVE_LIBPCAP
1263       if (ld.pch != NULL) {
1264         /* We're capturing packets, so we're printing a count of packets
1265            captured; move to the line after the count. */
1266         fprintf(stderr, "\n");
1267       }
1268 #endif
1269       show_capture_file_io_error(cf->save_file, err, FALSE);
1270 #ifdef HAVE_LIBPCAP
1271       if (ld.pch != NULL)
1272         pcap_close(ld.pch);
1273 #endif
1274       wtap_dump_close(pdh, &err);
1275       exit(2);
1276     }
1277   }
1278   if (edt != NULL)
1279     epan_dissect_free(edt);
1280   if (cf->rfcode)
1281     clear_fdata(&fdata);
1282 }
1283
1284 static void
1285 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1286 {
1287   switch (err) {
1288
1289   case ENOSPC:
1290     fprintf(stderr,
1291 "tethereal: Not all the packets could be written to \"%s\" because there is "
1292 "no space left on the file system.\n",
1293         fname);
1294     break;
1295
1296 #ifdef EDQUOT
1297   case EDQUOT:
1298     fprintf(stderr,
1299 "tethereal: Not all the packets could be written to \"%s\" because you are "
1300 "too close to, or over your disk quota.\n",
1301         fname);
1302   break;
1303 #endif
1304
1305   case WTAP_ERR_CANT_CLOSE:
1306     fprintf(stderr,
1307 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1308         fname);
1309     break;
1310
1311   case WTAP_ERR_SHORT_WRITE:
1312     fprintf(stderr,
1313 "tethereal: Not all the packets could be written to \"%s\".\n",
1314         fname);
1315     break;
1316
1317   default:
1318     if (is_close) {
1319       fprintf(stderr,
1320 "tethereal: \"%s\" could not be closed: %s.\n",
1321         fname, wtap_strerror(err));
1322     } else {
1323       fprintf(stderr,
1324 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1325         fname, wtap_strerror(err));
1326     }
1327     break;
1328   }
1329 }
1330
1331 static void
1332 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1333   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1334 {
1335   cb_args_t    *args = (cb_args_t *) user;
1336   capture_file *cf = args->cf;
1337   frame_data    fdata;
1338   gboolean      passed;
1339   print_args_t  print_args;
1340   epan_dissect_t *edt;
1341   gboolean      create_proto_tree;
1342   int           i;
1343
1344   cf->count++;
1345
1346   fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1347
1348   passed = TRUE;
1349   if (cf->rfcode || verbose)
1350     create_proto_tree = TRUE;
1351   else
1352     create_proto_tree = FALSE;
1353   /* The protocol tree will be "visible", i.e., printed, only if we're
1354      not printing a summary.
1355
1356      We only need the columns if we're *not* verbose; in verbose mode,
1357      we print the protocol tree, not the protocol summary. */
1358   edt = epan_dissect_new(create_proto_tree, verbose);
1359   if (cf->rfcode) {
1360     epan_dissect_prime_dfilter(edt, cf->rfcode);
1361   }
1362   epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1363   if (cf->rfcode) {
1364     passed = dfilter_apply_edt(cf->rfcode, edt);
1365   }
1366   if (passed) {
1367     /* The packet passed the read filter. */
1368     if (verbose) {
1369       /* Print the information in the protocol tree. */
1370       print_args.to_file = TRUE;
1371       print_args.format = PR_FMT_TEXT;
1372       print_args.print_summary = FALSE;
1373       print_args.print_hex = print_hex;
1374       print_args.expand_all = TRUE;
1375       print_args.suppress_unmarked = FALSE;
1376       proto_tree_print(FALSE, &print_args, (GNode *)edt->tree,
1377                         &fdata, stdout);
1378       if (!print_hex) {
1379         /* "print_hex_data()" will put out a leading blank line, as well
1380            as a trailing one; print one here, to separate the packets,
1381            only if "print_hex_data()" won't be called. */
1382         printf("\n");
1383       }
1384     } else {
1385       /* Just fill in the columns. */
1386       epan_dissect_fill_in_columns(edt);
1387
1388       /* Now print them. */
1389       for (i = 0; i < cf->cinfo.num_cols; i++) {
1390         switch (cf->cinfo.col_fmt[i]) {
1391         case COL_NUMBER:
1392           /*
1393            * Don't print this if we're doing a live capture from a network
1394            * interface - if we're doing a live capture, you won't be
1395            * able to look at the capture in the future (it's not being
1396            * saved anywhere), so the frame numbers are unlikely to be
1397            * useful.
1398            *
1399            * (XXX - it might be nice to be able to save and print at
1400            * the same time, sort of like an "Update list of packets
1401            * in real time" capture in Ethereal.)
1402            */
1403           if (cf->iface != NULL)
1404             continue;
1405           printf("%3s", cf->cinfo.col_data[i]);
1406           break;
1407
1408         case COL_CLS_TIME:
1409         case COL_REL_TIME:
1410         case COL_ABS_TIME:
1411         case COL_ABS_DATE_TIME: /* XXX - wider */
1412           printf("%10s", cf->cinfo.col_data[i]);
1413           break;
1414
1415         case COL_DEF_SRC:
1416         case COL_RES_SRC:
1417         case COL_UNRES_SRC:
1418         case COL_DEF_DL_SRC:
1419         case COL_RES_DL_SRC:
1420         case COL_UNRES_DL_SRC:
1421         case COL_DEF_NET_SRC:
1422         case COL_RES_NET_SRC:
1423         case COL_UNRES_NET_SRC:
1424           printf("%12s", cf->cinfo.col_data[i]);
1425           break;
1426
1427         case COL_DEF_DST:
1428         case COL_RES_DST:
1429         case COL_UNRES_DST:
1430         case COL_DEF_DL_DST:
1431         case COL_RES_DL_DST:
1432         case COL_UNRES_DL_DST:
1433         case COL_DEF_NET_DST:
1434         case COL_RES_NET_DST:
1435         case COL_UNRES_NET_DST:
1436           printf("%-12s", cf->cinfo.col_data[i]);
1437           break;
1438
1439         default:
1440           printf("%s", cf->cinfo.col_data[i]);
1441           break;
1442         }
1443         if (i != cf->cinfo.num_cols - 1) {
1444           /*
1445            * This isn't the last column, so we need to print a
1446            * separator between this column and the next.
1447            *
1448            * If we printed a network source and are printing a
1449            * network destination of the same type next, separate
1450            * them with "->"; if we printed a network destination
1451            * and are printing a network source of the same type
1452            * next, separate them with "<-"; otherwise separate them
1453            * with a space.
1454            */
1455           switch (cf->cinfo.col_fmt[i]) {
1456
1457           case COL_DEF_SRC:
1458           case COL_RES_SRC:
1459           case COL_UNRES_SRC:
1460             switch (cf->cinfo.col_fmt[i + 1]) {
1461
1462             case COL_DEF_DST:
1463             case COL_RES_DST:
1464             case COL_UNRES_DST:
1465               printf(" -> ");
1466               break;
1467
1468             default:
1469               putchar(' ');
1470               break;
1471             }
1472             break;
1473
1474           case COL_DEF_DL_SRC:
1475           case COL_RES_DL_SRC:
1476           case COL_UNRES_DL_SRC:
1477             switch (cf->cinfo.col_fmt[i + 1]) {
1478
1479             case COL_DEF_DL_DST:
1480             case COL_RES_DL_DST:
1481             case COL_UNRES_DL_DST:
1482               printf(" -> ");
1483               break;
1484
1485             default:
1486               putchar(' ');
1487               break;
1488             }
1489             break;
1490
1491           case COL_DEF_NET_SRC:
1492           case COL_RES_NET_SRC:
1493           case COL_UNRES_NET_SRC:
1494             switch (cf->cinfo.col_fmt[i + 1]) {
1495
1496             case COL_DEF_NET_DST:
1497             case COL_RES_NET_DST:
1498             case COL_UNRES_NET_DST:
1499               printf(" -> ");
1500               break;
1501
1502             default:
1503               putchar(' ');
1504               break;
1505             }
1506             break;
1507
1508           case COL_DEF_DST:
1509           case COL_RES_DST:
1510           case COL_UNRES_DST:
1511             switch (cf->cinfo.col_fmt[i + 1]) {
1512
1513             case COL_DEF_SRC:
1514             case COL_RES_SRC:
1515             case COL_UNRES_SRC:
1516               printf(" <- ");
1517               break;
1518
1519             default:
1520               putchar(' ');
1521               break;
1522             }
1523             break;
1524
1525           case COL_DEF_DL_DST:
1526           case COL_RES_DL_DST:
1527           case COL_UNRES_DL_DST:
1528             switch (cf->cinfo.col_fmt[i + 1]) {
1529
1530             case COL_DEF_DL_SRC:
1531             case COL_RES_DL_SRC:
1532             case COL_UNRES_DL_SRC:
1533               printf(" <- ");
1534               break;
1535
1536             default:
1537               putchar(' ');
1538               break;
1539             }
1540             break;
1541
1542           case COL_DEF_NET_DST:
1543           case COL_RES_NET_DST:
1544           case COL_UNRES_NET_DST:
1545             switch (cf->cinfo.col_fmt[i + 1]) {
1546
1547             case COL_DEF_NET_SRC:
1548             case COL_RES_NET_SRC:
1549             case COL_UNRES_NET_SRC:
1550               printf(" <- ");
1551               break;
1552
1553             default:
1554               putchar(' ');
1555               break;
1556             }
1557             break;
1558
1559           default:
1560             putchar(' ');
1561             break;
1562           }
1563         }
1564       }
1565       putchar('\n');
1566     }
1567     if (print_hex) {
1568       print_hex_data(stdout, print_args.format, &fdata);
1569       putchar('\n');
1570     }
1571   }
1572
1573   /* The ANSI C standard does not appear to *require* that a line-buffered
1574      stream be flushed to the host environment whenever a newline is
1575      written, it just says that, on such a stream, characters "are
1576      intended to be transmitted to or from the host environment as a
1577      block when a new-line character is encountered".
1578
1579      The Visual C++ 6.0 C implementation doesn't do what is intended;
1580      even if you set a stream to be line-buffered, it still doesn't
1581      flush the buffer at the end of every line.
1582
1583      So, if the "-l" flag was specified, we flush the standard output
1584      at the end of a packet.  This will do the right thing if we're
1585      printing packet summary lines, and, as we print the entire protocol
1586      tree for a single packet without waiting for anything to happen,
1587      it should be as good as line-buffered mode if we're printing
1588      protocol trees.  (The whole reason for the "-l" flag in either
1589      tcpdump or Tethereal is to allow the output of a live capture to
1590      be piped to a program or script and to have that script see the
1591      information for the packet as soon as it's printed, rather than
1592      having to wait until a standard I/O buffer fills up. */
1593   if (line_buffered)
1594     fflush(stdout);
1595
1596   epan_dissect_free(edt);
1597
1598   clear_fdata(&fdata);
1599 }
1600
1601 char *
1602 file_open_error_message(int err, gboolean for_writing)
1603 {
1604   char *errmsg;
1605   static char errmsg_errno[1024+1];
1606
1607   switch (err) {
1608
1609   case WTAP_ERR_NOT_REGULAR_FILE:
1610     errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1611     break;
1612
1613   case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1614   case WTAP_ERR_UNSUPPORTED:
1615     /* Seen only when opening a capture file for reading. */
1616     errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1617     break;
1618
1619   case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1620     /* Seen only when opening a capture file for writing. */
1621     errmsg = "Tethereal does not support writing capture files in that format.";
1622     break;
1623
1624   case WTAP_ERR_UNSUPPORTED_ENCAP:
1625   case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1626     if (for_writing)
1627       errmsg = "Tethereal cannot save this capture in that format.";
1628     else
1629       errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1630     break;
1631
1632   case WTAP_ERR_BAD_RECORD:
1633     errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1634     break;
1635
1636   case WTAP_ERR_CANT_OPEN:
1637     if (for_writing)
1638       errmsg = "The file \"%s\" could not be created for some unknown reason.";
1639     else
1640       errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1641     break;
1642
1643   case WTAP_ERR_SHORT_READ:
1644     errmsg = "The file \"%s\" appears to have been cut short"
1645              " in the middle of a packet or other data.";
1646     break;
1647
1648   case WTAP_ERR_SHORT_WRITE:
1649     errmsg = "A full header couldn't be written to the file \"%s\".";
1650     break;
1651
1652   case ENOENT:
1653     if (for_writing)
1654       errmsg = "The path to the file \"%s\" does not exist.";
1655     else
1656       errmsg = "The file \"%s\" does not exist.";
1657     break;
1658
1659   case EACCES:
1660     if (for_writing)
1661       errmsg = "You do not have permission to create or write to the file \"%s\".";
1662     else
1663       errmsg = "You do not have permission to read the file \"%s\".";
1664     break;
1665
1666   case EISDIR:
1667     errmsg = "\"%s\" is a directory (folder), not a file.";
1668     break;
1669
1670   default:
1671     snprintf(errmsg_errno, sizeof(errmsg_errno),
1672              "The file \"%%s\" could not be opened: %s.",
1673              wtap_strerror(err));
1674     errmsg = errmsg_errno;
1675     break;
1676   }
1677   return errmsg;
1678 }
1679
1680 int
1681 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1682 {
1683   wtap       *wth;
1684   int         err;
1685   int         fd;
1686   struct stat cf_stat;
1687   char        err_msg[2048+1];
1688
1689   wth = wtap_open_offline(fname, &err, FALSE);
1690   if (wth == NULL)
1691     goto fail;
1692
1693   /* Find the size of the file. */
1694   fd = wtap_fd(wth);
1695   if (fstat(fd, &cf_stat) < 0) {
1696     err = errno;
1697     wtap_close(wth);
1698     goto fail;
1699   }
1700
1701   /* The open succeeded.  Fill in the information for this file. */
1702
1703   /* Initialize the table of conversations. */
1704   epan_conversation_init();
1705
1706   /* Initialize protocol-specific variables */
1707   init_all_protocols();
1708
1709   /* Initialize the common data structures for fragment reassembly.
1710      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
1711      may free up space for fragments, which it finds by using the
1712      data structures that "reassemble_init()" frees. */
1713   reassemble_init();
1714
1715   cf->wth = wth;
1716   cf->filed = fd;
1717   cf->f_len = cf_stat.st_size;
1718
1719   /* Set the file name because we need it to set the follow stream filter.
1720      XXX - is that still true?  We need it for other reasons, though,
1721      in any case. */
1722   cf->filename = g_strdup(fname);
1723
1724   /* Indicate whether it's a permanent or temporary file. */
1725   cf->is_tempfile = is_tempfile;
1726
1727   /* If it's a temporary capture buffer file, mark it as not saved. */
1728   cf->user_saved = !is_tempfile;
1729
1730   cf->cd_t      = wtap_file_type(cf->wth);
1731   cf->count     = 0;
1732   cf->drops_known = FALSE;
1733   cf->drops     = 0;
1734   cf->esec      = 0;
1735   cf->eusec     = 0;
1736   cf->snap      = wtap_snapshot_length(cf->wth);
1737   cf->progbar_quantum = 0;
1738   cf->progbar_nextstep = 0;
1739   firstsec = 0, firstusec = 0;
1740   prevsec = 0, prevusec = 0;
1741  
1742   return (0);
1743
1744 fail:
1745   snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1746   fprintf(stderr, "tethereal: %s\n", err_msg);
1747   return (err);
1748 }