Put the IGMP type field value into the PIM tree, as is done for other
[obnox/wireshark/wip.git] / tethereal.c
index b1adb1c6f7028352fa46d7cf6a7f0f0adedb8ed5..ff6722c75f6a53c9d4425630ac57fb44a6a1b638 100644 (file)
@@ -1,9 +1,9 @@
 /* tethereal.c
  *
- * $Id: tethereal.c,v 1.76 2001/04/05 05:58:03 gram Exp $
+ * $Id: tethereal.c,v 1.86 2001/06/08 08:50:49 guy Exp $
  *
  * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@zing.org>
+ * By Gerald Combs <gerald@ethereal.com>
  * Copyright 1998 Gerald Combs
  *
  * Text-mode variant, by Gilbert Ramirez <gram@xiexie.org>.
@@ -32,6 +32,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <locale.h>
+#include <limits.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -92,6 +93,7 @@
 #include "resolv.h"
 #include "util.h"
 #include "conversation.h"
+#include "reassemble.h"
 #include "plugins.h"
 #include "register.h"
 
@@ -136,7 +138,6 @@ static void wtap_dispatch_cb_print(u_char *, const struct wtap_pkthdr *, int,
 packet_info  pi;
 capture_file cfile;
 FILE        *data_out_file = NULL;
-guint        main_ctx, file_ctx;
 ts_type timestamp_type = RELATIVE;
 #ifdef HAVE_LIBPCAP
 static int promisc_mode = TRUE;
@@ -150,14 +151,14 @@ print_usage(void)
   fprintf(stderr, "This is GNU t%s %s, compiled %s\n", PACKAGE, VERSION,
        comp_info_str->str);
 #ifdef HAVE_LIBPCAP
-  fprintf(stderr, "t%s [ -DvVhlp ] [ -c count ] [ -f <capture filter> ]\n", PACKAGE);
-  fprintf(stderr, "\t[ -F <capture file type> ] [ -i interface ] [ -n ]\n");
-  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
-  fprintf(stderr, "\t[ -s snaplen ] [ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
+  fprintf(stderr, "t%s [ -DvVhlp ] [ -c <count> ] [ -f <capture filter> ]\n", PACKAGE);
+  fprintf(stderr, "\t[ -F <capture file type> ] [ -i <interface> ] [ -n ] [ -N <resolving> ]\n");
+  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
+  fprintf(stderr, "\t[ -s <snaplen> ] [ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
 #else
-  fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ]\n", PACKAGE);
-  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r infile ] [ -R <read filter> ]\n");
-  fprintf(stderr, "\t[ -t <time stamp format> ] [ -w savefile ] [ -x ]\n");
+  fprintf(stderr, "t%s [ -vVhl ] [ -F <capture file type> ] [ -n ] [ -N <resolving> ]\n", PACKAGE);
+  fprintf(stderr, "\t[ -o <preference setting> ] ... [ -r <infile> ] [ -R <read filter> ]\n");
+  fprintf(stderr, "\t[ -t <time stamp format> ] [ -w <savefile> ] [ -x ]\n");
 #endif
   fprintf(stderr, "Valid file type arguments to the \"-F\" flag:\n");
   for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
@@ -168,6 +169,31 @@ print_usage(void)
   fprintf(stderr, "\tdefault is libpcap\n");
 }
 
+int
+get_positive_int(const char *string, const char *name)
+{
+  long number;
+  char *p;
+
+  number = strtol(string, &p, 10);
+  if (p == string || *p != '\0') {
+    fprintf(stderr, "tethereal: The specified %s \"%s\" is not a decimal number\n",
+           name, string);
+    exit(1);
+  }
+  if (number < 0) {
+    fprintf(stderr, "tethereal: The specified %s \"%s\" is a negative number\n",
+           name, string);
+    exit(1);
+  }
+  if (number > INT_MAX) {
+    fprintf(stderr, "tethereal: The specified %s \"%s\" is too large (greater than %d)\n",
+           name, string, INT_MAX);
+    exit(1);
+  }
+  return number;
+}
+
 int
 main(int argc, char *argv[])
 {
@@ -197,10 +223,11 @@ main(int argc, char *argv[])
 #else
   gboolean             capture_option_specified = FALSE;
 #endif
-  int                 out_file_type = WTAP_FILE_PCAP;
+  int                  out_file_type = WTAP_FILE_PCAP;
   gchar               *cf_name = NULL, *rfilter = NULL;
   dfilter_t           *rfcode = NULL;
   e_prefs             *prefs;
+  char                 badopt;
 
   /* Register all dissectors; we must do this before checking for the
      "-G" flag, as the "-G" flag dumps a list of fields registered
@@ -310,11 +337,11 @@ main(int argc, char *argv[])
 #endif
     
   /* Now get our args */
-  while ((opt = getopt(argc, argv, "c:Df:F:hi:lno:pr:R:s:t:vw:Vx")) != EOF) {
+  while ((opt = getopt(argc, argv, "c:Df:F:hi:lnN:o:pr:R:s:t:vw:Vx")) != EOF) {
     switch (opt) {
       case 'c':        /* Capture xxx packets */
 #ifdef HAVE_LIBPCAP
-        packet_count = atoi(optarg);
+        packet_count = get_positive_int(optarg, "packet count");
 #else
         capture_option_specified = TRUE;
         arg_error = TRUE;
@@ -391,8 +418,18 @@ main(int argc, char *argv[])
        line_buffered = TRUE;
        break;
       case 'n':        /* No name resolution */
-       g_resolving_actif = 0;
-       break;
+        prefs->name_resolve = PREFS_RESOLV_NONE;
+        break;
+      case 'N':        /* Select what types of addresses/port #s to resolve */
+        if (prefs->name_resolve == PREFS_RESOLV_ALL)
+          prefs->name_resolve = PREFS_RESOLV_NONE;
+        badopt = string_to_name_resolve(optarg, &prefs->name_resolve);
+        if (badopt != '\0') {
+          fprintf(stderr, "tethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
+                       badopt);
+          exit(1);
+        }
+        break;
       case 'o':        /* Override preference from command line */
         switch (prefs_set_pref(optarg)) {
 
@@ -424,7 +461,7 @@ main(int argc, char *argv[])
         break;
       case 's':        /* Set the snapshot (capture) length */
 #ifdef HAVE_LIBPCAP
-        cfile.snap = atoi(optarg);
+        cfile.snap = get_positive_int(optarg, "snapshot length");
 #else
         capture_option_specified = TRUE;
         arg_error = TRUE;
@@ -588,7 +625,7 @@ main(int argc, char *argv[])
 
   epan_cleanup();
 
-  exit(0);
+  return 0;
 }
 
 #ifdef HAVE_LIBPCAP
@@ -615,6 +652,12 @@ capture(int packet_count, int out_file_type)
   /* Initialize protocol-specific variables */
   init_all_protocols();
 
+  /* Initialize the common data structures for fragment reassembly.
+     Must be done *after* "init_all_protocols()", as "init_all_protocols()"
+     may free up space for fragments, which it finds by using the
+     data structures that "reassemble_init()" frees. */
+  reassemble_init();
+
   ld.linktype       = WTAP_ENCAP_UNKNOWN;
   ld.pdh            = NULL;
 
@@ -639,9 +682,9 @@ capture(int packet_count, int out_file_type)
 #else
       /* If we got a "can't find PPA for XXX" message, warn the user (who
          is running Ethereal on HP-UX) that they don't have a version
-        of libpcap patched to properly handle HP-UX (the patched version
-        says "can't find /dev/dlpi PPA for XXX" rather than "can't find
-        PPA for XXX"). */
+        of libpcap that properly handles HP-UX (libpcap 0.6.x and later
+        versions, which properly handle HP-UX, say "can't find /dev/dlpi
+        PPA for XXX" rather than "can't find PPA for XXX"). */
       if (strncmp(err_str, ppamsg, sizeof ppamsg - 1) == 0)
        libpcap_warn =
          "\n\n"
@@ -649,14 +692,11 @@ capture(int packet_count, int out_file_type)
          "that doesn't handle HP-UX network devices well; this means that\n"
          "Tethereal may not be able to capture packets.\n"
          "\n"
-         "To fix this, you will need to download the source to Tethereal\n"
-         "from www.ethereal.com if you have not already done so, read\n"
-         "the instructions in the \"README.hpux\" file in the source\n"
-         "distribution, download the source to libpcap if you have not\n"
-         "already done so, patch libpcap as per the instructions, rebuild\n"
-         "and install libpcap, and then build Tethereal (if you have already\n"
-         "built Tethereal from source, do a \"make distclean\" and re-run\n"
-         "configure before building).";
+         "To fix this, you should install libpcap 0.6.2, or a later version\n"
+         "of libpcap, rather than libpcap 0.4 or 0.5.x.  It is available in\n"
+         "packaged binary form from the Software Porting And Archive Centre\n"
+         "for HP-UX; the Centre is at http://hpux.connect.org.uk/ - the page\n"
+         "at the URL lists a number of mirror sites.";
       else
        libpcap_warn = "";
     snprintf(errmsg, sizeof errmsg,
@@ -1039,7 +1079,8 @@ wtap_dispatch_cb_write(u_char *user, const struct wtap_pkthdr *phdr, int offset,
     proto_tree_free(protocol_tree);
   if (edt != NULL)
     epan_dissect_free(edt);
-  clear_fdata(&fdata);
+  if (cf->rfcode)
+    clear_fdata(&fdata);
 }
 
 static void
@@ -1128,7 +1169,7 @@ wtap_dispatch_cb_print(u_char *user, const struct wtap_pkthdr *phdr, int offset,
       print_args.print_hex = print_hex;
       print_args.expand_all = TRUE;
       proto_tree_print(FALSE, &print_args, (GNode *)protocol_tree,
-                       buf, &fdata, stdout);
+                       &fdata, stdout);
       if (!print_hex) {
         /* "print_hex_data()" will put out a leading blank line, as well
           as a trailing one; print one here, to separate the packets,
@@ -1467,6 +1508,12 @@ open_cap_file(char *fname, gboolean is_tempfile, capture_file *cf)
   /* Initialize protocol-specific variables */
   init_all_protocols();
 
+  /* Initialize the common data structures for fragment reassembly.
+     Must be done *after* "init_all_protocols()", as "init_all_protocols()"
+     may free up space for fragments, which it finds by using the
+     data structures that "reassemble_init()" frees. */
+  reassemble_init();
+
   cf->wth = wth;
   cf->filed = fd;
   cf->f_len = cf_stat.st_size;