3 * $Id: tethereal.c,v 1.35 2000/07/09 03:29:29 guy 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.
41 #include <sys/types.h>
46 #ifdef NEED_SNPRINTF_H
52 # include "snprintf.h"
55 #if defined(HAVE_UCD_SNMP_SNMP_H)
56 #ifdef HAVE_UCD_SNMP_VERSION_H
57 #include <ucd-snmp/version.h>
58 #endif /* HAVE_UCD_SNMP_VERSION_H */
59 #elif defined(HAVE_SNMP_SNMP_H)
60 #ifdef HAVE_SNMP_VERSION_H
61 #include <snmp/version.h>
62 #endif /* HAVE_SNMP_VERSION_H */
65 #ifdef NEED_STRERROR_H
74 #include "timestamp.h"
84 #include "conversation.h"
87 static guint32 firstsec, firstusec;
88 static guint32 prevsec, prevusec;
89 static gchar comp_info_str[256];
90 static gboolean verbose;
91 static gboolean print_hex;
94 typedef struct _loop_data {
102 static int capture(int, int);
103 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
105 static void capture_cleanup(int);
113 static int load_cap_file(capture_file *, int);
114 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, int,
115 union wtap_pseudo_header *, const u_char *);
116 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, int,
117 union wtap_pseudo_header *, const u_char *);
118 static gchar *col_info(frame_data *, gint);
122 FILE *data_out_file = NULL;
123 guint main_ctx, file_ctx;
124 ts_type timestamp_type = RELATIVE;
131 fprintf(stderr, "This is GNU t%s %s, compiled with %s\n", PACKAGE,
132 VERSION, comp_info_str);
134 fprintf(stderr, "t%s [ -vVh ] [ -c count ] [ -D ] [ -f <capture filter> ]\n", PACKAGE);
135 fprintf(stderr, "\t[ -F <capture file type> ] [ -i interface ] [ -n ]\n");
136 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
137 fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
139 fprintf(stderr, "t%s [ -vVh ] [ -D ] [ -F <capture file type> ] [ -n ]\n", PACKAGE);
140 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
141 fprintf(stderr, "\t[ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
143 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
144 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
145 if (wtap_dump_can_open(i))
146 fprintf(stderr, "\t%s - %s\n",
147 wtap_file_type_short_string(i), wtap_file_type_string(i));
149 fprintf(stderr, "\tdefault is libpcap\n");
153 main(int argc, char *argv[])
157 gboolean arg_error = FALSE;
160 char pcap_version[] = "0.4a6";
162 extern char pcap_version[];
165 char *gpf_path, *pf_path;
166 int gpf_open_errno, pf_open_errno;
169 gboolean capture_filter_specified = FALSE;
170 int packet_count = 0;
172 gchar err_str[PCAP_ERRBUF_SIZE];
174 gboolean capture_option_specified = FALSE;
176 int out_file_type = WTAP_FILE_PCAP;
177 gchar *cf_name = NULL, *rfilter = NULL;
178 dfilter *rfcode = NULL;
181 /* Register all dissectors; we must do this before checking for the
182 "-G" flag, as the "-G" flag dumps a list of fields registered
183 by the dissectors, and we must do it before we read the preferences,
184 in case any dissectors register preferences. */
187 /* Now register the preferences for any non-dissector modules.
188 We must do that before we read the preferences as well. */
189 prefs_register_modules();
191 /* If invoked with the "-G" flag, we dump out a glossary of
192 display filter symbols.
194 We do this here to mirror what happens in the GTK+ version, although
195 it's not necessary here. */
196 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
197 proto_registrar_dump();
201 /* Set the C-language locale to the native environment. */
202 setlocale(LC_ALL, "");
204 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
205 if (gpf_path != NULL) {
206 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
207 strerror(gpf_open_errno));
209 if (pf_path != NULL) {
210 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
211 strerror(pf_open_errno));
214 /* Initialize the capture file struct */
216 cfile.plist_end = NULL;
218 cfile.filename = NULL;
219 cfile.user_saved = FALSE;
220 cfile.is_tempfile = FALSE;
222 cfile.dfilter = NULL;
225 cfile.cfilter = g_strdup("");
228 cfile.save_file = NULL;
229 cfile.save_file_fd = -1;
230 cfile.snap = WTAP_MAX_PACKET_SIZE;
232 cfile.cinfo.num_cols = prefs->num_cols;
233 cfile.cinfo.col_fmt = (gint *) g_malloc(sizeof(gint) * cfile.cinfo.num_cols);
234 cfile.cinfo.fmt_matx = (gboolean **) g_malloc(sizeof(gboolean *) * cfile.cinfo.num_cols);
235 cfile.cinfo.col_width = (gint *) g_malloc(sizeof(gint) * cfile.cinfo.num_cols);
236 cfile.cinfo.col_title = (gchar **) g_malloc(sizeof(gchar *) * cfile.cinfo.num_cols);
237 cfile.cinfo.col_data = (gchar **) g_malloc(sizeof(gchar *) * cfile.cinfo.num_cols);
239 /* Assemble the compile-time options */
240 snprintf(comp_info_str, 256,
241 #ifdef GTK_MAJOR_VERSION
242 "GTK+ %d.%d.%d, %s%s, %s%s, %s%s", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
245 "GTK+ (version unknown), %s%s, %s%s, %s%s",
249 "with libpcap ", pcap_version,
251 "without libpcap", "",
256 "with libz ", ZLIB_VERSION,
257 #else /* ZLIB_VERSION */
258 "with libz ", "(version unknown)",
259 #endif /* ZLIB_VERSION */
260 #else /* HAVE_LIBZ */
262 #endif /* HAVE_LIBZ */
264 /* Oh, this is pretty */
265 #if defined(HAVE_UCD_SNMP_SNMP_H)
266 #ifdef HAVE_UCD_SNMP_VERSION_H
267 "with UCD SNMP ", VersionInfo
268 #else /* HAVE_UCD_SNMP_VERSION_H */
269 "with UCD SNMP ", "(version unknown)"
270 #endif /* HAVE_UCD_SNMP_VERSION_H */
271 #elif defined(HAVE_SNMP_SNMP_H)
272 #ifdef HAVE_SNMP_VERSION_H
273 "with CMU SNMP ", snmp_Version()
274 #else /* HAVE_SNMP_VERSION_H */
275 "with CMU SNMP ", "(version unknown)"
276 #endif /* HAVE_SNMP_VERSION_H */
282 /* Now get our args */
283 while ((opt = getopt(argc, argv, "c:Df:F:hi:no:r:R:s:t:vw:Vx")) != EOF) {
285 case 'c': /* Capture xxx packets */
287 packet_count = atoi(optarg);
289 capture_option_specified = TRUE;
293 case 'D': /* Turn off DSCP printing */
294 g_ip_dscp_actif = FALSE;
298 capture_filter_specified = TRUE;
299 cfile.cfilter = g_strdup(optarg);
301 capture_option_specified = TRUE;
306 out_file_type = wtap_short_string_to_file_type(optarg);
307 if (out_file_type < 0) {
308 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
313 case 'h': /* Print help and exit */
317 case 'i': /* Use interface xxx */
319 cfile.iface = g_strdup(optarg);
321 capture_option_specified = TRUE;
325 case 'n': /* No name resolution */
326 g_resolving_actif = 0;
328 case 'o': /* Override preference from command line */
329 switch (prefs_set_pref(optarg)) {
331 case PREFS_SET_SYNTAX_ERR:
332 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
336 case PREFS_SET_NO_SUCH_PREF:
337 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
343 case 'r': /* Read capture file xxx */
344 cf_name = g_strdup(optarg);
346 case 'R': /* Read file filter */
349 case 's': /* Set the snapshot (capture) length */
351 cfile.snap = atoi(optarg);
353 capture_option_specified = TRUE;
357 case 't': /* Time stamp type */
358 if (strcmp(optarg, "r") == 0)
359 timestamp_type = RELATIVE;
360 else if (strcmp(optarg, "a") == 0)
361 timestamp_type = ABSOLUTE;
362 else if (strcmp(optarg, "d") == 0)
363 timestamp_type = DELTA;
365 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
367 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
368 fprintf(stderr, "or \"d\" for delta.\n");
372 case 'v': /* Show version and exit */
373 printf("t%s %s, with %s\n", PACKAGE, VERSION, comp_info_str);
376 case 'w': /* Write to capture file xxx */
377 cfile.save_file = g_strdup(optarg);
379 case 'V': /* Verbose */
382 case 'x': /* Print packet data in hex (and ASCII) */
388 /* If no capture filter or read filter has been specified, and there are
389 still command-line arguments, treat them as the tokens of a capture
390 filter (if no "-r" flag was specified) or a read filter (if a "-r"
391 flag was specified. */
393 if (cf_name != NULL) {
394 if (rfilter != NULL) {
396 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
399 rfilter = get_args_as_string(argc, argv, optind);
402 if (capture_filter_specified) {
404 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
407 cfile.cfilter = get_args_as_string(argc, argv, optind);
409 capture_option_specified = TRUE;
414 /* Notify all registered modules that have had any of their preferences
415 changed either from one of the preferences file or from the command
416 line that its preferences have changed. */
420 if (capture_option_specified)
421 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
426 /* Build the column format array */
427 for (i = 0; i < cfile.cinfo.num_cols; i++) {
428 cfile.cinfo.col_fmt[i] = get_column_format(i);
429 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
430 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
432 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
433 if (cfile.cinfo.col_fmt[i] == COL_INFO)
434 cfile.cinfo.col_data[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
436 cfile.cinfo.col_data[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
440 cfile.snap = WTAP_MAX_PACKET_SIZE;
441 else if (cfile.snap < MIN_PACKET_SIZE)
442 cfile.snap = MIN_PACKET_SIZE;
444 if (rfilter != NULL) {
445 if (dfilter_compile(rfilter, &rfcode) != 0) {
446 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
451 cfile.rfcode = rfcode;
453 err = open_cap_file(cf_name, FALSE, &cfile);
458 err = load_cap_file(&cfile, out_file_type);
465 /* No capture file specified, so we're supposed to do a live capture;
466 do we have support for live captures? */
468 /* Yes; did the user specify an interface to use? */
469 if (cfile.iface == NULL) {
470 /* No - pick the first one from the list of interfaces. */
471 if_list = get_interface_list(&err, err_str);
472 if (if_list == NULL) {
475 case CANT_GET_INTERFACE_LIST:
476 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
480 case NO_INTERFACES_FOUND:
481 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
486 cfile.iface = g_strdup(if_list->data); /* first interface */
487 free_interface_list(if_list);
489 capture(packet_count, out_file_type);
492 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
503 /* Do the low-level work of a capture.
504 Returns TRUE if it succeeds, FALSE otherwise. */
506 capture(int packet_count, int out_file_type)
508 gchar err_str[PCAP_ERRBUF_SIZE];
509 bpf_u_int32 netnum, netmask;
510 void (*oldhandler)(int);
514 /* Initialize the table of conversations. */
517 /* Initialize protocol-specific variables */
518 init_all_protocols();
520 ld.linktype = WTAP_ENCAP_UNKNOWN;
523 /* Open the network interface to capture from it. */
524 ld.pch = pcap_open_live(cfile.iface, cfile.snap, 1, 1000, err_str);
526 if (ld.pch == NULL) {
527 /* Well, we couldn't start the capture.
528 If this is a child process that does the capturing in sync
529 mode or fork mode, it shouldn't do any UI stuff until we pop up the
530 capture-progress window, and, since we couldn't start the
531 capture, we haven't popped it up. */
532 snprintf(errmsg, sizeof errmsg,
533 "The capture session could not be initiated (%s).\n"
534 "Please check to make sure you have sufficient permissions, and that\n"
535 "you have the proper interface specified.", err_str);
540 /* A capture filter was specified; set it up. */
541 if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
542 snprintf(errmsg, sizeof errmsg,
543 "Can't use filter: Couldn't obtain netmask info (%s).", err_str);
546 if (pcap_compile(ld.pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
547 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
548 pcap_geterr(ld.pch));
551 if (pcap_setfilter(ld.pch, &cfile.fcode) < 0) {
552 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
553 pcap_geterr(ld.pch));
558 ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(ld.pch));
559 if (cfile.save_file != NULL) {
560 /* Set up to write to the capture file. */
561 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
562 strcpy(errmsg, "The network you're capturing from is of a type"
563 " that Tethereal doesn't support.");
566 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
567 ld.linktype, pcap_snapshot(ld.pch), &err);
569 if (ld.pdh == NULL) {
570 /* We couldn't set up to write to the capture file. */
573 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
574 strcpy(errmsg, "Tethereal does not support writing capture files in that format.");
577 case WTAP_ERR_UNSUPPORTED_ENCAP:
578 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
579 strcpy(errmsg, "Tethereal cannot save this capture in that format.");
582 case WTAP_ERR_CANT_OPEN:
583 strcpy(errmsg, "The file to which the capture would be written"
584 " couldn't be created for some unknown reason.");
587 case WTAP_ERR_SHORT_WRITE:
588 strcpy(errmsg, "A full header couldn't be written to the file"
589 " to which the capture would be written.");
594 sprintf(errmsg, "The file to which the capture would be"
595 " written (\"%s\") could not be opened: Error %d.",
596 cfile.save_file, err);
598 sprintf(errmsg, "The file to which the capture would be"
599 " written (\"%s\") could not be opened: %s.",
600 cfile.save_file, strerror(err));
608 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
610 XXX - deal with signal semantics on various platforms. Or just
611 use "sigaction()" and be done with it? */
612 signal(SIGTERM, capture_cleanup);
613 signal(SIGINT, capture_cleanup);
615 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
616 signal(SIGHUP, oldhandler);
619 /* Let the user know what interface was chosen. */
620 printf("Capturing on %s\n", cfile.iface);
622 inpkts = pcap_loop(ld.pch, packet_count, capture_pcap_cb, (u_char *) &ld);
628 g_free(cfile.save_file);
629 cfile.save_file = NULL;
630 fprintf(stderr, "tethereal: %s\n", errmsg);
638 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
641 struct wtap_pkthdr whdr;
642 loop_data *ld = (loop_data *) user;
645 whdr.ts.tv_sec = phdr->ts.tv_sec;
646 whdr.ts.tv_usec = phdr->ts.tv_usec;
647 whdr.caplen = phdr->caplen;
648 whdr.len = phdr->len;
649 whdr.pkt_encap = ld->linktype;
654 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
656 printf("\r%u ", cfile.count);
659 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
664 capture_cleanup(int signum)
671 wtap_dump_close(ld.pdh, &err);
672 /* XXX - complain if this fails */
675 #endif /* HAVE_LIBPCAP */
678 load_cap_file(capture_file *cf, int out_file_type)
686 linktype = wtap_file_encap(cf->wth);
687 if (cf->save_file != NULL) {
688 /* Set up to write to the capture file. */
689 pdh = wtap_dump_open(cf->save_file, out_file_type,
690 linktype, wtap_snapshot_length(cf->wth), &err);
693 /* We couldn't set up to write to the capture file. */
696 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
698 "tethereal: Capture files can't be written in that format.\n");
701 case WTAP_ERR_UNSUPPORTED_ENCAP:
702 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
704 "tethereal: The capture file being read cannot be written in that format.\n");
707 case WTAP_ERR_CANT_OPEN:
709 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
713 case WTAP_ERR_SHORT_WRITE:
715 "tethereal: A full header couldn't be written to the file \"%s\".\n",
722 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
726 "tethereal: The file \"%s\" could not be opened: %s\n.",
727 cf->save_file, strerror(err));
735 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
740 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
744 /* Print up a message box noting that the read failed somewhere along
748 case WTAP_ERR_UNSUPPORTED_ENCAP:
750 "tethereal: The capture file is for a network type that Tethereal doesn't support.\n");
753 case WTAP_ERR_CANT_READ:
755 "tethereal: An attempt to read from the file failed for some unknown reason.\n");
758 case WTAP_ERR_SHORT_READ:
760 "tethereal: The capture file appears to have been cut short in the middle of a packet.\n");
763 case WTAP_ERR_BAD_RECORD:
765 "tethereal: The capture file appears to be damaged or corrupt.\n");
770 "tethereal: An error occurred while reading the capture file: %s.\n",
784 fill_in_fdata(frame_data *fdata, capture_file *cf,
785 const struct wtap_pkthdr *phdr,
786 const union wtap_pseudo_header *pseudo_header, int offset)
792 fdata->pkt_len = phdr->len;
793 fdata->cap_len = phdr->caplen;
794 fdata->file_off = offset;
795 fdata->lnk_t = phdr->pkt_encap;
796 fdata->abs_secs = phdr->ts.tv_sec;
797 fdata->abs_usecs = phdr->ts.tv_usec;
798 fdata->flags.encoding = CHAR_ASCII;
799 fdata->flags.visited = 0;
802 fdata->num = cf->count;
804 /* If we don't have the time stamp of the first packet in the
805 capture, it's because this is the first packet. Save the time
806 stamp of this packet as the time stamp of the first packet. */
807 if (!firstsec && !firstusec) {
808 firstsec = fdata->abs_secs;
809 firstusec = fdata->abs_usecs;
812 /* Get the time elapsed between the first packet and this packet. */
813 cf->esec = fdata->abs_secs - firstsec;
814 if (firstusec <= fdata->abs_usecs) {
815 cf->eusec = fdata->abs_usecs - firstusec;
817 cf->eusec = (fdata->abs_usecs + 1000000) - firstusec;
821 /* If we don't have the time stamp of the previous displayed packet,
822 it's because this is the first displayed packet. Save the time
823 stamp of this packet as the time stamp of the previous displayed
825 if (!prevsec && !prevusec) {
826 prevsec = fdata->abs_secs;
827 prevusec = fdata->abs_usecs;
830 /* Get the time elapsed between the first packet and this packet. */
831 fdata->rel_secs = cf->esec;
832 fdata->rel_usecs = cf->eusec;
834 /* Get the time elapsed between the previous displayed packet and
836 fdata->del_secs = fdata->abs_secs - prevsec;
837 if (prevusec <= fdata->abs_usecs) {
838 fdata->del_usecs = fdata->abs_usecs - prevusec;
840 fdata->del_usecs = (fdata->abs_usecs + 1000000) - prevusec;
843 prevsec = fdata->abs_secs;
844 prevusec = fdata->abs_usecs;
846 fdata->cinfo = &cf->cinfo;
847 for (i = 0; i < fdata->cinfo->num_cols; i++) {
848 fdata->cinfo->col_data[i][0] = '\0';
853 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
854 union wtap_pseudo_header *pseudo_header, const u_char *buf)
856 cb_args_t *args = (cb_args_t *) user;
857 capture_file *cf = args->cf;
858 wtap_dumper *pdh = args->pdh;
860 proto_tree *protocol_tree;
866 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
867 protocol_tree = proto_tree_create_root();
868 dissect_packet(pseudo_header, buf, &fdata, protocol_tree);
869 passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
871 protocol_tree = NULL;
875 /* XXX - do something if this fails */
876 wtap_dump(pdh, phdr, pseudo_header, buf, &err);
878 if (protocol_tree != NULL)
879 proto_tree_free(protocol_tree);
883 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
884 union wtap_pseudo_header *pseudo_header, const u_char *buf)
886 cb_args_t *args = (cb_args_t *) user;
887 capture_file *cf = args->cf;
889 proto_tree *protocol_tree;
891 print_args_t print_args;
895 /* The protocol tree will be "visible", i.e., printed, only if we're
896 not printing a summary. */
897 proto_tree_is_visible = verbose;
899 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
902 if (cf->rfcode || verbose)
903 protocol_tree = proto_tree_create_root();
905 protocol_tree = NULL;
906 dissect_packet(pseudo_header, buf, &fdata, protocol_tree);
908 passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
910 /* The packet passed the read filter. */
912 /* Print the information in the protocol tree. */
913 print_args.to_file = TRUE;
914 print_args.format = PR_FMT_TEXT;
915 print_args.print_summary = FALSE;
916 print_args.print_hex = print_hex;
917 print_args.expand_all = TRUE;
918 proto_tree_print(FALSE, &print_args, (GNode *)protocol_tree,
919 buf, &fdata, stdout);
921 /* "print_hex_data()" will put out a leading blank line, as well
922 as a trailing one; print one here, to separate the packets,
923 only if "print_hex_data()" won't be called. */
927 /* Just fill in the columns. */
928 fill_in_columns(&fdata);
929 if (cf->iface == NULL) {
930 printf("%3s %10s %12s -> %-12s %s %s\n",
931 col_info(&fdata, COL_NUMBER),
932 col_info(&fdata, COL_CLS_TIME),
933 col_info(&fdata, COL_DEF_SRC),
934 col_info(&fdata, COL_DEF_DST),
935 col_info(&fdata, COL_PROTOCOL),
936 col_info(&fdata, COL_INFO));
938 printf("%12s -> %-12s %s %s\n",
939 col_info(&fdata, COL_DEF_SRC),
940 col_info(&fdata, COL_DEF_DST),
941 col_info(&fdata, COL_PROTOCOL),
942 col_info(&fdata, COL_INFO));
946 print_hex_data(stdout, print_args.format, buf,
947 fdata.cap_len, fdata.flags.encoding);
952 if (protocol_tree != NULL)
953 proto_tree_free(protocol_tree);
955 proto_tree_is_visible = FALSE;
959 file_open_error_message(int err, int for_writing)
962 static char errmsg_errno[1024+1];
966 case WTAP_ERR_NOT_REGULAR_FILE:
967 errmsg = "The file \"%s\" is invalid.";
970 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
971 case WTAP_ERR_UNSUPPORTED:
972 /* Seen only when opening a capture file for reading. */
973 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
976 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
977 /* Seen only when opening a capture file for writing. */
978 errmsg = "Tethereal does not support writing capture files in that format.";
981 case WTAP_ERR_UNSUPPORTED_ENCAP:
982 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
984 errmsg = "Tethereal cannot save this capture in that format.";
986 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
989 case WTAP_ERR_BAD_RECORD:
990 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
993 case WTAP_ERR_CANT_OPEN:
995 errmsg = "The file \"%s\" could not be created for some unknown reason.";
997 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1000 case WTAP_ERR_SHORT_READ:
1001 errmsg = "The file \"%s\" appears to have been cut short"
1002 " in the middle of a packet.";
1005 case WTAP_ERR_SHORT_WRITE:
1006 errmsg = "A full header couldn't be written to the file \"%s\".";
1011 errmsg = "The path to the file \"%s\" does not exist.";
1013 errmsg = "The file \"%s\" does not exist.";
1018 errmsg = "You do not have permission to create or write to the file \"%s\".";
1020 errmsg = "You do not have permission to read the file \"%s\".";
1024 sprintf(errmsg_errno, "The file \"%%s\" could not be opened: %s.",
1025 wtap_strerror(err));
1026 errmsg = errmsg_errno;
1033 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1039 struct stat cf_stat;
1040 char err_msg[2048+1];
1042 wth = wtap_open_offline(fname, &err, FALSE);
1046 /* Find the size of the file. */
1047 fh = wtap_file(wth);
1049 if (fstat(fd, &cf_stat) < 0) {
1055 /* The open succeeded. Fill in the information for this file. */
1057 /* Initialize the table of conversations. */
1058 conversation_init();
1060 /* Initialize protocol-specific variables */
1061 init_all_protocols();
1065 cf->f_len = cf_stat.st_size;
1067 /* Set the file name because we need it to set the follow stream filter.
1068 XXX - is that still true? We need it for other reasons, though,
1070 cf->filename = g_strdup(fname);
1072 /* Indicate whether it's a permanent or temporary file. */
1073 cf->is_tempfile = is_tempfile;
1075 /* If it's a temporary capture buffer file, mark it as not saved. */
1076 cf->user_saved = !is_tempfile;
1078 cf->cd_t = wtap_file_type(cf->wth);
1083 cf->snap = wtap_snapshot_length(cf->wth);
1084 cf->progbar_quantum = 0;
1085 cf->progbar_nextstep = 0;
1086 firstsec = 0, firstusec = 0;
1087 prevsec = 0, prevusec = 0;
1092 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1093 fprintf(stderr, "tethereal: %s\n", err_msg);
1097 /* Get the text in a given column */
1099 col_info(frame_data *fd, gint el) {
1103 for (i = 0; i < fd->cinfo->num_cols; i++) {
1104 if (fd->cinfo->fmt_matx[i][el])
1105 return fd->cinfo->col_data[i];