freebsd needs to define AF_INET6, seems to need sys/socket.h
[obnox/wireshark/wip.git] / capture_loop.c
index dc23f39d686ac9ff5bdd64771394e0ca14de442f..e2b2ae5cc5d4a9da57d84394469dbcd5c974da9f 100644 (file)
 
 #include <signal.h>
 #include <errno.h>
+#include <setjmp.h>
 
-#include <pcap.h>
 
 #include <glib.h>
 
-#include <epan/packet.h>
+#include <pcap.h>
+
+#include "wiretap/wtap.h"
+#include "wiretap/wtap-capture.h"
+
+#include "capture-pcap-util.h"
+
 #include "capture.h"
 #include "capture_sync.h"
-#include "pcap-util.h"
 
-#include "simple_dialog.h"
 #include "conditions.h"
 #include "capture_stop_conditions.h"
 #include "ringbuffer.h"
 
-#include "wiretap/libpcap.h"
-#include "wiretap/wtap.h"
-#include "wiretap/wtap-capture.h"
-
-#include <epan/prefs.h>
-/* XXX - try to remove this later */
-#include "ui_util.h"
-/* XXX - try to remove this later */
+#include "simple_dialog.h"
 #include "util.h"
-#include "alert_box.h"
 #include "log.h"
+#include "file_util.h"
 
 
-#include <epan/dissectors/packet-ap1394.h>
-#include <epan/dissectors/packet-atalk.h>
-#include <epan/dissectors/packet-atm.h>
-#include <epan/dissectors/packet-clip.h>
-#include <epan/dissectors/packet-eth.h>
-#include <epan/dissectors/packet-fddi.h>
-#include <epan/dissectors/packet-fr.h>
-#include <epan/dissectors/packet-null.h>
-#include <epan/dissectors/packet-ppp.h>
-#include <epan/dissectors/packet-raw.h>
-#include <epan/dissectors/packet-sll.h>
-#include <epan/dissectors/packet-tr.h>
-#include <epan/dissectors/packet-ieee80211.h>
-#include <epan/dissectors/packet-chdlc.h>
-#include <epan/dissectors/packet-prism.h>
-#include <epan/dissectors/packet-ipfc.h>
-#include <epan/dissectors/packet-arcnet.h>
-
-/* Win32 needs the O_BINARY flag for open() */
-#ifndef O_BINARY
-#define O_BINARY       0
-#endif
+#include "capture_loop.h"
 
 
 
 /*
- * We don't want to do a "select()" on the pcap_t's file descriptor on
- * BSD (because "select()" doesn't work correctly on BPF devices on at
- * least some releases of some flavors of BSD), and we don't want to do
- * it on Windows (because "select()" is something for sockets, not for
- * arbitrary handles).  (Note that "Windows" here includes Cygwin;
- * even in its pretend-it's-UNIX environment, we're using WinPcap, not
- * a UNIX libpcap.)
- *
- * We *do* want to do it on other platforms, as, on other platforms (with
- * the possible exception of Ultrix and Digital UNIX), the read timeout
- * doesn't expire if no packets have arrived, so a "pcap_dispatch()" call
- * will block until packets arrive, causing the UI to hang.
- *
- * XXX - the various BSDs appear to define BSD in <sys/param.h>; we don't
- * want to include it if it's not present on this platform, however.
+ * This needs to be static, so that the SIGUSR1 handler can clear the "go"
+ * flag.
  */
-#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
-    !defined(__bsdi__) && !defined(__APPLE__) && !defined(_WIN32) && \
-    !defined(__CYGWIN__)
-# define MUST_DO_SELECT
-#endif
-
-
-typedef struct _loop_data {
-  /* common */
-  gboolean       go;                    /* TRUE as long as we're supposed to keep capturing */
-  int            err;                   /* if non-zero, error seen while capturing */
-  gint           packets_max;           /* Number of packets we're supposed to capture - 0 means infinite */
-  gint           packets_sync_pipe;     /* packets not already send out to the sync_pipe */
-  packet_counts  counts;                /* several packet type counters */
-
-  /* pcap "input file" */
-  pcap_t        *pcap_h;                /* pcap handle */
-  gboolean       pcap_err;              /* TRUE if error from pcap */
-#ifdef MUST_DO_SELECT
-  int            pcap_fd;               /* pcap file descriptor */
-#endif
-
-  /* capture pipe (unix only "input file") */
-  gboolean       from_cap_pipe;         /* TRUE if we are capturing data from a capture pipe */
-#ifndef _WIN32
-  struct pcap_hdr cap_pipe_hdr;
-  int            cap_pipe_fd;           /* the file descriptor of the capture pipe */
-  gboolean       cap_pipe_modified;     /* TRUE if data in the pipe uses modified pcap headers */
-  gboolean       cap_pipe_byte_swapped; /* TRUE if data in the pipe is byte swapped */
-  unsigned int   cap_pipe_bytes_to_read;/* Used by cap_pipe_dispatch */
-  unsigned int   cap_pipe_bytes_read;   /* Used by cap_pipe_dispatch */
-  enum {
-         STATE_EXPECT_REC_HDR,
-         STATE_READ_REC_HDR,
-         STATE_EXPECT_DATA,
-         STATE_READ_DATA
-       } cap_pipe_state;
-
-  enum { PIPOK, PIPEOF, PIPERR, PIPNEXIST } cap_pipe_err;
-#endif
-
-  /* wiretap (output file) */
-  wtap_dumper   *wtap_pdh;
-  gint           wtap_linktype;
-
-} loop_data;
+static loop_data   ld;
 
 
 /*
@@ -184,9 +102,8 @@ typedef struct _loop_data {
  */
 #define        CAP_READ_TIMEOUT        250
 
-static void capture_loop_packet_cb(guchar *user, const struct pcap_pkthdr *phdr,
-  const guchar *pd);
-static void capture_loop_popup_errmsg(capture_options *capture_opts, const char *errmsg);
+static void capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr,
+  const u_char *pd);
 static void capture_loop_get_errmsg(char *errmsg, int errmsglen, const char *fname,
                          int err, gboolean is_close);
 
@@ -195,10 +112,10 @@ static void capture_loop_get_errmsg(char *errmsg, int errmsglen, const char *fna
 #ifndef _WIN32
 /* Take care of byte order in the libpcap headers read from pipes.
  * (function taken from wiretap/libpcap.c) */
-static void
-cap_pipe_adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
+void
+cap_pipe_adjust_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr)
 {
-  if (ld->cap_pipe_byte_swapped) {
+  if (byte_swapped) {
     /* Byte-swap the record header fields. */
     rechdr->ts_sec = BSWAP32(rechdr->ts_sec);
     rechdr->ts_usec = BSWAP32(rechdr->ts_usec);
@@ -229,7 +146,7 @@ cap_pipe_adjust_header(loop_data *ld, struct pcap_hdr *hdr, struct pcaprec_hdr *
  * header.
  * N.B. : we can't read the libpcap formats used in RedHat 6.1 or SuSE 6.3
  * because we can't seek on pipes (see wiretap/libpcap.c for details) */
-static int
+int
 cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
                  char *errmsg, int errmsgl)
 {
@@ -245,12 +162,12 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_open_live: %s", pipename);
 
   /*
-   * XXX Ethereal blocks until we return
+   * XXX (T)Ethereal blocks until we return
    */
   if (strcmp(pipename, "-") == 0)
     fd = 0; /* read from stdin */
   else {
-    if (stat(pipename, &pipe_stat) < 0) {
+    if (eth_stat(pipename, &pipe_stat) < 0) {
       if (errno == ENOENT || errno == ENOTDIR)
         ld->cap_pipe_err = PIPNEXIST;
       else {
@@ -276,7 +193,7 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
       }
       return -1;
     }
-    fd = open(pipename, O_RDONLY | O_NONBLOCK);
+    fd = eth_open(pipename, O_RDONLY | O_NONBLOCK, 0000 /* no creation so don't matter */);
     if (fd == -1) {
       g_snprintf(errmsg, errmsgl,
           "The capture session could not be initiated "
@@ -393,7 +310,7 @@ cap_pipe_open_live(char *pipename, struct pcap_hdr *hdr, loop_data *ld,
 error:
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "cap_pipe_open_live: error %s", errmsg);
   ld->cap_pipe_err = PIPERR;
-  close(fd);
+  eth_close(fd);
   return -1;
 
 }
@@ -401,7 +318,7 @@ error:
 
 /* We read one record from the pipe, take care of byte order in the record
  * header, write the record to the capture file, and update capture statistics. */
-static int
+int
 cap_pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr,
                struct pcaprec_modified_hdr *rechdr, guchar *data,
                char *errmsg, int errmsgl)
@@ -472,10 +389,10 @@ cap_pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr,
 
   case PD_REC_HDR_READ:
     /* We've read the header. Take care of byte order. */
-    cap_pipe_adjust_header(ld, hdr, &rechdr->hdr);
+    cap_pipe_adjust_header(ld->cap_pipe_byte_swapped, hdr, &rechdr->hdr);
     if (rechdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
       g_snprintf(errmsg, errmsgl, "Frame %u too long (%d bytes)",
-        ld->counts.total+1, rechdr->hdr.incl_len);
+        ld->packet_count+1, rechdr->hdr.incl_len);
       break;
     }
     ld->cap_pipe_state = STATE_EXPECT_DATA;
@@ -488,7 +405,7 @@ cap_pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr,
     phdr.caplen = rechdr->hdr.incl_len;
     phdr.len = rechdr->hdr.orig_len;
 
-    capture_loop_packet_cb((guchar *)ld, &phdr, data);
+    ld->packet_cb((u_char *)ld, &phdr, data);
 
     ld->cap_pipe_state = STATE_EXPECT_REC_HDR;
     return 1;
@@ -513,8 +430,9 @@ cap_pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr,
 
 
 /* open the capture input file (pcap or capture pipe) */
-static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld, char *errmsg, int errmsg_len) {
+gboolean capture_loop_open_input(capture_options *capture_opts, loop_data *ld, char *errmsg, int errmsg_len) {
   gchar       open_err_str[PCAP_ERRBUF_SIZE];
+  gchar      *sync_msg_str;
   const char *set_linktype_err_str;
 #ifdef _WIN32
   int         err;
@@ -522,12 +440,15 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
   WSADATA     wsaData;
 #else
   static const char ppamsg[] = "can't find PPA for ";
-  char       *libpcap_warn;
+  const char  *libpcap_warn;
 #endif
 
 
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_open_input : %s", capture_opts->iface);
 
+
+/* XXX - opening Winsock on tethereal? */
+
   /* Initialize Windows Socket if we are in a WIN32 OS
      This needs to be done before querying the interface for network/netmask */
 #ifdef _WIN32
@@ -589,7 +510,7 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
 #ifdef _WIN32
     /* try to set the capture buffer size */
     if (pcap_setbuff(ld->pcap_h, capture_opts->buffer_size * 1024 * 1024) != 0) {
-        simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+        sync_msg_str = g_strdup_printf(
           "%sCouldn't set the capture buffer size!%s\n"
           "\n"
           "The capture buffer size of %luMB seems to be too high for your machine,\n"
@@ -597,6 +518,8 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
           "\n"
           "Nonetheless, the capture is started.\n",
           simple_dialog_primary_start(), simple_dialog_primary_end(), capture_opts->buffer_size);
+        sync_pipe_errmsg_to_parent(sync_msg_str);
+        g_free(sync_msg_str);
     }
 #endif
 
@@ -618,24 +541,35 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
     /* On Win32 OSes, the capture devices are probably available to all
        users; don't warn about permissions problems.
 
-       Do, however, warn that WAN devices aren't supported. */
+       Do, however, warn about the lack of 64-bit support, and warn that
+       WAN devices aren't supported. */
     g_snprintf(errmsg, errmsg_len,
 "%sThe capture session could not be initiated!%s\n"
 "\n"
 "(%s)\n"
 "\n"
-"Please check that you have the proper interface specified.\n"
+"Please check that \"%s\" is the proper interface.\n"
 "\n"
-"Note that version 3.0 of WinPcap, and earlier versions of WinPcap, don't\n"
-"support capturing on PPP/WAN interfaces in Windows NT 4.0 / 2000 / XP / Server 2003.\n"
 "\n"
-"WinPcap 3.1 has experimental support for it on Windows 2000 / XP / Server 2003,\n"
-"but has no support for it on Windows NT 4.0.  WinPcap 3.1 is currently in beta,\n"
-"so using it might introduce bugs not present in WinPcap 3.0; you should report\n"
-"all problems you see to the WinPcap developers, so they can try to fix\n"
-"them before the final WinPcap 3.1 release.",
+"Help can be found at:\n"
+"\n"
+"       %shttp://wiki.ethereal.com/CaptureSetup%s\n"
+"\n"
+"64-bit Windows:\n"
+"WinPcap does not support 64-bit Windows, you will have to use some other\n"
+"tool to capture traffic, such as netcap.\n"
+"For netcap details see: http://support.microsoft.com/?id=310875\n"
+"\n"
+"Modem (PPP/WAN):\n"
+"Note that version 3.0 of WinPcap, and earlier versions of WinPcap, don't\n"
+"support capturing on PPP/WAN interfaces on Windows NT 4.0 / 2000 / XP /\n"
+"Server 2003.\n"
+"WinPcap 3.1 has support for it on Windows 2000 / XP / Server 2003, but has no\n"
+"support for it on Windows NT 4.0 or Windows Vista (Beta 1).",
        simple_dialog_primary_start(), simple_dialog_primary_end(),
-    open_err_str);
+    open_err_str,
+    capture_opts->iface,
+       simple_dialog_primary_start(), simple_dialog_primary_end());
     return FALSE;
 #else
     /* try to open iface as a pipe */
@@ -647,16 +581,16 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
        /* Pipe doesn't exist, so output message for interface */
 
        /* 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
+          is running (T)Ethereal on HP-UX) that they don't have a version
           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(open_err_str, ppamsg, sizeof ppamsg - 1) == 0)
          libpcap_warn =
            "\n\n"
-           "You are running Ethereal with a version of the libpcap library\n"
+           "You are running (T)Ethereal with a version of the libpcap library\n"
            "that doesn't handle HP-UX network devices well; this means that\n"
-           "Ethereal may not be able to capture packets.\n"
+           "(T)Ethereal may not be able to capture packets.\n"
            "\n"
            "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"
@@ -683,6 +617,7 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
 #endif
   }
 
+/* XXX - will this work for tethereal? */
 #ifdef MUST_DO_SELECT
   if (!ld->from_cap_pipe) {
 #ifdef HAVE_PCAP_GET_SELECTABLE_FD
@@ -695,8 +630,11 @@ static int capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
 
   /* Does "open_err_str" contain a non-empty string?  If so, "pcap_open_live()"
      returned a warning; print it, but keep capturing. */
-  if (open_err_str[0] != '\0')
-    g_warning("%s.", open_err_str);
+  if (open_err_str[0] != '\0') {
+    sync_msg_str = g_strdup_printf("%s.", open_err_str);
+    sync_pipe_errmsg_to_parent(sync_msg_str);
+    g_free(sync_msg_str);
+  }
 
   return TRUE;
 }
@@ -711,7 +649,7 @@ static void capture_loop_close_input(loop_data *ld) {
   /* if open, close the capture pipe "input file" */
   if (ld->cap_pipe_fd >= 0) {
     g_assert(ld->from_cap_pipe);
-    close(ld->cap_pipe_fd);
+    eth_close(ld->cap_pipe_fd);
   }
 #endif
 
@@ -729,7 +667,7 @@ static void capture_loop_close_input(loop_data *ld) {
 
 
 /* init the capture filter */
-static int capture_loop_init_filter(loop_data *ld, const gchar * iface, gchar * cfilter, char *errmsg, int errmsg_len) {
+gboolean capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, const gchar * iface, gchar * cfilter, char *errmsg, int errmsg_len) {
   bpf_u_int32 netnum, netmask;
   gchar       lookup_net_err_str[PCAP_ERRBUF_SIZE];
   struct bpf_program fcode;
@@ -738,7 +676,7 @@ static int capture_loop_init_filter(loop_data *ld, const gchar * iface, gchar *
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_init_filter: %s", cfilter);
 
   /* capture filters only work on real interfaces */
-  if (cfilter && !ld->from_cap_pipe) {
+  if (cfilter && !from_cap_pipe) {
     /* A capture filter was specified; set it up. */
     if (pcap_lookupnet(iface, &netnum, &netmask, lookup_net_err_str) < 0) {
       /*
@@ -750,11 +688,18 @@ static int capture_loop_init_filter(loop_data *ld, const gchar * iface, gchar *
        * a difference (only filters that check for IP broadcast addresses
        * use the netmask).
        */
+      /*cmdarg_err(
+        "Warning:  Couldn't obtain netmask info (%s).", lookup_net_err_str);*/
       netmask = 0;
     }
-    if (pcap_compile(ld->pcap_h, &fcode, cfilter, 1, netmask) < 0) {
+    if (pcap_compile(pcap_h, &fcode, cfilter, 1, netmask) < 0) {
       dfilter_t   *rfcode = NULL;
+      gchar *safe_cfilter = simple_dialog_format_message(cfilter);
+      gchar *safe_cfilter_error_msg = simple_dialog_format_message(
+         pcap_geterr(pcap_h));
+
       /* filter string invalid, did the user tried a display filter? */
+#ifndef DUMPCAP
       if (dfilter_compile(cfilter, &rfcode) && rfcode != NULL) {
         g_snprintf(errmsg, errmsg_len,
           "%sInvalid capture filter: \"%s\"!%s\n"
@@ -765,24 +710,28 @@ static int capture_loop_init_filter(loop_data *ld, const gchar * iface, gchar *
           "Note that display filters and capture filters don't have the same syntax,\n"
           "so you can't use most display filter expressions as capture filters.\n"
           "\n"
-          "See the help for a description of the capture filter syntax.",
-          simple_dialog_primary_start(), cfilter, simple_dialog_primary_end(),
-          pcap_geterr(ld->pcap_h));
+          "See the User's Guide for a description of the capture filter syntax.",
+          simple_dialog_primary_start(), safe_cfilter,
+          simple_dialog_primary_end(), safe_cfilter_error_msg);
        dfilter_free(rfcode);
-      } else {
+      } else 
+#endif
+      {
         g_snprintf(errmsg, errmsg_len,
           "%sInvalid capture filter: \"%s\"!%s\n"
           "\n"
           "That string isn't a valid capture filter (%s).\n"
-          "See the help for a description of the capture filter syntax.",
-          simple_dialog_primary_start(), cfilter, simple_dialog_primary_end(),
-          pcap_geterr(ld->pcap_h));
+          "See the User's Guide for a description of the capture filter syntax.",
+          simple_dialog_primary_start(), safe_cfilter,
+          simple_dialog_primary_end(), safe_cfilter_error_msg);
       }
+      g_free(safe_cfilter_error_msg);
+      g_free(safe_cfilter);
       return FALSE;
     }
-    if (pcap_setfilter(ld->pcap_h, &fcode) < 0) {
+    if (pcap_setfilter(pcap_h, &fcode) < 0) {
       g_snprintf(errmsg, errmsg_len, "Can't install filter (%s).",
-       pcap_geterr(ld->pcap_h));
+       pcap_geterr(pcap_h));
 #ifdef HAVE_PCAP_FREECODE
       pcap_freecode(&fcode);
 #endif
@@ -798,7 +747,7 @@ static int capture_loop_init_filter(loop_data *ld, const gchar * iface, gchar *
 
 
 /* open the wiretap part of the capture output file */
-static int capture_loop_init_wiretap_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len) {
+gboolean capture_loop_init_wiretap_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len) {
   int         pcap_encap;
   int         file_snaplen;
   int         err;
@@ -823,7 +772,7 @@ static int capture_loop_init_wiretap_output(capture_options *capture_opts, int s
   if (ld->wtap_linktype == WTAP_ENCAP_UNKNOWN) {
     g_snprintf(errmsg, errmsg_len,
        "The network you're capturing from is of a type"
-       " that Ethereal doesn't support (data link type %d).", pcap_encap);
+       " that (T)Ethereal doesn't support (data link type %d).", pcap_encap);
     return FALSE;
   }
   if (capture_opts->multi_files_on) {
@@ -831,11 +780,12 @@ static int capture_loop_init_wiretap_output(capture_options *capture_opts, int s
       file_snaplen, &err);
   } else {
     ld->wtap_pdh = wtap_dump_fdopen(save_file_fd, WTAP_FILE_PCAP,
-      ld->wtap_linktype, file_snaplen, &err);
+      ld->wtap_linktype, file_snaplen, FALSE /* compressed */, &err);
   }
 
   if (ld->wtap_pdh == NULL) {
     /* We couldn't set up to write to the capture file. */
+    /* XXX - use cf_open_error_message from tethereal instead? */
     switch (err) {
 
     case WTAP_ERR_CANT_OPEN:
@@ -869,7 +819,7 @@ static int capture_loop_init_wiretap_output(capture_options *capture_opts, int s
   return TRUE;
 }
 
-static gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close) {
+gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close) {
 
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_close_output");
 
@@ -882,14 +832,13 @@ static gboolean capture_loop_close_output(capture_options *capture_opts, loop_da
 
 /* dispatch incoming packets (pcap or capture pipe) */
 static int
-capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
+capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
                      char *errmsg, int errmsg_len) {
   int       inpkts;
 #ifndef _WIN32
   fd_set    set1;
   struct timeval timeout;
   int         sel_ret;
-  struct pcaprec_modified_hdr rechdr;
   guchar pcap_data[WTAP_MAX_PACKET_SIZE];
 #endif
 
@@ -909,14 +858,14 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
         if (sel_ret < 0 && errno != EINTR) {
           g_snprintf(errmsg, errmsg_len,
             "Unexpected error from select: %s", strerror(errno));
-          capture_loop_popup_errmsg(capture_opts, errmsg);
+          sync_pipe_errmsg_to_parent(errmsg);
           ld->go = FALSE;
         }
       } else {
        /*
         * "select()" says we can read from the pipe without blocking
         */
-       inpkts = cap_pipe_dispatch(ld->cap_pipe_fd, ld, &ld->cap_pipe_hdr, &rechdr, pcap_data,
+       inpkts = cap_pipe_dispatch(ld->cap_pipe_fd, ld, &ld->cap_pipe_hdr, &ld->cap_pipe_rechdr, pcap_data,
           errmsg, errmsg_len);
        if (inpkts < 0) {
          ld->go = FALSE;
@@ -979,7 +928,7 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
            * "select()" says we can read from it without blocking; go for
            * it.
            */
-          inpkts = pcap_dispatch(ld->pcap_h, 1, capture_loop_packet_cb, (gchar *)ld);
+          inpkts = pcap_dispatch(ld->pcap_h, 1, ld->packet_cb, (u_char *)ld);
           if (inpkts < 0) {
             ld->pcap_err = TRUE;
             ld->go = FALSE;
@@ -989,7 +938,7 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
           if (sel_ret < 0 && errno != EINTR) {
             g_snprintf(errmsg, errmsg_len,
               "Unexpected error from select: %s", strerror(errno));
-            capture_loop_popup_errmsg(capture_opts, errmsg);
+            sync_pipe_errmsg_to_parent(errmsg);
             ld->go = FALSE;
           }
         }
@@ -1002,7 +951,7 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
 #ifdef LOG_CAPTURE_VERBOSE
         g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_dispatch: from pcap_dispatch");
 #endif
-        inpkts = pcap_dispatch(ld->pcap_h, 1, capture_loop_packet_cb, (gchar *) ld);
+        inpkts = pcap_dispatch(ld->pcap_h, 1, ld->packet_cb, (u_char *) ld);
         if (inpkts < 0) {
           ld->pcap_err = TRUE;
           ld->go = FALSE;
@@ -1024,7 +973,7 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
 
             inpkts = 0;
             while( (in = pcap_next_ex(ld->pcap_h, &pkt_header, &pkt_data)) == 1) {
-                capture_loop_packet_cb( (gchar *) ld, pkt_header, pkt_data);
+                ld->packet_cb( (u_char *) ld, pkt_header, pkt_data);
                 inpkts++;
             }
 
@@ -1046,9 +995,9 @@ capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
 }
 
 
-/* open the output file (temporary/specified name/ringbuffer) */
+/* open the output file (temporary/specified name/ringbuffer/named pipe/stdout) */
 /* Returns TRUE if the file opened successfully, FALSE otherwise. */
-static gboolean
+gboolean
 capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
                      char *errmsg, int errmsg_len) {
 
@@ -1066,20 +1015,33 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
      * case the caller destroys it after we return.
      */
     capfile_name = g_strdup(capture_opts->save_file);
-    if (capture_opts->multi_files_on) {
-      /* ringbuffer is enabled */
-      *save_file_fd = ringbuf_init(capfile_name,
-          (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);
-
-      /* we need the ringbuf name */
-      if(*save_file_fd != -1) {
-          g_free(capfile_name);
-          capfile_name = g_strdup(ringbuf_current_filename());
+    if (strcmp(capfile_name, "-") == 0) {
+      /* Write to the standard output. */
+      if (capture_opts->multi_files_on) {
+        /* ringbuffer is enabled; that doesn't work with standard output */
+        g_snprintf(errmsg, errmsg_len,
+           "Ring buffer requested, but capture is being written to the standard output.");
+        g_free(capfile_name);
+        return FALSE;
+      } else {
+        *save_file_fd = 1;
       }
     } else {
-      /* Try to open/create the specified file for use as a capture buffer. */
-      *save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
-                               0600);
+      if (capture_opts->multi_files_on) {
+        /* ringbuffer is enabled */
+        *save_file_fd = ringbuf_init(capfile_name,
+            (capture_opts->has_ring_num_files) ? capture_opts->ring_num_files : 0);
+
+        /* we need the ringbuf name */
+        if(*save_file_fd != -1) {
+            g_free(capfile_name);
+            capfile_name = g_strdup(ringbuf_current_filename());
+        }
+      } else {
+        /* Try to open/create the specified file for use as a capture buffer. */
+        *save_file_fd = open(capfile_name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
+                             0600);
+      }
     }
     is_tempfile = FALSE;
   } else {
@@ -1104,8 +1066,6 @@ capture_loop_open_output(capture_options *capture_opts, int *save_file_fd,
            "The file to which the capture would be saved (\"%s\") "
         "could not be opened: %s.", capfile_name, 
         strerror(errno));
-
-      /*open_failure_alert_box(capfile_name, errno, TRUE);*/
     }
     g_free(capfile_name);
     return FALSE;
@@ -1136,11 +1096,34 @@ capture_loop_stop_signal_handler(int signo _U_)
 #define TIME_GET() time(NULL)
 #endif
 
-/*
- * This needs to be static, so that the SIGUSR1 handler can clear the "go"
- * flag.
- */
-static loop_data   ld;
+#ifdef _WIN32
+static gboolean
+signal_pipe_stopped(void)
+{
+    /* any news from our parent (stdin)? -> just stop the capture */
+    HANDLE handle;
+    DWORD avail = 0;
+    gboolean result;
+
+
+    handle = (HANDLE) GetStdHandle(STD_INPUT_HANDLE);
+    result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
+
+    if(!result || avail > 0) {
+        /* peek failed or some bytes really available */
+
+        /* XXX - if not piping from stdin this fails */
+        /*g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG,
+            "Signal pipe: handle: %x result: %u avail: %u", handle, result, avail);
+        return FALSE;*/
+        return TRUE;
+    } else {
+        /* pipe ok and no bytes available */
+        return FALSE;
+    }
+}
+#endif
+
 
 /* Do the low-level work of a capture.
    Returns TRUE if it succeeds, FALSE otherwise. */
@@ -1149,7 +1132,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
 {
   time_t      upd_time, cur_time;
   time_t      start_time;
-  int         err_close, inpkts;
+  int         err_close;
+  int         inpkts;
+  gint        inpkts_to_sync_pipe = 0;     /* packets not already send out to the sync_pipe */
   condition  *cnd_file_duration = NULL;
   condition  *cnd_autostop_files = NULL;
   condition  *cnd_autostop_size = NULL;
@@ -1157,34 +1142,21 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   guint32     autostop_files = 0;
   gboolean    write_ok;
   gboolean    close_ok;
-  capture_info   capture_ui;
   char        errmsg[4096+1];
   int         save_file_fd;
 
 
   /* init the loop data */
   ld.go                 = TRUE;
+  ld.packet_count       = 0;
   if (capture_opts->has_autostop_packets)
-    ld.packets_max      = capture_opts->autostop_packets;
+    ld.packet_max       = capture_opts->autostop_packets;
   else
-    ld.packets_max      = 0;   /* no limit */
+    ld.packet_max       = 0;   /* no limit */
   ld.err                = 0;   /* no error seen yet */
   ld.wtap_linktype      = WTAP_ENCAP_UNKNOWN;
   ld.pcap_err           = FALSE;
   ld.from_cap_pipe      = FALSE;
-  ld.packets_sync_pipe  = 0;
-  ld.counts.total       = 0;
-  ld.counts.sctp        = 0;
-  ld.counts.tcp         = 0;
-  ld.counts.udp         = 0;
-  ld.counts.icmp        = 0;
-  ld.counts.ospf        = 0;
-  ld.counts.gre         = 0;
-  ld.counts.ipx         = 0;
-  ld.counts.netbios     = 0;
-  ld.counts.vines       = 0;
-  ld.counts.other       = 0;
-  ld.counts.arp         = 0;
   ld.wtap_pdh           = NULL;
 #ifndef _WIN32
   ld.cap_pipe_fd        = -1;
@@ -1192,6 +1164,11 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
 #ifdef MUST_DO_SELECT
   ld.pcap_fd            = 0;
 #endif
+  ld.packet_cb          = capture_loop_packet_cb;
+
+
+  /* We haven't yet gotten the capture statistics. */
+  *stats_known      = FALSE;
 
 #ifndef _WIN32
   /*
@@ -1201,13 +1178,8 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
     signal(SIGUSR1, capture_loop_stop_signal_handler);
 #endif
 
-  /* We haven't yet gotten the capture statistics. */
-  *stats_known      = FALSE;
-
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture child starting ...");
-#ifdef LOG_CAPTURE_VERBOSE
   capture_opts_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, capture_opts);
-#endif
 
   /* open the output file (temporary/specified name/ringbuffer) */
   if (!capture_loop_open_output(capture_opts, &save_file_fd, errmsg, sizeof(errmsg))) {
@@ -1220,7 +1192,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   }
 
   /* init the input filter from the network interface (capture pipe will do nothing) */
-  if (!capture_loop_init_filter(&ld, capture_opts->iface, capture_opts->cfilter, errmsg, sizeof(errmsg))) {
+  if (!capture_loop_init_filter(ld.pcap_h, ld.from_cap_pipe, capture_opts->iface, capture_opts->cfilter, errmsg, sizeof(errmsg))) {
     goto error;
   }
 
@@ -1242,7 +1214,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
      message to our parent so that they'll open the capture file and
      update its windows to indicate that we have a live capture in
      progress. */
-  fflush(wtap_dump_file(ld.wtap_pdh));
+  wtap_dump_flush(ld.wtap_pdh);
   sync_pipe_filename_to_parent(capture_opts->save_file);
 
   /* initialize capture stop (and alike) conditions */
@@ -1250,7 +1222,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   /* create stop conditions */
   if (capture_opts->has_autostop_filesize)
     cnd_autostop_size =
-        cnd_new(CND_CLASS_CAPTURESIZE,(long)capture_opts->autostop_filesize);
+        cnd_new(CND_CLASS_CAPTURESIZE,(long)capture_opts->autostop_filesize * 1024);
   if (capture_opts->has_autostop_duration)
     cnd_autostop_duration =
         cnd_new(CND_CLASS_TIMEOUT,(gint32)capture_opts->autostop_duration);
@@ -1265,50 +1237,29 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
            cnd_new(CND_CLASS_CAPTURESIZE, capture_opts->autostop_files);
   }
 
-  /* start capture info dialog */
-  if(capture_opts->show_info) {
-      capture_ui.callback_data  = &ld;
-      capture_ui.counts         = &ld.counts;
-      capture_info_create(&capture_ui, capture_opts->iface);
-  }
-
   /* init the time values */
   start_time = TIME_GET();
   upd_time = TIME_GET();
 
-
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture child running!");
 
   /* WOW, everything is prepared! */
   /* please fasten your seat belts, we will enter now the actual capture loop */
   while (ld.go) {
-    main_window_update();
-
     /* dispatch incoming packets */
     inpkts = capture_loop_dispatch(capture_opts, &ld, errmsg, sizeof(errmsg));
 
-    main_window_update();
-
 #ifdef _WIN32
-      /* some news from our parent (signal pipe)? -> just stop the capture */
-      {
-          HANDLE handle;
-          DWORD avail = 0;
-          gboolean result;
-
-
-          handle = (HANDLE) _get_osfhandle (0);
-          result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
+    /*fprintf(stderr, "signal pipe ret: %u\n", signal_pipe_stopped());*/
 
-          if(!result || avail > 0) {
-            ld.go = FALSE;
-            /*g_warning("loop closing");*/
-          }
-      }
+    /* any news from our parent (signal pipe)? -> just stop the capture */
+    if (signal_pipe_stopped()) {
+      ld.go = FALSE;
+    }
 #endif
 
     if (inpkts > 0) {
-      ld.packets_sync_pipe += inpkts;
+      inpkts_to_sync_pipe += inpkts;
 
       /* check capture size condition */
       if (cnd_autostop_size != NULL && cnd_eval(cnd_autostop_size,
@@ -1328,8 +1279,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
             if (cnd_file_duration) {
               cnd_reset(cnd_file_duration);
             }
-            fflush(wtap_dump_file(ld.wtap_pdh));
+            wtap_dump_flush(ld.wtap_pdh);
             sync_pipe_filename_to_parent(capture_opts->save_file);
+                       inpkts_to_sync_pipe = 0;
           } else {
             /* File switch failed: stop here */
             ld.go = FALSE;
@@ -1341,9 +1293,12 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
           continue;
         }
       } /* cnd_autostop_size */
+      if (capture_opts->output_to_pipe) {
+        wtap_dump_flush(ld.wtap_pdh);
+      }
     } /* inpkts */
 
-    /* Only update once a second so as not to overload slow displays */
+    /* Only update once a second (Win32: 500ms) so as not to overload slow displays */
     cur_time = TIME_GET();
 #ifdef _WIN32
     if ( (cur_time - upd_time) > 500) {
@@ -1356,28 +1311,16 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
         *stats_known = TRUE;
       }*/
 
-      /* calculate and display running time */
-      if(capture_opts->show_info) {
-          cur_time -= start_time;
-#ifdef _WIN32
-          capture_ui.running_time   = cur_time / 1000;
-#else
-          capture_ui.running_time   = cur_time;
-#endif
-          capture_ui.new_packets    = ld.packets_sync_pipe;
-          capture_info_update(&capture_ui);
-      }
-
       /* Let the parent process know. */
-      if (ld.packets_sync_pipe) {
+      if (inpkts_to_sync_pipe) {
         /* do sync here */
-        fflush(wtap_dump_file(ld.wtap_pdh));
+        wtap_dump_flush(ld.wtap_pdh);
 
-         /* Send our parent a message saying we've written out "ld.sync_packets"
+         /* Send our parent a message saying we've written out "inpkts_to_sync_pipe"
             packets to the capture file. */
-        sync_pipe_packet_count_to_parent(ld.packets_sync_pipe);
+        sync_pipe_packet_count_to_parent(inpkts_to_sync_pipe);
 
-        ld.packets_sync_pipe = 0;
+        inpkts_to_sync_pipe = 0;
       }
 
       /* check capture duration condition */
@@ -1403,8 +1346,9 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
             cnd_reset(cnd_file_duration);
             if(cnd_autostop_size)
               cnd_reset(cnd_autostop_size);
-            fflush(wtap_dump_file(ld.wtap_pdh));
+            wtap_dump_flush(ld.wtap_pdh);
             sync_pipe_filename_to_parent(capture_opts->save_file);
+                       inpkts_to_sync_pipe = 0;
           } else {
             /* File switch failed: stop here */
                ld.go = FALSE;
@@ -1422,11 +1366,6 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
 
   g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_INFO, "Capture child stopping ...");
 
-  /* close capture info dialog */
-  if(capture_opts->show_info) {
-    capture_info_destroy(&capture_ui);
-  }
-
   /* delete stop conditions */
   if (cnd_file_duration != NULL)
     cnd_delete(cnd_file_duration);
@@ -1441,11 +1380,11 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   if (ld.pcap_err) {
     g_snprintf(errmsg, sizeof(errmsg), "Error while capturing packets: %s",
       pcap_geterr(ld.pcap_h));
-    capture_loop_popup_errmsg(capture_opts, errmsg);
+    sync_pipe_errmsg_to_parent(errmsg);
   }
 #ifndef _WIN32
     else if (ld.from_cap_pipe && ld.cap_pipe_err == PIPERR)
-      capture_loop_popup_errmsg(capture_opts, errmsg);
+      sync_pipe_errmsg_to_parent(errmsg);
 #endif
 
   /* did we had an error while capturing? */
@@ -1454,7 +1393,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   } else {
     capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, ld.err,
                              FALSE);
-    capture_loop_popup_errmsg(capture_opts, errmsg);
+    sync_pipe_errmsg_to_parent(errmsg);
     write_ok = FALSE;
   }
 
@@ -1466,7 +1405,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
   if (!close_ok && write_ok) {
     capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, err_close,
                TRUE);
-    capture_loop_popup_errmsg(capture_opts, errmsg);
+    sync_pipe_errmsg_to_parent(errmsg);
   }
 
   /*
@@ -1491,7 +1430,7 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
       g_snprintf(errmsg, sizeof(errmsg),
                "Can't get packet-drop statistics: %s",
                pcap_geterr(ld.pcap_h));
-      capture_loop_popup_errmsg(capture_opts, errmsg);
+      sync_pipe_errmsg_to_parent(errmsg);
     }
   }
 
@@ -1510,15 +1449,15 @@ error:
   } else {
     /* We can't use the save file, and we have no wtap_dump stream
        to close in order to close it, so close the FD directly. */
-    close(save_file_fd);
+    eth_close(save_file_fd);
 
     /* We couldn't even start the capture, so get rid of the capture
        file. */
-    unlink(capture_opts->save_file); /* silently ignore error */
+    eth_unlink(capture_opts->save_file); /* silently ignore error */
     g_free(capture_opts->save_file);
   }
   capture_opts->save_file = NULL;
-  capture_loop_popup_errmsg(capture_opts, errmsg);
+  sync_pipe_errmsg_to_parent(errmsg);
 
   /* close the input file (pcap or cap_pipe) */
   capture_loop_close_input(&ld);
@@ -1593,19 +1532,11 @@ capture_loop_get_errmsg(char *errmsg, int errmsglen, const char *fname,
   }
 }
 
-static void
-capture_loop_popup_errmsg(capture_options *capture_opts _U_, const char *errmsg)
-{
-    /* Send the error message to our parent, so they can display a
-       dialog box containing it. */
-    sync_pipe_errmsg_to_parent(errmsg);
-}
-
 
 /* one packet was captured, process it */
 static void
-capture_loop_packet_cb(guchar *user, const struct pcap_pkthdr *phdr,
-  const guchar *pd)
+capture_loop_packet_cb(u_char *user, const struct pcap_pkthdr *phdr,
+  const u_char *pd)
 {
   struct wtap_pkthdr whdr;
   union wtap_pseudo_header pseudo_header;
@@ -1613,8 +1544,8 @@ capture_loop_packet_cb(guchar *user, const struct pcap_pkthdr *phdr,
   int err;
 
   /* if the user told us to stop after x packets, do we have enough? */
-  ld->counts.total++;
-  if ((ld->packets_max > 0) && (ld->counts.total >= ld->packets_max))
+  ld->packet_count++;
+  if ((ld->packet_max > 0) && (ld->packet_count >= ld->packet_max))
   {
      ld->go = FALSE;
   }
@@ -1639,69 +1570,6 @@ capture_loop_packet_cb(guchar *user, const struct pcap_pkthdr *phdr,
       ld->err = err;
     }
   }
-
-  switch (ld->wtap_linktype) {
-    case WTAP_ENCAP_ETHERNET:
-      capture_eth(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_FDDI:
-    case WTAP_ENCAP_FDDI_BITSWAPPED:
-      capture_fddi(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_PRISM_HEADER:
-      capture_prism(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_TOKEN_RING:
-      capture_tr(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_NULL:
-      capture_null(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_PPP:
-      capture_ppp_hdlc(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_RAW_IP:
-      capture_raw(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_SLL:
-      capture_sll(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_LINUX_ATM_CLIP:
-      capture_clip(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_IEEE_802_11:
-    case WTAP_ENCAP_IEEE_802_11_WITH_RADIO:
-      capture_ieee80211(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_CHDLC:
-      capture_chdlc(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_LOCALTALK:
-      capture_llap(&ld->counts);
-      break;
-    case WTAP_ENCAP_ATM_PDUS:
-      capture_atm(&pseudo_header, pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_IP_OVER_FC:
-      capture_ipfc(pd, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_ARCNET:
-      capture_arcnet(pd, whdr.caplen, &ld->counts, FALSE, TRUE);
-      break;
-    case WTAP_ENCAP_ARCNET_LINUX:
-      capture_arcnet(pd, whdr.caplen, &ld->counts, TRUE, FALSE);
-      break;
-    case WTAP_ENCAP_APPLE_IP_OVER_IEEE1394:
-      capture_ap1394(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    case WTAP_ENCAP_FRELAY:
-    case WTAP_ENCAP_FRELAY_WITH_PHDR:
-      capture_fr(pd, 0, whdr.caplen, &ld->counts);
-      break;
-    /* XXX - some ATM drivers on FreeBSD might prepend a 4-byte ATM
-       pseudo-header to DLT_ATM_RFC1483, with LLC header following;
-       we might have to implement that at some point. */
-  }
 }
 
 #endif /* HAVE_LIBPCAP */