Ensure that all value_string arrays end in {0, NULL}. Dissectors got away
[obnox/wireshark/wip.git] / tethereal.c
1 /* tethereal.c
2  *
3  * $Id: tethereal.c,v 1.60 2000/12/03 22:12:18 guy Exp $
4  *
5  * Ethereal - Network traffic analyzer
6  * By Gerald Combs <gerald@zing.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * Text-mode variant, by Gilbert Ramirez <gram@xiexie.org>.
10  *
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.
15  * 
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.
20  * 
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.
24  *
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <locale.h>
35
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39
40 #include <errno.h>
41
42 #ifdef HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
45
46 #ifdef HAVE_SYS_STAT_H
47 #include <sys/stat.h>
48 #endif
49
50 #ifdef HAVE_FCNTL_H
51 #include <fcntl.h>
52 #endif
53
54 #include <signal.h>
55
56 #ifdef NEED_SNPRINTF_H
57 # include "snprintf.h"
58 #endif
59
60 #if defined(HAVE_UCD_SNMP_SNMP_H)
61 #ifdef HAVE_UCD_SNMP_VERSION_H
62 #include <ucd-snmp/version.h>
63 #endif /* HAVE_UCD_SNMP_VERSION_H */
64 #elif defined(HAVE_SNMP_SNMP_H)
65 #ifdef HAVE_SNMP_VERSION_H
66 #include <snmp/version.h>
67 #endif /* HAVE_SNMP_VERSION_H */
68 #endif /* SNMP */
69
70 #ifdef NEED_STRERROR_H
71 #include "strerror.h"
72 #endif
73
74 #ifdef NEED_GETOPT_H
75 #include "getopt.h"
76 #endif
77
78 #include <glib.h>
79 #include <epan.h>
80
81 #include "globals.h"
82 #include "timestamp.h"
83 #include "packet.h"
84 #include "file.h"
85 #include "prefs.h"
86 #include "column.h"
87 #include "print.h"
88 #include "resolv.h"
89 #include "util.h"
90 #include "conversation.h"
91 #include "plugins.h"
92
93 static guint32 firstsec, firstusec;
94 static guint32 prevsec, prevusec;
95 static gchar   comp_info_str[256];
96 static gboolean verbose;
97 static gboolean print_hex;
98
99 #ifdef HAVE_LIBPCAP
100 typedef struct _loop_data {
101   gint           linktype;
102   pcap_t        *pch;
103   wtap_dumper   *pdh;
104 } loop_data;
105
106 static loop_data ld;
107
108 static int capture(int, int);
109 static void capture_pcap_cb(u_char *, const struct pcap_pkthdr *,
110   const u_char *);
111 static void capture_cleanup(int);
112 #endif
113
114 typedef struct {
115   capture_file *cf;
116   wtap_dumper *pdh;
117 } cb_args_t;
118
119 static int load_cap_file(capture_file *, int);
120 static void wtap_dispatch_cb_write(u_char *, const struct wtap_pkthdr *, int,
121     union wtap_pseudo_header *, const u_char *);
122 static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, int,
123     union wtap_pseudo_header *, const u_char *);
124
125 packet_info  pi;
126 capture_file cfile;
127 FILE        *data_out_file = NULL;
128 guint        main_ctx, file_ctx;
129 ts_type timestamp_type = RELATIVE;
130 static int promisc_mode = TRUE;
131
132 static void 
133 print_usage(void)
134 {
135   int i;
136
137   fprintf(stderr, "This is GNU t%s %s, compiled with %s\n", PACKAGE,
138           VERSION, comp_info_str);
139 #ifdef HAVE_LIBPCAP
140   fprintf(stderr, "t%s [ -vVhlp ] [ -c count ] [ -f <capture filter> ]\n", PACKAGE);
141   fprintf(stderr, "\t[ -F <capture file type> ] [ -i interface ] [ -n ]\n");
142   fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
143   fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
144 #else
145   fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ]\n", PACKAGE);
146   fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
147   fprintf(stderr, "\t[ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
148 #endif
149   fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
150   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
151     if (wtap_dump_can_open(i))
152       fprintf(stderr, "\t%s - %s\n",
153         wtap_file_type_short_string(i), wtap_file_type_string(i));
154   }
155   fprintf(stderr, "\tdefault is libpcap\n");
156 }
157
158 int
159 main(int argc, char *argv[])
160 {
161   int                  opt, i;
162   extern char         *optarg;
163   gboolean             arg_error = FALSE;
164 #ifdef HAVE_LIBPCAP
165 #ifdef WIN32
166   char pcap_version[] = "0.4a6";
167 #else
168   extern char          pcap_version[];
169 #endif
170 #endif
171
172 #ifdef WIN32
173   WSADATA               wsaData;
174 #endif
175
176   char                *gpf_path, *pf_path;
177   int                  gpf_open_errno, pf_open_errno;
178   int                  err;
179 #ifdef HAVE_LIBPCAP
180   gboolean             capture_filter_specified = FALSE;
181   int                  packet_count = 0;
182   GList               *if_list;
183   gchar                err_str[PCAP_ERRBUF_SIZE];
184 #else
185   gboolean             capture_option_specified = FALSE;
186 #endif
187   int                 out_file_type = WTAP_FILE_PCAP;
188   gchar               *cf_name = NULL, *rfilter = NULL;
189   dfilter             *rfcode = NULL;
190   e_prefs             *prefs;
191
192   /* Register all dissectors; we must do this before checking for the
193      "-G" flag, as the "-G" flag dumps a list of fields registered
194      by the dissectors, and we must do it before we read the preferences,
195      in case any dissectors register preferences. */
196   epan_init(PLUGIN_DIR);
197
198   /* Now register the preferences for any non-dissector modules.
199      We must do that before we read the preferences as well. */
200   prefs_register_modules();
201
202   /* If invoked with the "-G" flag, we dump out a glossary of
203      display filter symbols.
204
205      We do this here to mirror what happens in the GTK+ version, although
206      it's not necessary here. */
207   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
208     proto_registrar_dump();
209     exit(0);
210   }
211
212   /* Set the C-language locale to the native environment. */
213   setlocale(LC_ALL, "");
214
215   prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
216   if (gpf_path != NULL) {
217     fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path,
218         strerror(gpf_open_errno));
219   }
220   if (pf_path != NULL) {
221     fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path,
222         strerror(pf_open_errno));
223   }
224     
225   /* Initialize the capture file struct */
226   cfile.plist           = NULL;
227   cfile.plist_end       = NULL;
228   cfile.wth             = NULL;
229   cfile.filename        = NULL;
230   cfile.user_saved      = FALSE;
231   cfile.is_tempfile     = FALSE;
232   cfile.rfcode          = NULL;
233   cfile.dfilter         = NULL;
234   cfile.dfcode          = NULL;
235 #ifdef HAVE_LIBPCAP
236   cfile.cfilter         = g_strdup("");
237 #endif
238   cfile.iface           = NULL;
239   cfile.save_file       = NULL;
240   cfile.save_file_fd    = -1;
241   cfile.snap            = WTAP_MAX_PACKET_SIZE;
242   cfile.count           = 0;
243   col_init(&cfile.cinfo, prefs->num_cols);
244
245   /* Assemble the compile-time options */
246   snprintf(comp_info_str, 256,
247 #ifdef GTK_MAJOR_VERSION
248     "GTK+ %d.%d.%d, %s%s, %s%s, %s%s", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
249     GTK_MICRO_VERSION,
250 #else
251     "GTK+ (version unknown), %s%s, %s%s, %s%s",
252 #endif
253
254 #ifdef HAVE_LIBPCAP
255    "with libpcap ", pcap_version,
256 #else
257    "without libpcap", "",
258 #endif
259
260 #ifdef HAVE_LIBZ
261 #ifdef ZLIB_VERSION
262    "with libz ", ZLIB_VERSION,
263 #else /* ZLIB_VERSION */
264    "with libz ", "(version unknown)",
265 #endif /* ZLIB_VERSION */
266 #else /* HAVE_LIBZ */
267    "without libz", "",
268 #endif /* HAVE_LIBZ */
269
270 /* Oh, this is pretty */
271 #if defined(HAVE_UCD_SNMP_SNMP_H)
272 #ifdef HAVE_UCD_SNMP_VERSION_H
273    "with UCD SNMP ", VersionInfo
274 #else /* HAVE_UCD_SNMP_VERSION_H */
275    "with UCD SNMP ", "(version unknown)"
276 #endif /* HAVE_UCD_SNMP_VERSION_H */
277 #elif defined(HAVE_SNMP_SNMP_H)
278 #ifdef HAVE_SNMP_VERSION_H
279    "with CMU SNMP ", snmp_Version()
280 #else /* HAVE_SNMP_VERSION_H */
281    "with CMU SNMP ", "(version unknown)"
282 #endif /* HAVE_SNMP_VERSION_H */
283 #else /* no SNMP */
284    "without SNMP", ""
285 #endif
286    );
287     
288   /* Now get our args */
289   while ((opt = getopt(argc, argv, "c:Df:F:hi:lno:pr:R:s:t:vw:Vx")) != EOF) {
290     switch (opt) {
291       case 'c':        /* Capture xxx packets */
292 #ifdef HAVE_LIBPCAP
293         packet_count = atoi(optarg);
294 #else
295         capture_option_specified = TRUE;
296         arg_error = TRUE;
297 #endif
298         break;
299       case 'f':
300 #ifdef HAVE_LIBPCAP
301         capture_filter_specified = TRUE;
302         cfile.cfilter = g_strdup(optarg);
303 #else
304         capture_option_specified = TRUE;
305         arg_error = TRUE;
306 #endif
307         break;
308       case 'F':
309         out_file_type = wtap_short_string_to_file_type(optarg);
310         if (out_file_type < 0) {
311           fprintf(stderr, "tethereal: \"%s\" is not a valid capture file type\n",
312                         optarg);
313           exit(1);
314         }
315         break;
316       case 'h':        /* Print help and exit */
317         print_usage();
318         exit(0);
319         break;
320       case 'i':        /* Use interface xxx */
321 #ifdef HAVE_LIBPCAP
322         cfile.iface = g_strdup(optarg);
323 #else
324         capture_option_specified = TRUE;
325         arg_error = TRUE;
326 #endif
327         break;
328       case 'l':        /* Line-buffer standard output */
329         setvbuf(stdout, NULL, _IOLBF, 0);
330         break;
331       case 'n':        /* No name resolution */
332         g_resolving_actif = 0;
333         break;
334       case 'o':        /* Override preference from command line */
335         switch (prefs_set_pref(optarg)) {
336
337         case PREFS_SET_SYNTAX_ERR:
338           fprintf(stderr, "tethereal: Invalid -o flag \"%s\"\n", optarg);
339           exit(1);
340           break;
341
342         case PREFS_SET_NO_SUCH_PREF:
343           fprintf(stderr, "tethereal: -o flag \"%s\" specifies unknown preference\n",
344                         optarg);
345           exit(1);
346           break;
347         }
348         break;
349       case 'p':        /* Don't capture in promiscuous mode */
350 #ifdef HAVE_LIBPCAP
351         promisc_mode = 0;
352 #else
353         capture_option_specified = TRUE;
354         arg_error = TRUE;
355 #endif
356         break;
357       case 'r':        /* Read capture file xxx */
358         cf_name = g_strdup(optarg);
359         break;
360       case 'R':        /* Read file filter */
361         rfilter = optarg;
362         break;
363       case 's':        /* Set the snapshot (capture) length */
364 #ifdef HAVE_LIBPCAP
365         cfile.snap = atoi(optarg);
366 #else
367         capture_option_specified = TRUE;
368         arg_error = TRUE;
369 #endif
370         break;
371       case 't':        /* Time stamp type */
372         if (strcmp(optarg, "r") == 0)
373           timestamp_type = RELATIVE;
374         else if (strcmp(optarg, "a") == 0)
375           timestamp_type = ABSOLUTE;
376         else if (strcmp(optarg, "ad") == 0)
377           timestamp_type = ABSOLUTE_WITH_DATE;
378         else if (strcmp(optarg, "d") == 0)
379           timestamp_type = DELTA;
380         else {
381           fprintf(stderr, "tethereal: Invalid time stamp type \"%s\"\n",
382             optarg);
383           fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
384           fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
385           exit(1);
386         }
387         break;
388       case 'v':        /* Show version and exit */
389         printf("t%s %s, with %s\n", PACKAGE, VERSION, comp_info_str);
390         exit(0);
391         break;
392       case 'w':        /* Write to capture file xxx */
393         cfile.save_file = g_strdup(optarg);
394         break;
395       case 'V':        /* Verbose */
396         verbose = TRUE;
397         break;
398       case 'x':        /* Print packet data in hex (and ASCII) */
399         print_hex = TRUE;
400         break;
401     }
402   }
403   
404   /* If no capture filter or read filter has been specified, and there are
405      still command-line arguments, treat them as the tokens of a capture
406      filter (if no "-r" flag was specified) or a read filter (if a "-r"
407      flag was specified. */
408   if (optind < argc) {
409     if (cf_name != NULL) {
410       if (rfilter != NULL) {
411         fprintf(stderr,
412 "tethereal: Read filters were specified both with \"-R\" and with additional command-line arguments\n");
413         exit(2);
414       }
415       rfilter = get_args_as_string(argc, argv, optind);
416     } else {
417 #ifdef HAVE_LIBPCAP
418       if (capture_filter_specified) {
419         fprintf(stderr,
420 "tethereal: Capture filters were specified both with \"-f\" and with additional command-line arguments\n");
421         exit(2);
422       }
423       cfile.cfilter = get_args_as_string(argc, argv, optind);
424 #else
425       capture_option_specified = TRUE;
426 #endif
427     }
428   }
429
430 #ifdef WIN32
431   /* Start windows sockets */
432   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
433 #endif
434
435   /* Notify all registered modules that have had any of their preferences
436      changed either from one of the preferences file or from the command
437      line that its preferences have changed. */
438   prefs_apply_all();
439
440 #ifndef HAVE_LIBPCAP
441   if (capture_option_specified)
442     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
443 #endif
444   if (arg_error)
445     print_usage();
446
447   /* Build the column format array */  
448   for (i = 0; i < cfile.cinfo.num_cols; i++) {
449     cfile.cinfo.col_fmt[i] = get_column_format(i);
450     cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
451     cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
452       NUM_COL_FMTS);
453     get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
454     cfile.cinfo.col_data[i] = NULL;
455     if (cfile.cinfo.col_fmt[i] == COL_INFO)
456       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
457     else
458       cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
459   }
460
461   if (cfile.snap < 1)
462     cfile.snap = WTAP_MAX_PACKET_SIZE;
463   else if (cfile.snap < MIN_PACKET_SIZE)
464     cfile.snap = MIN_PACKET_SIZE;
465   
466   if (rfilter != NULL) {
467     if (dfilter_compile(rfilter, &rfcode) != 0) {
468       fprintf(stderr, "tethereal: %s\n", dfilter_error_msg);
469       epan_cleanup();
470       exit(2);
471     }
472   }
473   cfile.rfcode = rfcode;
474   if (cf_name) {
475     err = open_cap_file(cf_name, FALSE, &cfile);
476     if (err != 0) {
477       epan_cleanup();
478       exit(2);
479     }
480     err = load_cap_file(&cfile, out_file_type);
481     if (err != 0) {
482       epan_cleanup();
483       exit(2);
484     }
485     cf_name[0] = '\0';
486   } else {
487     /* No capture file specified, so we're supposed to do a live capture;
488        do we have support for live captures? */
489 #ifdef HAVE_LIBPCAP
490     /* Yes; did the user specify an interface to use? */
491     if (cfile.iface == NULL) {
492         /* No - pick the first one from the list of interfaces. */
493         if_list = get_interface_list(&err, err_str);
494         if (if_list == NULL) {
495             switch (err) {
496
497             case CANT_GET_INTERFACE_LIST:
498                 fprintf(stderr, "tethereal: Can't get list of interfaces: %s\n",
499                         err_str);
500                 break;
501
502             case NO_INTERFACES_FOUND:
503                 fprintf(stderr, "tethereal: There are no interfaces on which a capture can be done\n");
504                 break;
505             }
506             exit(2);
507         }
508         cfile.iface = g_strdup(if_list->data);  /* first interface */
509         free_interface_list(if_list);
510     }
511     capture(packet_count, out_file_type);
512 #else
513     /* No - complain. */
514     fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");
515     exit(2);
516 #endif
517   }
518
519   epan_cleanup();
520
521   exit(0);
522 }
523
524 #ifdef HAVE_LIBPCAP
525 /* Do the low-level work of a capture.
526    Returns TRUE if it succeeds, FALSE otherwise. */
527 static int
528 capture(int packet_count, int out_file_type)
529 {
530   gchar       err_str[PCAP_ERRBUF_SIZE];
531   bpf_u_int32 netnum, netmask;
532   void        (*oldhandler)(int);
533   int         err, inpkts;
534   char        errmsg[1024+1];
535 #ifndef _WIN32
536   static const char ppamsg[] = "can't find PPA for ";
537   char       *libpcap_warn;
538 #endif
539
540   /* Initialize the table of conversations. */
541   epan_conversation_init();
542
543   /* Initialize protocol-specific variables */
544   init_all_protocols();
545
546   ld.linktype       = WTAP_ENCAP_UNKNOWN;
547   ld.pdh            = NULL;
548
549   /* Open the network interface to capture from it. */
550   ld.pch = pcap_open_live(cfile.iface, cfile.snap, promisc_mode, 1000, err_str);
551
552   if (ld.pch == NULL) {
553     /* Well, we couldn't start the capture. */
554 #ifdef _WIN32
555     /* On Win32 OSes, the capture devices are probably available to all
556        users; don't warn about permissions problems.
557
558        Do, however, warn that Token Ring and PPP devices aren't supported. */
559     snprintf(errmsg, sizeof errmsg,
560         "The capture session could not be initiated (%s).\n"
561         "Please check that you have the proper interface specified.\n"
562         "\n"
563         "Note that the driver Tethereal uses for packet capture on Windows\n"
564         "doesn't support capturing on Token Ring interfaces, and doesn't\n"
565         "support capturing on PPP/WAN interfaces in Windows NT/2000.\n",
566         err_str);
567 #else
568       /* If we got a "can't find PPA for XXX" message, warn the user (who
569          is running Ethereal on HP-UX) that they don't have a version
570          of libpcap patched to properly handle HP-UX (the patched version
571          says "can't find /dev/dlpi PPA for XXX" rather than "can't find
572          PPA for XXX"). */
573       if (strncmp(err_str, ppamsg, sizeof ppamsg - 1) == 0)
574         libpcap_warn =
575           "\n\n"
576           "You are running Tethereal with a version of the libpcap library\n"
577           "that doesn't handle HP-UX network devices well; this means that\n"
578           "Tethereal may not be able to capture packets.\n"
579           "\n"
580           "To fix this, you will need to download the source to Tethereal\n"
581           "from www.ethereal.com if you have not already done so, read\n"
582           "the instructions in the \"README.hpux\" file in the source\n"
583           "distribution, download the source to libpcap if you have not\n"
584           "already done so, patch libpcap as per the instructions, rebuild\n"
585           "and install libpcap, and then build Tethereal (if you have already\n"
586           "built Tethereal from source, do a \"make distclean\" and re-run\n"
587           "configure before building).";
588       else
589         libpcap_warn = "";
590     snprintf(errmsg, sizeof errmsg,
591       "The capture session could not be initiated (%s).\n"
592       "Please check to make sure you have sufficient permissions, and that\n"
593       "you have the proper interface specified.%s", err_str, libpcap_warn);
594 #endif
595     goto error;
596   }
597
598   if (cfile.cfilter) {
599     /* A capture filter was specified; set it up. */
600     if (pcap_lookupnet (cfile.iface, &netnum, &netmask, err_str) < 0) {
601       /*
602        * Well, we can't get the netmask for this interface; it's used
603        * only for filters that check for broadcast IP addresses, so
604        * we just warn the user, and punt and use 0.
605        */
606       fprintf(stderr, 
607         "Warning:  Couldn't obtain netmask info (%s)\n.", err_str);
608       netmask = 0;
609     }
610     if (pcap_compile(ld.pch, &cfile.fcode, cfile.cfilter, 1, netmask) < 0) {
611       snprintf(errmsg, sizeof errmsg, "Unable to parse filter string (%s).",
612         pcap_geterr(ld.pch));
613       goto error;
614     }
615     if (pcap_setfilter(ld.pch, &cfile.fcode) < 0) {
616       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
617         pcap_geterr(ld.pch));
618       goto error;
619     }
620   }
621
622   ld.linktype = wtap_pcap_encap_to_wtap_encap(pcap_datalink(ld.pch));
623   if (cfile.save_file != NULL) {
624     /* Set up to write to the capture file. */
625     if (ld.linktype == WTAP_ENCAP_UNKNOWN) {
626       strcpy(errmsg, "The network you're capturing from is of a type"
627                " that Tethereal doesn't support.");
628       goto error;
629     }
630     ld.pdh = wtap_dump_open(cfile.save_file, out_file_type,
631                 ld.linktype, pcap_snapshot(ld.pch), &err);
632
633     if (ld.pdh == NULL) {
634       snprintf(errmsg, sizeof errmsg, file_open_error_message(errno, TRUE),
635                 cfile.save_file);
636       goto error;
637     }
638   }
639
640   /* Catch SIGINT and SIGTERM and, if we get either of them, clean up
641      and exit.
642      XXX - deal with signal semantics on various platforms.  Or just
643      use "sigaction()" and be done with it? */
644   signal(SIGTERM, capture_cleanup);
645   signal(SIGINT, capture_cleanup);
646 #if !defined(WIN32)
647   if ((oldhandler = signal(SIGHUP, capture_cleanup)) != SIG_DFL)
648     signal(SIGHUP, oldhandler);
649 #endif
650
651   /* Let the user know what interface was chosen. */
652   printf("Capturing on %s\n", cfile.iface);
653
654   inpkts = pcap_loop(ld.pch, packet_count, capture_pcap_cb, (u_char *) &ld);
655   pcap_close(ld.pch);
656
657   /* Send a newline if we were printing packet counts to stdout */
658   if (cfile.save_file != NULL) {
659     printf("\n");
660   }
661
662   return TRUE;
663
664 error:
665   g_free(cfile.save_file);
666   cfile.save_file = NULL;
667   fprintf(stderr, "tethereal: %s\n", errmsg);
668   if (ld.pch != NULL)
669     pcap_close(ld.pch);
670
671   return FALSE;
672 }
673
674 static void
675 capture_pcap_cb(u_char *user, const struct pcap_pkthdr *phdr,
676   const u_char *pd)
677 {
678   struct wtap_pkthdr whdr;
679   loop_data *ld = (loop_data *) user;
680   cb_args_t args;
681
682   whdr.ts.tv_sec = phdr->ts.tv_sec;
683   whdr.ts.tv_usec = phdr->ts.tv_usec;
684   whdr.caplen = phdr->caplen;
685   whdr.len = phdr->len;
686   whdr.pkt_encap = ld->linktype;
687
688   args.cf = &cfile;
689   args.pdh = ld->pdh;
690   if (ld->pdh) {
691     wtap_dispatch_cb_write((u_char *)&args, &whdr, 0, NULL, pd);
692     printf("\r%u ", cfile.count);
693     fflush(stdout);
694   } else {
695     wtap_dispatch_cb_print((u_char *)&args, &whdr, 0, NULL, pd);
696   }
697 }
698
699 static void
700 capture_cleanup(int signum)
701 {
702   int err;
703
704   printf("\n");
705   pcap_close(ld.pch);
706   if (ld.pdh != NULL)
707     wtap_dump_close(ld.pdh, &err);
708   /* XXX - complain if this fails */
709   exit(0);
710 }
711 #endif /* HAVE_LIBPCAP */
712
713 static int
714 load_cap_file(capture_file *cf, int out_file_type)
715 {
716   gint         linktype;
717   wtap_dumper *pdh;
718   int          err;
719   int          success;
720   cb_args_t    args;
721
722   linktype = wtap_file_encap(cf->wth);
723   if (cf->save_file != NULL) {
724     /* Set up to write to the capture file. */
725     pdh = wtap_dump_open(cf->save_file, out_file_type,
726                 linktype, wtap_snapshot_length(cf->wth), &err);
727
728     if (pdh == NULL) {
729       /* We couldn't set up to write to the capture file. */
730       switch (err) {
731
732       case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
733         fprintf(stderr,
734                 "tethereal: Capture files can't be written in that format.\n");
735         break;
736
737       case WTAP_ERR_UNSUPPORTED_ENCAP:
738       case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
739         fprintf(stderr,
740 "tethereal: The capture file being read cannot be written in that format.\n");
741         break;
742
743       case WTAP_ERR_CANT_OPEN:
744         fprintf(stderr,
745 "tethereal: The file \"%s\" couldn't be created for some unknown reason.\n",
746                  cf->save_file);
747         break;
748
749       case WTAP_ERR_SHORT_WRITE:
750         fprintf(stderr,
751 "tethereal: A full header couldn't be written to the file \"%s\".\n",
752                 cf->save_file);
753         break;
754
755       default:
756         if (err < 0) {
757           fprintf(stderr,
758                 "tethereal: The file \"%s\" could not be opened: Error %d.\n",
759                 cf->save_file, err);
760         } else {
761           fprintf(stderr,
762                 "tethereal: The file \"%s\" could not be opened: %s\n.",
763                 cf->save_file, strerror(err));
764         }
765         break;
766       }
767       goto out;
768     }
769     args.cf = cf;
770     args.pdh = pdh;
771     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_write, (u_char *) &args,
772                         &err);
773   } else {
774     args.cf = cf;
775     args.pdh = NULL;
776     success = wtap_loop(cf->wth, 0, wtap_dispatch_cb_print, (u_char *) &args,
777                         &err);
778   }
779   if (!success) {
780     /* Print up a message box noting that the read failed somewhere along
781        the line. */
782     switch (err) {
783
784     case WTAP_ERR_UNSUPPORTED_ENCAP:
785       fprintf(stderr,
786 "tethereal: The capture file is for a network type that Tethereal doesn't support.\n");
787       break;
788
789     case WTAP_ERR_CANT_READ:
790       fprintf(stderr,
791 "tethereal: An attempt to read from the file failed for some unknown reason.\n");
792       break;
793
794     case WTAP_ERR_SHORT_READ:
795       fprintf(stderr,
796 "tethereal: The capture file appears to have been cut short in the middle of a packet.\n");
797       break;
798
799     case WTAP_ERR_BAD_RECORD:
800       fprintf(stderr,
801 "tethereal: The capture file appears to be damaged or corrupt.\n");
802       break;
803
804     default:
805       fprintf(stderr,
806 "tethereal: An error occurred while reading the capture file: %s.\n",
807         wtap_strerror(err));
808       break;
809     }
810   }
811
812 out:
813   wtap_close(cf->wth);
814   cf->wth = NULL;
815
816   return err;
817 }
818
819 static void
820 fill_in_fdata(frame_data *fdata, capture_file *cf,
821         const struct wtap_pkthdr *phdr,
822         const union wtap_pseudo_header *pseudo_header, int offset)
823 {
824   int i;
825
826   fdata->next = NULL;
827   fdata->prev = NULL;
828   fdata->pfd = NULL;
829   fdata->num = cf->count;
830   fdata->pkt_len = phdr->len;
831   fdata->cap_len = phdr->caplen;
832   fdata->file_off = offset;
833   fdata->cinfo = NULL;
834   fdata->lnk_t = phdr->pkt_encap;
835   fdata->abs_secs  = phdr->ts.tv_sec;
836   fdata->abs_usecs = phdr->ts.tv_usec;
837   fdata->flags.passed_dfilter = 0;
838   fdata->flags.encoding = CHAR_ASCII;
839   fdata->flags.visited = 0;
840   fdata->flags.marked = 0;
841
842   /* If we don't have the time stamp of the first packet in the
843      capture, it's because this is the first packet.  Save the time
844      stamp of this packet as the time stamp of the first packet. */
845   if (!firstsec && !firstusec) {
846     firstsec  = fdata->abs_secs;
847     firstusec = fdata->abs_usecs;
848   }
849
850   /* If we don't have the time stamp of the previous displayed packet,
851      it's because this is the first displayed packet.  Save the time
852      stamp of this packet as the time stamp of the previous displayed
853      packet. */
854   if (!prevsec && !prevusec) {
855     prevsec  = fdata->abs_secs;
856     prevusec = fdata->abs_usecs;
857   }
858
859   /* Get the time elapsed between the first packet and this packet. */
860   compute_timestamp_diff(&fdata->rel_secs, &fdata->rel_usecs,
861                 fdata->abs_secs, fdata->abs_usecs, firstsec, firstusec);
862
863   /* If it's greater than the current elapsed time, set the elapsed time
864      to it (we check for "greater than" so as not to be confused by
865      time moving backwards). */
866   if (cf->esec < fdata->rel_secs
867         || (cf->esec == fdata->rel_secs && cf->eusec < fdata->rel_usecs)) {
868     cf->esec = fdata->rel_secs;
869     cf->eusec = fdata->rel_usecs;
870   }
871   
872   /* Get the time elapsed between the previous displayed packet and
873      this packet. */
874   compute_timestamp_diff(&fdata->del_secs, &fdata->del_usecs,
875                 fdata->abs_secs, fdata->abs_usecs, prevsec, prevusec);
876   prevsec = fdata->abs_secs;
877   prevusec = fdata->abs_usecs;
878
879   fdata->cinfo = &cf->cinfo;
880   for (i = 0; i < fdata->cinfo->num_cols; i++) {
881     fdata->cinfo->col_buf[i][0] = '\0';
882     fdata->cinfo->col_data[i] = fdata->cinfo->col_buf[i];
883   }
884 }
885
886 static void
887 wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
888   union wtap_pseudo_header *pseudo_header, const u_char *buf)
889 {
890   cb_args_t    *args = (cb_args_t *) user;
891   capture_file *cf = args->cf;
892   wtap_dumper  *pdh = args->pdh;
893   frame_data    fdata;
894   proto_tree   *protocol_tree;
895   int           err;
896   gboolean      passed;
897   epan_dissect_t *edt;
898
899   cf->count++;
900   if (cf->rfcode) {
901     fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
902     protocol_tree = proto_tree_create_root();
903     edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
904     passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
905   } else {
906     protocol_tree = NULL;
907     passed = TRUE;
908     edt = NULL;
909   }
910   if (passed) {
911     /* XXX - do something if this fails */
912     wtap_dump(pdh, phdr, pseudo_header, buf, &err);
913   }
914   if (protocol_tree != NULL)
915     proto_tree_free(protocol_tree);
916   if (edt != NULL)
917     epan_dissect_free(edt);
918 }
919
920 static void
921 wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
922   union wtap_pseudo_header *pseudo_header, const u_char *buf)
923 {
924   cb_args_t    *args = (cb_args_t *) user;
925   capture_file *cf = args->cf;
926   frame_data    fdata;
927   proto_tree   *protocol_tree;
928   gboolean      passed;
929   print_args_t  print_args;
930   epan_dissect_t *edt;
931   int           i;
932
933   cf->count++;
934
935   /* The protocol tree will be "visible", i.e., printed, only if we're
936      not printing a summary. */
937   proto_tree_is_visible = verbose;
938
939   fill_in_fdata(&fdata, cf, phdr, pseudo_header, offset);
940
941   passed = TRUE;
942   if (cf->rfcode || verbose)
943     protocol_tree = proto_tree_create_root();
944   else
945     protocol_tree = NULL;
946   edt = epan_dissect_new(pseudo_header, buf, &fdata, protocol_tree);
947   if (cf->rfcode)
948     passed = dfilter_apply(cf->rfcode, protocol_tree, buf, fdata.cap_len);
949   if (passed) {
950     /* The packet passed the read filter. */
951     if (verbose) {
952       /* Print the information in the protocol tree. */
953       print_args.to_file = TRUE;
954       print_args.format = PR_FMT_TEXT;
955       print_args.print_summary = FALSE;
956       print_args.print_hex = print_hex;
957       print_args.expand_all = TRUE;
958       proto_tree_print(FALSE, &print_args, (GNode *)protocol_tree,
959                         buf, &fdata, stdout);
960       if (!print_hex) {
961         /* "print_hex_data()" will put out a leading blank line, as well
962            as a trailing one; print one here, to separate the packets,
963            only if "print_hex_data()" won't be called. */
964         printf("\n");
965       }
966     } else {
967       /* Just fill in the columns. */
968       fill_in_columns(&fdata);
969
970       /* Now print them. */
971       for (i = 0; i < cf->cinfo.num_cols; i++) {
972         switch (cf->cinfo.col_fmt[i]) {
973         case COL_NUMBER:
974           /*
975            * Don't print this if we're doing a live capture from a network
976            * interface - if we're doing a live capture, you won't be
977            * able to look at the capture in the future (it's not being
978            * saved anywhere), so the frame numbers are unlikely to be
979            * useful.
980            *
981            * (XXX - it might be nice to be able to save and print at
982            * the same time, sort of like an "Update list of packets
983            * in real time" capture in Ethereal.)
984            */
985           if (cf->iface != NULL)
986             continue;
987           printf("%3s", cf->cinfo.col_data[i]);
988           break;
989
990         case COL_CLS_TIME:
991         case COL_REL_TIME:
992         case COL_ABS_TIME:
993         case COL_ABS_DATE_TIME: /* XXX - wider */
994           printf("%10s", cf->cinfo.col_data[i]);
995           break;
996
997         case COL_DEF_SRC:
998         case COL_RES_SRC:
999         case COL_UNRES_SRC:
1000         case COL_DEF_DL_SRC:
1001         case COL_RES_DL_SRC:
1002         case COL_UNRES_DL_SRC:
1003         case COL_DEF_NET_SRC:
1004         case COL_RES_NET_SRC:
1005         case COL_UNRES_NET_SRC:
1006           printf("%12s", cf->cinfo.col_data[i]);
1007           break;
1008
1009         case COL_DEF_DST:
1010         case COL_RES_DST:
1011         case COL_UNRES_DST:
1012         case COL_DEF_DL_DST:
1013         case COL_RES_DL_DST:
1014         case COL_UNRES_DL_DST:
1015         case COL_DEF_NET_DST:
1016         case COL_RES_NET_DST:
1017         case COL_UNRES_NET_DST:
1018           printf("%-12s", cf->cinfo.col_data[i]);
1019           break;
1020
1021         default:
1022           printf("%s", cf->cinfo.col_data[i]);
1023           break;
1024         }
1025         if (i != cf->cinfo.num_cols - 1) {
1026           /*
1027            * This isn't the last column, so we need to print a
1028            * separator between this column and the next.
1029            *
1030            * If we printed a network source and are printing a
1031            * network destination of the same type next, separate
1032            * them with "->"; if we printed a network destination
1033            * and are printing a network source of the same type
1034            * next, separate them with "<-"; otherwise separate them
1035            * with a space.
1036            */
1037           switch (cf->cinfo.col_fmt[i]) {
1038
1039           case COL_DEF_SRC:
1040           case COL_RES_SRC:
1041           case COL_UNRES_SRC:
1042             switch (cf->cinfo.col_fmt[i + 1]) {
1043
1044             case COL_DEF_DST:
1045             case COL_RES_DST:
1046             case COL_UNRES_DST:
1047               printf(" -> ");
1048               break;
1049
1050             default:
1051               putchar(' ');
1052               break;
1053             }
1054             break;
1055
1056           case COL_DEF_DL_SRC:
1057           case COL_RES_DL_SRC:
1058           case COL_UNRES_DL_SRC:
1059             switch (cf->cinfo.col_fmt[i + 1]) {
1060
1061             case COL_DEF_DL_DST:
1062             case COL_RES_DL_DST:
1063             case COL_UNRES_DL_DST:
1064               printf(" -> ");
1065               break;
1066
1067             default:
1068               putchar(' ');
1069               break;
1070             }
1071             break;
1072
1073           case COL_DEF_NET_SRC:
1074           case COL_RES_NET_SRC:
1075           case COL_UNRES_NET_SRC:
1076             switch (cf->cinfo.col_fmt[i + 1]) {
1077
1078             case COL_DEF_NET_DST:
1079             case COL_RES_NET_DST:
1080             case COL_UNRES_NET_DST:
1081               printf(" -> ");
1082               break;
1083
1084             default:
1085               putchar(' ');
1086               break;
1087             }
1088             break;
1089
1090           case COL_DEF_DST:
1091           case COL_RES_DST:
1092           case COL_UNRES_DST:
1093             switch (cf->cinfo.col_fmt[i + 1]) {
1094
1095             case COL_DEF_SRC:
1096             case COL_RES_SRC:
1097             case COL_UNRES_SRC:
1098               printf(" <- ");
1099               break;
1100
1101             default:
1102               putchar(' ');
1103               break;
1104             }
1105             break;
1106
1107           case COL_DEF_DL_DST:
1108           case COL_RES_DL_DST:
1109           case COL_UNRES_DL_DST:
1110             switch (cf->cinfo.col_fmt[i + 1]) {
1111
1112             case COL_DEF_DL_SRC:
1113             case COL_RES_DL_SRC:
1114             case COL_UNRES_DL_SRC:
1115               printf(" <- ");
1116               break;
1117
1118             default:
1119               putchar(' ');
1120               break;
1121             }
1122             break;
1123
1124           case COL_DEF_NET_DST:
1125           case COL_RES_NET_DST:
1126           case COL_UNRES_NET_DST:
1127             switch (cf->cinfo.col_fmt[i + 1]) {
1128
1129             case COL_DEF_NET_SRC:
1130             case COL_RES_NET_SRC:
1131             case COL_UNRES_NET_SRC:
1132               printf(" <- ");
1133               break;
1134
1135             default:
1136               putchar(' ');
1137               break;
1138             }
1139             break;
1140
1141           default:
1142             putchar(' ');
1143             break;
1144           }
1145         }
1146       }
1147       putchar('\n');
1148     }
1149     if (print_hex) {
1150       print_hex_data(stdout, print_args.format, buf,
1151                         fdata.cap_len, fdata.flags.encoding);
1152       putchar('\n');
1153     }
1154     fdata.cinfo = NULL;
1155   }
1156   if (protocol_tree != NULL)
1157     proto_tree_free(protocol_tree);
1158
1159   epan_dissect_free(edt);
1160
1161   proto_tree_is_visible = FALSE;
1162 }
1163
1164 char *
1165 file_open_error_message(int err, gboolean for_writing)
1166 {
1167   char *errmsg;
1168   static char errmsg_errno[1024+1];
1169
1170   switch (err) {
1171
1172   case WTAP_ERR_NOT_REGULAR_FILE:
1173     errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
1174     break;
1175
1176   case WTAP_ERR_FILE_UNKNOWN_FORMAT:
1177   case WTAP_ERR_UNSUPPORTED:
1178     /* Seen only when opening a capture file for reading. */
1179     errmsg = "The file \"%s\" is not a capture file in a format Tethereal understands.";
1180     break;
1181
1182   case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
1183     /* Seen only when opening a capture file for writing. */
1184     errmsg = "Tethereal does not support writing capture files in that format.";
1185     break;
1186
1187   case WTAP_ERR_UNSUPPORTED_ENCAP:
1188   case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
1189     if (for_writing)
1190       errmsg = "Tethereal cannot save this capture in that format.";
1191     else
1192       errmsg = "The file \"%s\" is a capture for a network type that Tethereal doesn't support.";
1193     break;
1194
1195   case WTAP_ERR_BAD_RECORD:
1196     errmsg = "The file \"%s\" appears to be damaged or corrupt.";
1197     break;
1198
1199   case WTAP_ERR_CANT_OPEN:
1200     if (for_writing)
1201       errmsg = "The file \"%s\" could not be created for some unknown reason.";
1202     else
1203       errmsg = "The file \"%s\" could not be opened for some unknown reason.";
1204     break;
1205
1206   case WTAP_ERR_SHORT_READ:
1207     errmsg = "The file \"%s\" appears to have been cut short"
1208              " in the middle of a packet.";
1209     break;
1210
1211   case WTAP_ERR_SHORT_WRITE:
1212     errmsg = "A full header couldn't be written to the file \"%s\".";
1213     break;
1214
1215   case ENOENT:
1216     if (for_writing)
1217       errmsg = "The path to the file \"%s\" does not exist.";
1218     else
1219       errmsg = "The file \"%s\" does not exist.";
1220     break;
1221
1222   case EACCES:
1223     if (for_writing)
1224       errmsg = "You do not have permission to create or write to the file \"%s\".";
1225     else
1226       errmsg = "You do not have permission to read the file \"%s\".";
1227     break;
1228
1229   case EISDIR:
1230     errmsg = "\"%s\" is a directory (folder), not a file.";
1231     break;
1232
1233   default:
1234     snprintf(errmsg_errno, sizeof(errmsg_errno),
1235              "The file \"%%s\" could not be opened: %s.",
1236              wtap_strerror(err));
1237     errmsg = errmsg_errno;
1238     break;
1239   }
1240   return errmsg;
1241 }
1242
1243 int
1244 open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
1245 {
1246   wtap       *wth;
1247   int         err;
1248   FILE_T      fh;
1249   int         fd;
1250   struct stat cf_stat;
1251   char        err_msg[2048+1];
1252
1253   wth = wtap_open_offline(fname, &err, FALSE);
1254   if (wth == NULL)
1255     goto fail;
1256
1257   /* Find the size of the file. */
1258   fh = wtap_file(wth);
1259   fd = wtap_fd(wth);
1260   if (fstat(fd, &cf_stat) < 0) {
1261     err = errno;
1262     wtap_close(wth);
1263     goto fail;
1264   }
1265
1266   /* The open succeeded.  Fill in the information for this file. */
1267
1268   /* Initialize the table of conversations. */
1269   epan_conversation_init();
1270
1271   /* Initialize protocol-specific variables */
1272   init_all_protocols();
1273
1274   cf->wth = wth;
1275   cf->filed = fd;
1276   cf->f_len = cf_stat.st_size;
1277
1278   /* Set the file name because we need it to set the follow stream filter.
1279      XXX - is that still true?  We need it for other reasons, though,
1280      in any case. */
1281   cf->filename = g_strdup(fname);
1282
1283   /* Indicate whether it's a permanent or temporary file. */
1284   cf->is_tempfile = is_tempfile;
1285
1286   /* If it's a temporary capture buffer file, mark it as not saved. */
1287   cf->user_saved = !is_tempfile;
1288
1289   cf->cd_t      = wtap_file_type(cf->wth);
1290   cf->count     = 0;
1291   cf->drops     = 0;
1292   cf->esec      = 0;
1293   cf->eusec     = 0;
1294   cf->snap      = wtap_snapshot_length(cf->wth);
1295   cf->progbar_quantum = 0;
1296   cf->progbar_nextstep = 0;
1297   firstsec = 0, firstusec = 0;
1298   prevsec = 0, prevusec = 0;
1299  
1300   return (0);
1301
1302 fail:
1303   snprintf(err_msg, sizeof err_msg, file_open_error_message(err, FALSE), fname);
1304   fprintf(stderr, "tethereal: %s\n", err_msg);
1305   return (err);
1306 }