3 * $Id: tethereal.c,v 1.109 2001/12/21 19:58:30 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"
110 #include "epan_dissect.h"
113 #include "capture-wpcap.h"
116 static guint32 firstsec, firstusec;
117 static guint32 prevsec, prevusec;
118 static GString *comp_info_str;
119 static gboolean verbose;
120 static gboolean print_hex;
121 static gboolean line_buffered;
124 typedef struct _loop_data {
133 static int capture(int, int);
134 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
136 static void capture_cleanup(int);
144 static int load_cap_file(capture_file *, int);
145 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, long,
146 union wtap_pseudo_header *, const u_char *);
147 static void show_capture_file_io_error(const char *, int, gboolean);
148 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, long,
149 union wtap_pseudo_header *, const u_char *);
152 FILE *data_out_file = NULL;
153 ts_type timestamp_type = RELATIVE;
155 static int promisc_mode = TRUE;
163 fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
166 fprintf(stderr, "t%s [ -DvVhlp ] [ -a <capture autostop condition> ] ...\n",
168 fprintf(stderr, "\t[ -b <number of ring buffer files> ] [ -c <count> ]\n");
169 fprintf(stderr, "\t[ -f <capture filter> ] [ -F <capture file type> ]\n");
170 fprintf(stderr, "\t[ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
171 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
172 fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
174 fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
175 fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
176 fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
178 fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
179 for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
180 if (wtap_dump_can_open(i))
181 fprintf(stderr, "\t%s - %s\n",
182 wtap_file_type_short_string(i), wtap_file_type_string(i));
184 fprintf(stderr, "\tdefault is libpcap\n");
188 get_positive_int(const char *string, const char *name)
193 number = strtol(string, &p, 10);
194 if (p == string || *p != '\0') {
195 fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
200 fprintf(stderr, "tethereal: The specified %s \"%s\" is a negative number\n",
204 if (number > INT_MAX) {
205 fprintf(stderr, "tethereal: The specified %s \"%s\" is too large (greater than %d)\n",
206 name, string, INT_MAX);
213 * Given a string of the form "<autostop criterion>:<value>", as might appear
214 * as an argument to a "-a" option, parse it and set the criterion in
215 * question. Return an indication of whether it succeeded or failed
219 set_autostop_criterion(const char *autostoparg)
223 colonp = strchr(autostoparg, ':');
231 * Skip over any white space (there probably won't be any, but
232 * as we allow it in the preferences file, we might as well
239 * Put the colon back, so if our caller uses, in an
240 * error message, the string they passed us, the message
246 if (strcmp(autostoparg,"duration") == 0) {
247 cfile.autostop_duration = get_positive_int(p,"autostop duration");
248 } else if (strcmp(autostoparg,"filesize") == 0) {
249 cfile.autostop_filesize = get_positive_int(p,"autostop filesize");
253 *colonp = ':'; /* put the colon back */
258 main(int argc, char *argv[])
262 gboolean arg_error = FALSE;
264 #ifdef HAVE_PCAP_VERSION
265 extern char pcap_version[];
266 #endif /* HAVE_PCAP_VERSION */
267 #endif /* HAVE_LIBPCAP */
275 int gpf_open_errno, pf_open_errno;
278 gboolean capture_filter_specified = FALSE;
279 guint packet_count = 0;
280 GList *if_list, *if_entry;
281 gchar err_str[PCAP_ERRBUF_SIZE];
283 gboolean capture_option_specified = FALSE;
285 int out_file_type = WTAP_FILE_PCAP;
286 gchar *cf_name = NULL, *rfilter = NULL;
287 dfilter_t *rfcode = NULL;
291 /* Register all dissectors; we must do this before checking for the
292 "-G" flag, as the "-G" flag dumps a list of fields registered
293 by the dissectors, and we must do it before we read the preferences,
294 in case any dissectors register preferences. */
295 epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
297 /* Now register the preferences for any non-dissector modules.
298 We must do that before we read the preferences as well. */
299 prefs_register_modules();
301 /* If invoked with the "-G" flag, we dump out a glossary of
302 display filter symbols.
304 We do this here to mirror what happens in the GTK+ version, although
305 it's not necessary here. */
306 if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
307 proto_registrar_dump();
311 /* Set the C-language locale to the native environment. */
312 setlocale(LC_ALL, "");
314 prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
315 if (gpf_path != NULL) {
316 fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
317 strerror(gpf_open_errno));
319 if (pf_path != NULL) {
320 fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
321 strerror(pf_open_errno));
325 /* Load Wpcap, if possible */
329 /* Initialize the capture file struct */
331 cfile.plist_end = NULL;
333 cfile.filename = NULL;
334 cfile.user_saved = FALSE;
335 cfile.is_tempfile = FALSE;
337 cfile.dfilter = NULL;
340 cfile.cfilter = g_strdup("");
343 cfile.save_file = NULL;
344 cfile.save_file_fd = -1;
345 cfile.snap = WTAP_MAX_PACKET_SIZE;
348 cfile.autostop_duration = 0;
349 cfile.autostop_filesize = 0;
350 cfile.ringbuffer_on = FALSE;
351 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
353 col_init(&cfile.cinfo, prefs->num_cols);
355 /* Assemble the compile-time options */
356 comp_info_str = g_string_new("");
358 g_string_append(comp_info_str, "with ");
359 g_string_sprintfa(comp_info_str,
360 #ifdef GLIB_MAJOR_VERSION
361 "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
364 "GLib (version unknown)");
368 g_string_append(comp_info_str, ", with libpcap ");
369 #ifdef HAVE_PCAP_VERSION
370 g_string_append(comp_info_str, pcap_version);
371 #else /* HAVE_PCAP_VERSION */
372 g_string_append(comp_info_str, "(version unknown)");
373 #endif /* HAVE_PCAP_VERSION */
374 #else /* HAVE_LIBPCAP */
375 g_string_append(comp_info_str, ", without libpcap");
376 #endif /* HAVE_LIBPCAP */
379 g_string_append(comp_info_str, ", with libz ");
381 g_string_append(comp_info_str, ZLIB_VERSION);
382 #else /* ZLIB_VERSION */
383 g_string_append(comp_info_str, "(version unknown)");
384 #endif /* ZLIB_VERSION */
385 #else /* HAVE_LIBZ */
386 g_string_append(comp_info_str, ", without libz");
387 #endif /* HAVE_LIBZ */
389 /* Oh, this is pretty */
390 #if defined(HAVE_UCD_SNMP_SNMP_H)
391 g_string_append(comp_info_str, ", with UCD SNMP ");
392 #ifdef HAVE_UCD_SNMP_VERSION_H
393 g_string_append(comp_info_str, VersionInfo);
394 #else /* HAVE_UCD_SNMP_VERSION_H */
395 g_string_append(comp_info_str, "(version unknown)");
396 #endif /* HAVE_UCD_SNMP_VERSION_H */
397 #elif defined(HAVE_SNMP_SNMP_H)
398 g_string_append(comp_info_str, ", with CMU SNMP ");
399 #ifdef HAVE_SNMP_VERSION_H
400 g_string_append(comp_info_str, snmp_Version());
401 #else /* HAVE_SNMP_VERSION_H */
402 g_string_append(comp_info_str, "(version unknown)");
403 #endif /* HAVE_SNMP_VERSION_H */
405 g_string_append(comp_info_str, ", without SNMP");
408 /* Now get our args */
409 while ((opt = getopt(argc, argv, "a:b:c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != EOF) {
411 case 'a': /* autostop criteria */
413 if (set_autostop_criterion(optarg) == FALSE) {
414 fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
418 capture_option_specified = TRUE;
422 case 'b': /* Ringbuffer option */
424 cfile.ringbuffer_on = TRUE;
425 /* get optional ringbuffer number of files parameter */
426 if (optarg[0] != '-') {
427 cfile.ringbuffer_num_files = get_positive_int(optarg, "ring buffer number of files");
429 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
433 capture_option_specified = TRUE;
437 case 'c': /* Capture xxx packets */
439 packet_count = get_positive_int(optarg, "packet count");
441 capture_option_specified = TRUE;
445 case 'D': /* Print a list of capture devices */
447 if_list = get_interface_list(&err, err_str);
448 if (if_list == NULL) {
451 case CANT_GET_INTERFACE_LIST:
452 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
456 case NO_INTERFACES_FOUND:
457 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
462 for (if_entry = g_list_first(if_list); if_entry != NULL;
463 if_entry = g_list_next(if_entry))
464 printf("%s\n", (char *)if_entry->data);
465 free_interface_list(if_list);
468 capture_option_specified = TRUE;
474 capture_filter_specified = TRUE;
475 cfile.cfilter = g_strdup(optarg);
477 capture_option_specified = TRUE;
482 out_file_type = wtap_short_string_to_file_type(optarg);
483 if (out_file_type < 0) {
484 fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
489 case 'h': /* Print help and exit */
493 case 'i': /* Use interface xxx */
495 cfile.iface = g_strdup(optarg);
497 capture_option_specified = TRUE;
501 case 'l': /* "Line-buffer" standard output */
502 /* This isn't line-buffering, strictly speaking, it's just
503 flushing the standard output after the information for
504 each packet is printed; however, that should be good
505 enough for all the purposes to which "-l" is put.
507 See the comment in "wtap_dispatch_cb_print()" for an
508 explanation of why we do that, and why we don't just
509 use "setvbuf()" to make the standard output line-buffered
510 (short version: in Windows, "line-buffered" is the same
511 as "fully-buffered", and the output buffer is only flushed
512 when it fills up). */
513 line_buffered = TRUE;
515 case 'n': /* No name resolution */
516 prefs->name_resolve = PREFS_RESOLV_NONE;
518 case 'N': /* Select what types of addresses/port #s to resolve */
519 if (prefs->name_resolve == PREFS_RESOLV_ALL)
520 prefs->name_resolve = PREFS_RESOLV_NONE;
521 badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
522 if (badopt != '\0') {
523 fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
528 case 'o': /* Override preference from command line */
529 switch (prefs_set_pref(optarg)) {
531 case PREFS_SET_SYNTAX_ERR:
532 fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
536 case PREFS_SET_NO_SUCH_PREF:
537 case PREFS_SET_OBSOLETE:
538 fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
544 case 'p': /* Don't capture in promiscuous mode */
548 capture_option_specified = TRUE;
552 case 'r': /* Read capture file xxx */
553 cf_name = g_strdup(optarg);
555 case 'R': /* Read file filter */
558 case 's': /* Set the snapshot (capture) length */
560 cfile.snap = get_positive_int(optarg, "snapshot length");
562 capture_option_specified = TRUE;
566 case 't': /* Time stamp type */
567 if (strcmp(optarg, "r") == 0)
568 timestamp_type = RELATIVE;
569 else if (strcmp(optarg, "a") == 0)
570 timestamp_type = ABSOLUTE;
571 else if (strcmp(optarg, "ad") == 0)
572 timestamp_type = ABSOLUTE_WITH_DATE;
573 else if (strcmp(optarg, "d") == 0)
574 timestamp_type = DELTA;
576 fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
578 fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
579 fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
583 case 'v': /* Show version and exit */
584 printf("t%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
587 case 'w': /* Write to capture file xxx */
588 cfile.save_file = g_strdup(optarg);
590 case 'V': /* Verbose */
593 case 'x': /* Print packet data in hex (and ASCII) */
599 /* If no capture filter or read filter has been specified, and there are
600 still command-line arguments, treat them as the tokens of a capture
601 filter (if no "-r" flag was specified) or a read filter (if a "-r"
602 flag was specified. */
604 if (cf_name != NULL) {
605 if (rfilter != NULL) {
607 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
610 rfilter = get_args_as_string(argc, argv, optind);
613 if (capture_filter_specified) {
615 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
618 cfile.cfilter = get_args_as_string(argc, argv, optind);
620 capture_option_specified = TRUE;
625 /* If they didn't specify a "-w" flag, but specified a maximum capture
626 file size, tell them that this doesn't work, and exit. */
627 if (cfile.autostop_filesize != 0 && cfile.save_file == NULL) {
628 fprintf(stderr, "tethereal: Maximum capture file size specified, but capture isn't being saved to a file.\n");
633 /* Start windows sockets */
634 WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
637 /* Notify all registered modules that have had any of their preferences
638 changed either from one of the preferences file or from the command
639 line that its preferences have changed. */
643 if (capture_option_specified)
644 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
649 /* Build the column format array */
650 for (i = 0; i < cfile.cinfo.num_cols; i++) {
651 cfile.cinfo.col_fmt[i] = get_column_format(i);
652 cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
653 cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
655 get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
656 cfile.cinfo.col_data[i] = NULL;
657 if (cfile.cinfo.col_fmt[i] == COL_INFO)
658 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
660 cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
664 cfile.snap = WTAP_MAX_PACKET_SIZE;
665 else if (cfile.snap < MIN_PACKET_SIZE)
666 cfile.snap = MIN_PACKET_SIZE;
668 if (cfile.ringbuffer_on) {
669 /* Ringbuffer works just under certain conditions:*/
670 if (cfile.save_file == NULL) {
671 /* Ringbuffer does not work with temporary files */
672 fprintf(stderr, "tethereal: Turning ring buffer off (no save file specified).\n");
673 cfile.ringbuffer_on = FALSE;
675 if (cfile.autostop_filesize == 0) {
676 /* It makes no sense to enable the ring buffer if the maximum
677 file size is set to infinite */
678 fprintf(stderr, "tethereal: Turning ring buffer off (file size = 0).\n");
679 cfile.ringbuffer_on = FALSE;
683 /* Check the value range of the ringbuffer_num_files parameter */
684 if (cfile.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
685 cfile.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
686 else if (cfile.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
687 cfile.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
689 if (rfilter != NULL) {
690 if (!dfilter_compile(rfilter, &rfcode)) {
691 fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
696 cfile.rfcode = rfcode;
698 err = open_cap_file(cf_name, FALSE, &cfile);
703 err = load_cap_file(&cfile, out_file_type);
710 /* No capture file specified, so we're supposed to do a live capture;
711 do we have support for live captures? */
716 fprintf(stderr, "tethereal: Could not load wpcap.dll.\n");
721 /* Yes; did the user specify an interface to use? */
722 if (cfile.iface == NULL) {
723 /* No - pick the first one from the list of interfaces. */
724 if_list = get_interface_list(&err, err_str);
725 if (if_list == NULL) {
728 case CANT_GET_INTERFACE_LIST:
729 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
733 case NO_INTERFACES_FOUND:
734 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
739 cfile.iface = g_strdup(if_list->data); /* first interface */
740 free_interface_list(if_list);
742 capture(packet_count, out_file_type);
744 if (cfile.ringbuffer_on) {
749 fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
760 /* Do the low-level work of a capture.
761 Returns TRUE if it succeeds, FALSE otherwise. */
763 capture(int packet_count, int out_file_type)
765 gchar open_err_str[PCAP_ERRBUF_SIZE];
766 gchar lookup_net_err_str[PCAP_ERRBUF_SIZE];
767 bpf_u_int32 netnum, netmask;
768 struct bpf_program fcode;
769 void (*oldhandler)(int);
772 condition *cnd_stop_capturesize;
773 condition *cnd_stop_timeout;
775 static const char ppamsg[] = "can't find PPA for ";
778 struct pcap_stat stats;
781 /* Initialize the table of conversations. */
782 epan_conversation_init();
784 /* Initialize protocol-specific variables */
785 init_all_protocols();
787 /* Initialize the common data structures for fragment reassembly.
788 Must be done *after* "init_all_protocols()", as "init_all_protocols()"
789 may free up space for fragments, which it finds by using the
790 data structures that "reassemble_init()" frees. */
793 ld.linktype = WTAP_ENCAP_UNKNOWN;
796 /* Open the network interface to capture from it.
797 Some versions of libpcap may put warnings into the error buffer
798 if they succeed; to tell if that's happened, we have to clear
799 the error buffer, and check if it's still a null string. */
800 open_err_str[0] = '\0';
801 ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000,
804 if (ld.pch == NULL) {
805 /* Well, we couldn't start the capture. */
807 /* On Win32 OSes, the capture devices are probably available to all
808 users; don't warn about permissions problems.
810 Do, however, warn that Token Ring and PPP devices aren't supported. */
811 snprintf(errmsg, sizeof errmsg,
812 "The capture session could not be initiated (%s).\n"
813 "Please check that you have the proper interface specified.\n"
815 "Note that the driver Tethereal uses for packet capture on Windows\n"
816 "doesn't support capturing on Token Ring interfaces, and doesn't\n"
817 "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
820 /* If we got a "can't find PPA for XXX" message, warn the user (who
821 is running Ethereal on HP-UX) that they don't have a version
822 of libpcap that properly handles HP-UX (libpcap 0.6.x and later
823 versions, which properly handle HP-UX, say "can't find /dev/dlpi
824 PPA for XXX" rather than "can't find PPA for XXX"). */
825 if (strncmp(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
828 "You are running Tethereal with a version of the libpcap library\n"
829 "that doesn't handle HP-UX network devices well; this means that\n"
830 "Tethereal may not be able to capture packets.\n"
832 "To fix this, you should install libpcap 0.6.2, or a later version\n"
833 "of libpcap, rather than libpcap 0.4 or 0.5.x. It is available in\n"
834 "packaged binary form from the Software Porting And Archive Centre\n"
835 "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
836 "at the URL lists a number of mirror sites.";
839 snprintf(errmsg, sizeof errmsg,
840 "The capture session could not be initiated (%s).\n"
841 "Please check to make sure you have sufficient permissions, and that\n"
842 "you have the proper interface specified.%s", open_err_str, libpcap_warn);
848 /* A capture filter was specified; set it up. */
849 if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
851 * Well, we can't get the netmask for this interface; it's used
852 * only for filters that check for broadcast IP addresses, so
853 * we just warn the user, and punt and use 0.
856 "Warning: Couldn't obtain netmask info (%s)\n.", lookup_net_err_str);
859 if (pcap_compile(ld.pch, &fcode, cfile.cfilter, 1, netmask) < 0) {
860 snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
861 pcap_geterr(ld.pch));
864 if (pcap_setfilter(ld.pch, &fcode) < 0) {
865 snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
866 pcap_geterr(ld.pch));
871 ld.linktype = wtap_pcap_encap_to_wtap_encap(get_pcap_linktype(ld.pch,
873 if (cfile.save_file != NULL) {
874 /* Set up to write to the capture file. */
875 if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
876 strcpy(errmsg, "The network you're capturing from is of a type"
877 " that Tethereal doesn't support.");
880 if (cfile.ringbuffer_on) {
881 cfile.save_file_fd = ringbuf_init(cfile.save_file,
882 cfile.ringbuffer_num_files);
883 if (cfile.save_file_fd != -1) {
884 ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
885 pcap_snapshot(ld.pch), &err);
890 ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
891 ld.linktype, pcap_snapshot(ld.pch), &err);
894 if (ld.pdh == NULL) {
895 snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
901 /* Does "open_err_str" contain a non-empty string? If so, "pcap_open_live()"
902 returned a warning; print it, but keep capturing. */
903 if (open_err_str[0] != '\0')
904 fprintf(stderr, "tethereal: WARNING: %s.\n", open_err_str);
906 /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
908 XXX - deal with signal semantics on various platforms. Or just
909 use "sigaction()" and be done with it? */
910 signal(SIGTERM, capture_cleanup);
911 signal(SIGINT, capture_cleanup);
913 if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
914 signal(SIGHUP, oldhandler);
917 /* Let the user know what interface was chosen. */
918 fprintf(stderr, "Capturing on %s\n", cfile.iface);
921 /* initialize capture stop conditions */
922 init_capture_stop_conditions();
923 /* create stop conditions */
924 cnd_stop_capturesize = cnd_new((char*)CND_CLASS_CAPTURESIZE,
925 (long)cfile.autostop_filesize * 1000);
926 cnd_stop_timeout = cnd_new((char*)CND_CLASS_TIMEOUT,
927 (gint32)cfile.autostop_duration);
929 if (packet_count == 0)
930 packet_count = -1; /* infinite capturng */
933 if (packet_count > 0)
935 inpkts = pcap_dispatch(ld.pch, 1, capture_pcap_cb, (u_char *) &ld);
936 if (packet_count == 0) {
938 } else if (cnd_eval(cnd_stop_timeout) == TRUE) {
939 /* The specified capture time has elapsed; stop the capture. */
941 } else if (ld.pdh != NULL && (cnd_eval(cnd_stop_capturesize,
942 (guint32)wtap_get_bytes_dumped(ld.pdh))) == TRUE){
943 /* We're saving the capture to a file, and the capture file reached
945 if (cfile.ringbuffer_on) {
946 /* Switch to the next ringbuffer file */
947 if (ringbuf_switch_file(&cfile, &ld.pdh, &err) == TRUE) {
948 /* File switch failed: reset the condition */
949 cnd_reset(cnd_stop_capturesize);
951 /* File switch failed: stop here */
956 /* No ringbuffer - just stop. */
962 /* delete stop conditions */
963 cnd_delete(cnd_stop_capturesize);
964 cnd_delete(cnd_stop_timeout);
966 if (cfile.save_file != NULL) {
967 /* We're saving to a file, which means we're printing packet counts
968 to the standard output. Send a newline so that we move to the
969 line after the packet count. */
970 fprintf(stderr, "\n");
973 /* If we got an error while capturing, report it. */
975 fprintf(stderr, "tethereal: Error while capturing packets: %s\n",
976 pcap_geterr(ld.pch));
979 /* Get the capture statistics, and, if any packets were dropped, report
981 if (pcap_stats(ld.pch, &stats) >= 0) {
982 if (stats.ps_drop != 0) {
983 fprintf(stderr, "%u packets dropped\n", stats.ps_drop);
986 fprintf(stderr, "tethereal: Can't get packet-drop statistics: %s\n",
987 pcap_geterr(ld.pch));
992 if (cfile.save_file != NULL) {
993 /* We're saving to a file or files; close all files. */
994 if (cfile.ringbuffer_on) {
995 dump_ok = ringbuf_wtap_dump_close(&cfile, &err);
997 dump_ok = wtap_dump_close(ld.pdh, &err);
1000 show_capture_file_io_error(cfile.save_file, err, TRUE);
1006 if (cfile.ringbuffer_on) {
1007 ringbuf_error_cleanup();
1009 g_free(cfile.save_file);
1010 cfile.save_file = NULL;
1011 fprintf(stderr, "tethereal: %s\n", errmsg);
1019 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
1022 struct wtap_pkthdr whdr;
1023 loop_data *ld = (loop_data *) user;
1026 whdr.ts.tv_sec = phdr->ts.tv_sec;
1027 whdr.ts.tv_usec = phdr->ts.tv_usec;
1028 whdr.caplen = phdr->caplen;
1029 whdr.len = phdr->len;
1030 whdr.pkt_encap = ld->linktype;
1035 wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
1036 fprintf(stderr, "\r%u ", cfile.count);
1039 wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
1044 capture_cleanup(int signum)
1046 /* Just set the loop flag to false. This will initiate
1047 a proper termination. */
1050 #endif /* HAVE_LIBPCAP */
1053 load_cap_file(capture_file *cf, int out_file_type)
1061 linktype = wtap_file_encap(cf->wth);
1062 if (cf->save_file != NULL) {
1063 /* Set up to write to the capture file. */
1064 pdh = wtap_dump_open(cf->save_file, out_file_type,
1065 linktype, wtap_snapshot_length(cf->wth), &err);
1068 /* We couldn't set up to write to the capture file. */
1071 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1073 "tethereal: Capture files can't be written in that format.\n");
1076 case WTAP_ERR_UNSUPPORTED_ENCAP:
1077 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1079 "tethereal: The capture file being read cannot be written in that format.\n");
1082 case WTAP_ERR_CANT_OPEN:
1084 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
1088 case WTAP_ERR_SHORT_WRITE:
1090 "tethereal: A full header couldn't be written to the file \"%s\".\n",
1097 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
1098 cf->save_file, err);
1101 "tethereal: The file \"%s\" could not be opened: %s\n.",
1102 cf->save_file, strerror(err));
1110 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
1113 /* Now close the capture file. */
1114 if (!wtap_dump_close(pdh, &err))
1115 show_capture_file_io_error(cfile.save_file, err, TRUE);
1119 success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
1123 /* Print up a message box noting that the read failed somewhere along
1127 case WTAP_ERR_UNSUPPORTED_ENCAP:
1129 "tethereal: \"%s\" is a capture file is for a network type that Tethereal doesn't support.\n",
1133 case WTAP_ERR_CANT_READ:
1135 "tethereal: An attempt to read from \"%s\" failed for some unknown reason.\n",
1139 case WTAP_ERR_SHORT_READ:
1141 "tethereal: \"%s\" appears to have been cut short in the middle of a packet.\n",
1145 case WTAP_ERR_BAD_RECORD:
1147 "tethereal: \"%s\" appears to be damaged or corrupt.\n",
1153 "tethereal: An error occurred while reading \"%s\": %s.\n",
1154 cf->filename, wtap_strerror(err));
1160 wtap_close(cf->wth);
1167 fill_in_fdata(frame_data *fdata, capture_file *cf,
1168 const struct wtap_pkthdr *phdr,
1169 const union wtap_pseudo_header *pseudo_header, long offset)
1176 fdata->data_src = NULL;
1177 fdata->num = cf->count;
1178 fdata->pkt_len = phdr->len;
1179 fdata->cap_len = phdr->caplen;
1180 fdata->file_off = offset;
1181 fdata->lnk_t = phdr->pkt_encap;
1182 fdata->abs_secs = phdr->ts.tv_sec;
1183 fdata->abs_usecs = phdr->ts.tv_usec;
1184 fdata->flags.passed_dfilter = 0;
1185 fdata->flags.encoding = CHAR_ASCII;
1186 fdata->flags.visited = 0;
1187 fdata->flags.marked = 0;
1189 /* If we don't have the time stamp of the first packet in the
1190 capture, it's because this is the first packet. Save the time
1191 stamp of this packet as the time stamp of the first packet. */
1192 if (!firstsec && !firstusec) {
1193 firstsec = fdata->abs_secs;
1194 firstusec = fdata->abs_usecs;
1197 /* If we don't have the time stamp of the previous displayed packet,
1198 it's because this is the first displayed packet. Save the time
1199 stamp of this packet as the time stamp of the previous displayed
1201 if (!prevsec && !prevusec) {
1202 prevsec = fdata->abs_secs;
1203 prevusec = fdata->abs_usecs;
1206 /* Get the time elapsed between the first packet and this packet. */
1207 compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
1208 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
1210 /* If it's greater than the current elapsed time, set the elapsed time
1211 to it (we check for "greater than" so as not to be confused by
1212 time moving backwards). */
1213 if ((gint32)cf->esec < fdata->rel_secs
1214 || ((gint32)cf->esec == fdata->rel_secs && (gint32)cf->eusec < fdata->rel_usecs)) {
1215 cf->esec = fdata->rel_secs;
1216 cf->eusec = fdata->rel_usecs;
1219 /* Get the time elapsed between the previous displayed packet and
1221 compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
1222 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
1223 prevsec = fdata->abs_secs;
1224 prevusec = fdata->abs_usecs;
1227 /* Free up all data attached to a "frame_data" structure. */
1229 clear_fdata(frame_data *fdata)
1232 g_slist_free(fdata->pfd);
1233 if (fdata->data_src)
1234 g_slist_free(fdata->data_src);
1238 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr,
1239 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1241 cb_args_t *args = (cb_args_t *) user;
1242 capture_file *cf = args->cf;
1243 wtap_dumper *pdh = args->pdh;
1247 epan_dissect_t *edt;
1251 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1252 edt = epan_dissect_new(TRUE, FALSE);
1253 epan_dissect_prime_dfilter(edt, cf->rfcode);
1254 epan_dissect_run(edt, pseudo_header, buf, &fdata, NULL);
1255 passed = dfilter_apply_edt(cf->rfcode, edt);
1261 if (!wtap_dump(pdh, phdr, pseudo_header, buf, &err)) {
1263 if (ld.pch != NULL) {
1264 /* We're capturing packets, so we're printing a count of packets
1265 captured; move to the line after the count. */
1266 fprintf(stderr, "\n");
1269 show_capture_file_io_error(cf->save_file, err, FALSE);
1274 wtap_dump_close(pdh, &err);
1279 epan_dissect_free(edt);
1281 clear_fdata(&fdata);
1285 show_capture_file_io_error(const char *fname, int err, gboolean is_close)
1291 "tethereal: Not all the packets could be written to \"%s\" because there is "
1292 "no space left on the file system.\n",
1299 "tethereal: Not all the packets could be written to \"%s\" because you are "
1300 "too close to, or over your disk quota.\n",
1305 case WTAP_ERR_CANT_CLOSE:
1307 "tethereal: \"%s\" couldn't be closed for some unknown reason.\n",
1311 case WTAP_ERR_SHORT_WRITE:
1313 "tethereal: Not all the packets could be written to \"%s\".\n",
1320 "tethereal: \"%s\" could not be closed: %s.\n",
1321 fname, wtap_strerror(err));
1324 "tethereal: An error occurred while writing to \"%s\": %s.\n",
1325 fname, wtap_strerror(err));
1332 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr,
1333 long offset, union wtap_pseudo_header *pseudo_header, const u_char *buf)
1335 cb_args_t *args = (cb_args_t *) user;
1336 capture_file *cf = args->cf;
1339 print_args_t print_args;
1340 epan_dissect_t *edt;
1341 gboolean create_proto_tree;
1346 fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
1349 if (cf->rfcode || verbose)
1350 create_proto_tree = TRUE;
1352 create_proto_tree = FALSE;
1353 /* The protocol tree will be "visible", i.e., printed, only if we're
1354 not printing a summary.
1356 We only need the columns if we're *not* verbose; in verbose mode,
1357 we print the protocol tree, not the protocol summary. */
1358 edt = epan_dissect_new(create_proto_tree, verbose);
1360 epan_dissect_prime_dfilter(edt, cf->rfcode);
1362 epan_dissect_run(edt, pseudo_header, buf, &fdata, verbose ? NULL : &cf->cinfo);
1364 passed = dfilter_apply_edt(cf->rfcode, edt);
1367 /* The packet passed the read filter. */
1369 /* Print the information in the protocol tree. */
1370 print_args.to_file = TRUE;
1371 print_args.format = PR_FMT_TEXT;
1372 print_args.print_summary = FALSE;
1373 print_args.print_hex = print_hex;
1374 print_args.expand_all = TRUE;
1375 print_args.suppress_unmarked = FALSE;
1376 proto_tree_print(FALSE, &print_args, (GNode *)edt->tree,
1379 /* "print_hex_data()" will put out a leading blank line, as well
1380 as a trailing one; print one here, to separate the packets,
1381 only if "print_hex_data()" won't be called. */
1385 /* Just fill in the columns. */
1386 epan_dissect_fill_in_columns(edt);
1388 /* Now print them. */
1389 for (i = 0; i < cf->cinfo.num_cols; i++) {
1390 switch (cf->cinfo.col_fmt[i]) {
1393 * Don't print this if we're doing a live capture from a network
1394 * interface - if we're doing a live capture, you won't be
1395 * able to look at the capture in the future (it's not being
1396 * saved anywhere), so the frame numbers are unlikely to be
1399 * (XXX - it might be nice to be able to save and print at
1400 * the same time, sort of like an "Update list of packets
1401 * in real time" capture in Ethereal.)
1403 if (cf->iface != NULL)
1405 printf("%3s", cf->cinfo.col_data[i]);
1411 case COL_ABS_DATE_TIME: /* XXX - wider */
1412 printf("%10s", cf->cinfo.col_data[i]);
1418 case COL_DEF_DL_SRC:
1419 case COL_RES_DL_SRC:
1420 case COL_UNRES_DL_SRC:
1421 case COL_DEF_NET_SRC:
1422 case COL_RES_NET_SRC:
1423 case COL_UNRES_NET_SRC:
1424 printf("%12s", cf->cinfo.col_data[i]);
1430 case COL_DEF_DL_DST:
1431 case COL_RES_DL_DST:
1432 case COL_UNRES_DL_DST:
1433 case COL_DEF_NET_DST:
1434 case COL_RES_NET_DST:
1435 case COL_UNRES_NET_DST:
1436 printf("%-12s", cf->cinfo.col_data[i]);
1440 printf("%s", cf->cinfo.col_data[i]);
1443 if (i != cf->cinfo.num_cols - 1) {
1445 * This isn't the last column, so we need to print a
1446 * separator between this column and the next.
1448 * If we printed a network source and are printing a
1449 * network destination of the same type next, separate
1450 * them with "->"; if we printed a network destination
1451 * and are printing a network source of the same type
1452 * next, separate them with "<-"; otherwise separate them
1455 switch (cf->cinfo.col_fmt[i]) {
1460 switch (cf->cinfo.col_fmt[i + 1]) {
1474 case COL_DEF_DL_SRC:
1475 case COL_RES_DL_SRC:
1476 case COL_UNRES_DL_SRC:
1477 switch (cf->cinfo.col_fmt[i + 1]) {
1479 case COL_DEF_DL_DST:
1480 case COL_RES_DL_DST:
1481 case COL_UNRES_DL_DST:
1491 case COL_DEF_NET_SRC:
1492 case COL_RES_NET_SRC:
1493 case COL_UNRES_NET_SRC:
1494 switch (cf->cinfo.col_fmt[i + 1]) {
1496 case COL_DEF_NET_DST:
1497 case COL_RES_NET_DST:
1498 case COL_UNRES_NET_DST:
1511 switch (cf->cinfo.col_fmt[i + 1]) {
1525 case COL_DEF_DL_DST:
1526 case COL_RES_DL_DST:
1527 case COL_UNRES_DL_DST:
1528 switch (cf->cinfo.col_fmt[i + 1]) {
1530 case COL_DEF_DL_SRC:
1531 case COL_RES_DL_SRC:
1532 case COL_UNRES_DL_SRC:
1542 case COL_DEF_NET_DST:
1543 case COL_RES_NET_DST:
1544 case COL_UNRES_NET_DST:
1545 switch (cf->cinfo.col_fmt[i + 1]) {
1547 case COL_DEF_NET_SRC:
1548 case COL_RES_NET_SRC:
1549 case COL_UNRES_NET_SRC:
1568 print_hex_data(stdout, print_args.format, &fdata);
1573 /* The ANSI C standard does not appear to *require* that a line-buffered
1574 stream be flushed to the host environment whenever a newline is
1575 written, it just says that, on such a stream, characters "are
1576 intended to be transmitted to or from the host environment as a
1577 block when a new-line character is encountered".
1579 The Visual C++ 6.0 C implementation doesn't do what is intended;
1580 even if you set a stream to be line-buffered, it still doesn't
1581 flush the buffer at the end of every line.
1583 So, if the "-l" flag was specified, we flush the standard output
1584 at the end of a packet. This will do the right thing if we're
1585 printing packet summary lines, and, as we print the entire protocol
1586 tree for a single packet without waiting for anything to happen,
1587 it should be as good as line-buffered mode if we're printing
1588 protocol trees. (The whole reason for the "-l" flag in either
1589 tcpdump or Tethereal is to allow the output of a live capture to
1590 be piped to a program or script and to have that script see the
1591 information for the packet as soon as it's printed, rather than
1592 having to wait until a standard I/O buffer fills up. */
1596 epan_dissect_free(edt);
1598 clear_fdata(&fdata);
1602 file_open_error_message(int err, gboolean for_writing)
1605 static char errmsg_errno[1024+1];
1609 case WTAP_ERR_NOT_REGULAR_FILE:
1610 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1613 case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1614 case WTAP_ERR_UNSUPPORTED:
1615 /* Seen only when opening a capture file for reading. */
1616 errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1619 case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1620 /* Seen only when opening a capture file for writing. */
1621 errmsg = "Tethereal does not support writing capture files in that format.";
1624 case WTAP_ERR_UNSUPPORTED_ENCAP:
1625 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1627 errmsg = "Tethereal cannot save this capture in that format.";
1629 errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1632 case WTAP_ERR_BAD_RECORD:
1633 errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1636 case WTAP_ERR_CANT_OPEN:
1638 errmsg = "The file \"%s\" could not be created for some unknown reason.";
1640 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1643 case WTAP_ERR_SHORT_READ:
1644 errmsg = "The file \"%s\" appears to have been cut short"
1645 " in the middle of a packet or other data.";
1648 case WTAP_ERR_SHORT_WRITE:
1649 errmsg = "A full header couldn't be written to the file \"%s\".";
1654 errmsg = "The path to the file \"%s\" does not exist.";
1656 errmsg = "The file \"%s\" does not exist.";
1661 errmsg = "You do not have permission to create or write to the file \"%s\".";
1663 errmsg = "You do not have permission to read the file \"%s\".";
1667 errmsg = "\"%s\" is a directory (folder), not a file.";
1671 snprintf(errmsg_errno, sizeof(errmsg_errno),
1672 "The file \"%%s\" could not be opened: %s.",
1673 wtap_strerror(err));
1674 errmsg = errmsg_errno;
1681 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1686 struct stat cf_stat;
1687 char err_msg[2048+1];
1689 wth = wtap_open_offline(fname, &err, FALSE);
1693 /* Find the size of the file. */
1695 if (fstat(fd, &cf_stat) < 0) {
1701 /* The open succeeded. Fill in the information for this file. */
1703 /* Initialize the table of conversations. */
1704 epan_conversation_init();
1706 /* Initialize protocol-specific variables */
1707 init_all_protocols();
1709 /* Initialize the common data structures for fragment reassembly.
1710 Must be done *after* "init_all_protocols()", as "init_all_protocols()"
1711 may free up space for fragments, which it finds by using the
1712 data structures that "reassemble_init()" frees. */
1717 cf->f_len = cf_stat.st_size;
1719 /* Set the file name because we need it to set the follow stream filter.
1720 XXX - is that still true? We need it for other reasons, though,
1722 cf->filename = g_strdup(fname);
1724 /* Indicate whether it's a permanent or temporary file. */
1725 cf->is_tempfile = is_tempfile;
1727 /* If it's a temporary capture buffer file, mark it as not saved. */
1728 cf->user_saved = !is_tempfile;
1730 cf->cd_t = wtap_file_type(cf->wth);
1732 cf->drops_known = FALSE;
1736 cf->snap = wtap_snapshot_length(cf->wth);
1737 cf->progbar_quantum = 0;
1738 cf->progbar_nextstep = 0;
1739 firstsec = 0, firstusec = 0;
1740 prevsec = 0, prevusec = 0;
1745 snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1746 fprintf(stderr, "tethereal: %s\n", err_msg);