3 * $Id: tethereal.c,v 1.135 2002/03/31 20:56:59 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 a list of fields registered
325 by the dissectors, and we must do it before we read the preferences,
326 in 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 a glossary of
334 display filter symbols.
336 We do this here to mirror what happens in the GTK+ version, although
337 it's not necessary here. */
338 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
339 proto_registrar_dump();
343 /* Set the C-language locale to the native environment. */
344 setlocale(LC_ALL, "");
346 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
347 if (gpf_path != NULL) {
348 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
349 strerror(gpf_open_errno));
351 if (pf_path != NULL) {
352 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
353 strerror(pf_open_errno));
356 /* Set the name resolution code's flags from the preferences. */
357 g_resolv_flags = prefs->name_resolve;
360 /* Load Wpcap, if possible */
364 /* Initialize the capture file struct */
366 cfile.plist_end = NULL;
368 cfile.filename = NULL;
369 cfile.user_saved = FALSE;
370 cfile.is_tempfile = FALSE;
372 cfile.dfilter = NULL;
375 cfile.cfilter = g_strdup("");
378 cfile.save_file = NULL;
379 cfile.save_file_fd = -1;
380 cfile.has_snap = FALSE;
381 cfile.snap = WTAP_MAX_PACKET_SIZE;
383 col_init(&cfile.cinfo, prefs->num_cols);
385 /* Assemble the compile-time options */
386 comp_info_str = g_string_new("");
388 g_string_append(comp_info_str, "with ");
389 g_string_sprintfa(comp_info_str,
390 #ifdef GLIB_MAJOR_VERSION
391 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
394 "GLib (version unknown)");
398 g_string_append(comp_info_str, ", with libpcap ");
399 #ifdef HAVE_PCAP_VERSION
400 g_string_append(comp_info_str, pcap_version);
401 #else /* HAVE_PCAP_VERSION */
402 g_string_append(comp_info_str, "(version unknown)");
403 #endif /* HAVE_PCAP_VERSION */
404 #else /* HAVE_LIBPCAP */
405 g_string_append(comp_info_str, ", without libpcap");
406 #endif /* HAVE_LIBPCAP */
409 g_string_append(comp_info_str, ", with libz ");
411 g_string_append(comp_info_str, ZLIB_VERSION);
412 #else /* ZLIB_VERSION */
413 g_string_append(comp_info_str, "(version unknown)");
414 #endif /* ZLIB_VERSION */
415 #else /* HAVE_LIBZ */
416 g_string_append(comp_info_str, ", without libz");
417 #endif /* HAVE_LIBZ */
419 /* Oh, this is pretty */
421 g_string_append(comp_info_str, ", with UCD SNMP ");
422 #ifdef HAVE_UCD_SNMP_VERSION_H
423 g_string_append(comp_info_str, VersionInfo);
424 #else /* HAVE_UCD_SNMP_VERSION_H */
425 g_string_append(comp_info_str, "(version unknown)");
426 #endif /* HAVE_UCD_SNMP_VERSION_H */
427 #else /* no SNMP library */
428 g_string_append(comp_info_str, ", without UCD SNMP");
431 /* Now get our args */
432 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pqr:R:s:t:vw:Vx")) != -1) {
434 case 'a': /* autostop criteria */
436 if (set_autostop_criterion(optarg) == FALSE) {
437 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
441 capture_option_specified = TRUE;
445 case 'b': /* Ringbuffer option */
447 capture_opts.ringbuffer_on = TRUE;
448 capture_opts.ringbuffer_num_files =
449 get_positive_int(optarg, "number of ring buffer files");
451 capture_option_specified = TRUE;
455 case 'c': /* Capture xxx packets */
457 capture_opts.autostop_count =
458 get_positive_int(optarg, "packet count");
460 capture_option_specified = TRUE;
464 case 'D': /* Print a list of capture devices */
466 if_list = get_interface_list(&err, err_str);
467 if (if_list == NULL) {
470 case CANT_GET_INTERFACE_LIST:
471 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
475 case NO_INTERFACES_FOUND:
476 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
481 for (if_entry = g_list_first(if_list); if_entry != NULL;
482 if_entry = g_list_next(if_entry))
483 printf("%s\n", (char *)if_entry->data);
484 free_interface_list(if_list);
487 capture_option_specified = TRUE;
493 capture_filter_specified = TRUE;
494 cfile.cfilter = g_strdup(optarg);
496 capture_option_specified = TRUE;
501 out_file_type = wtap_short_string_to_file_type(optarg);
502 if (out_file_type < 0) {
503 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
508 case 'h': /* Print help and exit */
512 case 'i': /* Use interface xxx */
514 cfile.iface = g_strdup(optarg);
516 capture_option_specified = TRUE;
520 case 'l': /* "Line-buffer" standard output */
521 /* This isn't line-buffering, strictly speaking, it's just
522 flushing the standard output after the information for
523 each packet is printed; however, that should be good
524 enough for all the purposes to which "-l" is put.
526 See the comment in "wtap_dispatch_cb_print()" for an
527 explanation of why we do that, and why we don't just
528 use "setvbuf()" to make the standard output line-buffered
529 (short version: in Windows, "line-buffered" is the same
530 as "fully-buffered", and the output buffer is only flushed
531 when it fills up). */
532 line_buffered = TRUE;
534 case 'n': /* No name resolution */
535 g_resolv_flags = RESOLV_NONE;
537 case 'N': /* Select what types of addresses/port #s to resolve */
538 if (g_resolv_flags == RESOLV_ALL)
539 g_resolv_flags = RESOLV_NONE;
540 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
541 if (badopt != '\0') {
542 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
547 case 'o': /* Override preference from command line */
548 switch (prefs_set_pref(optarg)) {
550 case PREFS_SET_SYNTAX_ERR:
551 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
555 case PREFS_SET_NO_SUCH_PREF:
556 case PREFS_SET_OBSOLETE:
557 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
563 case 'p': /* Don't capture in promiscuous mode */
565 capture_opts.promisc_mode = FALSE;
567 capture_option_specified = TRUE;
571 case 'q': /* Quiet */
574 case 'r': /* Read capture file xxx */
575 cf_name = g_strdup(optarg);
577 case 'R': /* Read file filter */
580 case 's': /* Set the snapshot (capture) length */
582 capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
584 capture_option_specified = TRUE;
588 case 't': /* Time stamp type */
589 if (strcmp(optarg, "r") == 0)
590 timestamp_type = RELATIVE;
591 else if (strcmp(optarg, "a") == 0)
592 timestamp_type = ABSOLUTE;
593 else if (strcmp(optarg, "ad") == 0)
594 timestamp_type = ABSOLUTE_WITH_DATE;
595 else if (strcmp(optarg, "d") == 0)
596 timestamp_type = DELTA;
598 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
600 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
601 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
605 case 'v': /* Show version and exit */
606 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
609 case 'w': /* Write to capture file xxx */
610 cfile.save_file = g_strdup(optarg);
612 case 'V': /* Verbose */
615 case 'x': /* Print packet data in hex (and ASCII) */
621 /* If no capture filter or read filter has been specified, and there are
622 still command-line arguments, treat them as the tokens of a capture
623 filter (if no "-r" flag was specified) or a read filter (if a "-r"
624 flag was specified. */
626 if (cf_name != NULL) {
627 if (rfilter != NULL) {
629 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
632 rfilter = get_args_as_string(argc, argv, optind);
635 if (capture_filter_specified) {
637 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
640 cfile.cfilter = get_args_as_string(argc, argv, optind);
642 capture_option_specified = TRUE;
648 /* If they didn't specify a "-w" flag, but specified a maximum capture
649 file size, tell them that this doesn't work, and exit. */
650 if (capture_opts.has_autostop_filesize && cfile.save_file == NULL) {
651 fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
655 if (capture_opts.ringbuffer_on) {
656 /* Ring buffer works only under certain conditions:
657 a) ring buffer does not work if you're not saving the capture to
659 b) ring buffer only works if you're saving in libpcap format;
660 c) it makes no sense to enable the ring buffer if the maximum
661 file size is set to "infinite". */
662 if (cfile.save_file == NULL) {
663 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved to a file.\n");
666 if (out_file_type != WTAP_FILE_PCAP) {
667 fprintf(stderr, "tethereal: Ring buffer requested, but capture isn't being saved in libpcap format.\n");
670 if (!capture_opts.has_autostop_filesize) {
671 fprintf(stderr, "tethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
678 /* Start windows sockets */
679 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
682 /* Notify all registered modules that have had any of their preferences
683 changed either from one of the preferences file or from the command
684 line that its preferences have changed. */
688 if (capture_option_specified)
689 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
694 /* Build the column format array */
695 for (i = 0; i < cfile.cinfo.num_cols; i++) {
696 cfile.cinfo.col_fmt[i] = get_column_format(i);
697 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
698 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
700 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
701 cfile.cinfo.col_data[i] = NULL;
702 if (cfile.cinfo.col_fmt[i] == COL_INFO)
703 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
705 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
707 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
708 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
712 if (capture_opts.snaplen < 1)
713 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
714 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
715 capture_opts.snaplen = MIN_PACKET_SIZE;
717 /* Check the value range of the ringbuffer_num_files parameter */
718 if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
719 capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
720 else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
721 capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
724 if (rfilter != NULL) {
725 if (!dfilter_compile(rfilter, &rfcode)) {
726 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
731 cfile.rfcode = rfcode;
733 err = open_cap_file(cf_name, FALSE, &cfile);
738 err = load_cap_file(&cfile, out_file_type);
745 /* No capture file specified, so we're supposed to do a live capture;
746 do we have support for live captures? */
751 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
756 /* Yes; did the user specify an interface to use? */
757 if (cfile.iface == NULL) {
758 /* No - is a default specified in the preferences file? */
759 if (prefs->capture_device != NULL) {
761 cfile.iface = g_strdup(prefs->capture_device);
763 /* No - pick the first one from the list of interfaces. */
764 if_list = get_interface_list(&err, err_str);
765 if (if_list == NULL) {
768 case CANT_GET_INTERFACE_LIST:
769 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
773 case NO_INTERFACES_FOUND:
774 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
779 cfile.iface = g_strdup(if_list->data); /* first interface */
780 free_interface_list(if_list);
783 capture(capture_opts.autostop_count, out_file_type);
785 if (capture_opts.ringbuffer_on) {
790 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
801 /* Do the low-level work of a capture.
802 Returns TRUE if it succeeds, FALSE otherwise. */
804 capture(volatile int packet_count, int out_file_type)
806 gchar open_err_str[PCAP_ERRBUF_SIZE];
807 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
808 bpf_u_int32 netnum, netmask;
809 struct bpf_program fcode;
810 void (*oldhandler)(int);
812 volatile int inpkts = 0;
814 condition *volatile cnd_stop_capturesize = NULL;
815 condition *volatile cnd_stop_timeout = NULL;
817 static const char ppamsg[] = "can't find PPA for ";
820 struct pcap_stat stats;
823 /* Initialize all data structures used for dissection. */
826 ld.linktype = WTAP_ENCAP_UNKNOWN;
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, capture_opts.snaplen,
835 capture_opts.promisc_mode, 1000, open_err_str);
837 if (ld.pch == NULL) {
838 /* Well, we couldn't start the capture. */
840 /* On Win32 OSes, the capture devices are probably available to all
841 users; don't warn about permissions problems.
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"
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",
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)
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"
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.";
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);
881 /* A capture filter was specified; set it up. */
882 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
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.
889 "Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
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));
897 if (pcap_setfilter(ld.pch, &fcode) < 0) {
898 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
899 pcap_geterr(ld.pch));
904 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
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.");
913 if (capture_opts.ringbuffer_on) {
914 cfile.save_file_fd = ringbuf_init(cfile.save_file,
915 capture_opts.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);
923 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
924 ld.linktype, pcap_snapshot(ld.pch), &err);
927 if (ld.pdh == NULL) {
928 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
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);
939 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
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);
946 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
947 signal(SIGHUP, oldhandler);
950 /* Let the user know what interface was chosen. */
951 fprintf(stderr, "Capturing on %s\n", cfile.iface);
954 /* initialize capture stop conditions */
955 init_capture_stop_conditions();
956 /* create stop conditions */
957 if (capture_opts.has_autostop_filesize)
958 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
959 (long)capture_opts.autostop_filesize * 1000);
960 if (capture_opts.has_autostop_duration)
961 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
962 (gint32)capture_opts.autostop_duration);
964 if (packet_count == 0)
965 packet_count = -1; /* infinite capturng */
966 if (!setjmp(ld.stopenv))
971 if (packet_count > 0)
973 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
974 if (packet_count == 0 || inpkts < 0) {
976 } else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
977 /* The specified capture time has elapsed; stop the capture. */
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
984 if (capture_opts.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);
990 /* File switch failed: stop here */
995 /* No ringbuffer - just stop. */
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);
1007 if ((cfile.save_file != NULL) && !quiet) {
1008 /* We're saving to a file, which means we're printing packet counts
1009 to the standard output if we are not running silent and deep.
1010 Send a newline so that we move to the line after the packet count. */
1011 fprintf(stderr, "\n");
1014 /* If we got an error while capturing, report it. */
1016 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
1017 pcap_geterr(ld.pch));
1020 /* Get the capture statistics, and, if any packets were dropped, report
1022 if (pcap_stats(ld.pch, &stats) >= 0) {
1023 if (stats.ps_drop != 0) {
1024 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
1027 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
1028 pcap_geterr(ld.pch));
1030 /* Report the number of captured packets if not reported during capture and
1031 we are not saving to a file. */
1032 if (quiet && (cfile.save_file != NULL)) {
1033 fprintf(stderr, "\r%u packets captured\n", cfile.count);
1038 if (cfile.save_file != NULL) {
1039 /* We're saving to a file or files; close all files. */
1040 if (capture_opts.ringbuffer_on) {
1041 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
1043 dump_ok = wtap_dump_close(ld.pdh, &err);
1046 show_capture_file_io_error(cfile.save_file, err, TRUE);
1052 if (capture_opts.ringbuffer_on) {
1053 ringbuf_error_cleanup();
1055 g_free(cfile.save_file);
1056 cfile.save_file = NULL;
1057 fprintf(stderr, "tethereal: %s\n", errmsg);
1065 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1068 struct wtap_pkthdr whdr;
1069 loop_data *ld = (loop_data *) user;
1072 whdr.ts.tv_sec = phdr->ts.tv_sec;
1073 whdr.ts.tv_usec = phdr->ts.tv_usec;
1074 whdr.caplen = phdr->caplen;
1075 whdr.len = phdr->len;
1076 whdr.pkt_encap = ld->linktype;
1081 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1082 /* Report packet capture count if not quiet */
1084 fprintf(stderr, "\r%u ", cfile.count);
1088 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1093 capture_cleanup(int signum _U_)
1095 /* Longjmp back to the starting point; "pcap_dispatch()", on many
1096 platforms, just keeps looping if it gets EINTR, so if we set
1097 "ld.go" to FALSE and return, we won't break out of it and quit
1099 longjmp(ld.stopenv, 1);
1101 #endif /* HAVE_LIBPCAP */
1104 load_cap_file(capture_file *cf, int out_file_type)
1107 int snapshot_length;
1113 linktype = wtap_file_encap(cf->wth);
1114 if (cf->save_file != NULL) {
1115 /* Set up to write to the capture file. */
1116 snapshot_length = wtap_snapshot_length(cf->wth);
1117 if (snapshot_length == 0) {
1118 /* Snapshot length of input file not known. */
1119 snapshot_length = WTAP_MAX_PACKET_SIZE;
1121 pdh = wtap_dump_open(cf->save_file, out_file_type,
1122 linktype, snapshot_length, &err);
1125 /* We couldn't set up to write to the capture file. */
1128 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1130 "tethereal: Capture files can't be written in that format.\n");
1133 case WTAP_ERR_UNSUPPORTED_ENCAP:
1134 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1136 "tethereal: The capture file being read cannot be written in that format.\n");
1139 case WTAP_ERR_CANT_OPEN:
1141 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1145 case WTAP_ERR_SHORT_WRITE:
1147 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1154 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1155 cf->save_file, err);
1158 "tethereal: The file \"%s\" could not be opened: %s\n.",
1159 cf->save_file, strerror(err));
1167 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1170 /* Now close the capture file. */
1171 if (!wtap_dump_close(pdh, &err))
1172 show_capture_file_io_error(cfile.save_file, err, TRUE);
1176 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1180 /* Print up a message box noting that the read failed somewhere along
1184 case WTAP_ERR_UNSUPPORTED_ENCAP:
1186 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1190 case WTAP_ERR_CANT_READ:
1192 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1196 case WTAP_ERR_SHORT_READ:
1198 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1202 case WTAP_ERR_BAD_RECORD:
1204 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1210 "tethereal: An error occurred while reading \"%s\": %s.\n",
1211 cf->filename, wtap_strerror(err));
1217 wtap_close(cf->wth);
1224 fill_in_fdata(frame_data *fdata, capture_file *cf,
1225 const struct wtap_pkthdr *phdr, long offset)
1230 fdata->data_src = NULL;
1231 fdata->num = cf->count;
1232 fdata->pkt_len = phdr->len;
1233 fdata->cap_len = phdr->caplen;
1234 fdata->file_off = offset;
1235 fdata->lnk_t = phdr->pkt_encap;
1236 fdata->abs_secs = phdr->ts.tv_sec;
1237 fdata->abs_usecs = phdr->ts.tv_usec;
1238 fdata->flags.passed_dfilter = 0;
1239 fdata->flags.encoding = CHAR_ASCII;
1240 fdata->flags.visited = 0;
1241 fdata->flags.marked = 0;
1243 /* If we don't have the time stamp of the first packet in the
1244 capture, it's because this is the first packet. Save the time
1245 stamp of this packet as the time stamp of the first packet. */
1246 if (!firstsec && !firstusec) {
1247 firstsec = fdata->abs_secs;
1248 firstusec = fdata->abs_usecs;
1251 /* If we don't have the time stamp of the previous displayed packet,
1252 it's because this is the first displayed packet. Save the time
1253 stamp of this packet as the time stamp of the previous displayed
1255 if (!prevsec && !prevusec) {
1256 prevsec = fdata->abs_secs;
1257 prevusec = fdata->abs_usecs;
1260 /* Get the time elapsed between the first packet and this packet. */
1261 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1262 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1264 /* If it's greater than the current elapsed time, set the elapsed time
1265 to it (we check for "greater than" so as not to be confused by
1266 time moving backwards). */
1267 if ((gint32)cf->esec < fdata->rel_secs
1268 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1269 cf->esec = fdata->rel_secs;
1270 cf->eusec = fdata->rel_usecs;
1273 /* Get the time elapsed between the previous displayed packet and
1275 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1276 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1277 prevsec = fdata->abs_secs;
1278 prevusec = fdata->abs_usecs;
1281 /* Free up all data attached to a "frame_data" structure. */
1283 clear_fdata(frame_data *fdata)
1286 g_slist_free(fdata->pfd);
1287 free_data_sources(fdata); /* release data source list */
1291 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1292 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1294 cb_args_t *args = (cb_args_t *) user;
1295 capture_file *cf = args->cf;
1296 wtap_dumper *pdh = args->pdh;
1300 epan_dissect_t *edt;
1304 fill_in_fdata(&fdata, cf, phdr, offset);
1305 edt = epan_dissect_new(TRUE, FALSE);
1306 epan_dissect_prime_dfilter(edt, cf->rfcode);
1307 epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1308 passed = dfilter_apply_edt(cf->rfcode, edt);
1314 if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1316 if (ld.pch != NULL) {
1317 /* We're capturing packets, so we're printing a count of packets
1318 captured; move to the line after the count. */
1319 fprintf(stderr, "\n");
1322 show_capture_file_io_error(cf->save_file, err, FALSE);
1327 wtap_dump_close(pdh, &err);
1332 epan_dissect_free(edt);
1334 clear_fdata(&fdata);
1338 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1344 "tethereal: Not all the packets could be written to \"%s\" because there is "
1345 "no space left on the file system.\n",
1352 "tethereal: Not all the packets could be written to \"%s\" because you are "
1353 "too close to, or over your disk quota.\n",
1358 case WTAP_ERR_CANT_CLOSE:
1360 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1364 case WTAP_ERR_SHORT_WRITE:
1366 "tethereal: Not all the packets could be written to \"%s\".\n",
1373 "tethereal: \"%s\" could not be closed: %s.\n",
1374 fname, wtap_strerror(err));
1377 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1378 fname, wtap_strerror(err));
1385 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1386 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1388 cb_args_t *args = (cb_args_t *) user;
1389 capture_file *cf = args->cf;
1392 print_args_t print_args;
1393 epan_dissect_t *edt;
1394 gboolean create_proto_tree;
1399 fill_in_fdata(&fdata, cf, phdr, offset);
1402 if (cf->rfcode || verbose)
1403 create_proto_tree = TRUE;
1405 create_proto_tree = FALSE;
1406 /* The protocol tree will be "visible", i.e., printed, only if we're
1407 not printing a summary.
1409 We only need the columns if we're *not* verbose; in verbose mode,
1410 we print the protocol tree, not the protocol summary. */
1411 edt = epan_dissect_new(create_proto_tree, verbose);
1413 epan_dissect_prime_dfilter(edt, cf->rfcode);
1415 epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1417 passed = dfilter_apply_edt(cf->rfcode, edt);
1420 /* The packet passed the read filter. */
1422 /* Print the information in the protocol tree. */
1423 print_args.to_file = TRUE;
1424 print_args.format = PR_FMT_TEXT;
1425 print_args.print_summary = FALSE;
1426 print_args.print_hex = print_hex;
1427 print_args.expand_all = TRUE;
1428 print_args.suppress_unmarked = FALSE;
1429 proto_tree_print(&print_args, (GNode *)edt->tree,
1432 /* "print_hex_data()" will put out a leading blank line, as well
1433 as a trailing one; print one here, to separate the packets,
1434 only if "print_hex_data()" won't be called. */
1438 /* Just fill in the columns. */
1439 epan_dissect_fill_in_columns(edt);
1441 /* Now print them. */
1442 for (i = 0; i < cf->cinfo.num_cols; i++) {
1443 switch (cf->cinfo.col_fmt[i]) {
1446 * Don't print this if we're doing a live capture from a network
1447 * interface - if we're doing a live capture, you won't be
1448 * able to look at the capture in the future (it's not being
1449 * saved anywhere), so the frame numbers are unlikely to be
1452 * (XXX - it might be nice to be able to save and print at
1453 * the same time, sort of like an "Update list of packets
1454 * in real time" capture in Ethereal.)
1456 if (cf->iface != NULL)
1458 printf("%3s", cf->cinfo.col_data[i]);
1464 case COL_ABS_DATE_TIME: /* XXX - wider */
1465 printf("%10s", cf->cinfo.col_data[i]);
1471 case COL_DEF_DL_SRC:
1472 case COL_RES_DL_SRC:
1473 case COL_UNRES_DL_SRC:
1474 case COL_DEF_NET_SRC:
1475 case COL_RES_NET_SRC:
1476 case COL_UNRES_NET_SRC:
1477 printf("%12s", cf->cinfo.col_data[i]);
1483 case COL_DEF_DL_DST:
1484 case COL_RES_DL_DST:
1485 case COL_UNRES_DL_DST:
1486 case COL_DEF_NET_DST:
1487 case COL_RES_NET_DST:
1488 case COL_UNRES_NET_DST:
1489 printf("%-12s", cf->cinfo.col_data[i]);
1493 printf("%s", cf->cinfo.col_data[i]);
1496 if (i != cf->cinfo.num_cols - 1) {
1498 * This isn't the last column, so we need to print a
1499 * separator between this column and the next.
1501 * If we printed a network source and are printing a
1502 * network destination of the same type next, separate
1503 * them with "->"; if we printed a network destination
1504 * and are printing a network source of the same type
1505 * next, separate them with "<-"; otherwise separate them
1508 switch (cf->cinfo.col_fmt[i]) {
1513 switch (cf->cinfo.col_fmt[i + 1]) {
1527 case COL_DEF_DL_SRC:
1528 case COL_RES_DL_SRC:
1529 case COL_UNRES_DL_SRC:
1530 switch (cf->cinfo.col_fmt[i + 1]) {
1532 case COL_DEF_DL_DST:
1533 case COL_RES_DL_DST:
1534 case COL_UNRES_DL_DST:
1544 case COL_DEF_NET_SRC:
1545 case COL_RES_NET_SRC:
1546 case COL_UNRES_NET_SRC:
1547 switch (cf->cinfo.col_fmt[i + 1]) {
1549 case COL_DEF_NET_DST:
1550 case COL_RES_NET_DST:
1551 case COL_UNRES_NET_DST:
1564 switch (cf->cinfo.col_fmt[i + 1]) {
1578 case COL_DEF_DL_DST:
1579 case COL_RES_DL_DST:
1580 case COL_UNRES_DL_DST:
1581 switch (cf->cinfo.col_fmt[i + 1]) {
1583 case COL_DEF_DL_SRC:
1584 case COL_RES_DL_SRC:
1585 case COL_UNRES_DL_SRC:
1595 case COL_DEF_NET_DST:
1596 case COL_RES_NET_DST:
1597 case COL_UNRES_NET_DST:
1598 switch (cf->cinfo.col_fmt[i + 1]) {
1600 case COL_DEF_NET_SRC:
1601 case COL_RES_NET_SRC:
1602 case COL_UNRES_NET_SRC:
1621 print_hex_data(stdout, print_args.format, &fdata);
1626 /* The ANSI C standard does not appear to *require* that a line-buffered
1627 stream be flushed to the host environment whenever a newline is
1628 written, it just says that, on such a stream, characters "are
1629 intended to be transmitted to or from the host environment as a
1630 block when a new-line character is encountered".
1632 The Visual C++ 6.0 C implementation doesn't do what is intended;
1633 even if you set a stream to be line-buffered, it still doesn't
1634 flush the buffer at the end of every line.
1636 So, if the "-l" flag was specified, we flush the standard output
1637 at the end of a packet. This will do the right thing if we're
1638 printing packet summary lines, and, as we print the entire protocol
1639 tree for a single packet without waiting for anything to happen,
1640 it should be as good as line-buffered mode if we're printing
1641 protocol trees. (The whole reason for the "-l" flag in either
1642 tcpdump or Tethereal is to allow the output of a live capture to
1643 be piped to a program or script and to have that script see the
1644 information for the packet as soon as it's printed, rather than
1645 having to wait until a standard I/O buffer fills up. */
1649 epan_dissect_free(edt);
1651 clear_fdata(&fdata);
1655 file_open_error_message(int err, gboolean for_writing)
1658 static char errmsg_errno[1024+1];
1662 case WTAP_ERR_NOT_REGULAR_FILE:
1663 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1666 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1667 case WTAP_ERR_UNSUPPORTED:
1668 /* Seen only when opening a capture file for reading. */
1669 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1672 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1673 /* Seen only when opening a capture file for writing. */
1674 errmsg = "Tethereal does not support writing capture files in that format.";
1677 case WTAP_ERR_UNSUPPORTED_ENCAP:
1678 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1680 errmsg = "Tethereal cannot save this capture in that format.";
1682 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1685 case WTAP_ERR_BAD_RECORD:
1686 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1689 case WTAP_ERR_CANT_OPEN:
1691 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1693 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1696 case WTAP_ERR_SHORT_READ:
1697 errmsg = "The file \"%s\" appears to have been cut short"
1698 " in the middle of a packet or other data.";
1701 case WTAP_ERR_SHORT_WRITE:
1702 errmsg = "A full header couldn't be written to the file \"%s\".";
1707 errmsg = "The path to the file \"%s\" does not exist.";
1709 errmsg = "The file \"%s\" does not exist.";
1714 errmsg = "You do not have permission to create or write to the file \"%s\".";
1716 errmsg = "You do not have permission to read the file \"%s\".";
1720 errmsg = "\"%s\" is a directory (folder), not a file.";
1724 snprintf(errmsg_errno, sizeof(errmsg_errno),
1725 "The file \"%%s\" could not be opened: %s.",
1726 wtap_strerror(err));
1727 errmsg = errmsg_errno;
1734 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1739 struct stat cf_stat;
1740 char err_msg[2048+1];
1742 wth = wtap_open_offline(fname, &err, FALSE);
1746 /* Find the size of the file. */
1748 if (fstat(fd, &cf_stat) < 0) {
1754 /* The open succeeded. Fill in the information for this file. */
1756 /* Initialize all data structures used for dissection. */
1761 cf->f_len = cf_stat.st_size;
1763 /* Set the file name because we need it to set the follow stream filter.
1764 XXX - is that still true? We need it for other reasons, though,
1766 cf->filename = g_strdup(fname);
1768 /* Indicate whether it's a permanent or temporary file. */
1769 cf->is_tempfile = is_tempfile;
1771 /* If it's a temporary capture buffer file, mark it as not saved. */
1772 cf->user_saved = !is_tempfile;
1774 cf->cd_t = wtap_file_type(cf->wth);
1776 cf->drops_known = FALSE;
1780 cf->snap = wtap_snapshot_length(cf->wth);
1781 if (cf->snap == 0) {
1782 /* Snapshot length not known. */
1783 cf->has_snap = FALSE;
1784 cf->snap = WTAP_MAX_PACKET_SIZE;
1786 cf->has_snap = TRUE;
1787 cf->progbar_quantum = 0;
1788 cf->progbar_nextstep = 0;
1789 firstsec = 0, firstusec = 0;
1790 prevsec = 0, prevusec = 0;
1795 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1796 fprintf(stderr, "tethereal: %s\n", err_msg);