Document the "-o dec" changes.
[obnox/wireshark/wip.git] / capture_loop.h
index defb31110bf6aead73e091f9a5c180269fb27a8a..77d0720d71a03e9612fec9dbe6742cf7affe827b 100644 (file)
@@ -3,8 +3,8 @@
  *
  * $Id$
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
 
 
 /** @file
- *  
+ *
  *  Do the low-level work of a capture.
  *
  */
 #ifndef __CAPTURE_LOOP_H__
 #define __CAPTURE_LOOP_H__
 
-#ifndef _WIN32
 /*
  * Get information about libpcap format from "wiretap/libpcap.h".
  * XXX - can we just use pcap_open_offline() to read the pipe?
  */
 #include "wiretap/libpcap.h"
-#endif
 
 /** Do the low-level work of a capture.
  *  Returns TRUE if it succeeds, FALSE otherwise. */
@@ -50,111 +48,90 @@ extern void capture_loop_stop(void);
 
 /*** the following is internal only (should be moved to capture_loop_int.h) ***/
 
-
+#if !defined (__linux__)
+#ifndef HAVE_PCAP_BREAKLOOP
 /*
- * 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 don't have pcap_breakloop(), which is the only way to ensure that
+ * pcap_dispatch(), pcap_loop(), or even pcap_next() or pcap_next_ex()
+ * won't, if the call to read the next packet or batch of packets is
+ * is interrupted by a signal on UN*X, just go back and try again to
+ * read again.
+ *
+ * On UN*X, we catch SIGUSR1 as a "stop capturing" signal, and, in
+ * the signal handler, set a flag to stop capturing; however, without
+ * a guarantee of that sort, we can't guarantee that we'll stop capturing
+ * if the read will be retried and won't time out if no packets arrive.
  *
- * 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.
+ * Therefore, on at least some platforms, we work around the lack of
+ * pcap_breakloop() by doing a select() on the pcap_t's file descriptor
+ * to wait for packets to arrive, so that we're probably going to be
+ * blocked in the select() when the signal arrives, and can just bail
+ * out of the loop at that point.
+ *
+ * However, we don't want to that 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.)
+ *
+ * Fortunately, we don't need to do it on BSD, because the libpcap timeout
+ * on BSD times out even if no packets have arrived, so we'll eventually
+ * exit pcap_dispatch() with an indication that no packets have arrived,
+ * and will break out of the capture loop at that point.
+ *
+ * On Windows, we can't send a SIGUSR1 to stop capturing, so none of this
+ * applies in any case.
  *
  * 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.
  */
-#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
+# if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
     !defined(__bsdi__) && !defined(__APPLE__) && !defined(_WIN32) && \
     !defined(__CYGWIN__)
-# define MUST_DO_SELECT
+#  define MUST_DO_SELECT
+# endif /* avoid select */
+#endif /* HAVE_PCAP_BREAKLOOP */
+#else /* linux */
+/* whatever the deal with pcap_breakloop, linux doesn't support timeouts
+ * in pcap_dispatch(); on the other hand, select() works just fine there.
+ * Hence we use a select for that come what may.
+ */
+#define MUST_DO_SELECT
 #endif
 
 typedef void (*capture_packet_cb_fct)(u_char *, const struct pcap_pkthdr *, const u_char *);
 
-
-/* moved from capture_loop.c here, so we can combine it (and the related functions) with tethereal */
-/* XXX - should be moved back to capture_loop.c */
-/* E: capture_loop.c only (Ethereal/dumpcap) T: tethereal only */
-typedef struct _loop_data {
-  /* common */
-  gboolean       go;                    /* TRUE as long as we're supposed to keep capturing */
-  int            err;                   /* E: if non-zero, error seen while capturing */
-  gint           packet_count;          /* Number of packets we have already captured */
-  gint           packet_max;            /* E: Number of packets we're supposed to capture - 0 means infinite */
-
-  jmp_buf        stopenv;               /* T: starting point of loop (jump back this point on SIG...) */
-
-  char          *save_file;             /* T: Name of file to which we're writing */
-  capture_packet_cb_fct  packet_cb;     /* callback for a single captured packet */
-
-  /* pcap "input file" */
-  pcap_t        *pcap_h;                /* pcap handle */
-  gboolean       pcap_err;              /* E: 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;         /* ? */
-  struct pcaprec_modified_hdr cap_pipe_rechdr;  /* ? */
-  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;
-
-
-
 /** init the capture filter */
-extern gboolean 
-capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, const gchar * iface, gchar * cfilter, char *errmsg, int errmsg_len);
+typedef enum {
+  INITFILTER_NO_ERROR,
+  INITFILTER_BAD_FILTER,
+  INITFILTER_OTHER_ERROR
+} initfilter_status_t;
 
-/** Take care of byte order in the libpcap headers read from pipes. */
-extern void
-cap_pipe_adjust_header(gboolean byte_swapped, struct pcap_hdr *hdr, struct pcaprec_hdr *rechdr);
+/*
+ * Routines called by the capture loop code to report things.
+ */
 
-#ifdef HAVE_LIBPCAP
-#ifndef _WIN32
-extern int 
-cap_pipe_open_live(char *, struct pcap_hdr *, loop_data *, char *, int);
+/** Report a new capture file having been opened. */
+extern void
+report_new_capture_file(const char *filename);
 
-extern int 
-cap_pipe_dispatch(int, loop_data *, struct pcap_hdr *, \
-                struct pcaprec_modified_hdr *, guchar *, char *, int);
-#endif /* _WIN32 */
-#endif
+/** Report a number of new packets captured. */
+extern void
+report_packet_count(int packet_count);
 
-extern gboolean 
-capture_loop_open_input(capture_options *capture_opts, loop_data *ld, char *errmsg, int errmsg_len);
+/** Report the packet drops once the capture finishes. */
+extern void
+report_packet_drops(int drops);
 
-extern gboolean
-capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, char *errmsg, int errmsg_len);
+/** Report an error in the capture. */
+extern void
+report_capture_error(const char *error_msg, const char *secondary_error_msg);
 
-extern gboolean
-capture_loop_init_wiretap_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len);
+/** Report an error with a capture filter. */
+extern void
+report_cfilter_error(const char *cfilter, const char *errmsg);
 
-extern gboolean 
-capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close);
 
 #endif /* capture_loop.h */