3 * $Id: tethereal.c,v 1.129 2002/02/28 19:35:08 gram 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 #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 */
81 #ifdef NEED_STRERROR_H
90 #include <epan/epan.h>
93 #include <epan/timestamp.h>
94 #include <epan/packet.h>
99 #include <epan/resolv.h>
102 #include "pcap-util.h"
104 #include <epan/conversation.h>
105 #include <epan/plugins.h>
106 #include "register.h"
107 #include "conditions.h"
108 #include "capture_stop_conditions.h"
109 #include "ringbuffer.h"
110 #include <epan/epan_dissect.h>
113 #include "capture-wpcap.h"
116 static guint32 firstsec, firstusec;
117 static guint32 prevsec, prevusec;
118 static GString *comp_info_str;
119 static gboolean verbose;
120 static gboolean print_hex;
121 static gboolean line_buffered;
124 typedef struct _loop_data {
125 gboolean go; /* TRUE as long as we're supposed to keep capturing */
134 static int capture(volatile int, int);
135 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
137 static void capture_cleanup(int);
145 static int load_cap_file(capture_file *, int);
146 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, long,
147 union wtap_pseudo_header *, const u_char *);
148 static void show_capture_file_io_error(const char *, int, gboolean);
149 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, long,
150 union wtap_pseudo_header *, const u_char *);
153 ts_type timestamp_type = RELATIVE;
156 int snaplen; /* Maximum captured packet length */
157 int promisc_mode; /* Capture in promiscuous mode */
158 int autostop_count; /* Maximum packet count */
159 gboolean has_autostop_duration; /* TRUE if maximum capture duration
161 gint32 autostop_duration; /* Maximum capture duration */
162 gboolean has_autostop_filesize; /* TRUE if maximum capture file size
164 gint32 autostop_filesize; /* Maximum capture file size */
165 gboolean ringbuffer_on; /* TRUE if ring buffer in use */
166 guint32 ringbuffer_num_files; /* Number of ring buffer files */
169 static capture_options capture_opts = {
170 WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
171 infinite, in effect */
172 TRUE, /* promiscuous mode is the default */
173 0, /* max packet count - default is 0,
175 FALSE, /* maximum capture duration not
176 specified by default */
177 0, /* maximum capture duration */
178 FALSE, /* maximum capture file size not
179 specified by default */
180 0, /* maximum capture file size */
181 FALSE, /* ring buffer off by default */
182 RINGBUFFER_MIN_NUM_FILES /* default number of ring buffer
192 fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
195 fprintf(stderr, "t%s [ -DvVhlp ] [ -a <capture autostop condition> ] ...\n",
197 fprintf(stderr, "\t[ -b <number of ring buffer files> ] [ -c <count> ]\n");
198 fprintf(stderr, "\t[ -f <capture filter> ] [ -F <capture file type> ]\n");
199 fprintf(stderr, "\t[ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
200 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
201 fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
203 fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
204 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
205 fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
207 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
208 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
209 if (wtap_dump_can_open(i))
210 fprintf(stderr, "\t%s - %s\n",
211 wtap_file_type_short_string(i), wtap_file_type_string(i));
213 fprintf(stderr, "\tdefault is libpcap\n");
217 get_positive_int(const char *string, const char *name)
222 number = strtol(string, &p, 10);
223 if (p == string || *p != '\0') {
224 fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
229 fprintf(stderr, "tethereal: The specified %s is a negative number\n",
234 fprintf(stderr, "tethereal: The specified %s is zero\n",
238 if (number > INT_MAX) {
239 fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
248 * Given a string of the form "<autostop criterion>:<value>", as might appear
249 * as an argument to a "-a" option, parse it and set the criterion in
250 * question. Return an indication of whether it succeeded or failed
254 set_autostop_criterion(const char *autostoparg)
258 colonp = strchr(autostoparg, ':');
266 * Skip over any white space (there probably won't be any, but
267 * as we allow it in the preferences file, we might as well
274 * Put the colon back, so if our caller uses, in an
275 * error message, the string they passed us, the message
281 if (strcmp(autostoparg,"duration") == 0) {
282 capture_opts.has_autostop_duration = TRUE;
283 capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
284 } else if (strcmp(autostoparg,"filesize") == 0) {
285 capture_opts.has_autostop_filesize = TRUE;
286 capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
290 *colonp = ':'; /* put the colon back */
296 main(int argc, char *argv[])
300 gboolean arg_error = FALSE;
302 #ifdef HAVE_PCAP_VERSION
303 extern char pcap_version[];
304 #endif /* HAVE_PCAP_VERSION */
305 #endif /* HAVE_LIBPCAP */
313 int gpf_open_errno, pf_open_errno;
316 gboolean capture_filter_specified = FALSE;
317 GList *if_list, *if_entry;
318 gchar err_str[PCAP_ERRBUF_SIZE];
320 gboolean capture_option_specified = FALSE;
322 int out_file_type = WTAP_FILE_PCAP;
323 gchar *cf_name = NULL, *rfilter = NULL;
324 dfilter_t *rfcode = NULL;
328 /* Register all dissectors; we must do this before checking for the
329 "-G" flag, as the "-G" flag dumps a list of fields registered
330 by the dissectors, and we must do it before we read the preferences,
331 in case any dissectors register preferences. */
332 epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
334 /* Now register the preferences for any non-dissector modules.
335 We must do that before we read the preferences as well. */
336 prefs_register_modules();
338 /* If invoked with the "-G" flag, we dump out a glossary of
339 display filter symbols.
341 We do this here to mirror what happens in the GTK+ version, although
342 it's not necessary here. */
343 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
344 proto_registrar_dump();
348 /* Set the C-language locale to the native environment. */
349 setlocale(LC_ALL, "");
351 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
352 if (gpf_path != NULL) {
353 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
354 strerror(gpf_open_errno));
356 if (pf_path != NULL) {
357 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
358 strerror(pf_open_errno));
361 /* Set the name resolution code's flags from the preferences. */
362 g_resolv_flags = prefs->name_resolve;
365 /* Load Wpcap, if possible */
369 /* Initialize the capture file struct */
371 cfile.plist_end = NULL;
373 cfile.filename = NULL;
374 cfile.user_saved = FALSE;
375 cfile.is_tempfile = FALSE;
377 cfile.dfilter = NULL;
380 cfile.cfilter = g_strdup("");
383 cfile.save_file = NULL;
384 cfile.save_file_fd = -1;
385 cfile.has_snap = FALSE;
386 cfile.snap = WTAP_MAX_PACKET_SIZE;
388 col_init(&cfile.cinfo, prefs->num_cols);
390 /* Assemble the compile-time options */
391 comp_info_str = g_string_new("");
393 g_string_append(comp_info_str, "with ");
394 g_string_sprintfa(comp_info_str,
395 #ifdef GLIB_MAJOR_VERSION
396 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
399 "GLib (version unknown)");
403 g_string_append(comp_info_str, ", with libpcap ");
404 #ifdef HAVE_PCAP_VERSION
405 g_string_append(comp_info_str, pcap_version);
406 #else /* HAVE_PCAP_VERSION */
407 g_string_append(comp_info_str, "(version unknown)");
408 #endif /* HAVE_PCAP_VERSION */
409 #else /* HAVE_LIBPCAP */
410 g_string_append(comp_info_str, ", without libpcap");
411 #endif /* HAVE_LIBPCAP */
414 g_string_append(comp_info_str, ", with libz ");
416 g_string_append(comp_info_str, ZLIB_VERSION);
417 #else /* ZLIB_VERSION */
418 g_string_append(comp_info_str, "(version unknown)");
419 #endif /* ZLIB_VERSION */
420 #else /* HAVE_LIBZ */
421 g_string_append(comp_info_str, ", without libz");
422 #endif /* HAVE_LIBZ */
424 /* Oh, this is pretty */
425 #if defined(HAVE_UCD_SNMP_SNMP_H)
426 g_string_append(comp_info_str, ", with UCD SNMP ");
427 #ifdef HAVE_UCD_SNMP_VERSION_H
428 g_string_append(comp_info_str, VersionInfo);
429 #else /* HAVE_UCD_SNMP_VERSION_H */
430 g_string_append(comp_info_str, "(version unknown)");
431 #endif /* HAVE_UCD_SNMP_VERSION_H */
432 #elif defined(HAVE_SNMP_SNMP_H)
433 g_string_append(comp_info_str, ", with CMU SNMP ");
434 #ifdef HAVE_SNMP_VERSION_H
435 g_string_append(comp_info_str, snmp_Version());
436 #else /* HAVE_SNMP_VERSION_H */
437 g_string_append(comp_info_str, "(version unknown)");
438 #endif /* HAVE_SNMP_VERSION_H */
440 g_string_append(comp_info_str, ", without SNMP");
443 /* Now get our args */
444 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != -1) {
446 case 'a': /* autostop criteria */
448 if (set_autostop_criterion(optarg) == FALSE) {
449 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
453 capture_option_specified = TRUE;
457 case 'b': /* Ringbuffer option */
459 capture_opts.ringbuffer_on = TRUE;
460 capture_opts.ringbuffer_num_files =
461 get_positive_int(optarg, "number of ring buffer files");
463 capture_option_specified = TRUE;
467 case 'c': /* Capture xxx packets */
469 capture_opts.autostop_count =
470 get_positive_int(optarg, "packet count");
472 capture_option_specified = TRUE;
476 case 'D': /* Print a list of capture devices */
478 if_list = get_interface_list(&err, err_str);
479 if (if_list == NULL) {
482 case CANT_GET_INTERFACE_LIST:
483 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
487 case NO_INTERFACES_FOUND:
488 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
493 for (if_entry = g_list_first(if_list); if_entry != NULL;
494 if_entry = g_list_next(if_entry))
495 printf("%s\n", (char *)if_entry->data);
496 free_interface_list(if_list);
499 capture_option_specified = TRUE;
505 capture_filter_specified = TRUE;
506 cfile.cfilter = g_strdup(optarg);
508 capture_option_specified = TRUE;
513 out_file_type = wtap_short_string_to_file_type(optarg);
514 if (out_file_type < 0) {
515 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
520 case 'h': /* Print help and exit */
524 case 'i': /* Use interface xxx */
526 cfile.iface = g_strdup(optarg);
528 capture_option_specified = TRUE;
532 case 'l': /* "Line-buffer" standard output */
533 /* This isn't line-buffering, strictly speaking, it's just
534 flushing the standard output after the information for
535 each packet is printed; however, that should be good
536 enough for all the purposes to which "-l" is put.
538 See the comment in "wtap_dispatch_cb_print()" for an
539 explanation of why we do that, and why we don't just
540 use "setvbuf()" to make the standard output line-buffered
541 (short version: in Windows, "line-buffered" is the same
542 as "fully-buffered", and the output buffer is only flushed
543 when it fills up). */
544 line_buffered = TRUE;
546 case 'n': /* No name resolution */
547 g_resolv_flags = RESOLV_NONE;
549 case 'N': /* Select what types of addresses/port #s to resolve */
550 if (g_resolv_flags == RESOLV_ALL)
551 g_resolv_flags = RESOLV_NONE;
552 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
553 if (badopt != '\0') {
554 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
559 case 'o': /* Override preference from command line */
560 switch (prefs_set_pref(optarg)) {
562 case PREFS_SET_SYNTAX_ERR:
563 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
567 case PREFS_SET_NO_SUCH_PREF:
568 case PREFS_SET_OBSOLETE:
569 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
575 case 'p': /* Don't capture in promiscuous mode */
577 capture_opts.promisc_mode = FALSE;
579 capture_option_specified = TRUE;
583 case 'r': /* Read capture file xxx */
584 cf_name = g_strdup(optarg);
586 case 'R': /* Read file filter */
589 case 's': /* Set the snapshot (capture) length */
591 capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
593 capture_option_specified = TRUE;
597 case 't': /* Time stamp type */
598 if (strcmp(optarg, "r") == 0)
599 timestamp_type = RELATIVE;
600 else if (strcmp(optarg, "a") == 0)
601 timestamp_type = ABSOLUTE;
602 else if (strcmp(optarg, "ad") == 0)
603 timestamp_type = ABSOLUTE_WITH_DATE;
604 else if (strcmp(optarg, "d") == 0)
605 timestamp_type = DELTA;
607 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
609 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
610 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
614 case 'v': /* Show version and exit */
615 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
618 case 'w': /* Write to capture file xxx */
619 cfile.save_file = g_strdup(optarg);
621 case 'V': /* Verbose */
624 case 'x': /* Print packet data in hex (and ASCII) */
630 /* If no capture filter or read filter has been specified, and there are
631 still command-line arguments, treat them as the tokens of a capture
632 filter (if no "-r" flag was specified) or a read filter (if a "-r"
633 flag was specified. */
635 if (cf_name != NULL) {
636 if (rfilter != NULL) {
638 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
641 rfilter = get_args_as_string(argc, argv, optind);
644 if (capture_filter_specified) {
646 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
649 cfile.cfilter = get_args_as_string(argc, argv, optind);
651 capture_option_specified = TRUE;
657 /* If they didn't specify a "-w" flag, but specified a maximum capture
658 file size, tell them that this doesn't work, and exit. */
659 if (capture_opts.has_autostop_filesize && cfile.save_file == NULL) {
660 fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
664 if (capture_opts.ringbuffer_on) {
665 /* Ring buffer works only under certain conditions:
666 a) ring buffer does not work if you're not saving the capture to
668 b) ring buffer only works if you're saving in libpcap format;
669 c) it makes no sense to enable the ring buffer if the maximum
670 file size is set to "infinite". */
671 if (cfile.save_file == NULL) {
672 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved to a file.\n");
675 if (out_file_type != WTAP_FILE_PCAP) {
676 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved in libpcap format.\n");
679 if (!capture_opts.has_autostop_filesize) {
680 fprintf(stderr, "tethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
687 /* Start windows sockets */
688 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
691 /* Notify all registered modules that have had any of their preferences
692 changed either from one of the preferences file or from the command
693 line that its preferences have changed. */
697 if (capture_option_specified)
698 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
703 /* Build the column format array */
704 for (i = 0; i < cfile.cinfo.num_cols; i++) {
705 cfile.cinfo.col_fmt[i] = get_column_format(i);
706 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
707 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
709 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
710 cfile.cinfo.col_data[i] = NULL;
711 if (cfile.cinfo.col_fmt[i] == COL_INFO)
712 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
714 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
716 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
717 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
721 if (capture_opts.snaplen < 1)
722 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
723 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
724 capture_opts.snaplen = MIN_PACKET_SIZE;
726 /* Check the value range of the ringbuffer_num_files parameter */
727 if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
728 capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
729 else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
730 capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
733 if (rfilter != NULL) {
734 if (!dfilter_compile(rfilter, &rfcode)) {
735 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
740 cfile.rfcode = rfcode;
742 err = open_cap_file(cf_name, FALSE, &cfile);
747 err = load_cap_file(&cfile, out_file_type);
754 /* No capture file specified, so we're supposed to do a live capture;
755 do we have support for live captures? */
760 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
765 /* Yes; did the user specify an interface to use? */
766 if (cfile.iface == NULL) {
767 /* No - is a default specified in the preferences file? */
768 if (prefs->capture_device != NULL) {
770 cfile.iface = g_strdup(prefs->capture_device);
772 /* No - pick the first one from the list of interfaces. */
773 if_list = get_interface_list(&err, err_str);
774 if (if_list == NULL) {
777 case CANT_GET_INTERFACE_LIST:
778 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
782 case NO_INTERFACES_FOUND:
783 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
788 cfile.iface = g_strdup(if_list->data); /* first interface */
789 free_interface_list(if_list);
792 capture(capture_opts.autostop_count, out_file_type);
794 if (capture_opts.ringbuffer_on) {
799 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
810 /* Do the low-level work of a capture.
811 Returns TRUE if it succeeds, FALSE otherwise. */
813 capture(volatile int packet_count, int out_file_type)
815 gchar open_err_str[PCAP_ERRBUF_SIZE];
816 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
817 bpf_u_int32 netnum, netmask;
818 struct bpf_program fcode;
819 void (*oldhandler)(int);
821 volatile int inpkts = 0;
823 condition *volatile cnd_stop_capturesize = NULL;
824 condition *volatile cnd_stop_timeout = NULL;
826 static const char ppamsg[] = "can't find PPA for ";
829 struct pcap_stat stats;
832 /* Initialize all data structures used for dissection. */
835 ld.linktype = WTAP_ENCAP_UNKNOWN;
838 /* Open the network interface to capture from it.
839 Some versions of libpcap may put warnings into the error buffer
840 if they succeed; to tell if that's happened, we have to clear
841 the error buffer, and check if it's still a null string. */
842 open_err_str[0] = '\0';
843 ld.pch = pcap_open_live(cfile.iface, capture_opts.snaplen,
844 capture_opts.promisc_mode, 1000, open_err_str);
846 if (ld.pch == NULL) {
847 /* Well, we couldn't start the capture. */
849 /* On Win32 OSes, the capture devices are probably available to all
850 users; don't warn about permissions problems.
852 Do, however, warn that Token Ring and PPP devices aren't supported. */
853 snprintf(errmsg, sizeof errmsg,
854 "The capture session could not be initiated (%s).\n"
855 "Please check that you have the proper interface specified.\n"
857 "Note that the driver Tethereal uses for packet capture on Windows\n"
858 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
859 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
862 /* If we got a "can't find PPA for XXX" message, warn the user (who
863 is running Ethereal on HP-UX) that they don't have a version
864 of libpcap that properly handles HP-UX (libpcap 0.6.x and later
865 versions, which properly handle HP-UX, say "can't find /dev/dlpi
866 PPA for XXX" rather than "can't find PPA for XXX"). */
867 if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
870 "You are running Tethereal with a version of the libpcap library\n"
871 "that doesn't handle HP-UX network devices well; this means that\n"
872 "Tethereal may not be able to capture packets.\n"
874 "To fix this, you should install libpcap 0.6.2, or a later version\n"
875 "of libpcap, rather than libpcap 0.4 or 0.5.x. It is available in\n"
876 "packaged binary form from the Software Porting And Archive Centre\n"
877 "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
878 "at the URL lists a number of mirror sites.";
881 snprintf(errmsg, sizeof errmsg,
882 "The capture session could not be initiated (%s).\n"
883 "Please check to make sure you have sufficient permissions, and that\n"
884 "you have the proper interface specified.%s", open_err_str, libpcap_warn);
890 /* A capture filter was specified; set it up. */
891 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
893 * Well, we can't get the netmask for this interface; it's used
894 * only for filters that check for broadcast IP addresses, so
895 * we just warn the user, and punt and use 0.
898 "Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
901 if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
902 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
903 pcap_geterr(ld.pch));
906 if (pcap_setfilter(ld.pch, &fcode) < 0) {
907 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
908 pcap_geterr(ld.pch));
913 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
915 if (cfile.save_file != NULL) {
916 /* Set up to write to the capture file. */
917 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
918 strcpy(errmsg, "The network you're capturing from is of a type"
919 " that Tethereal doesn't support.");
922 if (capture_opts.ringbuffer_on) {
923 cfile.save_file_fd = ringbuf_init(cfile.save_file,
924 capture_opts.ringbuffer_num_files);
925 if (cfile.save_file_fd != -1) {
926 ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
927 pcap_snapshot(ld.pch), &err);
932 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
933 ld.linktype, pcap_snapshot(ld.pch), &err);
936 if (ld.pdh == NULL) {
937 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
943 /* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
944 returned a warning; print it, but keep capturing. */
945 if (open_err_str[0] != '\0')
946 fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
948 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
950 XXX - deal with signal semantics on various platforms. Or just
951 use "sigaction()" and be done with it? */
952 signal(SIGTERM, capture_cleanup);
953 signal(SIGINT, capture_cleanup);
955 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
956 signal(SIGHUP, oldhandler);
959 /* Let the user know what interface was chosen. */
960 fprintf(stderr, "Capturing on %s\n", cfile.iface);
963 /* initialize capture stop conditions */
964 init_capture_stop_conditions();
965 /* create stop conditions */
966 if (capture_opts.has_autostop_filesize)
967 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
968 (long)capture_opts.autostop_filesize * 1000);
969 if (capture_opts.has_autostop_duration)
970 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
971 (gint32)capture_opts.autostop_duration);
973 if (packet_count == 0)
974 packet_count = -1; /* infinite capturng */
975 if (!setjmp(ld.stopenv))
980 if (packet_count > 0)
982 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
983 if (packet_count == 0 || inpkts < 0) {
985 } else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
986 /* The specified capture time has elapsed; stop the capture. */
988 } else if (ld.pdh != NULL && cnd_stop_capturesize != NULL &&
989 cnd_eval(cnd_stop_capturesize,
990 (guint32)wtap_get_bytes_dumped(ld.pdh))) {
991 /* We're saving the capture to a file, and the capture file reached
993 if (capture_opts.ringbuffer_on) {
994 /* Switch to the next ringbuffer file */
995 if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
996 /* File switch failed: reset the condition */
997 cnd_reset(cnd_stop_capturesize);
999 /* File switch failed: stop here */
1004 /* No ringbuffer - just stop. */
1010 /* delete stop conditions */
1011 if (cnd_stop_capturesize != NULL)
1012 cnd_delete(cnd_stop_capturesize);
1013 if (cnd_stop_timeout != NULL)
1014 cnd_delete(cnd_stop_timeout);
1016 if (cfile.save_file != NULL) {
1017 /* We're saving to a file, which means we're printing packet counts
1018 to the standard output. Send a newline so that we move to the
1019 line after the packet count. */
1020 fprintf(stderr, "\n");
1023 /* If we got an error while capturing, report it. */
1025 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
1026 pcap_geterr(ld.pch));
1029 /* Get the capture statistics, and, if any packets were dropped, report
1031 if (pcap_stats(ld.pch, &stats) >= 0) {
1032 if (stats.ps_drop != 0) {
1033 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
1036 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
1037 pcap_geterr(ld.pch));
1042 if (cfile.save_file != NULL) {
1043 /* We're saving to a file or files; close all files. */
1044 if (capture_opts.ringbuffer_on) {
1045 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
1047 dump_ok = wtap_dump_close(ld.pdh, &err);
1050 show_capture_file_io_error(cfile.save_file, err, TRUE);
1056 if (capture_opts.ringbuffer_on) {
1057 ringbuf_error_cleanup();
1059 g_free(cfile.save_file);
1060 cfile.save_file = NULL;
1061 fprintf(stderr, "tethereal: %s\n", errmsg);
1069 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1072 struct wtap_pkthdr whdr;
1073 loop_data *ld = (loop_data *) user;
1076 whdr.ts.tv_sec = phdr->ts.tv_sec;
1077 whdr.ts.tv_usec = phdr->ts.tv_usec;
1078 whdr.caplen = phdr->caplen;
1079 whdr.len = phdr->len;
1080 whdr.pkt_encap = ld->linktype;
1085 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1086 fprintf(stderr, "\r%u ", cfile.count);
1089 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1094 capture_cleanup(int signum)
1096 /* Longjmp back to the starting point; "pcap_dispatch()", on many
1097 platforms, just keeps looping if it gets EINTR, so if we set
1098 "ld.go" to FALSE and return, we won't break out of it and quit
1100 longjmp(ld.stopenv, 1);
1102 #endif /* HAVE_LIBPCAP */
1105 load_cap_file(capture_file *cf, int out_file_type)
1108 int snapshot_length;
1114 linktype = wtap_file_encap(cf->wth);
1115 if (cf->save_file != NULL) {
1116 /* Set up to write to the capture file. */
1117 snapshot_length = wtap_snapshot_length(cf->wth);
1118 if (snapshot_length == 0) {
1119 /* Snapshot length of input file not known. */
1120 snapshot_length = WTAP_MAX_PACKET_SIZE;
1122 pdh = wtap_dump_open(cf->save_file, out_file_type,
1123 linktype, snapshot_length, &err);
1126 /* We couldn't set up to write to the capture file. */
1129 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1131 "tethereal: Capture files can't be written in that format.\n");
1134 case WTAP_ERR_UNSUPPORTED_ENCAP:
1135 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1137 "tethereal: The capture file being read cannot be written in that format.\n");
1140 case WTAP_ERR_CANT_OPEN:
1142 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1146 case WTAP_ERR_SHORT_WRITE:
1148 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1155 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1156 cf->save_file, err);
1159 "tethereal: The file \"%s\" could not be opened: %s\n.",
1160 cf->save_file, strerror(err));
1168 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1171 /* Now close the capture file. */
1172 if (!wtap_dump_close(pdh, &err))
1173 show_capture_file_io_error(cfile.save_file, err, TRUE);
1177 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1181 /* Print up a message box noting that the read failed somewhere along
1185 case WTAP_ERR_UNSUPPORTED_ENCAP:
1187 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1191 case WTAP_ERR_CANT_READ:
1193 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1197 case WTAP_ERR_SHORT_READ:
1199 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1203 case WTAP_ERR_BAD_RECORD:
1205 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1211 "tethereal: An error occurred while reading \"%s\": %s.\n",
1212 cf->filename, wtap_strerror(err));
1218 wtap_close(cf->wth);
1225 fill_in_fdata(frame_data *fdata, capture_file *cf,
1226 const struct wtap_pkthdr *phdr,
1227 const union wtap_pseudo_header *pseudo_header, long offset)
1232 fdata->data_src = NULL;
1233 fdata->num = cf->count;
1234 fdata->pkt_len = phdr->len;
1235 fdata->cap_len = phdr->caplen;
1236 fdata->file_off = offset;
1237 fdata->lnk_t = phdr->pkt_encap;
1238 fdata->abs_secs = phdr->ts.tv_sec;
1239 fdata->abs_usecs = phdr->ts.tv_usec;
1240 fdata->flags.passed_dfilter = 0;
1241 fdata->flags.encoding = CHAR_ASCII;
1242 fdata->flags.visited = 0;
1243 fdata->flags.marked = 0;
1245 /* If we don't have the time stamp of the first packet in the
1246 capture, it's because this is the first packet. Save the time
1247 stamp of this packet as the time stamp of the first packet. */
1248 if (!firstsec && !firstusec) {
1249 firstsec = fdata->abs_secs;
1250 firstusec = fdata->abs_usecs;
1253 /* If we don't have the time stamp of the previous displayed packet,
1254 it's because this is the first displayed packet. Save the time
1255 stamp of this packet as the time stamp of the previous displayed
1257 if (!prevsec && !prevusec) {
1258 prevsec = fdata->abs_secs;
1259 prevusec = fdata->abs_usecs;
1262 /* Get the time elapsed between the first packet and this packet. */
1263 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1264 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1266 /* If it's greater than the current elapsed time, set the elapsed time
1267 to it (we check for "greater than" so as not to be confused by
1268 time moving backwards). */
1269 if ((gint32)cf->esec < fdata->rel_secs
1270 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1271 cf->esec = fdata->rel_secs;
1272 cf->eusec = fdata->rel_usecs;
1275 /* Get the time elapsed between the previous displayed packet and
1277 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1278 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1279 prevsec = fdata->abs_secs;
1280 prevusec = fdata->abs_usecs;
1283 /* Free up all data attached to a "frame_data" structure. */
1285 clear_fdata(frame_data *fdata)
1288 g_slist_free(fdata->pfd);
1289 free_data_sources(fdata); /* release data source list */
1293 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1294 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1296 cb_args_t *args = (cb_args_t *) user;
1297 capture_file *cf = args->cf;
1298 wtap_dumper *pdh = args->pdh;
1302 epan_dissect_t *edt;
1306 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1307 edt = epan_dissect_new(TRUE, FALSE);
1308 epan_dissect_prime_dfilter(edt, cf->rfcode);
1309 epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1310 passed = dfilter_apply_edt(cf->rfcode, edt);
1316 if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1318 if (ld.pch != NULL) {
1319 /* We're capturing packets, so we're printing a count of packets
1320 captured; move to the line after the count. */
1321 fprintf(stderr, "\n");
1324 show_capture_file_io_error(cf->save_file, err, FALSE);
1329 wtap_dump_close(pdh, &err);
1334 epan_dissect_free(edt);
1336 clear_fdata(&fdata);
1340 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1346 "tethereal: Not all the packets could be written to \"%s\" because there is "
1347 "no space left on the file system.\n",
1354 "tethereal: Not all the packets could be written to \"%s\" because you are "
1355 "too close to, or over your disk quota.\n",
1360 case WTAP_ERR_CANT_CLOSE:
1362 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1366 case WTAP_ERR_SHORT_WRITE:
1368 "tethereal: Not all the packets could be written to \"%s\".\n",
1375 "tethereal: \"%s\" could not be closed: %s.\n",
1376 fname, wtap_strerror(err));
1379 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1380 fname, wtap_strerror(err));
1387 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1388 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1390 cb_args_t *args = (cb_args_t *) user;
1391 capture_file *cf = args->cf;
1394 print_args_t print_args;
1395 epan_dissect_t *edt;
1396 gboolean create_proto_tree;
1401 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1404 if (cf->rfcode || verbose)
1405 create_proto_tree = TRUE;
1407 create_proto_tree = FALSE;
1408 /* The protocol tree will be "visible", i.e., printed, only if we're
1409 not printing a summary.
1411 We only need the columns if we're *not* verbose; in verbose mode,
1412 we print the protocol tree, not the protocol summary. */
1413 edt = epan_dissect_new(create_proto_tree, verbose);
1415 epan_dissect_prime_dfilter(edt, cf->rfcode);
1417 epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1419 passed = dfilter_apply_edt(cf->rfcode, edt);
1422 /* The packet passed the read filter. */
1424 /* Print the information in the protocol tree. */
1425 print_args.to_file = TRUE;
1426 print_args.format = PR_FMT_TEXT;
1427 print_args.print_summary = FALSE;
1428 print_args.print_hex = print_hex;
1429 print_args.expand_all = TRUE;
1430 print_args.suppress_unmarked = FALSE;
1431 proto_tree_print(FALSE, &print_args, (GNode *)edt->tree,
1434 /* "print_hex_data()" will put out a leading blank line, as well
1435 as a trailing one; print one here, to separate the packets,
1436 only if "print_hex_data()" won't be called. */
1440 /* Just fill in the columns. */
1441 epan_dissect_fill_in_columns(edt);
1443 /* Now print them. */
1444 for (i = 0; i < cf->cinfo.num_cols; i++) {
1445 switch (cf->cinfo.col_fmt[i]) {
1448 * Don't print this if we're doing a live capture from a network
1449 * interface - if we're doing a live capture, you won't be
1450 * able to look at the capture in the future (it's not being
1451 * saved anywhere), so the frame numbers are unlikely to be
1454 * (XXX - it might be nice to be able to save and print at
1455 * the same time, sort of like an "Update list of packets
1456 * in real time" capture in Ethereal.)
1458 if (cf->iface != NULL)
1460 printf("%3s", cf->cinfo.col_data[i]);
1466 case COL_ABS_DATE_TIME: /* XXX - wider */
1467 printf("%10s", cf->cinfo.col_data[i]);
1473 case COL_DEF_DL_SRC:
1474 case COL_RES_DL_SRC:
1475 case COL_UNRES_DL_SRC:
1476 case COL_DEF_NET_SRC:
1477 case COL_RES_NET_SRC:
1478 case COL_UNRES_NET_SRC:
1479 printf("%12s", cf->cinfo.col_data[i]);
1485 case COL_DEF_DL_DST:
1486 case COL_RES_DL_DST:
1487 case COL_UNRES_DL_DST:
1488 case COL_DEF_NET_DST:
1489 case COL_RES_NET_DST:
1490 case COL_UNRES_NET_DST:
1491 printf("%-12s", cf->cinfo.col_data[i]);
1495 printf("%s", cf->cinfo.col_data[i]);
1498 if (i != cf->cinfo.num_cols - 1) {
1500 * This isn't the last column, so we need to print a
1501 * separator between this column and the next.
1503 * If we printed a network source and are printing a
1504 * network destination of the same type next, separate
1505 * them with "->"; if we printed a network destination
1506 * and are printing a network source of the same type
1507 * next, separate them with "<-"; otherwise separate them
1510 switch (cf->cinfo.col_fmt[i]) {
1515 switch (cf->cinfo.col_fmt[i + 1]) {
1529 case COL_DEF_DL_SRC:
1530 case COL_RES_DL_SRC:
1531 case COL_UNRES_DL_SRC:
1532 switch (cf->cinfo.col_fmt[i + 1]) {
1534 case COL_DEF_DL_DST:
1535 case COL_RES_DL_DST:
1536 case COL_UNRES_DL_DST:
1546 case COL_DEF_NET_SRC:
1547 case COL_RES_NET_SRC:
1548 case COL_UNRES_NET_SRC:
1549 switch (cf->cinfo.col_fmt[i + 1]) {
1551 case COL_DEF_NET_DST:
1552 case COL_RES_NET_DST:
1553 case COL_UNRES_NET_DST:
1566 switch (cf->cinfo.col_fmt[i + 1]) {
1580 case COL_DEF_DL_DST:
1581 case COL_RES_DL_DST:
1582 case COL_UNRES_DL_DST:
1583 switch (cf->cinfo.col_fmt[i + 1]) {
1585 case COL_DEF_DL_SRC:
1586 case COL_RES_DL_SRC:
1587 case COL_UNRES_DL_SRC:
1597 case COL_DEF_NET_DST:
1598 case COL_RES_NET_DST:
1599 case COL_UNRES_NET_DST:
1600 switch (cf->cinfo.col_fmt[i + 1]) {
1602 case COL_DEF_NET_SRC:
1603 case COL_RES_NET_SRC:
1604 case COL_UNRES_NET_SRC:
1623 print_hex_data(stdout, print_args.format, &fdata);
1628 /* The ANSI C standard does not appear to *require* that a line-buffered
1629 stream be flushed to the host environment whenever a newline is
1630 written, it just says that, on such a stream, characters "are
1631 intended to be transmitted to or from the host environment as a
1632 block when a new-line character is encountered".
1634 The Visual C++ 6.0 C implementation doesn't do what is intended;
1635 even if you set a stream to be line-buffered, it still doesn't
1636 flush the buffer at the end of every line.
1638 So, if the "-l" flag was specified, we flush the standard output
1639 at the end of a packet. This will do the right thing if we're
1640 printing packet summary lines, and, as we print the entire protocol
1641 tree for a single packet without waiting for anything to happen,
1642 it should be as good as line-buffered mode if we're printing
1643 protocol trees. (The whole reason for the "-l" flag in either
1644 tcpdump or Tethereal is to allow the output of a live capture to
1645 be piped to a program or script and to have that script see the
1646 information for the packet as soon as it's printed, rather than
1647 having to wait until a standard I/O buffer fills up. */
1651 epan_dissect_free(edt);
1653 clear_fdata(&fdata);
1657 file_open_error_message(int err, gboolean for_writing)
1660 static char errmsg_errno[1024+1];
1664 case WTAP_ERR_NOT_REGULAR_FILE:
1665 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1668 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1669 case WTAP_ERR_UNSUPPORTED:
1670 /* Seen only when opening a capture file for reading. */
1671 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1674 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1675 /* Seen only when opening a capture file for writing. */
1676 errmsg = "Tethereal does not support writing capture files in that format.";
1679 case WTAP_ERR_UNSUPPORTED_ENCAP:
1680 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1682 errmsg = "Tethereal cannot save this capture in that format.";
1684 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1687 case WTAP_ERR_BAD_RECORD:
1688 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1691 case WTAP_ERR_CANT_OPEN:
1693 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1695 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1698 case WTAP_ERR_SHORT_READ:
1699 errmsg = "The file \"%s\" appears to have been cut short"
1700 " in the middle of a packet or other data.";
1703 case WTAP_ERR_SHORT_WRITE:
1704 errmsg = "A full header couldn't be written to the file \"%s\".";
1709 errmsg = "The path to the file \"%s\" does not exist.";
1711 errmsg = "The file \"%s\" does not exist.";
1716 errmsg = "You do not have permission to create or write to the file \"%s\".";
1718 errmsg = "You do not have permission to read the file \"%s\".";
1722 errmsg = "\"%s\" is a directory (folder), not a file.";
1726 snprintf(errmsg_errno, sizeof(errmsg_errno),
1727 "The file \"%%s\" could not be opened: %s.",
1728 wtap_strerror(err));
1729 errmsg = errmsg_errno;
1736 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1741 struct stat cf_stat;
1742 char err_msg[2048+1];
1744 wth = wtap_open_offline(fname, &err, FALSE);
1748 /* Find the size of the file. */
1750 if (fstat(fd, &cf_stat) < 0) {
1756 /* The open succeeded. Fill in the information for this file. */
1758 /* Initialize all data structures used for dissection. */
1763 cf->f_len = cf_stat.st_size;
1765 /* Set the file name because we need it to set the follow stream filter.
1766 XXX - is that still true? We need it for other reasons, though,
1768 cf->filename = g_strdup(fname);
1770 /* Indicate whether it's a permanent or temporary file. */
1771 cf->is_tempfile = is_tempfile;
1773 /* If it's a temporary capture buffer file, mark it as not saved. */
1774 cf->user_saved = !is_tempfile;
1776 cf->cd_t = wtap_file_type(cf->wth);
1778 cf->drops_known = FALSE;
1782 cf->snap = wtap_snapshot_length(cf->wth);
1783 if (cf->snap == 0) {
1784 /* Snapshot length not known. */
1785 cf->has_snap = FALSE;
1786 cf->snap = WTAP_MAX_PACKET_SIZE;
1788 cf->has_snap = TRUE;
1789 cf->progbar_quantum = 0;
1790 cf->progbar_nextstep = 0;
1791 firstsec = 0, firstusec = 0;
1792 prevsec = 0, prevusec = 0;
1797 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1798 fprintf(stderr, "tethereal: %s\n", err_msg);