3 * $Id: tethereal.c,v 1.104 2001/12/10 00:25:41 guy Exp $
5 * Ethereal - Network traffic analyzer
6 * By Gerald Combs <gerald@ethereal.com>
7 * Copyright 1998 Gerald Combs
9 * Text-mode variant, by Gilbert Ramirez <gram@alumni.rice.edu>
10 * and Guy Harris <guy@alum.mit.edu>.
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #ifdef HAVE_SYS_TYPES_H
45 #include <sys/types.h>
48 #ifdef HAVE_SYS_STAT_H
63 #include <zlib.h> /* to get the libz version number */
66 #ifdef NEED_SNPRINTF_H
67 # include "snprintf.h"
70 #if defined(HAVE_UCD_SNMP_SNMP_H)
71 #ifdef HAVE_UCD_SNMP_VERSION_H
72 #include <ucd-snmp/version.h>
73 #endif /* HAVE_UCD_SNMP_VERSION_H */
74 #elif defined(HAVE_SNMP_SNMP_H)
75 #ifdef HAVE_SNMP_VERSION_H
76 #include <snmp/version.h>
77 #endif /* HAVE_SNMP_VERSION_H */
80 #ifdef NEED_STRERROR_H
92 #include "timestamp.h"
101 #include "pcap-util.h"
103 #include "conversation.h"
104 #include "reassemble.h"
106 #include "register.h"
107 #include "conditions.h"
108 #include "capture_stop_conditions.h"
109 #include "ringbuffer.h"
112 #include "capture-wpcap.h"
115 static guint32 firstsec, firstusec;
116 static guint32 prevsec, prevusec;
117 static GString *comp_info_str;
118 static gboolean verbose;
119 static gboolean print_hex;
120 static gboolean line_buffered;
123 typedef struct _loop_data {
132 static int capture(int, 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 FILE *data_out_file = NULL;
152 ts_type timestamp_type = RELATIVE;
154 static int promisc_mode = TRUE;
162 fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
165 fprintf(stderr, "t%s [ -DvVhlp ] [ -a <capture autostop condition> ] ...\n",
167 fprintf(stderr, "\t[ -b <number of ring buffer files> ] [ -c <count> ]\n");
168 fprintf(stderr, "\t[ -f <capture filter> ] [ -F <capture file type> ]\n");
169 fprintf(stderr, "\t[ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
170 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
171 fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
173 fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
174 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
175 fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
177 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
178 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
179 if (wtap_dump_can_open(i))
180 fprintf(stderr, "\t%s - %s\n",
181 wtap_file_type_short_string(i), wtap_file_type_string(i));
183 fprintf(stderr, "\tdefault is libpcap\n");
187 get_positive_int(const char *string, const char *name)
192 number = strtol(string, &p, 10);
193 if (p == string || *p != '\0') {
194 fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
199 fprintf(stderr, "tethereal: The specified %s \"%s\" is a negative number\n",
203 if (number > INT_MAX) {
204 fprintf(stderr, "tethereal: The specified %s \"%s\" is too large (greater than %d)\n",
205 name, string, INT_MAX);
212 * Given a string of the form "<autostop criterion>:<value>", as might appear
213 * as an argument to a "-a" option, parse it and set the criterion in
214 * question. Return an indication of whether it succeeded or failed
218 set_autostop_criterion(const char *autostoparg)
222 colonp = strchr(autostoparg, ':');
230 * Skip over any white space (there probably won't be any, but
231 * as we allow it in the preferences file, we might as well
238 * Put the colon back, so if our caller uses, in an
239 * error message, the string they passed us, the message
245 if (strcmp(autostoparg,"duration") == 0) {
246 cfile.autostop_duration = get_positive_int(p,"autostop duration");
247 } else if (strcmp(autostoparg,"filesize") == 0) {
248 cfile.autostop_filesize = get_positive_int(p,"autostop filesize");
252 *colonp = ':'; /* put the colon back */
257 main(int argc, char *argv[])
261 gboolean arg_error = FALSE;
263 #ifdef HAVE_PCAP_VERSION
264 extern char pcap_version[];
265 #endif /* HAVE_PCAP_VERSION */
266 #endif /* HAVE_LIBPCAP */
274 int gpf_open_errno, pf_open_errno;
277 gboolean capture_filter_specified = FALSE;
278 guint packet_count = 0;
279 GList *if_list, *if_entry;
280 gchar err_str[PCAP_ERRBUF_SIZE];
282 gboolean capture_option_specified = FALSE;
284 int out_file_type = WTAP_FILE_PCAP;
285 gchar *cf_name = NULL, *rfilter = NULL;
286 dfilter_t *rfcode = NULL;
290 /* Register all dissectors; we must do this before checking for the
291 "-G" flag, as the "-G" flag dumps a list of fields registered
292 by the dissectors, and we must do it before we read the preferences,
293 in case any dissectors register preferences. */
294 epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
296 /* Now register the preferences for any non-dissector modules.
297 We must do that before we read the preferences as well. */
298 prefs_register_modules();
300 /* If invoked with the "-G" flag, we dump out a glossary of
301 display filter symbols.
303 We do this here to mirror what happens in the GTK+ version, although
304 it's not necessary here. */
305 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
306 proto_registrar_dump();
310 /* Set the C-language locale to the native environment. */
311 setlocale(LC_ALL, "");
313 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
314 if (gpf_path != NULL) {
315 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
316 strerror(gpf_open_errno));
318 if (pf_path != NULL) {
319 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
320 strerror(pf_open_errno));
324 /* Load Wpcap, if possible */
328 /* Initialize the capture file struct */
330 cfile.plist_end = NULL;
332 cfile.filename = NULL;
333 cfile.user_saved = FALSE;
334 cfile.is_tempfile = FALSE;
336 cfile.dfilter = NULL;
339 cfile.cfilter = g_strdup("");
342 cfile.save_file = NULL;
343 cfile.save_file_fd = -1;
344 cfile.snap = WTAP_MAX_PACKET_SIZE;
347 cfile.autostop_duration = 0;
348 cfile.autostop_filesize = 0;
349 cfile.ringbuffer_on = FALSE;
350 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
352 col_init(&cfile.cinfo, prefs->num_cols);
354 /* Assemble the compile-time options */
355 comp_info_str = g_string_new("");
357 g_string_append(comp_info_str, "with ");
358 g_string_sprintfa(comp_info_str,
359 #ifdef GLIB_MAJOR_VERSION
360 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
363 "GLib (version unknown)");
367 g_string_append(comp_info_str, ", with libpcap ");
368 #ifdef HAVE_PCAP_VERSION
369 g_string_append(comp_info_str, pcap_version);
370 #else /* HAVE_PCAP_VERSION */
371 g_string_append(comp_info_str, "(version unknown)");
372 #endif /* HAVE_PCAP_VERSION */
373 #else /* HAVE_LIBPCAP */
374 g_string_append(comp_info_str, ", without libpcap");
375 #endif /* HAVE_LIBPCAP */
378 g_string_append(comp_info_str, ", with libz ");
380 g_string_append(comp_info_str, ZLIB_VERSION);
381 #else /* ZLIB_VERSION */
382 g_string_append(comp_info_str, "(version unknown)");
383 #endif /* ZLIB_VERSION */
384 #else /* HAVE_LIBZ */
385 g_string_append(comp_info_str, ", without libz");
386 #endif /* HAVE_LIBZ */
388 /* Oh, this is pretty */
389 #if defined(HAVE_UCD_SNMP_SNMP_H)
390 g_string_append(comp_info_str, ", with UCD SNMP ");
391 #ifdef HAVE_UCD_SNMP_VERSION_H
392 g_string_append(comp_info_str, VersionInfo);
393 #else /* HAVE_UCD_SNMP_VERSION_H */
394 g_string_append(comp_info_str, "(version unknown)");
395 #endif /* HAVE_UCD_SNMP_VERSION_H */
396 #elif defined(HAVE_SNMP_SNMP_H)
397 g_string_append(comp_info_str, ", with CMU SNMP ");
398 #ifdef HAVE_SNMP_VERSION_H
399 g_string_append(comp_info_str, snmp_Version());
400 #else /* HAVE_SNMP_VERSION_H */
401 g_string_append(comp_info_str, "(version unknown)");
402 #endif /* HAVE_SNMP_VERSION_H */
404 g_string_append(comp_info_str, ", without SNMP");
407 /* Now get our args */
408 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != EOF) {
410 case 'a': /* autostop criteria */
412 if (set_autostop_criterion(optarg) == FALSE) {
413 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
417 capture_option_specified = TRUE;
421 case 'b': /* Ringbuffer option */
423 cfile.ringbuffer_on = TRUE;
424 /* get optional ringbuffer number of files parameter */
425 if (optarg[0] != '-') {
426 cfile.ringbuffer_num_files = get_positive_int(optarg, "ring buffer number of files");
428 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
432 capture_option_specified = TRUE;
436 case 'c': /* Capture xxx packets */
438 packet_count = get_positive_int(optarg, "packet count");
440 capture_option_specified = TRUE;
444 case 'D': /* Print a list of capture devices */
446 if_list = get_interface_list(&err, err_str);
447 if (if_list == NULL) {
450 case CANT_GET_INTERFACE_LIST:
451 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
455 case NO_INTERFACES_FOUND:
456 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
461 for (if_entry = g_list_first(if_list); if_entry != NULL;
462 if_entry = g_list_next(if_entry))
463 printf("%s\n", (char *)if_entry->data);
464 free_interface_list(if_list);
467 capture_option_specified = TRUE;
473 capture_filter_specified = TRUE;
474 cfile.cfilter = g_strdup(optarg);
476 capture_option_specified = TRUE;
481 out_file_type = wtap_short_string_to_file_type(optarg);
482 if (out_file_type < 0) {
483 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
488 case 'h': /* Print help and exit */
492 case 'i': /* Use interface xxx */
494 cfile.iface = g_strdup(optarg);
496 capture_option_specified = TRUE;
500 case 'l': /* "Line-buffer" standard output */
501 /* This isn't line-buffering, strictly speaking, it's just
502 flushing the standard output after the information for
503 each packet is printed; however, that should be good
504 enough for all the purposes to which "-l" is put.
506 See the comment in "wtap_dispatch_cb_print()" for an
507 explanation of why we do that, and why we don't just
508 use "setvbuf()" to make the standard output line-buffered
509 (short version: in Windows, "line-buffered" is the same
510 as "fully-buffered", and the output buffer is only flushed
511 when it fills up). */
512 line_buffered = TRUE;
514 case 'n': /* No name resolution */
515 prefs->name_resolve = PREFS_RESOLV_NONE;
517 case 'N': /* Select what types of addresses/port #s to resolve */
518 if (prefs->name_resolve == PREFS_RESOLV_ALL)
519 prefs->name_resolve = PREFS_RESOLV_NONE;
520 badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
521 if (badopt != '\0') {
522 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
527 case 'o': /* Override preference from command line */
528 switch (prefs_set_pref(optarg)) {
530 case PREFS_SET_SYNTAX_ERR:
531 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
535 case PREFS_SET_NO_SUCH_PREF:
536 case PREFS_SET_OBSOLETE:
537 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
543 case 'p': /* Don't capture in promiscuous mode */
547 capture_option_specified = TRUE;
551 case 'r': /* Read capture file xxx */
552 cf_name = g_strdup(optarg);
554 case 'R': /* Read file filter */
557 case 's': /* Set the snapshot (capture) length */
559 cfile.snap = get_positive_int(optarg, "snapshot length");
561 capture_option_specified = TRUE;
565 case 't': /* Time stamp type */
566 if (strcmp(optarg, "r") == 0)
567 timestamp_type = RELATIVE;
568 else if (strcmp(optarg, "a") == 0)
569 timestamp_type = ABSOLUTE;
570 else if (strcmp(optarg, "ad") == 0)
571 timestamp_type = ABSOLUTE_WITH_DATE;
572 else if (strcmp(optarg, "d") == 0)
573 timestamp_type = DELTA;
575 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
577 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
578 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
582 case 'v': /* Show version and exit */
583 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
586 case 'w': /* Write to capture file xxx */
587 cfile.save_file = g_strdup(optarg);
589 case 'V': /* Verbose */
592 case 'x': /* Print packet data in hex (and ASCII) */
598 /* If no capture filter or read filter has been specified, and there are
599 still command-line arguments, treat them as the tokens of a capture
600 filter (if no "-r" flag was specified) or a read filter (if a "-r"
601 flag was specified. */
603 if (cf_name != NULL) {
604 if (rfilter != NULL) {
606 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
609 rfilter = get_args_as_string(argc, argv, optind);
612 if (capture_filter_specified) {
614 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
617 cfile.cfilter = get_args_as_string(argc, argv, optind);
619 capture_option_specified = TRUE;
625 /* Start windows sockets */
626 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
629 /* Notify all registered modules that have had any of their preferences
630 changed either from one of the preferences file or from the command
631 line that its preferences have changed. */
635 if (capture_option_specified)
636 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
641 /* Build the column format array */
642 for (i = 0; i < cfile.cinfo.num_cols; i++) {
643 cfile.cinfo.col_fmt[i] = get_column_format(i);
644 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
645 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
647 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
648 cfile.cinfo.col_data[i] = NULL;
649 if (cfile.cinfo.col_fmt[i] == COL_INFO)
650 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
652 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
656 cfile.snap = WTAP_MAX_PACKET_SIZE;
657 else if (cfile.snap < MIN_PACKET_SIZE)
658 cfile.snap = MIN_PACKET_SIZE;
660 if (cfile.ringbuffer_on) {
661 /* Ringbuffer works just under certain conditions:*/
662 if (cfile.save_file == NULL) {
663 /* Ringbuffer does not work with temporary files */
664 fprintf(stderr, "tethereal: Turning ring buffer off (no save file specified).\n");
665 cfile.ringbuffer_on = FALSE;
667 if (cfile.autostop_filesize == 0) {
668 /* It makes no sense to enable the ring buffer if the maximum
669 file size is set to infinite */
670 fprintf(stderr, "tethereal: Turning ring buffer off (file size = 0).\n");
671 cfile.ringbuffer_on = FALSE;
675 /* Check the value range of the ringbuffer_num_files parameter */
676 if (cfile.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
677 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
678 else if (cfile.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
679 cfile.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
681 if (rfilter != NULL) {
682 if (!dfilter_compile(rfilter, &rfcode)) {
683 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
688 cfile.rfcode = rfcode;
690 err = open_cap_file(cf_name, FALSE, &cfile);
695 err = load_cap_file(&cfile, out_file_type);
702 /* No capture file specified, so we're supposed to do a live capture;
703 do we have support for live captures? */
708 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
713 /* Yes; did the user specify an interface to use? */
714 if (cfile.iface == NULL) {
715 /* No - pick the first one from the list of interfaces. */
716 if_list = get_interface_list(&err, err_str);
717 if (if_list == NULL) {
720 case CANT_GET_INTERFACE_LIST:
721 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
725 case NO_INTERFACES_FOUND:
726 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
731 cfile.iface = g_strdup(if_list->data); /* first interface */
732 free_interface_list(if_list);
734 capture(packet_count, out_file_type);
736 if (cfile.ringbuffer_on) {
741 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
752 /* Do the low-level work of a capture.
753 Returns TRUE if it succeeds, FALSE otherwise. */
755 capture(int packet_count, int out_file_type)
757 gchar open_err_str[PCAP_ERRBUF_SIZE];
758 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
759 bpf_u_int32 netnum, netmask;
760 struct bpf_program fcode;
761 void (*oldhandler)(int);
764 condition *cnd_stop_capturesize;
765 condition *cnd_stop_timeout;
767 static const char ppamsg[] = "can't find PPA for ";
770 struct pcap_stat stats;
773 /* Initialize the table of conversations. */
774 epan_conversation_init();
776 /* Initialize protocol-specific variables */
777 init_all_protocols();
779 /* Initialize the common data structures for fragment reassembly.
780 Must be done *after* "init_all_protocols()", as "init_all_protocols()"
781 may free up space for fragments, which it finds by using the
782 data structures that "reassemble_init()" frees. */
785 ld.linktype = WTAP_ENCAP_UNKNOWN;
788 /* Open the network interface to capture from it.
789 Some versions of libpcap may put warnings into the error buffer
790 if they succeed; to tell if that's happened, we have to clear
791 the error buffer, and check if it's still a null string. */
792 open_err_str[0] = '\0';
793 ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000,
796 if (ld.pch == NULL) {
797 /* Well, we couldn't start the capture. */
799 /* On Win32 OSes, the capture devices are probably available to all
800 users; don't warn about permissions problems.
802 Do, however, warn that Token Ring and PPP devices aren't supported. */
803 snprintf(errmsg, sizeof errmsg,
804 "The capture session could not be initiated (%s).\n"
805 "Please check that you have the proper interface specified.\n"
807 "Note that the driver Tethereal uses for packet capture on Windows\n"
808 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
809 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
812 /* If we got a "can't find PPA for XXX" message, warn the user (who
813 is running Ethereal on HP-UX) that they don't have a version
814 of libpcap that properly handles HP-UX (libpcap 0.6.x and later
815 versions, which properly handle HP-UX, say "can't find /dev/dlpi
816 PPA for XXX" rather than "can't find PPA for XXX"). */
817 if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
820 "You are running Tethereal with a version of the libpcap library\n"
821 "that doesn't handle HP-UX network devices well; this means that\n"
822 "Tethereal may not be able to capture packets.\n"
824 "To fix this, you should install libpcap 0.6.2, or a later version\n"
825 "of libpcap, rather than libpcap 0.4 or 0.5.x. It is available in\n"
826 "packaged binary form from the Software Porting And Archive Centre\n"
827 "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
828 "at the URL lists a number of mirror sites.";
831 snprintf(errmsg, sizeof errmsg,
832 "The capture session could not be initiated (%s).\n"
833 "Please check to make sure you have sufficient permissions, and that\n"
834 "you have the proper interface specified.%s", open_err_str, libpcap_warn);
840 /* A capture filter was specified; set it up. */
841 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
843 * Well, we can't get the netmask for this interface; it's used
844 * only for filters that check for broadcast IP addresses, so
845 * we just warn the user, and punt and use 0.
848 "Warning: Couldn't obtain netmask info (%s)\n.", lookup_net_err_str);
851 if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
852 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
853 pcap_geterr(ld.pch));
856 if (pcap_setfilter(ld.pch, &fcode) < 0) {
857 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
858 pcap_geterr(ld.pch));
863 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
865 if (cfile.save_file != NULL) {
866 /* Set up to write to the capture file. */
867 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
868 strcpy(errmsg, "The network you're capturing from is of a type"
869 " that Tethereal doesn't support.");
872 if (cfile.ringbuffer_on) {
873 cfile.save_file_fd = ringbuf_init(cfile.save_file,
874 cfile.ringbuffer_num_files);
875 if (cfile.save_file_fd != -1) {
876 ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
877 pcap_snapshot(ld.pch), &err);
882 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
883 ld.linktype, pcap_snapshot(ld.pch), &err);
886 if (ld.pdh == NULL) {
887 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
893 /* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
894 returned a warning; print it, but keep capturing. */
895 if (open_err_str[0] != '\0')
896 fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
898 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
900 XXX - deal with signal semantics on various platforms. Or just
901 use "sigaction()" and be done with it? */
902 signal(SIGTERM, capture_cleanup);
903 signal(SIGINT, capture_cleanup);
905 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
906 signal(SIGHUP, oldhandler);
909 /* Let the user know what interface was chosen. */
910 fprintf(stderr, "Capturing on %s\n", cfile.iface);
913 /* initialize capture stop conditions */
914 init_capture_stop_conditions();
915 /* create stop conditions */
916 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
917 (long)cfile.autostop_filesize * 1000);
918 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
919 (gint32)cfile.autostop_duration);
921 if (packet_count == 0)
922 packet_count = -1; /* infinite capturng */
925 if (packet_count > 0)
927 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
928 if (packet_count == 0) {
930 } else if (cnd_eval(cnd_stop_timeout) == TRUE) {
932 } else if ((cnd_eval(cnd_stop_capturesize,
933 (guint32)wtap_get_bytes_dumped(ld.pdh))) == TRUE){
934 /* A capture stop condition has become true. */
935 if (cfile.ringbuffer_on) {
936 /* Switch to the next ringbuffer file */
937 if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
938 /* File switch failed: reset the condition */
939 cnd_reset(cnd_stop_capturesize);
941 /* File switch failed: stop here */
946 /* No ringbuffer - just stop. */
952 /* delete stop conditions */
953 cnd_delete(cnd_stop_capturesize);
954 cnd_delete(cnd_stop_timeout);
956 if (cfile.save_file != NULL) {
957 /* We're saving to a file, which means we're printing packet counts
958 to the standard output. Send a newline so that we move to the
959 line after the packet count. */
960 fprintf(stderr, "\n");
963 /* If we got an error while capturing, report it. */
965 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
966 pcap_geterr(ld.pch));
969 /* Get the capture statistics, and, if any packets were dropped, report
971 if (pcap_stats(ld.pch, &stats) >= 0) {
972 if (stats.ps_drop != 0) {
973 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
976 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
977 pcap_geterr(ld.pch));
982 if (cfile.save_file != NULL) {
983 /* We're saving to a file or files; close all files. */
984 if (cfile.ringbuffer_on) {
985 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
987 dump_ok = wtap_dump_close(ld.pdh, &err);
990 show_capture_file_io_error(cfile.save_file, err, TRUE);
996 if (cfile.ringbuffer_on) {
997 ringbuf_error_cleanup();
999 g_free(cfile.save_file);
1000 cfile.save_file = NULL;
1001 fprintf(stderr, "tethereal: %s\n", errmsg);
1009 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1012 struct wtap_pkthdr whdr;
1013 loop_data *ld = (loop_data *) user;
1016 whdr.ts.tv_sec = phdr->ts.tv_sec;
1017 whdr.ts.tv_usec = phdr->ts.tv_usec;
1018 whdr.caplen = phdr->caplen;
1019 whdr.len = phdr->len;
1020 whdr.pkt_encap = ld->linktype;
1025 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1026 fprintf(stderr, "\r%u ", cfile.count);
1029 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1034 capture_cleanup(int signum)
1036 /* Just set the loop flag to false. This will initiate
1037 a proper termination. */
1040 #endif /* HAVE_LIBPCAP */
1043 load_cap_file(capture_file *cf, int out_file_type)
1051 linktype = wtap_file_encap(cf->wth);
1052 if (cf->save_file != NULL) {
1053 /* Set up to write to the capture file. */
1054 pdh = wtap_dump_open(cf->save_file, out_file_type,
1055 linktype, wtap_snapshot_length(cf->wth), &err);
1058 /* We couldn't set up to write to the capture file. */
1061 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1063 "tethereal: Capture files can't be written in that format.\n");
1066 case WTAP_ERR_UNSUPPORTED_ENCAP:
1067 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1069 "tethereal: The capture file being read cannot be written in that format.\n");
1072 case WTAP_ERR_CANT_OPEN:
1074 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1078 case WTAP_ERR_SHORT_WRITE:
1080 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1087 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1088 cf->save_file, err);
1091 "tethereal: The file \"%s\" could not be opened: %s\n.",
1092 cf->save_file, strerror(err));
1100 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1103 /* Now close the capture file. */
1104 if (!wtap_dump_close(pdh, &err))
1105 show_capture_file_io_error(cfile.save_file, err, TRUE);
1109 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1113 /* Print up a message box noting that the read failed somewhere along
1117 case WTAP_ERR_UNSUPPORTED_ENCAP:
1119 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1123 case WTAP_ERR_CANT_READ:
1125 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1129 case WTAP_ERR_SHORT_READ:
1131 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1135 case WTAP_ERR_BAD_RECORD:
1137 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1143 "tethereal: An error occurred while reading \"%s\": %s.\n",
1144 cf->filename, wtap_strerror(err));
1150 wtap_close(cf->wth);
1157 fill_in_fdata(frame_data *fdata, capture_file *cf,
1158 const struct wtap_pkthdr *phdr,
1159 const union wtap_pseudo_header *pseudo_header, long offset)
1166 fdata->data_src = NULL;
1167 fdata->num = cf->count;
1168 fdata->pkt_len = phdr->len;
1169 fdata->cap_len = phdr->caplen;
1170 fdata->file_off = offset;
1171 fdata->lnk_t = phdr->pkt_encap;
1172 fdata->abs_secs = phdr->ts.tv_sec;
1173 fdata->abs_usecs = phdr->ts.tv_usec;
1174 fdata->flags.passed_dfilter = 0;
1175 fdata->flags.encoding = CHAR_ASCII;
1176 fdata->flags.visited = 0;
1177 fdata->flags.marked = 0;
1179 /* If we don't have the time stamp of the first packet in the
1180 capture, it's because this is the first packet. Save the time
1181 stamp of this packet as the time stamp of the first packet. */
1182 if (!firstsec && !firstusec) {
1183 firstsec = fdata->abs_secs;
1184 firstusec = fdata->abs_usecs;
1187 /* If we don't have the time stamp of the previous displayed packet,
1188 it's because this is the first displayed packet. Save the time
1189 stamp of this packet as the time stamp of the previous displayed
1191 if (!prevsec && !prevusec) {
1192 prevsec = fdata->abs_secs;
1193 prevusec = fdata->abs_usecs;
1196 /* Get the time elapsed between the first packet and this packet. */
1197 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1198 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1200 /* If it's greater than the current elapsed time, set the elapsed time
1201 to it (we check for "greater than" so as not to be confused by
1202 time moving backwards). */
1203 if ((gint32)cf->esec < fdata->rel_secs
1204 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1205 cf->esec = fdata->rel_secs;
1206 cf->eusec = fdata->rel_usecs;
1209 /* Get the time elapsed between the previous displayed packet and
1211 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1212 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1213 prevsec = fdata->abs_secs;
1214 prevusec = fdata->abs_usecs;
1217 /* Free up all data attached to a "frame_data" structure. */
1219 clear_fdata(frame_data *fdata)
1222 g_slist_free(fdata->pfd);
1223 if (fdata->data_src)
1224 g_slist_free(fdata->data_src);
1228 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1229 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1231 cb_args_t *args = (cb_args_t *) user;
1232 capture_file *cf = args->cf;
1233 wtap_dumper *pdh = args->pdh;
1237 epan_dissect_t *edt;
1241 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1242 edt = epan_dissect_new(pseudo_header, buf, &fdata, TRUE, &cf->cinfo);
1243 passed = dfilter_apply_edt(cf->rfcode, edt);
1249 if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1251 if (ld.pch != NULL) {
1252 /* We're capturing packets, so we're printing a count of packets
1253 captured; move to the line after the count. */
1254 fprintf(stderr, "\n");
1257 show_capture_file_io_error(cf->save_file, err, FALSE);
1262 wtap_dump_close(pdh, &err);
1267 epan_dissect_free(edt);
1269 clear_fdata(&fdata);
1273 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1279 "tethereal: Not all the packets could be written to \"%s\" because there is "
1280 "no space left on the file system.\n",
1287 "tethereal: Not all the packets could be written to \"%s\" because you are "
1288 "too close to, or over your disk quota.\n",
1293 case WTAP_ERR_CANT_CLOSE:
1295 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1299 case WTAP_ERR_SHORT_WRITE:
1301 "tethereal: Not all the packets could be written to \"%s\".\n",
1308 "tethereal: \"%s\" could not be closed: %s.\n",
1309 fname, wtap_strerror(err));
1312 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1313 fname, wtap_strerror(err));
1320 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1321 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1323 cb_args_t *args = (cb_args_t *) user;
1324 capture_file *cf = args->cf;
1327 print_args_t print_args;
1328 epan_dissect_t *edt;
1329 gboolean create_proto_tree;
1334 /* The protocol tree will be "visible", i.e., printed, only if we're
1335 not printing a summary. */
1336 proto_tree_is_visible = verbose;
1338 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1341 if (cf->rfcode || verbose)
1342 create_proto_tree = TRUE;
1344 create_proto_tree = FALSE;
1345 edt = epan_dissect_new(pseudo_header, buf, &fdata, create_proto_tree,
1348 passed = dfilter_apply_edt(cf->rfcode, edt);
1350 /* The packet passed the read filter. */
1352 /* Print the information in the protocol tree. */
1353 print_args.to_file = TRUE;
1354 print_args.format = PR_FMT_TEXT;
1355 print_args.print_summary = FALSE;
1356 print_args.print_hex = print_hex;
1357 print_args.expand_all = TRUE;
1358 print_args.suppress_unmarked = FALSE;
1359 proto_tree_print(FALSE, &print_args, (GNode *)edt->tree,
1362 /* "print_hex_data()" will put out a leading blank line, as well
1363 as a trailing one; print one here, to separate the packets,
1364 only if "print_hex_data()" won't be called. */
1368 /* Just fill in the columns. */
1369 fill_in_columns(&edt->pi);
1371 /* Now print them. */
1372 for (i = 0; i < cf->cinfo.num_cols; i++) {
1373 switch (cf->cinfo.col_fmt[i]) {
1376 * Don't print this if we're doing a live capture from a network
1377 * interface - if we're doing a live capture, you won't be
1378 * able to look at the capture in the future (it's not being
1379 * saved anywhere), so the frame numbers are unlikely to be
1382 * (XXX - it might be nice to be able to save and print at
1383 * the same time, sort of like an "Update list of packets
1384 * in real time" capture in Ethereal.)
1386 if (cf->iface != NULL)
1388 printf("%3s", cf->cinfo.col_data[i]);
1394 case COL_ABS_DATE_TIME: /* XXX - wider */
1395 printf("%10s", cf->cinfo.col_data[i]);
1401 case COL_DEF_DL_SRC:
1402 case COL_RES_DL_SRC:
1403 case COL_UNRES_DL_SRC:
1404 case COL_DEF_NET_SRC:
1405 case COL_RES_NET_SRC:
1406 case COL_UNRES_NET_SRC:
1407 printf("%12s", cf->cinfo.col_data[i]);
1413 case COL_DEF_DL_DST:
1414 case COL_RES_DL_DST:
1415 case COL_UNRES_DL_DST:
1416 case COL_DEF_NET_DST:
1417 case COL_RES_NET_DST:
1418 case COL_UNRES_NET_DST:
1419 printf("%-12s", cf->cinfo.col_data[i]);
1423 printf("%s", cf->cinfo.col_data[i]);
1426 if (i != cf->cinfo.num_cols - 1) {
1428 * This isn't the last column, so we need to print a
1429 * separator between this column and the next.
1431 * If we printed a network source and are printing a
1432 * network destination of the same type next, separate
1433 * them with "->"; if we printed a network destination
1434 * and are printing a network source of the same type
1435 * next, separate them with "<-"; otherwise separate them
1438 switch (cf->cinfo.col_fmt[i]) {
1443 switch (cf->cinfo.col_fmt[i + 1]) {
1457 case COL_DEF_DL_SRC:
1458 case COL_RES_DL_SRC:
1459 case COL_UNRES_DL_SRC:
1460 switch (cf->cinfo.col_fmt[i + 1]) {
1462 case COL_DEF_DL_DST:
1463 case COL_RES_DL_DST:
1464 case COL_UNRES_DL_DST:
1474 case COL_DEF_NET_SRC:
1475 case COL_RES_NET_SRC:
1476 case COL_UNRES_NET_SRC:
1477 switch (cf->cinfo.col_fmt[i + 1]) {
1479 case COL_DEF_NET_DST:
1480 case COL_RES_NET_DST:
1481 case COL_UNRES_NET_DST:
1494 switch (cf->cinfo.col_fmt[i + 1]) {
1508 case COL_DEF_DL_DST:
1509 case COL_RES_DL_DST:
1510 case COL_UNRES_DL_DST:
1511 switch (cf->cinfo.col_fmt[i + 1]) {
1513 case COL_DEF_DL_SRC:
1514 case COL_RES_DL_SRC:
1515 case COL_UNRES_DL_SRC:
1525 case COL_DEF_NET_DST:
1526 case COL_RES_NET_DST:
1527 case COL_UNRES_NET_DST:
1528 switch (cf->cinfo.col_fmt[i + 1]) {
1530 case COL_DEF_NET_SRC:
1531 case COL_RES_NET_SRC:
1532 case COL_UNRES_NET_SRC:
1551 print_hex_data(stdout, print_args.format, &fdata);
1556 /* The ANSI C standard does not appear to *require* that a line-buffered
1557 stream be flushed to the host environment whenever a newline is
1558 written, it just says that, on such a stream, characters "are
1559 intended to be transmitted to or from the host environment as a
1560 block when a new-line character is encountered".
1562 The Visual C++ 6.0 C implementation doesn't do what is intended;
1563 even if you set a stream to be line-buffered, it still doesn't
1564 flush the buffer at the end of every line.
1566 So, if the "-l" flag was specified, we flush the standard output
1567 at the end of a packet. This will do the right thing if we're
1568 printing packet summary lines, and, as we print the entire protocol
1569 tree for a single packet without waiting for anything to happen,
1570 it should be as good as line-buffered mode if we're printing
1571 protocol trees. (The whole reason for the "-l" flag in either
1572 tcpdump or Tethereal is to allow the output of a live capture to
1573 be piped to a program or script and to have that script see the
1574 information for the packet as soon as it's printed, rather than
1575 having to wait until a standard I/O buffer fills up. */
1579 epan_dissect_free(edt);
1581 clear_fdata(&fdata);
1583 proto_tree_is_visible = FALSE;
1587 file_open_error_message(int err, gboolean for_writing)
1590 static char errmsg_errno[1024+1];
1594 case WTAP_ERR_NOT_REGULAR_FILE:
1595 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1598 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1599 case WTAP_ERR_UNSUPPORTED:
1600 /* Seen only when opening a capture file for reading. */
1601 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1604 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1605 /* Seen only when opening a capture file for writing. */
1606 errmsg = "Tethereal does not support writing capture files in that format.";
1609 case WTAP_ERR_UNSUPPORTED_ENCAP:
1610 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1612 errmsg = "Tethereal cannot save this capture in that format.";
1614 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1617 case WTAP_ERR_BAD_RECORD:
1618 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1621 case WTAP_ERR_CANT_OPEN:
1623 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1625 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1628 case WTAP_ERR_SHORT_READ:
1629 errmsg = "The file \"%s\" appears to have been cut short"
1630 " in the middle of a packet or other data.";
1633 case WTAP_ERR_SHORT_WRITE:
1634 errmsg = "A full header couldn't be written to the file \"%s\".";
1639 errmsg = "The path to the file \"%s\" does not exist.";
1641 errmsg = "The file \"%s\" does not exist.";
1646 errmsg = "You do not have permission to create or write to the file \"%s\".";
1648 errmsg = "You do not have permission to read the file \"%s\".";
1652 errmsg = "\"%s\" is a directory (folder), not a file.";
1656 snprintf(errmsg_errno, sizeof(errmsg_errno),
1657 "The file \"%%s\" could not be opened: %s.",
1658 wtap_strerror(err));
1659 errmsg = errmsg_errno;
1666 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1671 struct stat cf_stat;
1672 char err_msg[2048+1];
1674 wth = wtap_open_offline(fname, &err, FALSE);
1678 /* Find the size of the file. */
1680 if (fstat(fd, &cf_stat) < 0) {
1686 /* The open succeeded. Fill in the information for this file. */
1688 /* Initialize the table of conversations. */
1689 epan_conversation_init();
1691 /* Initialize protocol-specific variables */
1692 init_all_protocols();
1694 /* Initialize the common data structures for fragment reassembly.
1695 Must be done *after* "init_all_protocols()", as "init_all_protocols()"
1696 may free up space for fragments, which it finds by using the
1697 data structures that "reassemble_init()" frees. */
1702 cf->f_len = cf_stat.st_size;
1704 /* Set the file name because we need it to set the follow stream filter.
1705 XXX - is that still true? We need it for other reasons, though,
1707 cf->filename = g_strdup(fname);
1709 /* Indicate whether it's a permanent or temporary file. */
1710 cf->is_tempfile = is_tempfile;
1712 /* If it's a temporary capture buffer file, mark it as not saved. */
1713 cf->user_saved = !is_tempfile;
1715 cf->cd_t = wtap_file_type(cf->wth);
1717 cf->drops_known = FALSE;
1721 cf->snap = wtap_snapshot_length(cf->wth);
1722 cf->progbar_quantum = 0;
1723 cf->progbar_nextstep = 0;
1724 firstsec = 0, firstusec = 0;
1725 prevsec = 0, prevusec = 0;
1730 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1731 fprintf(stderr, "tethereal: %s\n", err_msg);