Fix the rest of the signed/unsigned comparison warnings.
[obnox/wireshark/wip.git] / tethereal.c
1 /* tethereal.c
2  *
3  * $Id: tethereal.c,v 1.95 2001/10/26 18:28:16 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@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           fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
450                         optarg);
451           exit(1);
452           break;
453         }
454         break;
455       case 'p':        /* Don't capture in promiscuous mode */
456 #ifdef HAVE_LIBPCAP
457         promisc_mode = 0;
458 #else
459         capture_option_specified = TRUE;
460         arg_error = TRUE;
461 #endif
462         break;
463       case 'r':        /* Read capture file xxx */
464         cf_name = g_strdup(optarg);
465         break;
466       case 'R':        /* Read file filter */
467         rfilter = optarg;
468         break;
469       case 's':        /* Set the snapshot (capture) length */
470 #ifdef HAVE_LIBPCAP
471         cfile.snap = get_positive_int(optarg, "snapshot length");
472 #else
473         capture_option_specified = TRUE;
474         arg_error = TRUE;
475 #endif
476         break;
477       case 't':        /* Time stamp type */
478         if (strcmp(optarg, "r") == 0)
479           timestamp_type = RELATIVE;
480         else if (strcmp(optarg, "a") == 0)
481           timestamp_type = ABSOLUTE;
482         else if (strcmp(optarg, "ad") == 0)
483           timestamp_type = ABSOLUTE_WITH_DATE;
484         else if (strcmp(optarg, "d") == 0)
485           timestamp_type = DELTA;
486         else {
487           fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
488             optarg);
489           fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
490           fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
491           exit(1);
492         }
493         break;
494       case 'v':        /* Show version and exit */
495         printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
496         exit(0);
497         break;
498       case 'w':        /* Write to capture file xxx */
499         cfile.save_file = g_strdup(optarg);
500         break;
501       case 'V':        /* Verbose */
502         verbose = TRUE;
503         break;
504       case 'x':        /* Print packet data in hex (and ASCII) */
505         print_hex = TRUE;
506         break;
507     }
508   }
509   
510   /* If no capture filter or read filter has been specified, and there are
511      still command-line arguments, treat them as the tokens of a capture
512      filter (if no "-r" flag was specified) or a read filter (if a "-r"
513      flag was specified. */
514   if (optind < argc) {
515     if (cf_name != NULL) {
516       if (rfilter != NULL) {
517         fprintf(stderr,
518 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
519         exit(2);
520       }
521       rfilter = get_args_as_string(argc, argv, optind);
522     } else {
523 #ifdef HAVE_LIBPCAP
524       if (capture_filter_specified) {
525         fprintf(stderr,
526 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
527         exit(2);
528       }
529       cfile.cfilter = get_args_as_string(argc, argv, optind);
530 #else
531       capture_option_specified = TRUE;
532 #endif
533     }
534   }
535
536 #ifdef WIN32
537   /* Start windows sockets */
538   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
539 #endif
540
541   /* Notify all registered modules that have had any of their preferences
542      changed either from one of the preferences file or from the command
543      line that its preferences have changed. */
544   prefs_apply_all();
545
546 #ifndef HAVE_LIBPCAP
547   if (capture_option_specified)
548     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
549 #endif
550   if (arg_error)
551     print_usage();
552
553   /* Build the column format array */  
554   for (i = 0; i < cfile.cinfo.num_cols; i++) {
555     cfile.cinfo.col_fmt[i] = get_column_format(i);
556     cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
557     cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
558       NUM_COL_FMTS);
559     get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
560     cfile.cinfo.col_data[i] = NULL;
561     if (cfile.cinfo.col_fmt[i] == COL_INFO)
562       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
563     else
564       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
565   }
566
567   if (cfile.snap < 1)
568     cfile.snap = WTAP_MAX_PACKET_SIZE;
569   else if (cfile.snap < MIN_PACKET_SIZE)
570     cfile.snap = MIN_PACKET_SIZE;
571   
572   if (rfilter != NULL) {
573     if (!dfilter_compile(rfilter, &rfcode)) {
574       fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
575       epan_cleanup();
576       exit(2);
577     }
578   }
579   cfile.rfcode = rfcode;
580   if (cf_name) {
581     err = open_cap_file(cf_name, FALSE, &cfile);
582     if (err != 0) {
583       epan_cleanup();
584       exit(2);
585     }
586     err = load_cap_file(&cfile, out_file_type);
587     if (err != 0) {
588       epan_cleanup();
589       exit(2);
590     }
591     cf_name[0] = '\0';
592   } else {
593     /* No capture file specified, so we're supposed to do a live capture;
594        do we have support for live captures? */
595 #ifdef HAVE_LIBPCAP
596
597 #ifdef _WIN32
598     if (!has_wpcap) {
599         fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
600         exit(2);
601     }
602 #endif
603
604     /* Yes; did the user specify an interface to use? */
605     if (cfile.iface == NULL) {
606         /* No - pick the first one from the list of interfaces. */
607         if_list = get_interface_list(&err, err_str);
608         if (if_list == NULL) {
609             switch (err) {
610
611             case CANT_GET_INTERFACE_LIST:
612                 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
613                         err_str);
614                 break;
615
616             case NO_INTERFACES_FOUND:
617                 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
618                 break;
619             }
620             exit(2);
621         }
622         cfile.iface = g_strdup(if_list->data);  /* first interface */
623         free_interface_list(if_list);
624     }
625     capture(packet_count, out_file_type);
626 #else
627     /* No - complain. */
628     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
629     exit(2);
630 #endif
631   }
632
633   epan_cleanup();
634
635   return 0;
636 }
637
638 #ifdef HAVE_LIBPCAP
639 /* Do the low-level work of a capture.
640    Returns TRUE if it succeeds, FALSE otherwise. */
641 static int
642 capture(int packet_count, int out_file_type)
643 {
644   gchar       open_err_str[PCAP_ERRBUF_SIZE];
645   gchar       lookup_net_err_str[PCAP_ERRBUF_SIZE];
646   bpf_u_int32 netnum, netmask;
647   struct bpf_program fcode;
648   void        (*oldhandler)(int);
649   int         err, inpkts;
650   char        errmsg[1024+1];
651 #ifndef _WIN32
652   static const char ppamsg[] = "can't find PPA for ";
653   char       *libpcap_warn;
654 #endif
655   struct pcap_stat stats;
656
657   /* Initialize the table of conversations. */
658   epan_conversation_init();
659
660   /* Initialize protocol-specific variables */
661   init_all_protocols();
662
663   /* Initialize the common data structures for fragment reassembly.
664      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
665      may free up space for fragments, which it finds by using the
666      data structures that "reassemble_init()" frees. */
667   reassemble_init();
668
669   ld.linktype       = WTAP_ENCAP_UNKNOWN;
670   ld.pdh            = NULL;
671
672   /* Open the network interface to capture from it.
673      Some versions of libpcap may put warnings into the error buffer
674      if they succeed; to tell if that's happened, we have to clear
675      the error buffer, and check if it's still a null string.  */
676   open_err_str[0] = '\0';
677   ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000,
678                           open_err_str);
679
680   if (ld.pch == NULL) {
681     /* Well, we couldn't start the capture. */
682 #ifdef _WIN32
683     /* On Win32 OSes, the capture devices are probably available to all
684        users; don't warn about permissions problems.
685
686        Do, however, warn that Token Ring and PPP devices aren't supported. */
687     snprintf(errmsg, sizeof errmsg,
688         "The capture session could not be initiated (%s).\n"
689         "Please check that you have the proper interface specified.\n"
690         "\n"
691         "Note that the driver Tethereal uses for packet capture on Windows\n"
692         "doesn't support capturing on Token Ring interfaces, and doesn't\n"
693         "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
694         open_err_str);
695 #else
696       /* If we got a "can't find PPA for XXX" message, warn the user (who
697          is running Ethereal on HP-UX) that they don't have a version
698          of libpcap that properly handles HP-UX (libpcap 0.6.x and later
699          versions, which properly handle HP-UX, say "can't find /dev/dlpi
700          PPA for XXX" rather than "can't find PPA for XXX"). */
701       if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
702         libpcap_warn =
703           "\n\n"
704           "You are running Tethereal with a version of the libpcap library\n"
705           "that doesn't handle HP-UX network devices well; this means that\n"
706           "Tethereal may not be able to capture packets.\n"
707           "\n"
708           "To fix this, you should install libpcap 0.6.2, or a later version\n"
709           "of libpcap, rather than libpcap 0.4 or 0.5.x.  It is available in\n"
710           "packaged binary form from the Software Porting And Archive Centre\n"
711           "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
712           "at the URL lists a number of mirror sites.";
713       else
714         libpcap_warn = "";
715     snprintf(errmsg, sizeof errmsg,
716       "The capture session could not be initiated (%s).\n"
717       "Please check to make sure you have sufficient permissions, and that\n"
718       "you have the proper interface specified.%s", open_err_str, libpcap_warn);
719 #endif
720     goto error;
721   }
722
723   if (cfile.cfilter) {
724     /* A capture filter was specified; set it up. */
725     if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
726       /*
727        * Well, we can't get the netmask for this interface; it's used
728        * only for filters that check for broadcast IP addresses, so
729        * we just warn the user, and punt and use 0.
730        */
731       fprintf(stderr, 
732         "Warning:  Couldn't obtain netmask info (%s)\n.", lookup_net_err_str);
733       netmask = 0;
734     }
735     if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
736       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
737         pcap_geterr(ld.pch));
738       goto error;
739     }
740     if (pcap_setfilter(ld.pch, &fcode) < 0) {
741       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
742         pcap_geterr(ld.pch));
743       goto error;
744     }
745   }
746
747   ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(ld.pch));
748   if (cfile.save_file != NULL) {
749     /* Set up to write to the capture file. */
750     if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
751       strcpy(errmsg, "The network you're capturing from is of a type"
752                " that Tethereal doesn't support.");
753       goto error;
754     }
755     ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
756                 ld.linktype, pcap_snapshot(ld.pch), &err);
757
758     if (ld.pdh == NULL) {
759       snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
760                 cfile.save_file);
761       goto error;
762     }
763   }
764
765   /* Does "open_err_str" contain a non-empty string?  If so, "pcap_open_live()"
766      returned a warning; print it, but keep capturing. */
767   if (open_err_str[0] != '\0')
768     fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
769
770   /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
771      and exit.
772      XXX - deal with signal semantics on various platforms.  Or just
773      use "sigaction()" and be done with it? */
774   signal(SIGTERM, capture_cleanup);
775   signal(SIGINT, capture_cleanup);
776 #if !defined(WIN32)
777   if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
778     signal(SIGHUP, oldhandler);
779 #endif
780
781   /* Let the user know what interface was chosen. */
782   fprintf(stderr, "Capturing on %s\n", cfile.iface);
783   fflush(stderr);
784
785   inpkts = pcap_loop(ld.pch, packet_count, capture_pcap_cb, (u_char *) &ld);
786
787   if (cfile.save_file != NULL) {
788     /* We're saving to a file, which means we're printing packet counts
789        to the standard output.  Send a newline so that we move to the
790        line after the packet count. */
791     fprintf(stderr, "\n");
792   }
793
794   /* If we got an error while capturing, report it. */
795   if (inpkts < 0) {
796     fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
797         pcap_geterr(ld.pch));
798   }
799
800   /* Get the capture statistics, and, if any packets were dropped, report
801      that. */
802   if (pcap_stats(ld.pch, &stats) >= 0) {
803     if (stats.ps_drop != 0) {
804       fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
805     }
806   } else {
807     fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
808         pcap_geterr(ld.pch));
809   }
810   pcap_close(ld.pch);
811
812   if (cfile.save_file != NULL) {
813     /* We're saving to a file; close the file. */
814     if (!wtap_dump_close(ld.pdh, &err))
815       show_capture_file_io_error(cfile.save_file, err, TRUE);
816   }
817
818   return TRUE;
819
820 error:
821   g_free(cfile.save_file);
822   cfile.save_file = NULL;
823   fprintf(stderr, "tethereal: %s\n", errmsg);
824   if (ld.pch != NULL)
825     pcap_close(ld.pch);
826
827   return FALSE;
828 }
829
830 static void
831 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
832   const u_char *pd)
833 {
834   struct wtap_pkthdr whdr;
835   loop_data *ld = (loop_data *) user;
836   cb_args_t args;
837
838   whdr.ts.tv_sec = phdr->ts.tv_sec;
839   whdr.ts.tv_usec = phdr->ts.tv_usec;
840   whdr.caplen = phdr->caplen;
841   whdr.len = phdr->len;
842   whdr.pkt_encap = ld->linktype;
843
844   args.cf = &cfile;
845   args.pdh = ld->pdh;
846   if (ld->pdh) {
847     wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
848     fprintf(stderr, "\r%u ", cfile.count);
849     fflush(stdout);
850   } else {
851     wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
852   }
853 }
854
855 static void
856 capture_cleanup(int signum)
857 {
858   int err;
859
860   fprintf(stderr, "\n");
861   pcap_close(ld.pch);
862   if (ld.pdh != NULL) {
863     if (!wtap_dump_close(ld.pdh, &err)) {
864       show_capture_file_io_error(cfile.save_file, err, TRUE);
865       exit(2);
866     }
867   }
868   exit(0);
869 }
870 #endif /* HAVE_LIBPCAP */
871
872 static int
873 load_cap_file(capture_file *cf, int out_file_type)
874 {
875   gint         linktype;
876   wtap_dumper *pdh;
877   int          err;
878   int          success;
879   cb_args_t    args;
880
881   linktype = wtap_file_encap(cf->wth);
882   if (cf->save_file != NULL) {
883     /* Set up to write to the capture file. */
884     pdh = wtap_dump_open(cf->save_file, out_file_type,
885                 linktype, wtap_snapshot_length(cf->wth), &err);
886
887     if (pdh == NULL) {
888       /* We couldn't set up to write to the capture file. */
889       switch (err) {
890
891       case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
892         fprintf(stderr,
893                 "tethereal: Capture files can't be written in that format.\n");
894         break;
895
896       case WTAP_ERR_UNSUPPORTED_ENCAP:
897       case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
898         fprintf(stderr,
899 "tethereal: The capture file being read cannot be written in that format.\n");
900         break;
901
902       case WTAP_ERR_CANT_OPEN:
903         fprintf(stderr,
904 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
905                  cf->save_file);
906         break;
907
908       case WTAP_ERR_SHORT_WRITE:
909         fprintf(stderr,
910 "tethereal: A full header couldn't be written to the file \"%s\".\n",
911                 cf->save_file);
912         break;
913
914       default:
915         if (err < 0) {
916           fprintf(stderr,
917                 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
918                 cf->save_file, err);
919         } else {
920           fprintf(stderr,
921                 "tethereal: The file \"%s\" could not be opened: %s\n.",
922                 cf->save_file, strerror(err));
923         }
924         break;
925       }
926       goto out;
927     }
928     args.cf = cf;
929     args.pdh = pdh;
930     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
931                         &err);
932
933     /* Now close the capture file. */
934     if (!wtap_dump_close(pdh, &err))
935       show_capture_file_io_error(cfile.save_file, err, TRUE);
936   } else {
937     args.cf = cf;
938     args.pdh = NULL;
939     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
940                         &err);
941   }
942   if (!success) {
943     /* Print up a message box noting that the read failed somewhere along
944        the line. */
945     switch (err) {
946
947     case WTAP_ERR_UNSUPPORTED_ENCAP:
948       fprintf(stderr,
949 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
950         cf->filename);
951       break;
952
953     case WTAP_ERR_CANT_READ:
954       fprintf(stderr,
955 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
956         cf->filename);
957       break;
958
959     case WTAP_ERR_SHORT_READ:
960       fprintf(stderr,
961 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
962         cf->filename);
963       break;
964
965     case WTAP_ERR_BAD_RECORD:
966       fprintf(stderr,
967 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
968         cf->filename);
969       break;
970
971     default:
972       fprintf(stderr,
973 "tethereal: An error occurred while reading \"%s\": %s.\n",
974         cf->filename, wtap_strerror(err));
975       break;
976     }
977   }
978
979 out:
980   wtap_close(cf->wth);
981   cf->wth = NULL;
982
983   return err;
984 }
985
986 static void
987 fill_in_fdata(frame_data *fdata, capture_file *cf,
988         const struct wtap_pkthdr *phdr,
989         const union wtap_pseudo_header *pseudo_header, long offset)
990 {
991   int i;
992
993   fdata->next = NULL;
994   fdata->prev = NULL;
995   fdata->pfd = NULL;
996   fdata->data_src = NULL;
997   fdata->num = cf->count;
998   fdata->pkt_len = phdr->len;
999   fdata->cap_len = phdr->caplen;
1000   fdata->file_off = offset;
1001   fdata->cinfo = NULL;
1002   fdata->lnk_t = phdr->pkt_encap;
1003   fdata->abs_secs  = phdr->ts.tv_sec;
1004   fdata->abs_usecs = phdr->ts.tv_usec;
1005   fdata->flags.passed_dfilter = 0;
1006   fdata->flags.encoding = CHAR_ASCII;
1007   fdata->flags.visited = 0;
1008   fdata->flags.marked = 0;
1009
1010   /* If we don't have the time stamp of the first packet in the
1011      capture, it's because this is the first packet.  Save the time
1012      stamp of this packet as the time stamp of the first packet. */
1013   if (!firstsec && !firstusec) {
1014     firstsec  = fdata->abs_secs;
1015     firstusec = fdata->abs_usecs;
1016   }
1017
1018   /* If we don't have the time stamp of the previous displayed packet,
1019      it's because this is the first displayed packet.  Save the time
1020      stamp of this packet as the time stamp of the previous displayed
1021      packet. */
1022   if (!prevsec && !prevusec) {
1023     prevsec  = fdata->abs_secs;
1024     prevusec = fdata->abs_usecs;
1025   }
1026
1027   /* Get the time elapsed between the first packet and this packet. */
1028   compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1029                 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1030
1031   /* If it's greater than the current elapsed time, set the elapsed time
1032      to it (we check for "greater than" so as not to be confused by
1033      time moving backwards). */
1034   if ((gint32)cf->esec < fdata->rel_secs
1035         || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1036     cf->esec = fdata->rel_secs;
1037     cf->eusec = fdata->rel_usecs;
1038   }
1039   
1040   /* Get the time elapsed between the previous displayed packet and
1041      this packet. */
1042   compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1043                 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1044   prevsec = fdata->abs_secs;
1045   prevusec = fdata->abs_usecs;
1046
1047   fdata->cinfo = &cf->cinfo;
1048   for (i = 0; i < fdata->cinfo->num_cols; i++) {
1049     fdata->cinfo->col_buf[i][0] = '\0';
1050     fdata->cinfo->col_data[i] = fdata->cinfo->col_buf[i];
1051   }
1052 }
1053
1054 /* Free up all data attached to a "frame_data" structure. */
1055 static void
1056 clear_fdata(frame_data *fdata)
1057 {
1058   if (fdata->pfd)
1059     g_slist_free(fdata->pfd);
1060   if (fdata->data_src)
1061     g_slist_free(fdata->data_src);
1062 }
1063
1064 static void
1065 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1066   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1067 {
1068   cb_args_t    *args = (cb_args_t *) user;
1069   capture_file *cf = args->cf;
1070   wtap_dumper  *pdh = args->pdh;
1071   frame_data    fdata;
1072   proto_tree   *protocol_tree;
1073   int           err;
1074   gboolean      passed;
1075   epan_dissect_t *edt;
1076
1077   cf->count++;
1078   if (cf->rfcode) {
1079     fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1080     protocol_tree = proto_tree_create_root();
1081     edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
1082     passed = dfilter_apply_edt(cf->rfcode, edt);
1083   } else {
1084     protocol_tree = NULL;
1085     passed = TRUE;
1086     edt = NULL;
1087   }
1088   if (passed) {
1089     if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1090 #ifdef HAVE_LIBPCAP
1091       if (ld.pch != NULL) {
1092         /* We're capturing packets, so we're printing a count of packets
1093            captured; move to the line after the count. */
1094         fprintf(stderr, "\n");
1095       }
1096 #endif
1097       show_capture_file_io_error(cf->save_file, err, FALSE);
1098 #ifdef HAVE_LIBPCAP
1099       if (ld.pch != NULL)
1100         pcap_close(ld.pch);
1101 #endif
1102       wtap_dump_close(pdh, &err);
1103       exit(2);
1104     }
1105   }
1106   if (protocol_tree != NULL)
1107     proto_tree_free(protocol_tree);
1108   if (edt != NULL)
1109     epan_dissect_free(edt);
1110   if (cf->rfcode)
1111     clear_fdata(&fdata);
1112 }
1113
1114 static void
1115 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1116 {
1117   switch (err) {
1118
1119   case ENOSPC:
1120     fprintf(stderr,
1121 "tethereal: Not all the packets could be written to \"%s\" because there is "
1122 "no space left on the file system.\n",
1123         fname);
1124     break;
1125
1126 #ifdef EDQUOT
1127   case EDQUOT:
1128     fprintf(stderr,
1129 "tethereal: Not all the packets could be written to \"%s\" because you are "
1130 "too close to, or over your disk quota.\n",
1131         fname);
1132   break;
1133 #endif
1134
1135   case WTAP_ERR_CANT_CLOSE:
1136     fprintf(stderr,
1137 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1138         fname);
1139     break;
1140
1141   case WTAP_ERR_SHORT_WRITE:
1142     fprintf(stderr,
1143 "tethereal: Not all the packets could be written to \"%s\".\n",
1144         fname);
1145     break;
1146
1147   default:
1148     if (is_close) {
1149       fprintf(stderr,
1150 "tethereal: \"%s\" could not be closed: %s.\n",
1151         fname, wtap_strerror(err));
1152     } else {
1153       fprintf(stderr,
1154 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1155         fname, wtap_strerror(err));
1156     }
1157     break;
1158   }
1159 }
1160
1161 static void
1162 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1163   long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1164 {
1165   cb_args_t    *args = (cb_args_t *) user;
1166   capture_file *cf = args->cf;
1167   frame_data    fdata;
1168   proto_tree   *protocol_tree;
1169   gboolean      passed;
1170   print_args_t  print_args;
1171   epan_dissect_t *edt;
1172   int           i;
1173
1174   cf->count++;
1175
1176   /* The protocol tree will be "visible", i.e., printed, only if we're
1177      not printing a summary. */
1178   proto_tree_is_visible = verbose;
1179
1180   fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1181
1182   passed = TRUE;
1183   if (cf->rfcode || verbose)
1184     protocol_tree = proto_tree_create_root();
1185   else
1186     protocol_tree = NULL;
1187   edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
1188   if (cf->rfcode)
1189     passed = dfilter_apply_edt(cf->rfcode, edt);
1190   if (passed) {
1191     /* The packet passed the read filter. */
1192     if (verbose) {
1193       /* Print the information in the protocol tree. */
1194       print_args.to_file = TRUE;
1195       print_args.format = PR_FMT_TEXT;
1196       print_args.print_summary = FALSE;
1197       print_args.print_hex = print_hex;
1198       print_args.expand_all = TRUE;
1199       print_args.suppress_unmarked = FALSE;
1200       proto_tree_print(FALSE, &print_args, (GNode *)protocol_tree,
1201                         &fdata, stdout);
1202       if (!print_hex) {
1203         /* "print_hex_data()" will put out a leading blank line, as well
1204            as a trailing one; print one here, to separate the packets,
1205            only if "print_hex_data()" won't be called. */
1206         printf("\n");
1207       }
1208     } else {
1209       /* Just fill in the columns. */
1210       fill_in_columns(&fdata);
1211
1212       /* Now print them. */
1213       for (i = 0; i < cf->cinfo.num_cols; i++) {
1214         switch (cf->cinfo.col_fmt[i]) {
1215         case COL_NUMBER:
1216           /*
1217            * Don't print this if we're doing a live capture from a network
1218            * interface - if we're doing a live capture, you won't be
1219            * able to look at the capture in the future (it's not being
1220            * saved anywhere), so the frame numbers are unlikely to be
1221            * useful.
1222            *
1223            * (XXX - it might be nice to be able to save and print at
1224            * the same time, sort of like an "Update list of packets
1225            * in real time" capture in Ethereal.)
1226            */
1227           if (cf->iface != NULL)
1228             continue;
1229           printf("%3s", cf->cinfo.col_data[i]);
1230           break;
1231
1232         case COL_CLS_TIME:
1233         case COL_REL_TIME:
1234         case COL_ABS_TIME:
1235         case COL_ABS_DATE_TIME: /* XXX - wider */
1236           printf("%10s", cf->cinfo.col_data[i]);
1237           break;
1238
1239         case COL_DEF_SRC:
1240         case COL_RES_SRC:
1241         case COL_UNRES_SRC:
1242         case COL_DEF_DL_SRC:
1243         case COL_RES_DL_SRC:
1244         case COL_UNRES_DL_SRC:
1245         case COL_DEF_NET_SRC:
1246         case COL_RES_NET_SRC:
1247         case COL_UNRES_NET_SRC:
1248           printf("%12s", cf->cinfo.col_data[i]);
1249           break;
1250
1251         case COL_DEF_DST:
1252         case COL_RES_DST:
1253         case COL_UNRES_DST:
1254         case COL_DEF_DL_DST:
1255         case COL_RES_DL_DST:
1256         case COL_UNRES_DL_DST:
1257         case COL_DEF_NET_DST:
1258         case COL_RES_NET_DST:
1259         case COL_UNRES_NET_DST:
1260           printf("%-12s", cf->cinfo.col_data[i]);
1261           break;
1262
1263         default:
1264           printf("%s", cf->cinfo.col_data[i]);
1265           break;
1266         }
1267         if (i != cf->cinfo.num_cols - 1) {
1268           /*
1269            * This isn't the last column, so we need to print a
1270            * separator between this column and the next.
1271            *
1272            * If we printed a network source and are printing a
1273            * network destination of the same type next, separate
1274            * them with "->"; if we printed a network destination
1275            * and are printing a network source of the same type
1276            * next, separate them with "<-"; otherwise separate them
1277            * with a space.
1278            */
1279           switch (cf->cinfo.col_fmt[i]) {
1280
1281           case COL_DEF_SRC:
1282           case COL_RES_SRC:
1283           case COL_UNRES_SRC:
1284             switch (cf->cinfo.col_fmt[i + 1]) {
1285
1286             case COL_DEF_DST:
1287             case COL_RES_DST:
1288             case COL_UNRES_DST:
1289               printf(" -> ");
1290               break;
1291
1292             default:
1293               putchar(' ');
1294               break;
1295             }
1296             break;
1297
1298           case COL_DEF_DL_SRC:
1299           case COL_RES_DL_SRC:
1300           case COL_UNRES_DL_SRC:
1301             switch (cf->cinfo.col_fmt[i + 1]) {
1302
1303             case COL_DEF_DL_DST:
1304             case COL_RES_DL_DST:
1305             case COL_UNRES_DL_DST:
1306               printf(" -> ");
1307               break;
1308
1309             default:
1310               putchar(' ');
1311               break;
1312             }
1313             break;
1314
1315           case COL_DEF_NET_SRC:
1316           case COL_RES_NET_SRC:
1317           case COL_UNRES_NET_SRC:
1318             switch (cf->cinfo.col_fmt[i + 1]) {
1319
1320             case COL_DEF_NET_DST:
1321             case COL_RES_NET_DST:
1322             case COL_UNRES_NET_DST:
1323               printf(" -> ");
1324               break;
1325
1326             default:
1327               putchar(' ');
1328               break;
1329             }
1330             break;
1331
1332           case COL_DEF_DST:
1333           case COL_RES_DST:
1334           case COL_UNRES_DST:
1335             switch (cf->cinfo.col_fmt[i + 1]) {
1336
1337             case COL_DEF_SRC:
1338             case COL_RES_SRC:
1339             case COL_UNRES_SRC:
1340               printf(" <- ");
1341               break;
1342
1343             default:
1344               putchar(' ');
1345               break;
1346             }
1347             break;
1348
1349           case COL_DEF_DL_DST:
1350           case COL_RES_DL_DST:
1351           case COL_UNRES_DL_DST:
1352             switch (cf->cinfo.col_fmt[i + 1]) {
1353
1354             case COL_DEF_DL_SRC:
1355             case COL_RES_DL_SRC:
1356             case COL_UNRES_DL_SRC:
1357               printf(" <- ");
1358               break;
1359
1360             default:
1361               putchar(' ');
1362               break;
1363             }
1364             break;
1365
1366           case COL_DEF_NET_DST:
1367           case COL_RES_NET_DST:
1368           case COL_UNRES_NET_DST:
1369             switch (cf->cinfo.col_fmt[i + 1]) {
1370
1371             case COL_DEF_NET_SRC:
1372             case COL_RES_NET_SRC:
1373             case COL_UNRES_NET_SRC:
1374               printf(" <- ");
1375               break;
1376
1377             default:
1378               putchar(' ');
1379               break;
1380             }
1381             break;
1382
1383           default:
1384             putchar(' ');
1385             break;
1386           }
1387         }
1388       }
1389       putchar('\n');
1390     }
1391     if (print_hex) {
1392       print_hex_data(stdout, print_args.format, &fdata);
1393       putchar('\n');
1394     }
1395     fdata.cinfo = NULL;
1396   }
1397
1398   /* The ANSI C standard does not appear to *require* that a line-buffered
1399      stream be flushed to the host environment whenever a newline is
1400      written, it just says that, on such a stream, characters "are
1401      intended to be transmitted to or from the host environment as a
1402      block when a new-line character is encountered".
1403
1404      The Visual C++ 6.0 C implementation doesn't do what is intended;
1405      even if you set a stream to be line-buffered, it still doesn't
1406      flush the buffer at the end of every line.
1407
1408      So, if the "-l" flag was specified, we flush the standard output
1409      at the end of a packet.  This will do the right thing if we're
1410      printing packet summary lines, and, as we print the entire protocol
1411      tree for a single packet without waiting for anything to happen,
1412      it should be as good as line-buffered mode if we're printing
1413      protocol trees.  (The whole reason for the "-l" flag in either
1414      tcpdump or Tethereal is to allow the output of a live capture to
1415      be piped to a program or script and to have that script see the
1416      information for the packet as soon as it's printed, rather than
1417      having to wait until a standard I/O buffer fills up. */
1418   if (line_buffered)
1419     fflush(stdout);
1420   if (protocol_tree != NULL)
1421     proto_tree_free(protocol_tree);
1422
1423   epan_dissect_free(edt);
1424
1425   clear_fdata(&fdata);
1426
1427   proto_tree_is_visible = FALSE;
1428 }
1429
1430 char *
1431 file_open_error_message(int err, gboolean for_writing)
1432 {
1433   char *errmsg;
1434   static char errmsg_errno[1024+1];
1435
1436   switch (err) {
1437
1438   case WTAP_ERR_NOT_REGULAR_FILE:
1439     errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1440     break;
1441
1442   case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1443   case WTAP_ERR_UNSUPPORTED:
1444     /* Seen only when opening a capture file for reading. */
1445     errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1446     break;
1447
1448   case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1449     /* Seen only when opening a capture file for writing. */
1450     errmsg = "Tethereal does not support writing capture files in that format.";
1451     break;
1452
1453   case WTAP_ERR_UNSUPPORTED_ENCAP:
1454   case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1455     if (for_writing)
1456       errmsg = "Tethereal cannot save this capture in that format.";
1457     else
1458       errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1459     break;
1460
1461   case WTAP_ERR_BAD_RECORD:
1462     errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1463     break;
1464
1465   case WTAP_ERR_CANT_OPEN:
1466     if (for_writing)
1467       errmsg = "The file \"%s\" could not be created for some unknown reason.";
1468     else
1469       errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1470     break;
1471
1472   case WTAP_ERR_SHORT_READ:
1473     errmsg = "The file \"%s\" appears to have been cut short"
1474              " in the middle of a packet.";
1475     break;
1476
1477   case WTAP_ERR_SHORT_WRITE:
1478     errmsg = "A full header couldn't be written to the file \"%s\".";
1479     break;
1480
1481   case ENOENT:
1482     if (for_writing)
1483       errmsg = "The path to the file \"%s\" does not exist.";
1484     else
1485       errmsg = "The file \"%s\" does not exist.";
1486     break;
1487
1488   case EACCES:
1489     if (for_writing)
1490       errmsg = "You do not have permission to create or write to the file \"%s\".";
1491     else
1492       errmsg = "You do not have permission to read the file \"%s\".";
1493     break;
1494
1495   case EISDIR:
1496     errmsg = "\"%s\" is a directory (folder), not a file.";
1497     break;
1498
1499   default:
1500     snprintf(errmsg_errno, sizeof(errmsg_errno),
1501              "The file \"%%s\" could not be opened: %s.",
1502              wtap_strerror(err));
1503     errmsg = errmsg_errno;
1504     break;
1505   }
1506   return errmsg;
1507 }
1508
1509 int
1510 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1511 {
1512   wtap       *wth;
1513   int         err;
1514   int         fd;
1515   struct stat cf_stat;
1516   char        err_msg[2048+1];
1517
1518   wth = wtap_open_offline(fname, &err, FALSE);
1519   if (wth == NULL)
1520     goto fail;
1521
1522   /* Find the size of the file. */
1523   fd = wtap_fd(wth);
1524   if (fstat(fd, &cf_stat) < 0) {
1525     err = errno;
1526     wtap_close(wth);
1527     goto fail;
1528   }
1529
1530   /* The open succeeded.  Fill in the information for this file. */
1531
1532   /* Initialize the table of conversations. */
1533   epan_conversation_init();
1534
1535   /* Initialize protocol-specific variables */
1536   init_all_protocols();
1537
1538   /* Initialize the common data structures for fragment reassembly.
1539      Must be done *after* "init_all_protocols()", as "init_all_protocols()"
1540      may free up space for fragments, which it finds by using the
1541      data structures that "reassemble_init()" frees. */
1542   reassemble_init();
1543
1544   cf->wth = wth;
1545   cf->filed = fd;
1546   cf->f_len = cf_stat.st_size;
1547
1548   /* Set the file name because we need it to set the follow stream filter.
1549      XXX - is that still true?  We need it for other reasons, though,
1550      in any case. */
1551   cf->filename = g_strdup(fname);
1552
1553   /* Indicate whether it's a permanent or temporary file. */
1554   cf->is_tempfile = is_tempfile;
1555
1556   /* If it's a temporary capture buffer file, mark it as not saved. */
1557   cf->user_saved = !is_tempfile;
1558
1559   cf->cd_t      = wtap_file_type(cf->wth);
1560   cf->count     = 0;
1561   cf->drops_known = FALSE;
1562   cf->drops     = 0;
1563   cf->esec      = 0;
1564   cf->eusec     = 0;
1565   cf->snap      = wtap_snapshot_length(cf->wth);
1566   cf->progbar_quantum = 0;
1567   cf->progbar_nextstep = 0;
1568   firstsec = 0, firstusec = 0;
1569   prevsec = 0, prevusec = 0;
1570  
1571   return (0);
1572
1573 fail:
1574   snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1575   fprintf(stderr, "tethereal: %s\n", err_msg);
1576   return (err);
1577 }