3 * $Id: tethereal.c,v 1.25 2000/04/13 20:39:19 gram Exp $
5 * Ethereal - Network traffic analyzer
6 * By Gerald Combs <gerald@zing.org>
7 * Copyright 1998 Gerald Combs
9 * Text-mode variant, by Gilbert Ramirez <gram@xiexie.org>.
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40 #include <sys/types.h>
45 #ifdef NEED_SNPRINTF_H
51 # include "snprintf.h"
54 #if defined(HAVE_UCD_SNMP_SNMP_H)
55 #ifdef HAVE_UCD_SNMP_VERSION_H
56 #include <ucd-snmp/version.h>
57 #endif /* HAVE_UCD_SNMP_VERSION_H */
58 #elif defined(HAVE_SNMP_SNMP_H)
59 #ifdef HAVE_SNMP_VERSION_H
60 #include <snmp/version.h>
61 #endif /* HAVE_SNMP_VERSION_H */
64 #ifdef NEED_STRERROR_H
73 #include "timestamp.h"
83 #include "conversation.h"
86 static guint32 firstsec, firstusec;
87 static guint32 prevsec, prevusec;
88 static gchar comp_info_str[256];
89 static gboolean verbose;
90 static gboolean print_hex;
93 typedef struct _loop_data {
101 static int capture(int, int);
102 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
104 static void capture_cleanup(int);
112 static int load_cap_file(capture_file *, int);
113 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, int,
115 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, int,
117 static gchar *col_info(frame_data *, gint);
121 FILE *data_out_file = NULL;
122 guint main_ctx, file_ctx;
123 ts_type timestamp_type = RELATIVE;
130 fprintf(stderr, "This is GNU t%s %s, compiled with %s\n", PACKAGE,
131 VERSION, comp_info_str);
133 fprintf(stderr, "t%s [ -vVh ] [ -c count ] [ -D ] [ -f <filter expression> ]\n", PACKAGE);
134 fprintf(stderr, "\t[ -F <capture file type> ] [ -i iface ] [ -n ] [ -r infile ]\n");
135 fprintf(stderr, "\t[ -R <filter expression> ] [ -s snaplen ] [ -t <time stamp format> ]\n");
136 fprintf(stderr, "\t[ -w savefile ] [ -x ]\n");
138 fprintf(stderr, "t%s [ -vVh ] [ -D ] [ -F <capture file type> ] [ -n ] [ -r infile ]\n", PACKAGE);
139 fprintf(stderr, "\t[ -R <filter expression> ] [ -t <time stamp format> ] [ -w savefile ]\n");
140 fprintf(stderr, "\t[ -x ]\n");
142 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
143 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
144 if (wtap_dump_can_open(i))
145 fprintf(stderr, "\t%s - %s\n",
146 wtap_file_type_short_string(i), wtap_file_type_string(i));
148 fprintf(stderr, "\tdefault is libpcap\n");
152 main(int argc, char *argv[])
156 gboolean arg_error = FALSE;
159 char pcap_version[] = "0.4a6";
161 extern char pcap_version[];
167 gboolean capture_filter_specified = FALSE;
168 int packet_count = 0;
170 gchar err_str[PCAP_ERRBUF_SIZE];
172 gboolean capture_option_specified = FALSE;
174 int out_file_type = WTAP_FILE_PCAP;
175 gchar *cf_name = NULL, *rfilter = NULL;
176 dfilter *rfcode = NULL;
179 /* If invoked with the "-G" flag, we dump out a glossary of
180 display filter symbols.
182 We do this here to mirror what happens in the GTK+ version, although
183 it's not necessary here. */
184 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
186 proto_registrar_dump();
190 prefs = read_prefs(&pf_path);
191 if (pf_path != NULL) {
192 fprintf(stderr, "Can't open preferences file \"%s\": %s.\n", pf_path,
196 /* Initialize the capture file struct */
202 cf.user_saved = FALSE;
203 cf.is_tempfile = FALSE;
208 cf.cfilter = g_strdup("");
212 cf.save_file_fd = -1;
213 cf.snap = WTAP_MAX_PACKET_SIZE;
215 cf.cinfo.num_cols = prefs->num_cols;
216 cf.cinfo.col_fmt = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
217 cf.cinfo.fmt_matx = (gboolean **) g_malloc(sizeof(gboolean *) * cf.cinfo.num_cols);
218 cf.cinfo.col_width = (gint *) g_malloc(sizeof(gint) * cf.cinfo.num_cols);
219 cf.cinfo.col_title = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
220 cf.cinfo.col_data = (gchar **) g_malloc(sizeof(gchar *) * cf.cinfo.num_cols);
222 /* Assemble the compile-time options */
223 snprintf(comp_info_str, 256,
224 #ifdef GTK_MAJOR_VERSION
225 "GTK+ %d.%d.%d, %s%s, %s%s, %s%s", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
228 "GTK+ (version unknown), %s%s, %s%s, %s%s",
232 "with libpcap ", pcap_version,
234 "without libpcap", "",
239 "with libz ", ZLIB_VERSION,
240 #else /* ZLIB_VERSION */
241 "with libz ", "(version unknown)",
242 #endif /* ZLIB_VERSION */
243 #else /* HAVE_LIBZ */
245 #endif /* HAVE_LIBZ */
247 /* Oh, this is pretty */
248 #if defined(HAVE_UCD_SNMP_SNMP_H)
249 #ifdef HAVE_UCD_SNMP_VERSION_H
250 "with UCD SNMP ", VersionInfo
251 #else /* HAVE_UCD_SNMP_VERSION_H */
252 "with UCD SNMP ", "(version unknown)"
253 #endif /* HAVE_UCD_SNMP_VERSION_H */
254 #elif defined(HAVE_SNMP_SNMP_H)
255 #ifdef HAVE_SNMP_VERSION_H
256 "with CMU SNMP ", snmp_Version()
257 #else /* HAVE_SNMP_VERSION_H */
258 "with CMU SNMP ", "(version unknown)"
259 #endif /* HAVE_SNMP_VERSION_H */
265 /* Now get our args */
266 while ((opt = getopt(argc, argv, "c:Df:F:hi:nr:R:s:t:vw:Vx")) != EOF) {
268 case 'c': /* Capture xxx packets */
270 packet_count = atoi(optarg);
272 capture_option_specified = TRUE;
276 case 'D': /* Turn off DSCP printing */
277 g_ip_dscp_actif = FALSE;
281 capture_filter_specified = TRUE;
282 cf.cfilter = g_strdup(optarg);
284 capture_option_specified = TRUE;
289 out_file_type = wtap_short_string_to_file_type(optarg);
290 if (out_file_type < 0) {
291 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
296 case 'h': /* Print help and exit */
300 case 'i': /* Use interface xxx */
302 cf.iface = g_strdup(optarg);
304 capture_option_specified = TRUE;
308 case 'n': /* No name resolution */
309 g_resolving_actif = 0;
311 case 'r': /* Read capture file xxx */
312 cf_name = g_strdup(optarg);
314 case 'R': /* Read file filter */
317 case 's': /* Set the snapshot (capture) length */
319 cf.snap = atoi(optarg);
321 capture_option_specified = TRUE;
325 case 't': /* Time stamp type */
326 if (strcmp(optarg, "r") == 0)
327 timestamp_type = RELATIVE;
328 else if (strcmp(optarg, "a") == 0)
329 timestamp_type = ABSOLUTE;
330 else if (strcmp(optarg, "d") == 0)
331 timestamp_type = DELTA;
333 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
335 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
336 fprintf(stderr, "or \"d\" for delta.\n");
340 case 'v': /* Show version and exit */
341 printf("t%s %s, with %s\n", PACKAGE, VERSION, comp_info_str);
344 case 'w': /* Write to capture file xxx */
345 cf.save_file = g_strdup(optarg);
347 case 'V': /* Verbose */
350 case 'x': /* Print packet data in hex (and ASCII) */
356 /* If no capture filter or read filter has been specified, and there are
357 still command-line arguments, treat them as the tokens of a capture
358 filter (if no "-r" flag was specified) or a read filter (if a "-r"
359 flag was specified. */
361 if (cf_name != NULL) {
362 if (rfilter != NULL) {
364 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
367 rfilter = get_args_as_string(argc, argv, optind);
370 if (capture_filter_specified) {
372 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
375 cf.cfilter = get_args_as_string(argc, argv, optind);
377 capture_option_specified = TRUE;
383 if (capture_option_specified)
384 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
389 /* Build the column format array */
390 for (i = 0; i < cf.cinfo.num_cols; i++) {
391 cf.cinfo.col_fmt[i] = get_column_format(i);
392 cf.cinfo.col_title[i] = g_strdup(get_column_title(i));
393 cf.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
395 get_column_format_matches(cf.cinfo.fmt_matx[i], cf.cinfo.col_fmt[i]);
396 if (cf.cinfo.col_fmt[i] == COL_INFO)
397 cf.cinfo.col_data[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
399 cf.cinfo.col_data[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
403 cf.snap = WTAP_MAX_PACKET_SIZE;
404 else if (cf.snap < MIN_PACKET_SIZE)
405 cf.snap = MIN_PACKET_SIZE;
407 dissect_init(); /* Init anything that needs initializing */
409 if (rfilter != NULL) {
410 if (dfilter_compile(rfilter, &rfcode) != 0) {
411 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
418 err = open_cap_file(cf_name, FALSE, &cf);
423 err = load_cap_file(&cf, out_file_type);
430 /* No capture file specified, so we're supposed to do a live capture;
431 do we have support for live captures? */
433 /* Yes; did the user specify an interface to use? */
434 if (cf.iface == NULL) {
435 /* No - pick the first one from the list of interfaces. */
436 if_list = get_interface_list(&err, err_str);
437 if (if_list == NULL) {
440 case CANT_GET_INTERFACE_LIST:
441 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
445 case NO_INTERFACES_FOUND:
446 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
451 cf.iface = g_strdup(if_list->data); /* first interface */
452 free_interface_list(if_list);
454 capture(packet_count, out_file_type);
457 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
468 /* Do the low-level work of a capture.
469 Returns TRUE if it succeeds, FALSE otherwise. */
471 capture(int packet_count, int out_file_type)
473 gchar err_str[PCAP_ERRBUF_SIZE];
474 bpf_u_int32 netnum, netmask;
475 void (*oldhandler)(int);
479 /* Initialize the table of conversations. */
482 /* Initialize protocol-specific variables */
483 init_all_protocols();
485 ld.linktype = WTAP_ENCAP_UNKNOWN;
488 /* Open the network interface to capture from it. */
489 ld.pch = pcap_open_live(cf.iface, cf.snap, 1, 1000, err_str);
491 if (ld.pch == NULL) {
492 /* Well, we couldn't start the capture.
493 If this is a child process that does the capturing in sync
494 mode or fork mode, it shouldn't do any UI stuff until we pop up the
495 capture-progress window, and, since we couldn't start the
496 capture, we haven't popped it up. */
497 snprintf(errmsg, sizeof errmsg,
498 "The capture session could not be initiated (%s).\n"
499 "Please check to make sure you have sufficient permissions, and that\n"
500 "you have the proper interface specified.", err_str);
505 /* A capture filter was specified; set it up. */
506 if (pcap_lookupnet (cf.iface, &netnum, &netmask, err_str) < 0) {
507 snprintf(errmsg, sizeof errmsg,
508 "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
511 if (pcap_compile(ld.pch, &cf.fcode, cf.cfilter, 1, netmask) < 0) {
512 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
513 pcap_geterr(ld.pch));
516 if (pcap_setfilter(ld.pch, &cf.fcode) < 0) {
517 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
518 pcap_geterr(ld.pch));
523 ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(ld.pch));
524 if (cf.save_file != NULL) {
525 /* Set up to write to the capture file. */
526 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
527 strcpy(errmsg, "The network you're capturing from is of a type"
528 " that Tethereal doesn't support.");
531 ld.pdh = wtap_dump_open(cf.save_file, out_file_type,
532 ld.linktype, pcap_snapshot(ld.pch), &err);
534 if (ld.pdh == NULL) {
535 /* We couldn't set up to write to the capture file. */
538 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
539 strcpy(errmsg, "Tethereal does not support writing capture files in that format.");
542 case WTAP_ERR_UNSUPPORTED_ENCAP:
543 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
544 strcpy(errmsg, "Tethereal cannot save this capture in that format.");
547 case WTAP_ERR_CANT_OPEN:
548 strcpy(errmsg, "The file to which the capture would be written"
549 " couldn't be created for some unknown reason.");
552 case WTAP_ERR_SHORT_WRITE:
553 strcpy(errmsg, "A full header couldn't be written to the file"
554 " to which the capture would be written.");
559 sprintf(errmsg, "The file to which the capture would be"
560 " written (\"%s\") could not be opened: Error %d.",
563 sprintf(errmsg, "The file to which the capture would be"
564 " written (\"%s\") could not be opened: %s.",
565 cf.save_file, strerror(err));
573 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
575 XXX - deal with signal semantics on various platforms. Or just
576 use "sigaction()" and be done with it? */
577 signal(SIGTERM, capture_cleanup);
578 signal(SIGINT, capture_cleanup);
580 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
581 signal(SIGHUP, oldhandler);
584 /* Let the user know what interface was chosen. */
585 printf("Capturing on %s\n", cf.iface);
587 inpkts = pcap_loop(ld.pch, packet_count, capture_pcap_cb, (u_char *) &ld);
593 g_free(cf.save_file);
595 fprintf(stderr, "tethereal: %s\n", errmsg);
603 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
606 struct wtap_pkthdr whdr;
607 loop_data *ld = (loop_data *) user;
610 whdr.ts.tv_sec = phdr->ts.tv_sec;
611 whdr.ts.tv_usec = phdr->ts.tv_usec;
612 whdr.caplen = phdr->caplen;
613 whdr.len = phdr->len;
614 whdr.pkt_encap = ld->linktype;
619 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, pd);
621 printf("\r%u ", cf.count);
624 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, pd);
629 capture_cleanup(int signum)
636 wtap_dump_close(ld.pdh, &err);
637 /* XXX - complain if this fails */
640 #endif /* HAVE_LIBPCAP */
643 load_cap_file(capture_file *cf, int out_file_type)
651 linktype = wtap_file_encap(cf->wth);
652 if (cf->save_file != NULL) {
653 /* Set up to write to the capture file. */
654 pdh = wtap_dump_open(cf->save_file, out_file_type,
655 linktype, wtap_snapshot_length(cf->wth), &err);
658 /* We couldn't set up to write to the capture file. */
661 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
663 "tethereal: Capture files can't be written in that format.\n");
666 case WTAP_ERR_UNSUPPORTED_ENCAP:
667 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
669 "tethereal: The capture file being read cannot be written in that format.\n");
672 case WTAP_ERR_CANT_OPEN:
674 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
678 case WTAP_ERR_SHORT_WRITE:
680 "tethereal: A full header couldn't be written to the file \"%s\".\n",
687 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
691 "tethereal: The file \"%s\" could not be opened: %s\n.",
692 cf->save_file, strerror(err));
700 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
705 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
709 /* Print up a message box noting that the read failed somewhere along
713 case WTAP_ERR_UNSUPPORTED_ENCAP:
715 "tethereal: The capture file is for a network type that Tethereal doesn't support.\n");
718 case WTAP_ERR_CANT_READ:
720 "tethereal: An attempt to read from the file failed for some unknown reason.\n");
723 case WTAP_ERR_SHORT_READ:
725 "tethereal: The capture file appears to have been cut short in the middle of a packet.\n");
728 case WTAP_ERR_BAD_RECORD:
730 "tethereal: The capture file appears to be damaged or corrupt.\n");
735 "tethereal: An error occurred while reading the capture file: %s.\n",
749 fill_in_fdata(frame_data *fdata, capture_file *cf,
750 const struct wtap_pkthdr *phdr, int offset)
756 fdata->pkt_len = phdr->len;
757 fdata->cap_len = phdr->caplen;
758 fdata->file_off = offset;
759 fdata->lnk_t = phdr->pkt_encap;
760 fdata->abs_secs = phdr->ts.tv_sec;
761 fdata->abs_usecs = phdr->ts.tv_usec;
762 fdata->flags.encoding = CHAR_ASCII;
763 fdata->flags.visited = 0;
764 fdata->pseudo_header = phdr->pseudo_header;
767 fdata->num = cf->count;
769 /* If we don't have the time stamp of the first packet in the
770 capture, it's because this is the first packet. Save the time
771 stamp of this packet as the time stamp of the first packet. */
772 if (!firstsec && !firstusec) {
773 firstsec = fdata->abs_secs;
774 firstusec = fdata->abs_usecs;
777 /* Get the time elapsed between the first packet and this packet. */
778 cf->esec = fdata->abs_secs - firstsec;
779 if (firstusec <= fdata->abs_usecs) {
780 cf->eusec = fdata->abs_usecs - firstusec;
782 cf->eusec = (fdata->abs_usecs + 1000000) - firstusec;
786 /* If we don't have the time stamp of the previous displayed packet,
787 it's because this is the first displayed packet. Save the time
788 stamp of this packet as the time stamp of the previous displayed
790 if (!prevsec && !prevusec) {
791 prevsec = fdata->abs_secs;
792 prevusec = fdata->abs_usecs;
795 /* Get the time elapsed between the first packet and this packet. */
796 fdata->rel_secs = cf->esec;
797 fdata->rel_usecs = cf->eusec;
799 /* Get the time elapsed between the previous displayed packet and
801 fdata->del_secs = fdata->abs_secs - prevsec;
802 if (prevusec <= fdata->abs_usecs) {
803 fdata->del_usecs = fdata->abs_usecs - prevusec;
805 fdata->del_usecs = (fdata->abs_usecs + 1000000) - prevusec;
808 prevsec = fdata->abs_secs;
809 prevusec = fdata->abs_usecs;
811 fdata->cinfo = &cf->cinfo;
812 for (i = 0; i < fdata->cinfo->num_cols; i++) {
813 fdata->cinfo->col_data[i][0] = '\0';
818 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
821 cb_args_t *args = (cb_args_t *) user;
822 capture_file *cf = args->cf;
823 wtap_dumper *pdh = args->pdh;
825 proto_tree *protocol_tree;
831 fill_in_fdata(&fdata, cf, phdr, offset);
832 protocol_tree = proto_tree_create_root();
833 dissect_packet(buf, &fdata, protocol_tree);
834 passed = dfilter_apply(cf->rfcode, protocol_tree, buf);
836 protocol_tree = NULL;
840 /* XXX - do something if this fails */
841 wtap_dump(pdh, phdr, buf, &err);
843 if (protocol_tree != NULL)
844 proto_tree_free(protocol_tree);
848 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
851 cb_args_t *args = (cb_args_t *) user;
852 capture_file *cf = args->cf;
854 proto_tree *protocol_tree;
856 print_args_t print_args;
860 fill_in_fdata(&fdata, cf, phdr, offset);
863 if (cf->rfcode || verbose)
864 protocol_tree = proto_tree_create_root();
866 protocol_tree = NULL;
867 dissect_packet(buf, &fdata, protocol_tree);
869 passed = dfilter_apply(cf->rfcode, protocol_tree, buf);
871 /* The packet passed the read filter. */
873 /* Print the information in the protocol tree. */
874 print_args.to_file = TRUE;
875 print_args.format = PR_FMT_TEXT;
876 print_args.print_summary = FALSE;
877 print_args.print_hex = print_hex;
878 print_args.expand_all = TRUE;
879 proto_tree_print(FALSE, &print_args, (GNode *)protocol_tree,
880 buf, &fdata, stdout);
882 /* "print_hex_data()" will put out a leading blank line, as well
883 as a trailing one; print one here, to separate the packets,
884 only if "print_hex_data()" won't be called. */
888 /* Just fill in the columns. */
889 fill_in_columns(&fdata);
890 if (cf->iface == NULL) {
891 printf("%3s %10s %12s -> %-12s %s %s\n",
892 col_info(&fdata, COL_NUMBER),
893 col_info(&fdata, COL_CLS_TIME),
894 col_info(&fdata, COL_DEF_SRC),
895 col_info(&fdata, COL_DEF_DST),
896 col_info(&fdata, COL_PROTOCOL),
897 col_info(&fdata, COL_INFO));
899 printf("%12s -> %-12s %s %s\n",
900 col_info(&fdata, COL_DEF_SRC),
901 col_info(&fdata, COL_DEF_DST),
902 col_info(&fdata, COL_PROTOCOL),
903 col_info(&fdata, COL_INFO));
907 print_hex_data(stdout, print_args.format, buf,
908 fdata.cap_len, fdata.flags.encoding);
913 if (protocol_tree != NULL)
914 proto_tree_free(protocol_tree);
918 file_open_error_message(int err, int for_writing)
921 static char errmsg_errno[1024+1];
925 case WTAP_ERR_NOT_REGULAR_FILE:
926 errmsg = "The file \"%s\" is invalid.";
929 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
930 case WTAP_ERR_UNSUPPORTED:
931 /* Seen only when opening a capture file for reading. */
932 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
935 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
936 /* Seen only when opening a capture file for writing. */
937 errmsg = "Tethereal does not support writing capture files in that format.";
940 case WTAP_ERR_UNSUPPORTED_ENCAP:
941 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
943 errmsg = "Tethereal cannot save this capture in that format.";
945 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
948 case WTAP_ERR_BAD_RECORD:
949 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
952 case WTAP_ERR_CANT_OPEN:
954 errmsg = "The file \"%s\" could not be created for some unknown reason.";
956 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
959 case WTAP_ERR_SHORT_READ:
960 errmsg = "The file \"%s\" appears to have been cut short"
961 " in the middle of a packet.";
964 case WTAP_ERR_SHORT_WRITE:
965 errmsg = "A full header couldn't be written to the file \"%s\".";
970 errmsg = "The path to the file \"%s\" does not exist.";
972 errmsg = "The file \"%s\" does not exist.";
977 errmsg = "You do not have permission to create or write to the file \"%s\".";
979 errmsg = "You do not have permission to read the file \"%s\".";
983 sprintf(errmsg_errno, "The file \"%%s\" could not be opened: %s.",
985 errmsg = errmsg_errno;
992 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
999 char err_msg[2048+1];
1001 wth = wtap_open_offline(fname, &err);
1005 /* Find the size of the file. */
1006 fh = wtap_file(wth);
1008 if (fstat(fd, &cf_stat) < 0) {
1014 /* The open succeeded. Fill in the information for this file. */
1016 /* Initialize the table of conversations. */
1017 conversation_init();
1019 /* Initialize protocol-specific variables */
1020 init_all_protocols();
1025 cf->f_len = cf_stat.st_size;
1027 /* Set the file name because we need it to set the follow stream filter.
1028 XXX - is that still true? We need it for other reasons, though,
1030 cf->filename = g_strdup(fname);
1032 /* Indicate whether it's a permanent or temporary file. */
1033 cf->is_tempfile = is_tempfile;
1035 /* If it's a temporary capture buffer file, mark it as not saved. */
1036 cf->user_saved = !is_tempfile;
1038 cf->cd_t = wtap_file_type(cf->wth);
1043 cf->snap = wtap_snapshot_length(cf->wth);
1044 cf->update_progbar = FALSE;
1045 cf->progbar_quantum = 0;
1046 cf->progbar_nextstep = 0;
1047 firstsec = 0, firstusec = 0;
1048 prevsec = 0, prevusec = 0;
1053 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1054 fprintf(stderr, "tethereal: %s\n", err_msg);
1058 /* Get the text in a given column */
1060 col_info(frame_data *fd, gint el) {
1064 for (i = 0; i < fd->cinfo->num_cols; i++) {
1065 if (fd->cinfo->fmt_matx[i][el])
1066 return fd->cinfo->col_data[i];