Avoid a buffer overflow in the cseq_method field, a fixed-length character array.
[obnox/wireshark/wip.git] / tethereal.c
index cc289fcd2b542d29d365cb231b9934b2626e5e7b..22495ff100d00a399bc3dc3d36dcde99f9b3f32a 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-/* With MSVC and a libethereal.dll this file needs to import some variables 
-   in a special way. Therefore _NEED_VAR_IMPORT_ is defined. */
-#define _NEED_VAR_IMPORT_
-
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
@@ -90,9 +86,6 @@
 #include "util.h"
 #include "clopts_common.h"
 #include "version_info.h"
-#ifdef HAVE_LIBPCAP
-#include "pcap-util.h"
-#endif
 #include <epan/conversation.h>
 #include <epan/plugins.h>
 #include "register.h"
 #include <epan/timestamp.h>
 
 #ifdef HAVE_LIBPCAP
+#include <pcap.h>
+#include "pcap-util.h"
 #include <wiretap/wtap-capture.h>
 #include <wiretap/libpcap.h>
-#endif
-
 #ifdef _WIN32
 #include "capture-wpcap.h"
 #endif
+#include "capture.h"
+#endif
+
 
 /*
  * This is the template for the decode as option; it is shared between the
@@ -122,7 +118,6 @@ static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_
 static guint32 firstsec, firstusec;
 static guint32 prevsec, prevusec;
 static GString *comp_info_str, *runtime_info_str;
-static gboolean quiet;
 
 static gboolean print_packet_info;     /* TRUE if we're to print packet information */
 /*
@@ -143,6 +138,11 @@ static print_format_e print_format = PR_FMT_TEXT;
 static print_stream_t *print_stream;
 
 #ifdef HAVE_LIBPCAP
+/*
+ * TRUE if we're to print packet counts to keep track of captured packets.
+ */
+static gboolean print_packet_counts;
+
 typedef struct _loop_data {
   gboolean       go;           /* TRUE as long as we're supposed to keep capturing */
   gint           linktype;
@@ -168,48 +168,8 @@ typedef struct _loop_data {
 static loop_data ld;
 
 #ifdef HAVE_LIBPCAP
-typedef struct {
-    gchar    *cfilter;              /* Capture filter string */
-    gchar    *iface;                /* the network interface to capture from */
-    int      snaplen;               /* Maximum captured packet length */
-    int      promisc_mode;          /* Capture in promiscuous mode */
-    int      autostop_count;        /* Maximum packet count */
-    gboolean has_autostop_duration; /* TRUE if maximum capture duration
-                                       is specified */
-    gint32   autostop_duration;     /* Maximum capture duration */
-    gboolean has_autostop_filesize; /* TRUE if maximum capture file size
-                                       is specified */
-    gint32   autostop_filesize;     /* Maximum capture file size */
-    gboolean ringbuffer_on;         /* TRUE if ring buffer in use */
-    guint32  ringbuffer_num_files;  /* Number of ring buffer files */
-    gboolean has_ring_duration;     /* TRUE if ring duration specified */
-    gint32   ringbuffer_duration;   /* Switch file after n seconds */
-    int      linktype;              /* Data link type to use, or -1 for
-                                       "use default" */
-} capture_options;
-
-static capture_options capture_opts = {
-    "",                             /* No capture filter string specified */
-    NULL,                           /* Default is "pick the first interface" */
-    WTAP_MAX_PACKET_SIZE,           /* snapshot length - default is
-                                       infinite, in effect */
-    TRUE,                           /* promiscuous mode is the default */
-    0,                              /* max packet count - default is 0,
-                                       meaning infinite */
-    FALSE,                          /* maximum capture duration not
-                                       specified by default */
-    0,                              /* maximum capture duration */
-    FALSE,                          /* maximum capture file size not
-                                       specified by default */
-    0,                              /* maximum capture file size */
-    FALSE,                          /* ring buffer off by default */
-    RINGBUFFER_MIN_NUM_FILES,       /* default number of ring buffer files */
-    FALSE,                          /* Switch ring file after some */
-    0,                              /* specified time is off by default */
-    -1                              /* Default to not change link type */
-};
+static capture_options capture_opts;
 
-static gboolean list_link_layer_types;
 
 #ifdef SIGINFO
 static gboolean infodelay;     /* if TRUE, don't print capture info in SIGINFO handler */
@@ -306,167 +266,6 @@ print_usage(gboolean print_ver)
   fprintf(output, "\tdefault is libpcap\n");
 }
 
-#ifdef HAVE_LIBPCAP
-static int
-get_natural_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\" isn't a decimal number\n",
-           name, string);
-    exit(1);
-  }
-  if (number < 0) {
-    fprintf(stderr, "tethereal: The specified %s is a negative number\n",
-           name);
-    exit(1);
-  }
-  if (number > INT_MAX) {
-    fprintf(stderr, "tethereal: The specified %s is too large (greater than %d)\n",
-           name, INT_MAX);
-    exit(1);
-  }
-  return number;
-}
-
-static int
-get_positive_int(const char *string, const char *name)
-{
-  long number;
-
-  number = get_natural_int(string, name);
-
-  if (number == 0) {
-    fprintf(stderr, "tethereal: The specified %s is zero\n",
-           name);
-    exit(1);
-  }
-
-  return number;
-}
-
-/*
- * Given a string of the form "<autostop criterion>:<value>", as might appear
- * as an argument to a "-a" option, parse it and set the criterion in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-set_autostop_criterion(const char *autostoparg)
-{
-  guchar *p, *colonp;
-
-  colonp = strchr(autostoparg, ':');
-  if (colonp == NULL)
-    return FALSE;
-
-  p = colonp;
-  *p++ = '\0';
-
-  /*
-   * Skip over any white space (there probably won't be any, but
-   * as we allow it in the preferences file, we might as well
-   * allow it here).
-   */
-  while (isspace(*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-  if (strcmp(autostoparg,"duration") == 0) {
-    capture_opts.has_autostop_duration = TRUE;
-    capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
-  } else if (strcmp(autostoparg,"filesize") == 0) {
-    capture_opts.has_autostop_filesize = TRUE;
-    capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
-  } else {
-    return FALSE;
-  }
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-
-/*
- * Given a string of the form "<ring buffer file>:<duration>", as might appear
- * as an argument to a "-b" option, parse it and set the arguments in
- * question.  Return an indication of whether it succeeded or failed
- * in some fashion.
- */
-static gboolean
-get_ring_arguments(const char *arg)
-{
-  guchar *p = NULL, *colonp;
-
-  colonp = strchr(arg, ':');
-
-  if (colonp != NULL) {
-    p = colonp;
-    *p++ = '\0';
-  }
-
-  capture_opts.ringbuffer_num_files = 
-    get_natural_int(arg, "number of ring buffer files");
-
-  if (colonp == NULL)
-    return TRUE;
-
-  /*
-   * Skip over any white space (there probably won't be any, but
-   * as we allow it in the preferences file, we might as well
-   * allow it here).
-   */
-  while (isspace(*p))
-    p++;
-  if (*p == '\0') {
-    /*
-     * Put the colon back, so if our caller uses, in an
-     * error message, the string they passed us, the message
-     * looks correct.
-     */
-    *colonp = ':';
-    return FALSE;
-  }
-
-  capture_opts.has_ring_duration = TRUE;
-  capture_opts.ringbuffer_duration = get_positive_int(p,
-                                                     "ring buffer duration");
-
-  *colonp = ':';       /* put the colon back */
-  return TRUE;
-}
-#endif
-
-/* structure to keep track of what tap listeners have been registered.
- */
-typedef struct _ethereal_tap_list {
-       struct _ethereal_tap_list *next;
-       char *cmd;
-       void (*func)(char *arg);
-} ethereal_tap_list;
-static ethereal_tap_list *tap_list=NULL;
-
-void
-register_ethereal_tap(char *cmd, void (*func)(char *arg))
-{
-       ethereal_tap_list *newtl;
-
-       newtl=malloc(sizeof(ethereal_tap_list));
-       newtl->next=tap_list;
-       tap_list=newtl;
-       newtl->cmd=cmd;
-       newtl->func=func;
-
-}
-
 /*
  * For a dissector table, print on the stream described by output,
  * its short name (which is what's used in the "-d" option) and its
@@ -839,13 +638,16 @@ main(int argc, char *argv[])
   char                *p;
   gchar                err_str[PCAP_ERRBUF_SIZE];
   gchar               *cant_get_if_list_errstr;
+  gboolean             list_link_layer_types = FALSE;
 #else
   gboolean             capture_option_specified = FALSE;
 #endif
+  gboolean             quiet = FALSE;
   gchar               *save_file = NULL;
   int                  out_file_type = WTAP_FILE_PCAP;
   gchar               *cf_name = NULL, *rfilter = NULL;
 #ifdef HAVE_LIBPCAP
+  gboolean             start_capture = FALSE;
   gchar               *if_text;
   GList               *lt_list, *lt_entry;
   data_link_info_t    *data_link_info;
@@ -856,11 +658,10 @@ main(int argc, char *argv[])
   dfilter_t           *rfcode = NULL;
   e_prefs             *prefs;
   char                 badopt;
-  ethereal_tap_list *tli;
-
-
-  /* XXX - better use capture_opts_init instead */
-  capture_opts.cfilter = g_strdup("");
+  
+#ifdef HAVE_LIBPCAP
+  capture_opts_init(&capture_opts, NULL /* cfile */);
+#endif
 
   set_timestamp_setting(TS_RELATIVE);
 
@@ -873,6 +674,11 @@ main(int argc, char *argv[])
 
   /* Register all tap listeners; we do this before we parse the arguments,
      as the "-z" argument can specify a registered tap. */
+  
+  /* we register the plugin taps before the other taps because
+         stats_tree taps plugins will be registered as tap listeners
+         by stats_tree_stat.c and need to registered before that */
+  register_all_plugin_tap_listeners();
   register_all_tap_listeners();
 
   /* Now register the preferences for any non-dissector modules.
@@ -971,32 +777,14 @@ main(int argc, char *argv[])
   while ((opt = getopt(argc, argv, "a:b:c:d:Df:F:hi:lLnN:o:pqr:R:s:St:T:vw:Vxy:z:")) != -1) {
     switch (opt) {
       case 'a':        /* autostop criteria */
-#ifdef HAVE_LIBPCAP
-        if (set_autostop_criterion(optarg) == FALSE) {
-          fprintf(stderr, "tethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
-          exit(1);
-        }
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'b':        /* Ringbuffer option */
-#ifdef HAVE_LIBPCAP
-        capture_opts.ringbuffer_on = TRUE;
-       if (get_ring_arguments(optarg) == FALSE) {
-          fprintf(stderr, "tethereal: Invalid or unknown -b arg \"%s\"\n", optarg);
-          exit(1);
-       }
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'c':        /* Capture xxx packets */
+      case 'f':        /* capture filter */
+      case 'p':        /* Don't capture in promiscuous mode */
+      case 's':        /* Set the snapshot (capture) length */
+      case 'y':        /* Set the pcap data link type */
 #ifdef HAVE_LIBPCAP
-        capture_opts.autostop_count =
-            get_positive_int(optarg, "packet count");
+        capture_opts_add_opt(&capture_opts, "tethereal", opt, optarg, &start_capture);
 #else
         capture_option_specified = TRUE;
         arg_error = TRUE;
@@ -1041,17 +829,6 @@ main(int argc, char *argv[])
         arg_error = TRUE;
 #endif
         break;
-      case 'f':
-#ifdef HAVE_LIBPCAP
-        capture_filter_specified = TRUE;
-       if (capture_opts.cfilter)
-               g_free(capture_opts.cfilter);
-       capture_opts.cfilter = g_strdup(optarg);
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-       break;
       case 'F':
         out_file_type = wtap_short_string_to_file_type(optarg);
         if (out_file_type < 0) {
@@ -1175,14 +952,6 @@ main(int argc, char *argv[])
           break;
         }
         break;
-      case 'p':        /* Don't capture in promiscuous mode */
-#ifdef HAVE_LIBPCAP
-       capture_opts.promisc_mode = FALSE;
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-       break;
       case 'q':        /* Quiet */
         quiet = TRUE;
         break;
@@ -1192,14 +961,6 @@ main(int argc, char *argv[])
       case 'R':        /* Read file filter */
         rfilter = optarg;
         break;
-      case 's':        /* Set the snapshot (capture) length */
-#ifdef HAVE_LIBPCAP
-        capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'S':        /* show packets in real time */
         print_packet_info = TRUE;
         break;
@@ -1257,39 +1018,18 @@ main(int argc, char *argv[])
       case 'x':        /* Print packet data in hex (and ASCII) */
         print_hex = TRUE;
         break;
-      case 'y':        /* Set the pcap data link type */
-#ifdef HAVE_LIBPCAP
-#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
-        capture_opts.linktype = pcap_datalink_name_to_val(optarg);
-        if (capture_opts.linktype == -1) {
-          fprintf(stderr, "tethereal: The specified data link type \"%s\" isn't valid\n",
-                  optarg);
-          exit(1);
-        }
-#else /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-        /* XXX - just treat it as a number */
-        capture_opts.linktype = get_natural_int(optarg, "data link type");
-#endif /* HAVE_PCAP_DATALINK_NAME_TO_VAL */
-#else
-        capture_option_specified = TRUE;
-        arg_error = TRUE;
-#endif
-        break;
       case 'z':
-        for(tli=tap_list;tli;tli=tli->next){
-          if(!strncmp(tli->cmd,optarg,strlen(tli->cmd))){
-            (*tli->func)(optarg);
-            break;
-          }
-        }
-        if(!tli){
-          fprintf(stderr,"tethereal: invalid -z argument.\n");
-          fprintf(stderr,"  -z argument must be one of :\n");
-          for(tli=tap_list;tli;tli=tli->next){
-            fprintf(stderr,"     %s\n",tli->cmd);
-          }
-          exit(1);
-        }
+        /* We won't call the init function for the tap this soon
+           as it would disallow MATE's fields (which are registered
+           by the preferences set callback) from being used as
+           part of a tap filter.  Instead, we just add the argument
+           to a list of tap arguments. */
+        if (!process_tap_cmd_arg(optarg)) {
+         fprintf(stderr,"tethereal: invalid -z argument.\n");
+         fprintf(stderr,"  -z argument must be one of :\n");
+         list_tap_cmd_args();
+         exit(1);
+       }
         break;
       default:
       case '?':        /* Bad flag - print usage message */
@@ -1410,7 +1150,7 @@ main(int argc, char *argv[])
       exit(1);
     }
     /* No - did they specify a ring buffer option? */
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       fprintf(stderr, "tethereal: Ring buffer requested, but a capture isn't being done.\n");
       exit(1);
     }
@@ -1423,7 +1163,7 @@ main(int argc, char *argv[])
       exit(1);
     }
 
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       /* Ring buffer works only under certain conditions:
         a) ring buffer does not work if you're not saving the capture to
            a file;
@@ -1465,6 +1205,11 @@ main(int argc, char *argv[])
      line that their preferences have changed. */
   prefs_apply_all();
 
+  /* At this point MATE will have registered its field array so we can
+     have a filter with one of MATE's late-registered fields as part
+     of the tap's filter.  We can now process all the "-z" arguments. */
+  start_requested_taps();
+  
   /* disabled protocols as per configuration file */
   if (gdp_path == NULL && dp_path == NULL) {
     set_disabled_protos_list();
@@ -1507,12 +1252,12 @@ main(int argc, char *argv[])
   else if (capture_opts.snaplen < MIN_PACKET_SIZE)
     capture_opts.snaplen = MIN_PACKET_SIZE;
 
-  /* Check the value range of the ringbuffer_num_files parameter */
-  if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
-    capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
+  /* Check the value range of the ring_num_files parameter */
+  if (capture_opts.ring_num_files > RINGBUFFER_MAX_NUM_FILES)
+    capture_opts.ring_num_files = RINGBUFFER_MAX_NUM_FILES;
 #if RINGBUFFER_MIN_NUM_FILES > 0
-  else if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
-    capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
+  else if (capture_opts.ring_num_files < RINGBUFFER_MIN_NUM_FILES)
+    capture_opts.ring_num_files = RINGBUFFER_MIN_NUM_FILES;
 #endif
 #endif
 
@@ -1671,9 +1416,17 @@ main(int argc, char *argv[])
       exit(0);
     }
 
+    if (!quiet) {
+      /*
+       * The user didn't ask us not to print a count of packets as
+       * they arrive, so do so.
+       */
+      print_packet_counts = TRUE;
+    }
+
     capture(save_file, out_file_type);
 
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       ringbuf_free();
     }
 #else
@@ -1864,8 +1617,14 @@ capture(char *save_file, int out_file_type)
     if (pcap_setfilter(ld.pch, &fcode) < 0) {
       snprintf(errmsg, sizeof errmsg, "Can't install filter (%s).",
        pcap_geterr(ld.pch));
+#ifdef HAVE_PCAP_FREECODE
+      pcap_freecode(&fcode);
+#endif
       goto error;
     }
+#ifdef HAVE_PCAP_FREECODE
+    pcap_freecode(&fcode);
+#endif
   }
 
   /* Set up to write to the capture file. */
@@ -1888,9 +1647,9 @@ capture(char *save_file, int out_file_type)
       goto error;
     }
     ld.save_file = save_file;
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       save_file_fd = ringbuf_init(save_file,
-        capture_opts.ringbuffer_num_files);
+        capture_opts.ring_num_files);
       if (save_file_fd != -1) {
         ld.pdh = ringbuf_init_wtap_dump_fdopen(out_file_type, ld.linktype,
           file_snaplen, &err);
@@ -1951,9 +1710,9 @@ capture(char *save_file, int out_file_type)
     cnd_stop_timeout = cnd_new((const char*)CND_CLASS_TIMEOUT,
                                (gint32)capture_opts.autostop_duration);
 
-  if (capture_opts.ringbuffer_on && capture_opts.has_ring_duration)
+  if (capture_opts.multi_files_on && capture_opts.has_file_duration)
     cnd_ring_timeout = cnd_new(CND_CLASS_TIMEOUT, 
-                              capture_opts.ringbuffer_duration);
+                              capture_opts.file_duration);
 
   if (!setjmp(ld.stopenv)) {
     ld.go = TRUE;
@@ -2004,15 +1763,15 @@ capture(char *save_file, int out_file_type)
          reading the FIFO sees the packets immediately and doesn't get
          any partial packet, forcing it to block in the middle of reading
          that packet. */
-      if (capture_opts.autostop_count == 0)
+      if (capture_opts.autostop_packets == 0)
         pcap_cnt = -1;
       else {
-        if (ld.packet_count >= capture_opts.autostop_count) {
+        if (ld.packet_count >= capture_opts.autostop_packets) {
           /* XXX do we need this test here? */
           /* It appears there's nothing more to capture. */
           break;
         }
-        pcap_cnt = capture_opts.autostop_count - ld.packet_count;
+        pcap_cnt = capture_opts.autostop_packets - ld.packet_count;
       }
     } else {
       /* We need to check the capture file size or the timeout after
@@ -2034,8 +1793,8 @@ capture(char *save_file, int out_file_type)
       /* The specified capture time has elapsed; stop the capture. */
       ld.go = FALSE;
     } else if (inpkts > 0) {
-      if (capture_opts.autostop_count != 0 &&
-                 ld.packet_count >= capture_opts.autostop_count) {
+      if (capture_opts.autostop_packets != 0 &&
+                 ld.packet_count >= capture_opts.autostop_packets) {
         /* The specified number of packets have been captured and have
            passed both any capture filter in effect and any read filter
            in effect. */
@@ -2045,7 +1804,7 @@ capture(char *save_file, int out_file_type)
                               (guint32)wtap_get_bytes_dumped(ld.pdh))) {
         /* We're saving the capture to a file, and the capture file reached
            its maximum size. */
-        if (capture_opts.ringbuffer_on) {
+        if (capture_opts.multi_files_on) {
           /* Switch to the next ringbuffer file */
           if (ringbuf_switch_file(&ld.pdh, &save_file, &save_file_fd, &loop_err)) {
             /* File switch succeeded: reset the condition */
@@ -2083,9 +1842,8 @@ capture(char *save_file, int out_file_type)
   if (cnd_ring_timeout != NULL)
     cnd_delete(cnd_ring_timeout);
 
-  if ((save_file != NULL) && !quiet) {
-    /* We're saving to a file, which means we're printing packet counts
-       to stderr if we are not running silent and deep.
+  if (print_packet_counts) {
+    /* We're printing packet counts to stderr.
        Send a newline so that we move to the line after the packet count. */
     fprintf(stderr, "\n");
   }
@@ -2115,7 +1873,7 @@ capture(char *save_file, int out_file_type)
 
   if (save_file != NULL) {
     /* We're saving to a file or files; close all files. */
-    if (capture_opts.ringbuffer_on) {
+    if (capture_opts.multi_files_on) {
       dump_ok = ringbuf_wtap_dump_close(&save_file, &err);
     } else {
       dump_ok = wtap_dump_close(ld.pdh, &err);
@@ -2152,7 +1910,7 @@ capture(char *save_file, int out_file_type)
   return TRUE;
 
 error:
-  if (capture_opts.ringbuffer_on) {
+  if (capture_opts.multi_files_on) {
     ringbuf_error_cleanup();
   }
   g_free(save_file);
@@ -2219,9 +1977,9 @@ capture_pcap_cb(guchar *user, const struct pcap_pkthdr *phdr,
 
   if (!process_packet(&cfile, ldat->pdh, 0, &whdr, &pseudo_header, pd, &err)) {
     /* Error writing to a capture file */
-    if (!quiet) {
-      /* We're capturing packets, so (if -q not specified) we're printing
-         a count of packets captured; move to the line after the count. */
+    if (print_packet_counts) {
+      /* We're printing counts of packets captured; move to the line after
+         the count. */
       fprintf(stderr, "\n");
     }
     show_capture_file_io_error(ldat->save_file, err, FALSE);
@@ -2295,7 +2053,7 @@ report_counts(void)
   signal(SIGINFO, report_counts_siginfo);
 #endif /* SIGINFO */
 
-  if (quiet || print_packet_info) {
+  if (!print_packet_counts) {
     /* Report the count only if we aren't printing a packet count
        as packets arrive. */
     fprintf(stderr, "%u packets captured\n", ld.packet_count);
@@ -2609,10 +2367,8 @@ process_packet(capture_file *cf, wtap_dumper *pdh, long offset,
       if (!wtap_dump(pdh, whdr, pseudo_header, pd, err))
         return FALSE;
 #ifdef HAVE_LIBPCAP
-      /* Report packet capture count if not quiet */
-      if (!quiet && !print_packet_info) {
-       /* Don't print a packet count if we were asked not to with "-q"
-          or if we're also printing packet info. */
+      if (print_packet_counts) {
+       /* We're printing packet counts. */
         if (ld.packet_count != 0) {
           fprintf(stderr, "\r%u ", ld.packet_count);
           /* stderr could be line buffered */
@@ -2771,6 +2527,7 @@ print_columns(capture_file *cf)
   for (i = 0; i < cf->cinfo.num_cols; i++) {
     switch (cf->cinfo.col_fmt[i]) {
     case COL_NUMBER:
+#ifdef HAVE_LIBPCAP
       /*
        * Don't print this if we're doing a live capture from a network
        * interface - if we're doing a live capture, you won't be
@@ -2784,6 +2541,7 @@ print_columns(capture_file *cf)
        */
       if (capture_opts.iface != NULL)
         continue;
+#endif
       column_len = strlen(cf->cinfo.col_data[i]);
       if (column_len < 3)
         column_len = 3;