3 * $Id: tethereal.c,v 1.143 2002/06/23 21:58:02 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>
60 #include <zlib.h> /* to get the libz version number */
63 #ifdef NEED_SNPRINTF_H
64 # include "snprintf.h"
67 #ifdef HAVE_UCD_SNMP_VERSION_H
68 #include <ucd-snmp/version.h>
69 #endif /* HAVE_UCD_SNMP_VERSION_H */
71 #ifdef NEED_STRERROR_H
80 #include <epan/epan.h>
81 #include <epan/filesystem.h>
84 #include <epan/timestamp.h>
85 #include <epan/packet.h>
90 #include <epan/resolv.h>
93 #include "pcap-util.h"
95 #include <epan/conversation.h>
96 #include <epan/plugins.h>
98 #include "conditions.h"
99 #include "capture_stop_conditions.h"
100 #include "ringbuffer.h"
101 #include <epan/epan_dissect.h>
104 #include <wiretap/wtap-capture.h>
108 #include "capture-wpcap.h"
111 static guint32 firstsec, firstusec;
112 static guint32 prevsec, prevusec;
113 static GString *comp_info_str;
114 static gboolean quiet;
115 static gboolean verbose;
116 static gboolean print_hex;
117 static gboolean line_buffered;
120 typedef struct _loop_data {
121 gboolean go; /* TRUE as long as we're supposed to keep capturing */
126 gboolean output_to_pipe;
132 static int capture(int);
133 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
135 static void capture_cleanup(int);
143 static int load_cap_file(capture_file *, int);
144 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, long,
145 union wtap_pseudo_header *, const u_char *);
146 static void show_capture_file_io_error(const char *, int, gboolean);
147 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, long,
148 union wtap_pseudo_header *, const u_char *);
151 ts_type timestamp_type = RELATIVE;
154 int snaplen; /* Maximum captured packet length */
155 int promisc_mode; /* Capture in promiscuous mode */
156 int autostop_count; /* Maximum packet count */
157 gboolean has_autostop_duration; /* TRUE if maximum capture duration
159 gint32 autostop_duration; /* Maximum capture duration */
160 gboolean has_autostop_filesize; /* TRUE if maximum capture file size
162 gint32 autostop_filesize; /* Maximum capture file size */
163 gboolean ringbuffer_on; /* TRUE if ring buffer in use */
164 guint32 ringbuffer_num_files; /* Number of ring buffer files */
167 static capture_options capture_opts = {
168 WTAP_MAX_PACKET_SIZE, /* snapshot length - default is
169 infinite, in effect */
170 TRUE, /* promiscuous mode is the default */
171 0, /* max packet count - default is 0,
173 FALSE, /* maximum capture duration not
174 specified by default */
175 0, /* maximum capture duration */
176 FALSE, /* maximum capture file size not
177 specified by default */
178 0, /* maximum capture file size */
179 FALSE, /* ring buffer off by default */
180 RINGBUFFER_MIN_NUM_FILES /* default number of ring buffer
186 print_usage(gboolean print_ver)
191 fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
195 fprintf(stderr, "\nt%s [ -DvVhqlp ] [ -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 <output 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, "\nt%s [ -vVhl ] [ -F <output 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 information registered by the
330 dissectors, and we must do it before we read the preferences, in
331 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 information based on
339 the argument to the "-G" flag; if no argument is specified,
340 for backwards compatibility we dump out a glossary of display
343 We do this here to mirror what happens in the GTK+ version, although
344 it's not necessary here. */
345 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
347 proto_registrar_dump_fields();
349 if (strcmp(argv[2], "fields") == 0)
350 proto_registrar_dump_fields();
351 else if (strcmp(argv[2], "protocols") == 0)
352 proto_registrar_dump_protocols();
354 fprintf(stderr, "tethereal: Invalid \"%s\" option for -G flag\n",
362 /* Set the C-language locale to the native environment. */
363 setlocale(LC_ALL, "");
365 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
366 if (gpf_path != NULL) {
367 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
368 strerror(gpf_open_errno));
370 if (pf_path != NULL) {
371 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
372 strerror(pf_open_errno));
375 /* Set the name resolution code's flags from the preferences. */
376 g_resolv_flags = prefs->name_resolve;
379 /* Load Wpcap, if possible */
383 /* Initialize the capture file struct */
385 cfile.plist_end = NULL;
387 cfile.filename = NULL;
388 cfile.user_saved = FALSE;
389 cfile.is_tempfile = FALSE;
391 cfile.dfilter = NULL;
394 cfile.cfilter = g_strdup("");
397 cfile.save_file = NULL;
398 cfile.save_file_fd = -1;
399 cfile.has_snap = FALSE;
400 cfile.snap = WTAP_MAX_PACKET_SIZE;
402 col_init(&cfile.cinfo, prefs->num_cols);
404 /* Assemble the compile-time options */
405 comp_info_str = g_string_new("");
407 g_string_append(comp_info_str, "with ");
408 g_string_sprintfa(comp_info_str,
409 #ifdef GLIB_MAJOR_VERSION
410 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
413 "GLib (version unknown)");
417 g_string_append(comp_info_str, ", with libpcap ");
418 #ifdef HAVE_PCAP_VERSION
419 g_string_append(comp_info_str, pcap_version);
420 #else /* HAVE_PCAP_VERSION */
421 g_string_append(comp_info_str, "(version unknown)");
422 #endif /* HAVE_PCAP_VERSION */
423 #else /* HAVE_LIBPCAP */
424 g_string_append(comp_info_str, ", without libpcap");
425 #endif /* HAVE_LIBPCAP */
428 g_string_append(comp_info_str, ", with libz ");
430 g_string_append(comp_info_str, ZLIB_VERSION);
431 #else /* ZLIB_VERSION */
432 g_string_append(comp_info_str, "(version unknown)");
433 #endif /* ZLIB_VERSION */
434 #else /* HAVE_LIBZ */
435 g_string_append(comp_info_str, ", without libz");
436 #endif /* HAVE_LIBZ */
438 /* Oh, this is pretty */
440 g_string_append(comp_info_str, ", with UCD SNMP ");
441 #ifdef HAVE_UCD_SNMP_VERSION_H
442 g_string_append(comp_info_str, VersionInfo);
443 #else /* HAVE_UCD_SNMP_VERSION_H */
444 g_string_append(comp_info_str, "(version unknown)");
445 #endif /* HAVE_UCD_SNMP_VERSION_H */
446 #else /* no SNMP library */
447 g_string_append(comp_info_str, ", without UCD SNMP");
450 /* Now get our args */
451 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pqr:R:s:t:vw:Vx")) != -1) {
453 case 'a': /* autostop criteria */
455 if (set_autostop_criterion(optarg) == FALSE) {
456 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
460 capture_option_specified = TRUE;
464 case 'b': /* Ringbuffer option */
466 capture_opts.ringbuffer_on = TRUE;
467 capture_opts.ringbuffer_num_files =
468 get_positive_int(optarg, "number of ring buffer files");
470 capture_option_specified = TRUE;
474 case 'c': /* Capture xxx packets */
476 capture_opts.autostop_count =
477 get_positive_int(optarg, "packet count");
479 capture_option_specified = TRUE;
483 case 'D': /* Print a list of capture devices */
485 if_list = get_interface_list(&err, err_str);
486 if (if_list == NULL) {
489 case CANT_GET_INTERFACE_LIST:
490 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
494 case NO_INTERFACES_FOUND:
495 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
500 for (if_entry = g_list_first(if_list); if_entry != NULL;
501 if_entry = g_list_next(if_entry))
502 printf("%s\n", (char *)if_entry->data);
503 free_interface_list(if_list);
506 capture_option_specified = TRUE;
512 capture_filter_specified = TRUE;
514 g_free(cfile.cfilter);
515 cfile.cfilter = g_strdup(optarg);
517 capture_option_specified = TRUE;
522 out_file_type = wtap_short_string_to_file_type(optarg);
523 if (out_file_type < 0) {
524 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
529 case 'h': /* Print help and exit */
533 case 'i': /* Use interface xxx */
535 cfile.iface = g_strdup(optarg);
537 capture_option_specified = TRUE;
541 case 'l': /* "Line-buffer" standard output */
542 /* This isn't line-buffering, strictly speaking, it's just
543 flushing the standard output after the information for
544 each packet is printed; however, that should be good
545 enough for all the purposes to which "-l" is put.
547 See the comment in "wtap_dispatch_cb_print()" for an
548 explanation of why we do that, and why we don't just
549 use "setvbuf()" to make the standard output line-buffered
550 (short version: in Windows, "line-buffered" is the same
551 as "fully-buffered", and the output buffer is only flushed
552 when it fills up). */
553 line_buffered = TRUE;
555 case 'n': /* No name resolution */
556 g_resolv_flags = RESOLV_NONE;
558 case 'N': /* Select what types of addresses/port #s to resolve */
559 if (g_resolv_flags == RESOLV_ALL)
560 g_resolv_flags = RESOLV_NONE;
561 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
562 if (badopt != '\0') {
563 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
568 case 'o': /* Override preference from command line */
569 switch (prefs_set_pref(optarg)) {
571 case PREFS_SET_SYNTAX_ERR:
572 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
576 case PREFS_SET_NO_SUCH_PREF:
577 case PREFS_SET_OBSOLETE:
578 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
584 case 'p': /* Don't capture in promiscuous mode */
586 capture_opts.promisc_mode = FALSE;
588 capture_option_specified = TRUE;
592 case 'q': /* Quiet */
595 case 'r': /* Read capture file xxx */
596 cf_name = g_strdup(optarg);
598 case 'R': /* Read file filter */
601 case 's': /* Set the snapshot (capture) length */
603 capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
605 capture_option_specified = TRUE;
609 case 't': /* Time stamp type */
610 if (strcmp(optarg, "r") == 0)
611 timestamp_type = RELATIVE;
612 else if (strcmp(optarg, "a") == 0)
613 timestamp_type = ABSOLUTE;
614 else if (strcmp(optarg, "ad") == 0)
615 timestamp_type = ABSOLUTE_WITH_DATE;
616 else if (strcmp(optarg, "d") == 0)
617 timestamp_type = DELTA;
619 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
621 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
622 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
626 case 'v': /* Show version and exit */
627 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
630 case 'w': /* Write to capture file xxx */
631 cfile.save_file = g_strdup(optarg);
633 case 'V': /* Verbose */
636 case 'x': /* Print packet data in hex (and ASCII) */
640 case '?': /* Bad flag - print usage message */
646 /* If no capture filter or read filter has been specified, and there are
647 still command-line arguments, treat them as the tokens of a capture
648 filter (if no "-r" flag was specified) or a read filter (if a "-r"
649 flag was specified. */
651 if (cf_name != NULL) {
652 if (rfilter != NULL) {
654 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
657 rfilter = get_args_as_string(argc, argv, optind);
660 if (capture_filter_specified) {
662 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
665 cfile.cfilter = get_args_as_string(argc, argv, optind);
667 capture_option_specified = TRUE;
672 /* See if we're writing a capture file and the file is a pipe */
673 ld.output_to_pipe = FALSE;
674 if (cfile.save_file != NULL) {
675 err = test_for_fifo(cfile.save_file);
678 case ENOENT: /* it doesn't exist, so we'll be creating it,
679 and it won't be a FIFO */
680 case ENOTDIR: /* XXX - why ignore this? */
681 case 0: /* found it, but it's not a FIFO */
684 case ESPIPE: /* it is a FIFO */
685 ld.output_to_pipe = TRUE;
688 default: /* couldn't stat it */
690 "tethereal: Error testing whether capture file is a pipe: %s\n",
697 /* If they didn't specify a "-w" flag, but specified a maximum capture
698 file size, tell them that this doesn't work, and exit. */
699 if (capture_opts.has_autostop_filesize && cfile.save_file == NULL) {
700 fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
704 if (capture_opts.ringbuffer_on) {
705 /* Ring buffer works only under certain conditions:
706 a) ring buffer does not work if you're not saving the capture to
708 b) ring buffer only works if you're saving in libpcap format;
709 c) it makes no sense to enable the ring buffer if the maximum
710 file size is set to "infinite";
711 d) file must not be a pipe. */
712 if (cfile.save_file == NULL) {
713 fprintf(stderr, "tethereal: Ring buffer requested, but "
714 "capture isn't being saved to a file.\n");
717 if (out_file_type != WTAP_FILE_PCAP) {
718 fprintf(stderr, "tethereal: Ring buffer requested, but "
719 "capture isn't being saved in libpcap format.\n");
722 if (!capture_opts.has_autostop_filesize) {
723 fprintf(stderr, "tethereal: Ring buffer requested, but "
724 "no maximum capture file size was specified.\n");
727 if (ld.output_to_pipe) {
728 fprintf(stderr, "tethereal: Ring buffer requested, but "
729 "capture file is a pipe.\n");
736 /* Start windows sockets */
737 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
740 /* Notify all registered modules that have had any of their preferences
741 changed either from one of the preferences file or from the command
742 line that its preferences have changed. */
746 if (capture_option_specified)
747 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
754 /* Build the column format array */
755 for (i = 0; i < cfile.cinfo.num_cols; i++) {
756 cfile.cinfo.col_fmt[i] = get_column_format(i);
757 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
758 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
760 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
761 cfile.cinfo.col_data[i] = NULL;
762 if (cfile.cinfo.col_fmt[i] == COL_INFO)
763 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
765 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
767 cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
768 cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
772 if (capture_opts.snaplen < 1)
773 capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
774 else if (capture_opts.snaplen < MIN_PACKET_SIZE)
775 capture_opts.snaplen = MIN_PACKET_SIZE;
777 /* Check the value range of the ringbuffer_num_files parameter */
778 if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
779 capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
780 else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
781 capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
784 if (rfilter != NULL) {
785 if (!dfilter_compile(rfilter, &rfcode)) {
786 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
791 cfile.rfcode = rfcode;
793 err = open_cap_file(cf_name, FALSE, &cfile);
798 err = load_cap_file(&cfile, out_file_type);
805 /* No capture file specified, so we're supposed to do a live capture;
806 do we have support for live captures? */
811 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
816 /* Yes; did the user specify an interface to use? */
817 if (cfile.iface == NULL) {
818 /* No - is a default specified in the preferences file? */
819 if (prefs->capture_device != NULL) {
821 cfile.iface = g_strdup(prefs->capture_device);
823 /* No - pick the first one from the list of interfaces. */
824 if_list = get_interface_list(&err, err_str);
825 if (if_list == NULL) {
828 case CANT_GET_INTERFACE_LIST:
829 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
833 case NO_INTERFACES_FOUND:
834 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
839 cfile.iface = g_strdup(if_list->data); /* first interface */
840 free_interface_list(if_list);
843 capture(out_file_type);
845 if (capture_opts.ringbuffer_on) {
850 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
861 /* Do the low-level work of a capture.
862 Returns TRUE if it succeeds, FALSE otherwise. */
864 capture(int out_file_type)
866 gchar open_err_str[PCAP_ERRBUF_SIZE];
867 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
868 bpf_u_int32 netnum, netmask;
869 struct bpf_program fcode;
870 void (*oldhandler)(int);
872 volatile int inpkts = 0;
874 condition *volatile cnd_stop_capturesize = NULL;
875 condition *volatile cnd_stop_timeout = NULL;
877 static const char ppamsg[] = "can't find PPA for ";
880 struct pcap_stat stats;
881 gboolean volatile write_err = FALSE;
884 /* Initialize all data structures used for dissection. */
887 ld.linktype = WTAP_ENCAP_UNKNOWN;
890 /* Open the network interface to capture from it.
891 Some versions of libpcap may put warnings into the error buffer
892 if they succeed; to tell if that's happened, we have to clear
893 the error buffer, and check if it's still a null string. */
894 open_err_str[0] = '\0';
895 ld.pch = pcap_open_live(cfile.iface, capture_opts.snaplen,
896 capture_opts.promisc_mode, 1000, open_err_str);
898 if (ld.pch == NULL) {
899 /* Well, we couldn't start the capture. */
901 /* On Win32 OSes, the capture devices are probably available to all
902 users; don't warn about permissions problems.
904 Do, however, warn that Token Ring and PPP devices aren't supported. */
905 snprintf(errmsg, sizeof errmsg,
906 "The capture session could not be initiated (%s).\n"
907 "Please check that you have the proper interface specified.\n"
909 "Note that the driver Tethereal uses for packet capture on Windows\n"
910 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
911 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
914 /* If we got a "can't find PPA for XXX" message, warn the user (who
915 is running Ethereal on HP-UX) that they don't have a version
916 of libpcap that properly handles HP-UX (libpcap 0.6.x and later
917 versions, which properly handle HP-UX, say "can't find /dev/dlpi
918 PPA for XXX" rather than "can't find PPA for XXX"). */
919 if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
922 "You are running Tethereal with a version of the libpcap library\n"
923 "that doesn't handle HP-UX network devices well; this means that\n"
924 "Tethereal may not be able to capture packets.\n"
926 "To fix this, you should install libpcap 0.6.2, or a later version\n"
927 "of libpcap, rather than libpcap 0.4 or 0.5.x. It is available in\n"
928 "packaged binary form from the Software Porting And Archive Centre\n"
929 "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
930 "at the URL lists a number of mirror sites.";
933 snprintf(errmsg, sizeof errmsg,
934 "The capture session could not be initiated (%s).\n"
935 "Please check to make sure you have sufficient permissions, and that\n"
936 "you have the proper interface specified.%s", open_err_str, libpcap_warn);
942 /* A capture filter was specified; set it up. */
943 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
945 * Well, we can't get the netmask for this interface; it's used
946 * only for filters that check for broadcast IP addresses, so
947 * we just warn the user, and punt and use 0.
950 "Warning: Couldn't obtain netmask info (%s).\n", lookup_net_err_str);
953 if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
954 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
955 pcap_geterr(ld.pch));
958 if (pcap_setfilter(ld.pch, &fcode) < 0) {
959 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
960 pcap_geterr(ld.pch));
965 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
967 if (cfile.save_file != NULL) {
968 /* Set up to write to the capture file. */
969 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
970 strcpy(errmsg, "The network you're capturing from is of a type"
971 " that Tethereal doesn't support.");
974 if (capture_opts.ringbuffer_on) {
975 cfile.save_file_fd = ringbuf_init(cfile.save_file,
976 capture_opts.ringbuffer_num_files);
977 if (cfile.save_file_fd != -1) {
978 ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
979 pcap_snapshot(ld.pch), &err);
984 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
985 ld.linktype, pcap_snapshot(ld.pch), &err);
988 if (ld.pdh == NULL) {
989 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
995 /* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
996 returned a warning; print it, but keep capturing. */
997 if (open_err_str[0] != '\0')
998 fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
1000 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
1002 XXX - deal with signal semantics on various platforms. Or just
1003 use "sigaction()" and be done with it? */
1004 signal(SIGTERM, capture_cleanup);
1005 signal(SIGINT, capture_cleanup);
1007 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
1008 signal(SIGHUP, oldhandler);
1011 /* Let the user know what interface was chosen. */
1012 fprintf(stderr, "Capturing on %s\n", cfile.iface);
1014 /* initialize capture stop conditions */
1015 init_capture_stop_conditions();
1016 /* create stop conditions */
1017 if (capture_opts.has_autostop_filesize)
1018 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
1019 (long)capture_opts.autostop_filesize * 1000);
1020 if (capture_opts.has_autostop_duration)
1021 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
1022 (gint32)capture_opts.autostop_duration);
1024 if (!setjmp(ld.stopenv))
1028 ld.packet_count = 0;
1030 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
1032 /* Error from "pcap_dispatch()". */
1034 } else if (capture_opts.autostop_count != 0 &&
1035 ld.packet_count >= capture_opts.autostop_count) {
1036 /* The specified number of packets have been captured and have
1037 passed both any capture filter in effect and any read filter
1040 } else if (cnd_stop_timeout != NULL && cnd_eval(cnd_stop_timeout)) {
1041 /* The specified capture time has elapsed; stop the capture. */
1043 } else if (ld.pdh != NULL && cnd_stop_capturesize != NULL &&
1044 cnd_eval(cnd_stop_capturesize,
1045 (guint32)wtap_get_bytes_dumped(ld.pdh))) {
1046 /* We're saving the capture to a file, and the capture file reached
1047 its maximum size. */
1048 if (capture_opts.ringbuffer_on) {
1049 /* Switch to the next ringbuffer file */
1050 if (ringbuf_switch_file(&cfile, &ld.pdh, &err)) {
1051 /* File switch succeeded: reset the condition */
1052 cnd_reset(cnd_stop_capturesize);
1054 /* File switch failed: stop here */
1059 /* No ringbuffer - just stop. */
1065 /* delete stop conditions */
1066 if (cnd_stop_capturesize != NULL)
1067 cnd_delete(cnd_stop_capturesize);
1068 if (cnd_stop_timeout != NULL)
1069 cnd_delete(cnd_stop_timeout);
1071 if ((cfile.save_file != NULL) && !quiet) {
1072 /* We're saving to a file, which means we're printing packet counts
1073 to the standard output if we are not running silent and deep.
1074 Send a newline so that we move to the line after the packet count. */
1075 fprintf(stderr, "\n");
1078 /* If we got an error while capturing, report it. */
1080 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
1081 pcap_geterr(ld.pch));
1085 show_capture_file_io_error(cfile.save_file, err, FALSE);
1089 if (cfile.save_file != NULL) {
1090 /* We're saving to a file or files; close all files. */
1091 if (capture_opts.ringbuffer_on) {
1092 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
1094 dump_ok = wtap_dump_close(ld.pdh, &err);
1096 if (!dump_ok && ! write_err)
1097 show_capture_file_io_error(cfile.save_file, err, TRUE);
1100 /* Get the capture statistics, and, if any packets were dropped, report
1102 if (pcap_stats(ld.pch, &stats) >= 0) {
1103 if (stats.ps_drop != 0) {
1104 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
1107 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
1108 pcap_geterr(ld.pch));
1110 /* Report the number of captured packets if not reported during capture
1111 and we are saving to a file. */
1112 if (quiet && (cfile.save_file != NULL)) {
1113 fprintf(stderr, "%u packets captured\n", ld.packet_count);
1121 if (capture_opts.ringbuffer_on) {
1122 ringbuf_error_cleanup();
1124 g_free(cfile.save_file);
1125 cfile.save_file = NULL;
1126 fprintf(stderr, "tethereal: %s\n", errmsg);
1134 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1137 struct wtap_pkthdr whdr;
1138 union wtap_pseudo_header pseudo_header;
1139 loop_data *ld = (loop_data *) user;
1143 /* Convert from libpcap to Wiretap format.
1144 If that fails, ignore the packet.
1145 XXX - print a message. */
1146 pd = wtap_process_pcap_packet(ld->linktype, phdr, pd, &pseudo_header,
1155 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, &pseudo_header, pd);
1156 /* Report packet capture count if not quiet */
1158 if (ld->packet_count != 0) {
1159 fprintf(stderr, "\r%u ", ld->packet_count);
1160 /* stderr could be line buffered */
1165 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, &pseudo_header, pd);
1170 capture_cleanup(int signum _U_)
1172 /* Longjmp back to the starting point; "pcap_dispatch()", on many
1173 platforms, just keeps looping if it gets EINTR, so if we set
1174 "ld.go" to FALSE and return, we won't break out of it and quit
1176 longjmp(ld.stopenv, 1);
1178 #endif /* HAVE_LIBPCAP */
1181 load_cap_file(capture_file *cf, int out_file_type)
1184 int snapshot_length;
1190 linktype = wtap_file_encap(cf->wth);
1191 if (cf->save_file != NULL) {
1192 /* Set up to write to the capture file. */
1193 snapshot_length = wtap_snapshot_length(cf->wth);
1194 if (snapshot_length == 0) {
1195 /* Snapshot length of input file not known. */
1196 snapshot_length = WTAP_MAX_PACKET_SIZE;
1198 pdh = wtap_dump_open(cf->save_file, out_file_type,
1199 linktype, snapshot_length, &err);
1202 /* We couldn't set up to write to the capture file. */
1205 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1207 "tethereal: Capture files can't be written in that format.\n");
1210 case WTAP_ERR_UNSUPPORTED_ENCAP:
1211 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1213 "tethereal: The capture file being read cannot be written in that format.\n");
1216 case WTAP_ERR_CANT_OPEN:
1218 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1222 case WTAP_ERR_SHORT_WRITE:
1224 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1231 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1232 cf->save_file, err);
1235 "tethereal: The file \"%s\" could not be opened: %s\n.",
1236 cf->save_file, strerror(err));
1244 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1247 /* Now close the capture file. */
1248 if (!wtap_dump_close(pdh, &err))
1249 show_capture_file_io_error(cfile.save_file, err, TRUE);
1253 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1257 /* Print up a message box noting that the read failed somewhere along
1261 case WTAP_ERR_UNSUPPORTED_ENCAP:
1263 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1267 case WTAP_ERR_CANT_READ:
1269 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1273 case WTAP_ERR_SHORT_READ:
1275 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1279 case WTAP_ERR_BAD_RECORD:
1281 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1287 "tethereal: An error occurred while reading \"%s\": %s.\n",
1288 cf->filename, wtap_strerror(err));
1294 wtap_close(cf->wth);
1301 fill_in_fdata(frame_data *fdata, capture_file *cf,
1302 const struct wtap_pkthdr *phdr, long offset)
1307 fdata->num = cf->count;
1308 fdata->pkt_len = phdr->len;
1309 fdata->cap_len = phdr->caplen;
1310 fdata->file_off = offset;
1311 fdata->lnk_t = phdr->pkt_encap;
1312 fdata->abs_secs = phdr->ts.tv_sec;
1313 fdata->abs_usecs = phdr->ts.tv_usec;
1314 fdata->flags.passed_dfilter = 0;
1315 fdata->flags.encoding = CHAR_ASCII;
1316 fdata->flags.visited = 0;
1317 fdata->flags.marked = 0;
1319 /* If we don't have the time stamp of the first packet in the
1320 capture, it's because this is the first packet. Save the time
1321 stamp of this packet as the time stamp of the first packet. */
1322 if (!firstsec && !firstusec) {
1323 firstsec = fdata->abs_secs;
1324 firstusec = fdata->abs_usecs;
1327 /* If we don't have the time stamp of the previous displayed packet,
1328 it's because this is the first displayed packet. Save the time
1329 stamp of this packet as the time stamp of the previous displayed
1331 if (!prevsec && !prevusec) {
1332 prevsec = fdata->abs_secs;
1333 prevusec = fdata->abs_usecs;
1336 /* Get the time elapsed between the first packet and this packet. */
1337 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1338 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1340 /* If it's greater than the current elapsed time, set the elapsed time
1341 to it (we check for "greater than" so as not to be confused by
1342 time moving backwards). */
1343 if ((gint32)cf->esec < fdata->rel_secs
1344 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1345 cf->esec = fdata->rel_secs;
1346 cf->eusec = fdata->rel_usecs;
1349 /* Get the time elapsed between the previous displayed packet and
1351 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1352 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1353 prevsec = fdata->abs_secs;
1354 prevusec = fdata->abs_usecs;
1357 /* Free up all data attached to a "frame_data" structure. */
1359 clear_fdata(frame_data *fdata)
1362 g_slist_free(fdata->pfd);
1366 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1367 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1369 cb_args_t *args = (cb_args_t *) user;
1370 capture_file *cf = args->cf;
1371 wtap_dumper *pdh = args->pdh;
1376 epan_dissect_t *edt;
1380 fill_in_fdata(&fdata, cf, phdr, offset);
1381 edt = epan_dissect_new(TRUE, FALSE);
1382 epan_dissect_prime_dfilter(edt, cf->rfcode);
1383 epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1384 passed = dfilter_apply_edt(cf->rfcode, edt);
1390 /* The packet passed the read filter. */
1392 io_ok = wtap_dump(pdh, phdr, pseudo_header, buf, &err);
1393 if (io_ok && ld.output_to_pipe) {
1394 io_ok = ! fflush(wtap_dump_file(ld.pdh));
1400 if (ld.pch != NULL && !quiet) {
1401 /* We're capturing packets, so (if -q not specified) we're printing
1402 a count of packets captured; move to the line after the count. */
1403 fprintf(stderr, "\n");
1406 show_capture_file_io_error(cf->save_file, err, FALSE);
1411 wtap_dump_close(pdh, &err);
1416 epan_dissect_free(edt);
1418 clear_fdata(&fdata);
1422 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1428 "tethereal: Not all the packets could be written to \"%s\" because there is "
1429 "no space left on the file system.\n",
1436 "tethereal: Not all the packets could be written to \"%s\" because you are "
1437 "too close to, or over your disk quota.\n",
1442 case WTAP_ERR_CANT_CLOSE:
1444 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1448 case WTAP_ERR_SHORT_WRITE:
1450 "tethereal: Not all the packets could be written to \"%s\".\n",
1457 "tethereal: \"%s\" could not be closed: %s.\n",
1458 fname, wtap_strerror(err));
1461 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1462 fname, wtap_strerror(err));
1469 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1470 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1472 cb_args_t *args = (cb_args_t *) user;
1473 capture_file *cf = args->cf;
1476 print_args_t print_args;
1477 epan_dissect_t *edt;
1478 gboolean create_proto_tree;
1483 fill_in_fdata(&fdata, cf, phdr, offset);
1486 if (cf->rfcode || verbose)
1487 create_proto_tree = TRUE;
1489 create_proto_tree = FALSE;
1490 /* The protocol tree will be "visible", i.e., printed, only if we're
1491 not printing a summary.
1493 We only need the columns if we're *not* verbose; in verbose mode,
1494 we print the protocol tree, not the protocol summary. */
1495 edt = epan_dissect_new(create_proto_tree, verbose);
1497 epan_dissect_prime_dfilter(edt, cf->rfcode);
1499 epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1501 passed = dfilter_apply_edt(cf->rfcode, edt);
1504 /* The packet passed the read filter. */
1507 /* Print the information in the protocol tree. */
1508 print_args.to_file = TRUE;
1509 print_args.format = PR_FMT_TEXT;
1510 print_args.print_summary = FALSE;
1511 print_args.print_hex = print_hex;
1512 print_args.expand_all = TRUE;
1513 print_args.suppress_unmarked = FALSE;
1514 proto_tree_print(&print_args, edt, stdout);
1516 /* "print_hex_data()" will put out a leading blank line, as well
1517 as a trailing one; print one here, to separate the packets,
1518 only if "print_hex_data()" won't be called. */
1522 /* Just fill in the columns. */
1523 epan_dissect_fill_in_columns(edt);
1525 /* Now print them. */
1526 for (i = 0; i < cf->cinfo.num_cols; i++) {
1527 switch (cf->cinfo.col_fmt[i]) {
1530 * Don't print this if we're doing a live capture from a network
1531 * interface - if we're doing a live capture, you won't be
1532 * able to look at the capture in the future (it's not being
1533 * saved anywhere), so the frame numbers are unlikely to be
1536 * (XXX - it might be nice to be able to save and print at
1537 * the same time, sort of like an "Update list of packets
1538 * in real time" capture in Ethereal.)
1540 if (cf->iface != NULL)
1542 printf("%3s", cf->cinfo.col_data[i]);
1548 case COL_ABS_DATE_TIME: /* XXX - wider */
1549 printf("%10s", cf->cinfo.col_data[i]);
1555 case COL_DEF_DL_SRC:
1556 case COL_RES_DL_SRC:
1557 case COL_UNRES_DL_SRC:
1558 case COL_DEF_NET_SRC:
1559 case COL_RES_NET_SRC:
1560 case COL_UNRES_NET_SRC:
1561 printf("%12s", cf->cinfo.col_data[i]);
1567 case COL_DEF_DL_DST:
1568 case COL_RES_DL_DST:
1569 case COL_UNRES_DL_DST:
1570 case COL_DEF_NET_DST:
1571 case COL_RES_NET_DST:
1572 case COL_UNRES_NET_DST:
1573 printf("%-12s", cf->cinfo.col_data[i]);
1577 printf("%s", cf->cinfo.col_data[i]);
1580 if (i != cf->cinfo.num_cols - 1) {
1582 * This isn't the last column, so we need to print a
1583 * separator between this column and the next.
1585 * If we printed a network source and are printing a
1586 * network destination of the same type next, separate
1587 * them with "->"; if we printed a network destination
1588 * and are printing a network source of the same type
1589 * next, separate them with "<-"; otherwise separate them
1592 switch (cf->cinfo.col_fmt[i]) {
1597 switch (cf->cinfo.col_fmt[i + 1]) {
1611 case COL_DEF_DL_SRC:
1612 case COL_RES_DL_SRC:
1613 case COL_UNRES_DL_SRC:
1614 switch (cf->cinfo.col_fmt[i + 1]) {
1616 case COL_DEF_DL_DST:
1617 case COL_RES_DL_DST:
1618 case COL_UNRES_DL_DST:
1628 case COL_DEF_NET_SRC:
1629 case COL_RES_NET_SRC:
1630 case COL_UNRES_NET_SRC:
1631 switch (cf->cinfo.col_fmt[i + 1]) {
1633 case COL_DEF_NET_DST:
1634 case COL_RES_NET_DST:
1635 case COL_UNRES_NET_DST:
1648 switch (cf->cinfo.col_fmt[i + 1]) {
1662 case COL_DEF_DL_DST:
1663 case COL_RES_DL_DST:
1664 case COL_UNRES_DL_DST:
1665 switch (cf->cinfo.col_fmt[i + 1]) {
1667 case COL_DEF_DL_SRC:
1668 case COL_RES_DL_SRC:
1669 case COL_UNRES_DL_SRC:
1679 case COL_DEF_NET_DST:
1680 case COL_RES_NET_DST:
1681 case COL_UNRES_NET_DST:
1682 switch (cf->cinfo.col_fmt[i + 1]) {
1684 case COL_DEF_NET_SRC:
1685 case COL_RES_NET_SRC:
1686 case COL_UNRES_NET_SRC:
1705 print_hex_data(stdout, print_args.format, edt);
1710 /* The ANSI C standard does not appear to *require* that a line-buffered
1711 stream be flushed to the host environment whenever a newline is
1712 written, it just says that, on such a stream, characters "are
1713 intended to be transmitted to or from the host environment as a
1714 block when a new-line character is encountered".
1716 The Visual C++ 6.0 C implementation doesn't do what is intended;
1717 even if you set a stream to be line-buffered, it still doesn't
1718 flush the buffer at the end of every line.
1720 So, if the "-l" flag was specified, we flush the standard output
1721 at the end of a packet. This will do the right thing if we're
1722 printing packet summary lines, and, as we print the entire protocol
1723 tree for a single packet without waiting for anything to happen,
1724 it should be as good as line-buffered mode if we're printing
1725 protocol trees. (The whole reason for the "-l" flag in either
1726 tcpdump or Tethereal is to allow the output of a live capture to
1727 be piped to a program or script and to have that script see the
1728 information for the packet as soon as it's printed, rather than
1729 having to wait until a standard I/O buffer fills up. */
1733 epan_dissect_free(edt);
1735 clear_fdata(&fdata);
1739 file_open_error_message(int err, gboolean for_writing)
1742 static char errmsg_errno[1024+1];
1746 case WTAP_ERR_NOT_REGULAR_FILE:
1747 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1750 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1751 case WTAP_ERR_UNSUPPORTED:
1752 /* Seen only when opening a capture file for reading. */
1753 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1756 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1757 /* Seen only when opening a capture file for writing. */
1758 errmsg = "Tethereal does not support writing capture files in that format.";
1761 case WTAP_ERR_UNSUPPORTED_ENCAP:
1762 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1764 errmsg = "Tethereal cannot save this capture in that format.";
1766 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1769 case WTAP_ERR_BAD_RECORD:
1770 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1773 case WTAP_ERR_CANT_OPEN:
1775 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1777 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1780 case WTAP_ERR_SHORT_READ:
1781 errmsg = "The file \"%s\" appears to have been cut short"
1782 " in the middle of a packet or other data.";
1785 case WTAP_ERR_SHORT_WRITE:
1786 errmsg = "A full header couldn't be written to the file \"%s\".";
1791 errmsg = "The path to the file \"%s\" does not exist.";
1793 errmsg = "The file \"%s\" does not exist.";
1798 errmsg = "You do not have permission to create or write to the file \"%s\".";
1800 errmsg = "You do not have permission to read the file \"%s\".";
1804 errmsg = "\"%s\" is a directory (folder), not a file.";
1808 snprintf(errmsg_errno, sizeof(errmsg_errno),
1809 "The file \"%%s\" could not be opened: %s.",
1810 wtap_strerror(err));
1811 errmsg = errmsg_errno;
1818 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1822 char err_msg[2048+1];
1824 wth = wtap_open_offline(fname, &err, FALSE);
1828 /* The open succeeded. Fill in the information for this file. */
1830 /* Initialize all data structures used for dissection. */
1834 cf->filed = -1; /* not used, but set it anyway */
1835 cf->f_len = 0; /* not used, but set it anyway */
1837 /* Set the file name because we need it to set the follow stream filter.
1838 XXX - is that still true? We need it for other reasons, though,
1840 cf->filename = g_strdup(fname);
1842 /* Indicate whether it's a permanent or temporary file. */
1843 cf->is_tempfile = is_tempfile;
1845 /* If it's a temporary capture buffer file, mark it as not saved. */
1846 cf->user_saved = !is_tempfile;
1848 cf->cd_t = wtap_file_type(cf->wth);
1850 cf->drops_known = FALSE;
1854 cf->snap = wtap_snapshot_length(cf->wth);
1855 if (cf->snap == 0) {
1856 /* Snapshot length not known. */
1857 cf->has_snap = FALSE;
1858 cf->snap = WTAP_MAX_PACKET_SIZE;
1860 cf->has_snap = TRUE;
1861 cf->progbar_quantum = 0;
1862 cf->progbar_nextstep = 0;
1863 firstsec = 0, firstusec = 0;
1864 prevsec = 0, prevusec = 0;
1869 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1870 fprintf(stderr, "tethereal: %s\n", err_msg);