3 * $Id: tethereal.c,v 1.137 2002/05/14 18:27:16 guy Exp $
5 * Ethereal - Network traffic analyzer
6 * By Gerald Combs <gerald@ethereal.com>
7 * Copyright 1998 Gerald Combs
9 * Text-mode variant, by Gilbert Ramirez <gram@alumni.rice.edu>
10 * and Guy Harris <guy@alum.mit.edu>.
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.
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.
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.
44 #ifdef HAVE_SYS_TYPES_H
45 #include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
64 #include <zlib.h> /* to get the libz version number */
67 #ifdef NEED_SNPRINTF_H
68 # include "snprintf.h"
71 #ifdef HAVE_UCD_SNMP_VERSION_H
72 #include <ucd-snmp/version.h>
73 #endif /* HAVE_UCD_SNMP_VERSION_H */
75 #ifdef NEED_STRERROR_H
84 #include <epan/epan.h>
87 #include <epan/timestamp.h>
88 #include <epan/packet.h>
93 #include <epan/resolv.h>
96 #include "pcap-util.h"
98 #include <epan/conversation.h>
99 #include <epan/plugins.h>
100 #include "register.h"
101 #include "conditions.h"
102 #include "capture_stop_conditions.h"
103 #include "ringbuffer.h"
104 #include <epan/epan_dissect.h>
107 #include "capture-wpcap.h"
110 static guint32 firstsec, firstusec;
111 static guint32 prevsec, prevusec;
112 static GString *comp_info_str;
113 static gboolean quiet;
114 static gboolean verbose;
115 static gboolean print_hex;
116 static gboolean line_buffered;
119 typedef struct _loop_data {
120 gboolean go; /* TRUE as long as we're supposed to keep capturing */
129 static int capture(volatile int, int);
130 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
132 static void capture_cleanup(int);
140 static int load_cap_file(capture_file *, int);
141 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, long,
142 union wtap_pseudo_header *, const u_char *);
143 static void show_capture_file_io_error(const char *, int, gboolean);
144 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, long,
145 union wtap_pseudo_header *, const u_char *);
148 ts_type timestamp_type = RELATIVE;
151 int snaplen; /* Maximum captured packet length */
152 int promisc_mode; /* Capture in promiscuous mode */
153 int autostop_count; /* Maximum packet count */
154 gboolean has_autostop_duration; /* TRUE if maximum capture duration
156 gint32 autostop_duration; /* Maximum capture duration */
157 gboolean has_autostop_filesize; /* TRUE if maximum capture file size
159 gint32 autostop_filesize; /* Maximum capture file size */
160 gboolean ringbuffer_on; /* TRUE if ring buffer in use */
161 guint32 ringbuffer_num_files; /* Number of ring buffer files */
164 static capture_options capture_opts = {
165 WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
166 infinite, in effect */
167 TRUE, /* promiscuous mode is the default */
168 0, /* max packet count - default is 0,
170 FALSE, /* maximum capture duration not
171 specified by default */
172 0, /* maximum capture duration */
173 FALSE, /* maximum capture file size not
174 specified by default */
175 0, /* maximum capture file size */
176 FALSE, /* ring buffer off by default */
177 RINGBUFFER_MIN_NUM_FILES /* default number of ring buffer
187 fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
190 fprintf(stderr, "t%s [ -DvVhlp ] [ -a <capture autostop condition> ] ...\n",
192 fprintf(stderr, "\t[ -b <number of ring buffer files> ] [ -c <count> ]\n");
193 fprintf(stderr, "\t[ -f <capture filter> ] [ -F <capture file type> ]\n");
194 fprintf(stderr, "\t[ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
195 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
196 fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
198 fprintf(stderr, "t%s [ -qvVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
199 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
200 fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
202 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
203 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
204 if (wtap_dump_can_open(i))
205 fprintf(stderr, "\t%s - %s\n",
206 wtap_file_type_short_string(i), wtap_file_type_string(i));
208 fprintf(stderr, "\tdefault is libpcap\n");
212 get_positive_int(const char *string, const char *name)
217 number = strtol(string, &p, 10);
218 if (p == string || *p != '\0') {
219 fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
224 fprintf(stderr, "tethereal: The specified %s is a negative number\n",
229 fprintf(stderr, "tethereal: The specified %s is zero\n",
233 if (number > INT_MAX) {
234 fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
243 * Given a string of the form "<autostop criterion>:<value>", as might appear
244 * as an argument to a "-a" option, parse it and set the criterion in
245 * question. Return an indication of whether it succeeded or failed
249 set_autostop_criterion(const char *autostoparg)
253 colonp = strchr(autostoparg, ':');
261 * Skip over any white space (there probably won't be any, but
262 * as we allow it in the preferences file, we might as well
269 * Put the colon back, so if our caller uses, in an
270 * error message, the string they passed us, the message
276 if (strcmp(autostoparg,"duration") == 0) {
277 capture_opts.has_autostop_duration = TRUE;
278 capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
279 } else if (strcmp(autostoparg,"filesize") == 0) {
280 capture_opts.has_autostop_filesize = TRUE;
281 capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
285 *colonp = ':'; /* put the colon back */
291 main(int argc, char *argv[])
295 gboolean arg_error = FALSE;
297 #ifdef HAVE_PCAP_VERSION
298 extern char pcap_version[];
299 #endif /* HAVE_PCAP_VERSION */
300 #endif /* HAVE_LIBPCAP */
308 int gpf_open_errno, pf_open_errno;
311 gboolean capture_filter_specified = FALSE;
312 GList *if_list, *if_entry;
313 gchar err_str[PCAP_ERRBUF_SIZE];
315 gboolean capture_option_specified = FALSE;
317 int out_file_type = WTAP_FILE_PCAP;
318 gchar *cf_name = NULL, *rfilter = NULL;
319 dfilter_t *rfcode = NULL;
323 /* Register all dissectors; we must do this before checking for the
324 "-G" flag, as the "-G" flag dumps information registered by the
325 dissectors, and we must do it before we read the preferences, in
326 case any dissectors register preferences. */
327 epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
329 /* Now register the preferences for any non-dissector modules.
330 We must do that before we read the preferences as well. */
331 prefs_register_modules();
333 /* If invoked with the "-G" flag, we dump out information based on
334 the argument to the "-G" flag; if no argument is specified,
335 for backwards compatibility we dump out a glossary of display
338 We do this here to mirror what happens in the GTK+ version, although
339 it's not necessary here. */
340 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
342 proto_registrar_dump_fields();
344 if (strcmp(argv[2], "fields") == 0)
345 proto_registrar_dump_fields();
346 else if (strcmp(argv[2], "protocols") == 0)
347 proto_registrar_dump_protocols();
349 fprintf(stderr, "tethereal: Invalid \"%s\" option for -G flag\n",
357 /* Set the C-language locale to the native environment. */
358 setlocale(LC_ALL, "");
360 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
361 if (gpf_path != NULL) {
362 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
363 strerror(gpf_open_errno));
365 if (pf_path != NULL) {
366 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
367 strerror(pf_open_errno));
370 /* Set the name resolution code's flags from the preferences. */
371 g_resolv_flags = prefs->name_resolve;
374 /* Load Wpcap, if possible */
378 /* Initialize the capture file struct */
380 cfile.plist_end = NULL;
382 cfile.filename = NULL;
383 cfile.user_saved = FALSE;
384 cfile.is_tempfile = FALSE;
386 cfile.dfilter = NULL;
389 cfile.cfilter = g_strdup("");
392 cfile.save_file = NULL;
393 cfile.save_file_fd = -1;
394 cfile.has_snap = FALSE;
395 cfile.snap = WTAP_MAX_PACKET_SIZE;
397 col_init(&cfile.cinfo, prefs->num_cols);
399 /* Assemble the compile-time options */
400 comp_info_str = g_string_new("");
402 g_string_append(comp_info_str, "with ");
403 g_string_sprintfa(comp_info_str,
404 #ifdef GLIB_MAJOR_VERSION
405 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
408 "GLib (version unknown)");
412 g_string_append(comp_info_str, ", with libpcap ");
413 #ifdef HAVE_PCAP_VERSION
414 g_string_append(comp_info_str, pcap_version);
415 #else /* HAVE_PCAP_VERSION */
416 g_string_append(comp_info_str, "(version unknown)");
417 #endif /* HAVE_PCAP_VERSION */
418 #else /* HAVE_LIBPCAP */
419 g_string_append(comp_info_str, ", without libpcap");
420 #endif /* HAVE_LIBPCAP */
423 g_string_append(comp_info_str, ", with libz ");
425 g_string_append(comp_info_str, ZLIB_VERSION);
426 #else /* ZLIB_VERSION */
427 g_string_append(comp_info_str, "(version unknown)");
428 #endif /* ZLIB_VERSION */
429 #else /* HAVE_LIBZ */
430 g_string_append(comp_info_str, ", without libz");
431 #endif /* HAVE_LIBZ */
433 /* Oh, this is pretty */
435 g_string_append(comp_info_str, ", with UCD SNMP ");
436 #ifdef HAVE_UCD_SNMP_VERSION_H
437 g_string_append(comp_info_str, VersionInfo);
438 #else /* HAVE_UCD_SNMP_VERSION_H */
439 g_string_append(comp_info_str, "(version unknown)");
440 #endif /* HAVE_UCD_SNMP_VERSION_H */
441 #else /* no SNMP library */
442 g_string_append(comp_info_str, ", without UCD SNMP");
445 /* Now get our args */
446 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pqr:R:s:t:vw:Vx")) != -1) {
448 case 'a': /* autostop criteria */
450 if (set_autostop_criterion(optarg) == FALSE) {
451 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
455 capture_option_specified = TRUE;
459 case 'b': /* Ringbuffer option */
461 capture_opts.ringbuffer_on = TRUE;
462 capture_opts.ringbuffer_num_files =
463 get_positive_int(optarg, "number of ring buffer files");
465 capture_option_specified = TRUE;
469 case 'c': /* Capture xxx packets */
471 capture_opts.autostop_count =
472 get_positive_int(optarg, "packet count");
474 capture_option_specified = TRUE;
478 case 'D': /* Print a list of capture devices */
480 if_list = get_interface_list(&err, err_str);
481 if (if_list == NULL) {
484 case CANT_GET_INTERFACE_LIST:
485 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
489 case NO_INTERFACES_FOUND:
490 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
495 for (if_entry = g_list_first(if_list); if_entry != NULL;
496 if_entry = g_list_next(if_entry))
497 printf("%s\n", (char *)if_entry->data);
498 free_interface_list(if_list);
501 capture_option_specified = TRUE;
507 capture_filter_specified = TRUE;
508 cfile.cfilter = g_strdup(optarg);
510 capture_option_specified = TRUE;
515 out_file_type = wtap_short_string_to_file_type(optarg);
516 if (out_file_type < 0) {
517 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
522 case 'h': /* Print help and exit */
526 case 'i': /* Use interface xxx */
528 cfile.iface = g_strdup(optarg);
530 capture_option_specified = TRUE;
534 case 'l': /* "Line-buffer" standard output */
535 /* This isn't line-buffering, strictly speaking, it's just
536 flushing the standard output after the information for
537 each packet is printed; however, that should be good
538 enough for all the purposes to which "-l" is put.
540 See the comment in "wtap_dispatch_cb_print()" for an
541 explanation of why we do that, and why we don't just
542 use "setvbuf()" to make the standard output line-buffered
543 (short version: in Windows, "line-buffered" is the same
544 as "fully-buffered", and the output buffer is only flushed
545 when it fills up). */
546 line_buffered = TRUE;
548 case 'n': /* No name resolution */
549 g_resolv_flags = RESOLV_NONE;
551 case 'N': /* Select what types of addresses/port #s to resolve */
552 if (g_resolv_flags == RESOLV_ALL)
553 g_resolv_flags = RESOLV_NONE;
554 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
555 if (badopt != '\0') {
556 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
561 case 'o': /* Override preference from command line */
562 switch (prefs_set_pref(optarg)) {
564 case PREFS_SET_SYNTAX_ERR:
565 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
569 case PREFS_SET_NO_SUCH_PREF:
570 case PREFS_SET_OBSOLETE:
571 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
577 case 'p': /* Don't capture in promiscuous mode */
579 capture_opts.promisc_mode = FALSE;
581 capture_option_specified = TRUE;
585 case 'q': /* Quiet */
588 case 'r': /* Read capture file xxx */
589 cf_name = g_strdup(optarg);
591 case 'R': /* Read file filter */
594 case 's': /* Set the snapshot (capture) length */
596 capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
598 capture_option_specified = TRUE;
602 case 't': /* Time stamp type */
603 if (strcmp(optarg, "r") == 0)
604 timestamp_type = RELATIVE;
605 else if (strcmp(optarg, "a") == 0)
606 timestamp_type = ABSOLUTE;
607 else if (strcmp(optarg, "ad") == 0)
608 timestamp_type = ABSOLUTE_WITH_DATE;
609 else if (strcmp(optarg, "d") == 0)
610 timestamp_type = DELTA;
612 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
614 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
615 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
619 case 'v': /* Show version and exit */
620 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
623 case 'w': /* Write to capture file xxx */
624 cfile.save_file = g_strdup(optarg);
626 case 'V': /* Verbose */
629 case 'x': /* Print packet data in hex (and ASCII) */
635 /* If no capture filter or read filter has been specified, and there are
636 still command-line arguments, treat them as the tokens of a capture
637 filter (if no "-r" flag was specified) or a read filter (if a "-r"
638 flag was specified. */
640 if (cf_name != NULL) {
641 if (rfilter != NULL) {
643 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
646 rfilter = get_args_as_string(argc, argv, optind);
649 if (capture_filter_specified) {
651 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
654 cfile.cfilter = get_args_as_string(argc, argv, optind);
656 capture_option_specified = TRUE;
662 /* If they didn't specify a "-w" flag, but specified a maximum capture
663 file size, tell them that this doesn't work, and exit. */
664 if (capture_opts.has_autostop_filesize && cfile.save_file == NULL) {
665 fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
669 if (capture_opts.ringbuffer_on) {
670 /* Ring buffer works only under certain conditions:
671 a) ring buffer does not work if you're not saving the capture to
673 b) ring buffer only works if you're saving in libpcap format;
674 c) it makes no sense to enable the ring buffer if the maximum
675 file size is set to "infinite". */
676 if (cfile.save_file == NULL) {
677 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved to a file.\n");
680 if (out_file_type != WTAP_FILE_PCAP) {
681 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved in libpcap format.\n");
684 if (!capture_opts.has_autostop_filesize) {
685 fprintf(stderr, "tethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
692 /* Start windows sockets */
693 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
696 /* Notify all registered modules that have had any of their preferences
697 changed either from one of the preferences file or from the command
698 line that its preferences have changed. */
702 if (capture_option_specified)
703 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
708 /* Build the column format array */
709 for (i = 0; i < cfile.cinfo.num_cols; i++) {
710 cfile.cinfo.col_fmt[i] = get_column_format(i);
711 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
712 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
714 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
715 cfile.cinfo.col_data[i] = NULL;
716 if (cfile.cinfo.col_fmt[i] == COL_INFO)
717 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
719 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
721 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
722 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
726 if (capture_opts.snaplen < 1)
727 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
728 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
729 capture_opts.snaplen = MIN_PACKET_SIZE;
731 /* Check the value range of the ringbuffer_num_files parameter */
732 if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
733 capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
734 else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
735 capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
738 if (rfilter != NULL) {
739 if (!dfilter_compile(rfilter, &rfcode)) {
740 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
745 cfile.rfcode = rfcode;
747 err = open_cap_file(cf_name, FALSE, &cfile);
752 err = load_cap_file(&cfile, out_file_type);
759 /* No capture file specified, so we're supposed to do a live capture;
760 do we have support for live captures? */
765 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
770 /* Yes; did the user specify an interface to use? */
771 if (cfile.iface == NULL) {
772 /* No - is a default specified in the preferences file? */
773 if (prefs->capture_device != NULL) {
775 cfile.iface = g_strdup(prefs->capture_device);
777 /* No - pick the first one from the list of interfaces. */
778 if_list = get_interface_list(&err, err_str);
779 if (if_list == NULL) {
782 case CANT_GET_INTERFACE_LIST:
783 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
787 case NO_INTERFACES_FOUND:
788 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
793 cfile.iface = g_strdup(if_list->data); /* first interface */
794 free_interface_list(if_list);
797 capture(capture_opts.autostop_count, out_file_type);
799 if (capture_opts.ringbuffer_on) {
804 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
815 /* Do the low-level work of a capture.
816 Returns TRUE if it succeeds, FALSE otherwise. */
818 capture(volatile int packet_count, int out_file_type)
820 gchar open_err_str[PCAP_ERRBUF_SIZE];
821 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
822 bpf_u_int32 netnum, netmask;
823 struct bpf_program fcode;
824 void (*oldhandler)(int);
826 volatile int inpkts = 0;
828 condition *volatile cnd_stop_capturesize = NULL;
829 condition *volatile cnd_stop_timeout = NULL;
831 static const char ppamsg[] = "can't find PPA for ";
834 struct pcap_stat stats;
837 /* Initialize all data structures used for dissection. */
840 ld.linktype = WTAP_ENCAP_UNKNOWN;
843 /* Open the network interface to capture from it.
844 Some versions of libpcap may put warnings into the error buffer
845 if they succeed; to tell if that's happened, we have to clear
846 the error buffer, and check if it's still a null string. */
847 open_err_str[0] = '\0';
848 ld.pch = pcap_open_live(cfile.iface, capture_opts.snaplen,
849 capture_opts.promisc_mode, 1000, open_err_str);
851 if (ld.pch == NULL) {
852 /* Well, we couldn't start the capture. */
854 /* On Win32 OSes, the capture devices are probably available to all
855 users; don't warn about permissions problems.
857 Do, however, warn that Token Ring and PPP devices aren't supported. */
858 snprintf(errmsg, sizeof errmsg,
859 "The capture session could not be initiated (%s).\n"
860 "Please check that you have the proper interface specified.\n"
862 "Note that the driver Tethereal uses for packet capture on Windows\n"
863 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
864 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
867 /* If we got a "can't find PPA for XXX" message, warn the user (who
868 is running Ethereal on HP-UX) that they don't have a version
869 of libpcap that properly handles HP-UX (libpcap 0.6.x and later
870 versions, which properly handle HP-UX, say "can't find /dev/dlpi
871 PPA for XXX" rather than "can't find PPA for XXX"). */
872 if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
875 "You are running Tethereal with a version of the libpcap library\n"
876 "that doesn't handle HP-UX network devices well; this means that\n"
877 "Tethereal may not be able to capture packets.\n"
879 "To fix this, you should install libpcap 0.6.2, or a later version\n"
880 "of libpcap, rather than libpcap 0.4 or 0.5.x. It is available in\n"
881 "packaged binary form from the Software Porting And Archive Centre\n"
882 "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
883 "at the URL lists a number of mirror sites.";
886 snprintf(errmsg, sizeof errmsg,
887 "The capture session could not be initiated (%s).\n"
888 "Please check to make sure you have sufficient permissions, and that\n"
889 "you have the proper interface specified.%s", open_err_str, libpcap_warn);
895 /* A capture filter was specified; set it up. */
896 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
898 * Well, we can't get the netmask for this interface; it's used
899 * only for filters that check for broadcast IP addresses, so
900 * we just warn the user, and punt and use 0.
903 "Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
906 if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
907 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
908 pcap_geterr(ld.pch));
911 if (pcap_setfilter(ld.pch, &fcode) < 0) {
912 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
913 pcap_geterr(ld.pch));
918 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
920 if (cfile.save_file != NULL) {
921 /* Set up to write to the capture file. */
922 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
923 strcpy(errmsg, "The network you're capturing from is of a type"
924 " that Tethereal doesn't support.");
927 if (capture_opts.ringbuffer_on) {
928 cfile.save_file_fd = ringbuf_init(cfile.save_file,
929 capture_opts.ringbuffer_num_files);
930 if (cfile.save_file_fd != -1) {
931 ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
932 pcap_snapshot(ld.pch), &err);
937 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
938 ld.linktype, pcap_snapshot(ld.pch), &err);
941 if (ld.pdh == NULL) {
942 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
948 /* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
949 returned a warning; print it, but keep capturing. */
950 if (open_err_str[0] != '\0')
951 fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
953 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
955 XXX - deal with signal semantics on various platforms. Or just
956 use "sigaction()" and be done with it? */
957 signal(SIGTERM, capture_cleanup);
958 signal(SIGINT, capture_cleanup);
960 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
961 signal(SIGHUP, oldhandler);
964 /* Let the user know what interface was chosen. */
965 fprintf(stderr, "Capturing on %s\n", cfile.iface);
968 /* initialize capture stop conditions */
969 init_capture_stop_conditions();
970 /* create stop conditions */
971 if (capture_opts.has_autostop_filesize)
972 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
973 (long)capture_opts.autostop_filesize * 1000);
974 if (capture_opts.has_autostop_duration)
975 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
976 (gint32)capture_opts.autostop_duration);
978 if (packet_count == 0)
979 packet_count = -1; /* infinite capturng */
980 if (!setjmp(ld.stopenv))
985 if (packet_count > 0)
987 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
988 if (packet_count == 0 || inpkts < 0) {
990 } else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
991 /* The specified capture time has elapsed; stop the capture. */
993 } else if (ld.pdh != NULL && cnd_stop_capturesize != NULL &&
994 cnd_eval(cnd_stop_capturesize,
995 (guint32)wtap_get_bytes_dumped(ld.pdh))) {
996 /* We're saving the capture to a file, and the capture file reached
998 if (capture_opts.ringbuffer_on) {
999 /* Switch to the next ringbuffer file */
1000 if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
1001 /* File switch failed: reset the condition */
1002 cnd_reset(cnd_stop_capturesize);
1004 /* File switch failed: stop here */
1009 /* No ringbuffer - just stop. */
1015 /* delete stop conditions */
1016 if (cnd_stop_capturesize != NULL)
1017 cnd_delete(cnd_stop_capturesize);
1018 if (cnd_stop_timeout != NULL)
1019 cnd_delete(cnd_stop_timeout);
1021 if ((cfile.save_file != NULL) && !quiet) {
1022 /* We're saving to a file, which means we're printing packet counts
1023 to the standard output if we are not running silent and deep.
1024 Send a newline so that we move to the line after the packet count. */
1025 fprintf(stderr, "\n");
1028 /* If we got an error while capturing, report it. */
1030 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
1031 pcap_geterr(ld.pch));
1034 /* Get the capture statistics, and, if any packets were dropped, report
1036 if (pcap_stats(ld.pch, &stats) >= 0) {
1037 if (stats.ps_drop != 0) {
1038 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
1041 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
1042 pcap_geterr(ld.pch));
1044 /* Report the number of captured packets if not reported during capture and
1045 we are not saving to a file. */
1046 if (quiet && (cfile.save_file != NULL)) {
1047 fprintf(stderr, "\r%u packets captured\n", cfile.count);
1052 if (cfile.save_file != NULL) {
1053 /* We're saving to a file or files; close all files. */
1054 if (capture_opts.ringbuffer_on) {
1055 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
1057 dump_ok = wtap_dump_close(ld.pdh, &err);
1060 show_capture_file_io_error(cfile.save_file, err, TRUE);
1066 if (capture_opts.ringbuffer_on) {
1067 ringbuf_error_cleanup();
1069 g_free(cfile.save_file);
1070 cfile.save_file = NULL;
1071 fprintf(stderr, "tethereal: %s\n", errmsg);
1079 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1082 struct wtap_pkthdr whdr;
1083 loop_data *ld = (loop_data *) user;
1086 whdr.ts.tv_sec = phdr->ts.tv_sec;
1087 whdr.ts.tv_usec = phdr->ts.tv_usec;
1088 whdr.caplen = phdr->caplen;
1089 whdr.len = phdr->len;
1090 whdr.pkt_encap = ld->linktype;
1095 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1096 /* Report packet capture count if not quiet */
1098 fprintf(stderr, "\r%u ", cfile.count);
1102 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1107 capture_cleanup(int signum _U_)
1109 /* Longjmp back to the starting point; "pcap_dispatch()", on many
1110 platforms, just keeps looping if it gets EINTR, so if we set
1111 "ld.go" to FALSE and return, we won't break out of it and quit
1113 longjmp(ld.stopenv, 1);
1115 #endif /* HAVE_LIBPCAP */
1118 load_cap_file(capture_file *cf, int out_file_type)
1121 int snapshot_length;
1127 linktype = wtap_file_encap(cf->wth);
1128 if (cf->save_file != NULL) {
1129 /* Set up to write to the capture file. */
1130 snapshot_length = wtap_snapshot_length(cf->wth);
1131 if (snapshot_length == 0) {
1132 /* Snapshot length of input file not known. */
1133 snapshot_length = WTAP_MAX_PACKET_SIZE;
1135 pdh = wtap_dump_open(cf->save_file, out_file_type,
1136 linktype, snapshot_length, &err);
1139 /* We couldn't set up to write to the capture file. */
1142 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1144 "tethereal: Capture files can't be written in that format.\n");
1147 case WTAP_ERR_UNSUPPORTED_ENCAP:
1148 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1150 "tethereal: The capture file being read cannot be written in that format.\n");
1153 case WTAP_ERR_CANT_OPEN:
1155 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1159 case WTAP_ERR_SHORT_WRITE:
1161 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1168 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1169 cf->save_file, err);
1172 "tethereal: The file \"%s\" could not be opened: %s\n.",
1173 cf->save_file, strerror(err));
1181 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1184 /* Now close the capture file. */
1185 if (!wtap_dump_close(pdh, &err))
1186 show_capture_file_io_error(cfile.save_file, err, TRUE);
1190 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1194 /* Print up a message box noting that the read failed somewhere along
1198 case WTAP_ERR_UNSUPPORTED_ENCAP:
1200 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1204 case WTAP_ERR_CANT_READ:
1206 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1210 case WTAP_ERR_SHORT_READ:
1212 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1216 case WTAP_ERR_BAD_RECORD:
1218 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1224 "tethereal: An error occurred while reading \"%s\": %s.\n",
1225 cf->filename, wtap_strerror(err));
1231 wtap_close(cf->wth);
1238 fill_in_fdata(frame_data *fdata, capture_file *cf,
1239 const struct wtap_pkthdr *phdr, long offset)
1244 fdata->data_src = NULL;
1245 fdata->num = cf->count;
1246 fdata->pkt_len = phdr->len;
1247 fdata->cap_len = phdr->caplen;
1248 fdata->file_off = offset;
1249 fdata->lnk_t = phdr->pkt_encap;
1250 fdata->abs_secs = phdr->ts.tv_sec;
1251 fdata->abs_usecs = phdr->ts.tv_usec;
1252 fdata->flags.passed_dfilter = 0;
1253 fdata->flags.encoding = CHAR_ASCII;
1254 fdata->flags.visited = 0;
1255 fdata->flags.marked = 0;
1257 /* If we don't have the time stamp of the first packet in the
1258 capture, it's because this is the first packet. Save the time
1259 stamp of this packet as the time stamp of the first packet. */
1260 if (!firstsec && !firstusec) {
1261 firstsec = fdata->abs_secs;
1262 firstusec = fdata->abs_usecs;
1265 /* If we don't have the time stamp of the previous displayed packet,
1266 it's because this is the first displayed packet. Save the time
1267 stamp of this packet as the time stamp of the previous displayed
1269 if (!prevsec && !prevusec) {
1270 prevsec = fdata->abs_secs;
1271 prevusec = fdata->abs_usecs;
1274 /* Get the time elapsed between the first packet and this packet. */
1275 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1276 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1278 /* If it's greater than the current elapsed time, set the elapsed time
1279 to it (we check for "greater than" so as not to be confused by
1280 time moving backwards). */
1281 if ((gint32)cf->esec < fdata->rel_secs
1282 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1283 cf->esec = fdata->rel_secs;
1284 cf->eusec = fdata->rel_usecs;
1287 /* Get the time elapsed between the previous displayed packet and
1289 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1290 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1291 prevsec = fdata->abs_secs;
1292 prevusec = fdata->abs_usecs;
1295 /* Free up all data attached to a "frame_data" structure. */
1297 clear_fdata(frame_data *fdata)
1300 g_slist_free(fdata->pfd);
1301 free_data_sources(fdata); /* release data source list */
1305 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1306 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1308 cb_args_t *args = (cb_args_t *) user;
1309 capture_file *cf = args->cf;
1310 wtap_dumper *pdh = args->pdh;
1314 epan_dissect_t *edt;
1318 fill_in_fdata(&fdata, cf, phdr, offset);
1319 edt = epan_dissect_new(TRUE, FALSE);
1320 epan_dissect_prime_dfilter(edt, cf->rfcode);
1321 epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1322 passed = dfilter_apply_edt(cf->rfcode, edt);
1328 if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1330 if (ld.pch != NULL) {
1331 /* We're capturing packets, so we're printing a count of packets
1332 captured; move to the line after the count. */
1333 fprintf(stderr, "\n");
1336 show_capture_file_io_error(cf->save_file, err, FALSE);
1341 wtap_dump_close(pdh, &err);
1346 epan_dissect_free(edt);
1348 clear_fdata(&fdata);
1352 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1358 "tethereal: Not all the packets could be written to \"%s\" because there is "
1359 "no space left on the file system.\n",
1366 "tethereal: Not all the packets could be written to \"%s\" because you are "
1367 "too close to, or over your disk quota.\n",
1372 case WTAP_ERR_CANT_CLOSE:
1374 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1378 case WTAP_ERR_SHORT_WRITE:
1380 "tethereal: Not all the packets could be written to \"%s\".\n",
1387 "tethereal: \"%s\" could not be closed: %s.\n",
1388 fname, wtap_strerror(err));
1391 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1392 fname, wtap_strerror(err));
1399 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1400 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1402 cb_args_t *args = (cb_args_t *) user;
1403 capture_file *cf = args->cf;
1406 print_args_t print_args;
1407 epan_dissect_t *edt;
1408 gboolean create_proto_tree;
1413 fill_in_fdata(&fdata, cf, phdr, offset);
1416 if (cf->rfcode || verbose)
1417 create_proto_tree = TRUE;
1419 create_proto_tree = FALSE;
1420 /* The protocol tree will be "visible", i.e., printed, only if we're
1421 not printing a summary.
1423 We only need the columns if we're *not* verbose; in verbose mode,
1424 we print the protocol tree, not the protocol summary. */
1425 edt = epan_dissect_new(create_proto_tree, verbose);
1427 epan_dissect_prime_dfilter(edt, cf->rfcode);
1429 epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1431 passed = dfilter_apply_edt(cf->rfcode, edt);
1434 /* The packet passed the read filter. */
1436 /* Print the information in the protocol tree. */
1437 print_args.to_file = TRUE;
1438 print_args.format = PR_FMT_TEXT;
1439 print_args.print_summary = FALSE;
1440 print_args.print_hex = print_hex;
1441 print_args.expand_all = TRUE;
1442 print_args.suppress_unmarked = FALSE;
1443 proto_tree_print(&print_args, (GNode *)edt->tree,
1446 /* "print_hex_data()" will put out a leading blank line, as well
1447 as a trailing one; print one here, to separate the packets,
1448 only if "print_hex_data()" won't be called. */
1452 /* Just fill in the columns. */
1453 epan_dissect_fill_in_columns(edt);
1455 /* Now print them. */
1456 for (i = 0; i < cf->cinfo.num_cols; i++) {
1457 switch (cf->cinfo.col_fmt[i]) {
1460 * Don't print this if we're doing a live capture from a network
1461 * interface - if we're doing a live capture, you won't be
1462 * able to look at the capture in the future (it's not being
1463 * saved anywhere), so the frame numbers are unlikely to be
1466 * (XXX - it might be nice to be able to save and print at
1467 * the same time, sort of like an "Update list of packets
1468 * in real time" capture in Ethereal.)
1470 if (cf->iface != NULL)
1472 printf("%3s", cf->cinfo.col_data[i]);
1478 case COL_ABS_DATE_TIME: /* XXX - wider */
1479 printf("%10s", cf->cinfo.col_data[i]);
1485 case COL_DEF_DL_SRC:
1486 case COL_RES_DL_SRC:
1487 case COL_UNRES_DL_SRC:
1488 case COL_DEF_NET_SRC:
1489 case COL_RES_NET_SRC:
1490 case COL_UNRES_NET_SRC:
1491 printf("%12s", cf->cinfo.col_data[i]);
1497 case COL_DEF_DL_DST:
1498 case COL_RES_DL_DST:
1499 case COL_UNRES_DL_DST:
1500 case COL_DEF_NET_DST:
1501 case COL_RES_NET_DST:
1502 case COL_UNRES_NET_DST:
1503 printf("%-12s", cf->cinfo.col_data[i]);
1507 printf("%s", cf->cinfo.col_data[i]);
1510 if (i != cf->cinfo.num_cols - 1) {
1512 * This isn't the last column, so we need to print a
1513 * separator between this column and the next.
1515 * If we printed a network source and are printing a
1516 * network destination of the same type next, separate
1517 * them with "->"; if we printed a network destination
1518 * and are printing a network source of the same type
1519 * next, separate them with "<-"; otherwise separate them
1522 switch (cf->cinfo.col_fmt[i]) {
1527 switch (cf->cinfo.col_fmt[i + 1]) {
1541 case COL_DEF_DL_SRC:
1542 case COL_RES_DL_SRC:
1543 case COL_UNRES_DL_SRC:
1544 switch (cf->cinfo.col_fmt[i + 1]) {
1546 case COL_DEF_DL_DST:
1547 case COL_RES_DL_DST:
1548 case COL_UNRES_DL_DST:
1558 case COL_DEF_NET_SRC:
1559 case COL_RES_NET_SRC:
1560 case COL_UNRES_NET_SRC:
1561 switch (cf->cinfo.col_fmt[i + 1]) {
1563 case COL_DEF_NET_DST:
1564 case COL_RES_NET_DST:
1565 case COL_UNRES_NET_DST:
1578 switch (cf->cinfo.col_fmt[i + 1]) {
1592 case COL_DEF_DL_DST:
1593 case COL_RES_DL_DST:
1594 case COL_UNRES_DL_DST:
1595 switch (cf->cinfo.col_fmt[i + 1]) {
1597 case COL_DEF_DL_SRC:
1598 case COL_RES_DL_SRC:
1599 case COL_UNRES_DL_SRC:
1609 case COL_DEF_NET_DST:
1610 case COL_RES_NET_DST:
1611 case COL_UNRES_NET_DST:
1612 switch (cf->cinfo.col_fmt[i + 1]) {
1614 case COL_DEF_NET_SRC:
1615 case COL_RES_NET_SRC:
1616 case COL_UNRES_NET_SRC:
1635 print_hex_data(stdout, print_args.format, &fdata);
1640 /* The ANSI C standard does not appear to *require* that a line-buffered
1641 stream be flushed to the host environment whenever a newline is
1642 written, it just says that, on such a stream, characters "are
1643 intended to be transmitted to or from the host environment as a
1644 block when a new-line character is encountered".
1646 The Visual C++ 6.0 C implementation doesn't do what is intended;
1647 even if you set a stream to be line-buffered, it still doesn't
1648 flush the buffer at the end of every line.
1650 So, if the "-l" flag was specified, we flush the standard output
1651 at the end of a packet. This will do the right thing if we're
1652 printing packet summary lines, and, as we print the entire protocol
1653 tree for a single packet without waiting for anything to happen,
1654 it should be as good as line-buffered mode if we're printing
1655 protocol trees. (The whole reason for the "-l" flag in either
1656 tcpdump or Tethereal is to allow the output of a live capture to
1657 be piped to a program or script and to have that script see the
1658 information for the packet as soon as it's printed, rather than
1659 having to wait until a standard I/O buffer fills up. */
1663 epan_dissect_free(edt);
1665 clear_fdata(&fdata);
1669 file_open_error_message(int err, gboolean for_writing)
1672 static char errmsg_errno[1024+1];
1676 case WTAP_ERR_NOT_REGULAR_FILE:
1677 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1680 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1681 case WTAP_ERR_UNSUPPORTED:
1682 /* Seen only when opening a capture file for reading. */
1683 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1686 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1687 /* Seen only when opening a capture file for writing. */
1688 errmsg = "Tethereal does not support writing capture files in that format.";
1691 case WTAP_ERR_UNSUPPORTED_ENCAP:
1692 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1694 errmsg = "Tethereal cannot save this capture in that format.";
1696 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1699 case WTAP_ERR_BAD_RECORD:
1700 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1703 case WTAP_ERR_CANT_OPEN:
1705 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1707 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1710 case WTAP_ERR_SHORT_READ:
1711 errmsg = "The file \"%s\" appears to have been cut short"
1712 " in the middle of a packet or other data.";
1715 case WTAP_ERR_SHORT_WRITE:
1716 errmsg = "A full header couldn't be written to the file \"%s\".";
1721 errmsg = "The path to the file \"%s\" does not exist.";
1723 errmsg = "The file \"%s\" does not exist.";
1728 errmsg = "You do not have permission to create or write to the file \"%s\".";
1730 errmsg = "You do not have permission to read the file \"%s\".";
1734 errmsg = "\"%s\" is a directory (folder), not a file.";
1738 snprintf(errmsg_errno, sizeof(errmsg_errno),
1739 "The file \"%%s\" could not be opened: %s.",
1740 wtap_strerror(err));
1741 errmsg = errmsg_errno;
1748 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1753 struct stat cf_stat;
1754 char err_msg[2048+1];
1756 wth = wtap_open_offline(fname, &err, FALSE);
1760 /* Find the size of the file. */
1762 if (fstat(fd, &cf_stat) < 0) {
1768 /* The open succeeded. Fill in the information for this file. */
1770 /* Initialize all data structures used for dissection. */
1775 cf->f_len = cf_stat.st_size;
1777 /* Set the file name because we need it to set the follow stream filter.
1778 XXX - is that still true? We need it for other reasons, though,
1780 cf->filename = g_strdup(fname);
1782 /* Indicate whether it's a permanent or temporary file. */
1783 cf->is_tempfile = is_tempfile;
1785 /* If it's a temporary capture buffer file, mark it as not saved. */
1786 cf->user_saved = !is_tempfile;
1788 cf->cd_t = wtap_file_type(cf->wth);
1790 cf->drops_known = FALSE;
1794 cf->snap = wtap_snapshot_length(cf->wth);
1795 if (cf->snap == 0) {
1796 /* Snapshot length not known. */
1797 cf->has_snap = FALSE;
1798 cf->snap = WTAP_MAX_PACKET_SIZE;
1800 cf->has_snap = TRUE;
1801 cf->progbar_quantum = 0;
1802 cf->progbar_nextstep = 0;
1803 firstsec = 0, firstusec = 0;
1804 prevsec = 0, prevusec = 0;
1809 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1810 fprintf(stderr, "tethereal: %s\n", err_msg);