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