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