Small update to svn:ignore
[obnox/wireshark/wip.git] / capture_loop.h
1 /* capture_loop.h
2  * Do the low-level work of a capture
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25
26 /** @file
27  *
28  *  Do the low-level work of a capture.
29  *
30  */
31
32 #ifndef __CAPTURE_LOOP_H__
33 #define __CAPTURE_LOOP_H__
34
35 /*
36  * Get information about libpcap format from "wiretap/libpcap.h".
37  * XXX - can we just use pcap_open_offline() to read the pipe?
38  */
39 #include "wiretap/libpcap.h"
40
41 /** Do the low-level work of a capture.
42  *  Returns TRUE if it succeeds, FALSE otherwise. */
43 extern int  capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct pcap_stat *stats);
44
45 /** Stop a low-level capture (stops the capture child). */
46 extern void capture_loop_stop(void);
47
48
49 /*** the following is internal only (should be moved to capture_loop_int.h) ***/
50
51 #if !defined (__linux__)
52 #ifndef HAVE_PCAP_BREAKLOOP
53 /*
54  * We don't have pcap_breakloop(), which is the only way to ensure that
55  * pcap_dispatch(), pcap_loop(), or even pcap_next() or pcap_next_ex()
56  * won't, if the call to read the next packet or batch of packets is
57  * is interrupted by a signal on UN*X, just go back and try again to
58  * read again.
59  *
60  * On UN*X, we catch SIGUSR1 as a "stop capturing" signal, and, in
61  * the signal handler, set a flag to stop capturing; however, without
62  * a guarantee of that sort, we can't guarantee that we'll stop capturing
63  * if the read will be retried and won't time out if no packets arrive.
64  *
65  * Therefore, on at least some platforms, we work around the lack of
66  * pcap_breakloop() by doing a select() on the pcap_t's file descriptor
67  * to wait for packets to arrive, so that we're probably going to be
68  * blocked in the select() when the signal arrives, and can just bail
69  * out of the loop at that point.
70  *
71  * However, we don't want to that on BSD (because "select()" doesn't work
72  * correctly on BPF devices on at least some releases of some flavors of
73  * BSD), and we don't want to do it on Windows (because "select()" is
74  * something for sockets, not for arbitrary handles).  (Note that "Windows"
75  * here includes Cygwin; even in its pretend-it's-UNIX environment, we're
76  * using WinPcap, not a UNIX libpcap.)
77  *
78  * Fortunately, we don't need to do it on BSD, because the libpcap timeout
79  * on BSD times out even if no packets have arrived, so we'll eventually
80  * exit pcap_dispatch() with an indication that no packets have arrived,
81  * and will break out of the capture loop at that point.
82  *
83  * On Windows, we can't send a SIGUSR1 to stop capturing, so none of this
84  * applies in any case.
85  *
86  * XXX - the various BSDs appear to define BSD in <sys/param.h>; we don't
87  * want to include it if it's not present on this platform, however.
88  */
89 # if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && \
90     !defined(__bsdi__) && !defined(__APPLE__) && !defined(_WIN32) && \
91     !defined(__CYGWIN__)
92 #  define MUST_DO_SELECT
93 # endif /* avoid select */
94 #endif /* HAVE_PCAP_BREAKLOOP */
95 #else /* linux */
96 /* whatever the deal with pcap_breakloop, linux doesn't support timeouts
97  * in pcap_dispatch(); on the other hand, select() works just fine there.
98  * Hence we use a select for that come what may.
99  */
100 #define MUST_DO_SELECT
101 #endif
102
103 typedef void (*capture_packet_cb_fct)(u_char *, const struct pcap_pkthdr *, const u_char *);
104
105
106 /* moved from capture_loop.c here, so we can combine it (and the related functions) with tshark */
107 /* XXX - should be moved back to capture_loop.c */
108 /* E: capture_loop.c only (Wireshark/dumpcap) T: tshark only */
109 typedef struct _loop_data {
110   /* common */
111   gboolean       go;                    /* TRUE as long as we're supposed to keep capturing */
112   int            err;                   /* E: if non-zero, error seen while capturing */
113   gint           packet_count;          /* Number of packets we have already captured */
114   gint           packet_max;            /* E: Number of packets we're supposed to capture - 0 means infinite */
115
116   jmp_buf        stopenv;               /* T: starting point of loop (jump back this point on SIG...) */
117
118   char          *save_file;             /* T: Name of file to which we're writing */
119   capture_packet_cb_fct  packet_cb;     /* callback for a single captured packet */
120
121   /* pcap "input file" */
122   pcap_t        *pcap_h;                /* pcap handle */
123   gboolean       pcap_err;              /* E: TRUE if error from pcap */
124 #ifdef MUST_DO_SELECT
125   int            pcap_fd;               /* pcap file descriptor */
126 #endif
127
128   /* capture pipe (unix only "input file") */
129   gboolean       from_cap_pipe;         /* TRUE if we are capturing data from a capture pipe */
130   struct pcap_hdr cap_pipe_hdr;         /* ? */
131   struct pcaprec_modified_hdr cap_pipe_rechdr;  /* ? */
132   int            cap_pipe_fd;           /* the file descriptor of the capture pipe */
133   gboolean       cap_pipe_modified;     /* TRUE if data in the pipe uses modified pcap headers */
134   gboolean       cap_pipe_byte_swapped; /* TRUE if data in the pipe is byte swapped */
135   unsigned int   cap_pipe_bytes_to_read;/* Used by cap_pipe_dispatch */
136   unsigned int   cap_pipe_bytes_read;   /* Used by cap_pipe_dispatch */
137   enum {
138          STATE_EXPECT_REC_HDR,
139          STATE_READ_REC_HDR,
140          STATE_EXPECT_DATA,
141          STATE_READ_DATA
142        } cap_pipe_state;
143   enum { PIPOK, PIPEOF, PIPERR, PIPNEXIST } cap_pipe_err;
144
145   /* output file */
146   FILE          *pdh;
147   int            linktype;
148   gint           wtap_linktype;
149   long           bytes_written;
150
151 } loop_data;
152
153
154
155 /** init the capture filter */
156 typedef enum {
157   INITFILTER_NO_ERROR,
158   INITFILTER_BAD_FILTER,
159   INITFILTER_OTHER_ERROR
160 } initfilter_status_t;
161
162 extern initfilter_status_t
163 capture_loop_init_filter(pcap_t *pcap_h, gboolean from_cap_pipe, gchar * iface, gchar * cfilter);
164
165 int
166 capture_loop_dispatch(capture_options *capture_opts _U_, loop_data *ld,
167                       char *errmsg, int errmsg_len);
168
169 extern gboolean
170 capture_loop_open_input(capture_options *capture_opts, loop_data *ld,
171                         char *errmsg, size_t errmsg_len,
172                         char *secondary_errmsg, size_t secondary_errmsg_len);
173
174 extern gboolean
175 capture_loop_open_output(capture_options *capture_opts, int *save_file_fd, char *errmsg, int errmsg_len);
176
177 extern gboolean
178 capture_loop_init_output(capture_options *capture_opts, int save_file_fd, loop_data *ld, char *errmsg, int errmsg_len);
179
180 extern gboolean
181 capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close);
182
183 /*
184  * Routines called by the capture loop code to report things.
185  */
186
187 /** Report a new capture file having been opened. */
188 extern void
189 report_new_capture_file(const char *filename);
190
191 /** Report a number of new packets captured. */
192 extern void
193 report_packet_count(int packet_count);
194
195 /** Report the packet drops once the capture finishes. */
196 extern void
197 report_packet_drops(int drops);
198
199 /** Report an error in the capture. */
200 extern void
201 report_capture_error(const char *error_msg, const char *secondary_error_msg);
202
203 /** Report an error with a capture filter. */
204 extern void
205 report_cfilter_error(const char *cfilter, const char *errmsg);
206
207
208 #endif /* capture_loop.h */