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