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