#include "pcap-util.h"
#include "simple_dialog.h"
-#include "globals.h"
#include "conditions.h"
#include "capture_stop_conditions.h"
#include "ringbuffer.h"
static void capture_loop_packet_cb(guchar *user, const struct pcap_pkthdr *phdr,
const guchar *pd);
-static void capture_loop_popup_errmsg(const char *);
-static void capture_loop_get_errmsg(char *, int, const char *, int, gboolean);
+static void capture_loop_popup_errmsg(capture_options *capture_opts, const char *errmsg);
+static void capture_loop_get_errmsg(char *errmsg, int errmsglen, const char *fname,
+ int err, gboolean is_close);
if they succeed; to tell if that's happened, we have to clear
the error buffer, and check if it's still a null string. */
open_err_str[0] = '\0';
- ld->pcap_h = pcap_open_live(cfile.iface,
+ ld->pcap_h = pcap_open_live(capture_opts->iface,
capture_opts->has_snaplen ? capture_opts->snaplen :
WTAP_MAX_PACKET_SIZE,
capture_opts->promisc_mode, CAP_READ_TIMEOUT,
open_err_str);
if (ld->pcap_h != NULL) {
- /* we've opened "cfile.iface" as a network device */
+ /* we've opened "iface" as a network device */
#ifdef _WIN32
/* try to set the capture buffer size */
if (pcap_setbuff(ld->pcap_h, capture_opts->buffer_size * 1024 * 1024) != 0) {
/* setting the data link type only works on real interfaces */
if (capture_opts->linktype != -1) {
- set_linktype_err_str = set_pcap_linktype(ld->pcap_h, cfile.iface,
+ set_linktype_err_str = set_pcap_linktype(ld->pcap_h, capture_opts->iface,
capture_opts->linktype);
if (set_linktype_err_str != NULL) {
g_snprintf(errmsg, errmsg_len, "Unable to set data link type (%s).",
}
}
} else {
- /* We couldn't open "cfile.iface" as a network device. */
+ /* We couldn't open "iface" as a network device. */
#ifdef _WIN32
/* On Windows, we don't support capturing on pipes, so we give up.
If this is a child process that does the capturing in sync
mode or fork mode, it shouldn't do any UI stuff until we pop up the
capture-progress window, and, since we couldn't start the
capture, we haven't popped it up. */
- if (!capture_child) {
+ if (!capture_opts->capture_child) {
main_window_update();
}
Do, however, warn that WAN devices aren't supported. */
g_snprintf(errmsg, errmsg_len,
- "The capture session could not be initiated (%s).\n"
- "Please check that you have the proper interface specified.\n"
- "\n"
- "Note that the WinPcap 2.x version of the driver Ethereal uses for packet\n"
- "capture on Windows doesn't support capturing on PPP/WAN interfaces in\n"
- "Windows NT/2000/XP/2003 Server, and that the WinPcap 3.0 and later versions\n"
- "don't support capturing on PPP/WAN interfaces at all.",
+"The capture session could not be initiated (%s).\n"
+"Please check that you have the proper interface specified.\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, Windows 2000,\n"
+"Windows XP, or Windows Server 2003. WinPcap 3.1 has experimental support\n"
+"for it on Windows 2000, Windows XP, and Windows Server 2003, but has no\n"
+"support for it on Windows NT 4.0. WinPcap 3.1 is currently in beta, so\n"
+"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.",
open_err_str);
return FALSE;
#else
- /* try to open cfile.iface as a pipe */
- ld->cap_pipe_fd = cap_pipe_open_live(cfile.iface, &ld->cap_pipe_hdr, ld, errmsg, errmsg_len);
+ /* try to open iface as a pipe */
+ ld->cap_pipe_fd = cap_pipe_open_live(capture_opts->iface, &ld->cap_pipe_hdr, ld, errmsg, errmsg_len);
if (ld->cap_pipe_fd == -1) {
* capture-progress window, and, since we couldn't start the
* capture, we haven't popped it up.
*/
- if (!capture_child) {
+ if (!capture_opts->capture_child) {
main_window_update();
}
"at the URL lists a number of mirror sites.";
else
libpcap_warn = "";
- g_snprintf(errmsg, sizeof errmsg,
+ g_snprintf(errmsg, errmsg_len,
"The capture session could not be initiated (%s).\n"
"Please check to make sure you have sufficient permissions, and that\n"
"you have the proper interface or pipe specified.%s", open_err_str,
/* init the capture filter */
-static int capture_loop_init_filter(loop_data *ld, char *errmsg, int errmsg_len) {
+static int capture_loop_init_filter(loop_data *ld, 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;
/* capture filters only work on real interfaces */
- if (cfile.cfilter && !ld->from_cap_pipe) {
+ if (cfilter && !ld->from_cap_pipe) {
/* A capture filter was specified; set it up. */
- if (pcap_lookupnet(cfile.iface, &netnum, &netmask, lookup_net_err_str) < 0) {
+ if (pcap_lookupnet(iface, &netnum, &netmask, lookup_net_err_str) < 0) {
/*
* Well, we can't get the netmask for this interface; it's used
* only for filters that check for broadcast IP addresses, so
*/
netmask = 0;
}
- if (pcap_compile(ld->pcap_h, &fcode, cfile.cfilter, 1, netmask) < 0) {
+ if (pcap_compile(ld->pcap_h, &fcode, cfilter, 1, netmask) < 0) {
dfilter_t *rfcode = NULL;
/* filter string invalid, did the user tried a display filter? */
- if (dfilter_compile(cfile.cfilter, &rfcode) && rfcode != NULL) {
+ if (dfilter_compile(cfilter, &rfcode) && rfcode != NULL) {
g_snprintf(errmsg, errmsg_len,
"%sInvalid capture filter: \"%s\"!%s\n"
"\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(), cfile.cfilter, simple_dialog_primary_end(),
+ simple_dialog_primary_start(), cfilter, simple_dialog_primary_end(),
pcap_geterr(ld->pcap_h));
dfilter_free(rfcode);
} else {
"\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(), cfile.cfilter, simple_dialog_primary_end(),
+ simple_dialog_primary_start(), cfilter, simple_dialog_primary_end(),
pcap_geterr(ld->pcap_h));
}
return FALSE;
} else
#endif
{
- pcap_encap = get_pcap_linktype(ld->pcap_h, cfile.iface);
+ pcap_encap = get_pcap_linktype(ld->pcap_h, capture_opts->iface);
file_snaplen = pcap_snapshot(ld->pcap_h);
}
ld->wtap_pdh = ringbuf_init_wtap_dump_fdopen(WTAP_FILE_PCAP, ld->wtap_linktype,
file_snaplen, &err);
} else {
- ld->wtap_pdh = wtap_dump_fdopen(cfile.save_file_fd, WTAP_FILE_PCAP,
+ ld->wtap_pdh = wtap_dump_fdopen(capture_opts->save_file_fd, WTAP_FILE_PCAP,
ld->wtap_linktype, file_snaplen, &err);
}
g_snprintf(errmsg, errmsg_len,
"The file to which the capture would be"
" saved (\"%s\") could not be opened: Error %d.",
- cfile.save_file, err);
+ capture_opts->save_file, err);
} else {
g_snprintf(errmsg, errmsg_len,
"The file to which the capture would be"
" saved (\"%s\") could not be opened: %s.",
- cfile.save_file, strerror(err));
+ capture_opts->save_file, strerror(err));
}
break;
}
static gboolean capture_loop_close_output(capture_options *capture_opts, loop_data *ld, int *err_close) {
if (capture_opts->multi_files_on) {
- return ringbuf_wtap_dump_close(&cfile, err_close);
+ return ringbuf_wtap_dump_close(&capture_opts->save_file, err_close);
} else {
return wtap_dump_close(ld->wtap_pdh, err_close);
}
/* dispatch incoming packets (pcap or capture pipe) */
static int
-capture_loop_dispatch(loop_data *ld, char *errmsg, int errmsg_len) {
+capture_loop_dispatch(capture_options *capture_opts, loop_data *ld,
+ char *errmsg, int errmsg_len) {
int inpkts;
#ifndef _WIN32
fd_set set1;
guchar pcap_data[WTAP_MAX_PACKET_SIZE];
#endif
-
#ifndef _WIN32
/* dispatch from capture pipe */
if (ld->from_cap_pipe) {
if (sel_ret < 0 && errno != EINTR) {
g_snprintf(errmsg, errmsg_len,
"Unexpected error from select: %s", strerror(errno));
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
ld->go = FALSE;
}
} else {
if (sel_ret < 0 && errno != EINTR) {
g_snprintf(errmsg, errmsg_len,
"Unexpected error from select: %s", strerror(errno));
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
ld->go = FALSE;
}
}
}
/* init the input filter from the network interface (capture pipe will do nothing) */
- if (!capture_loop_init_filter(&ld, errmsg, sizeof(errmsg))) {
+ if (!capture_loop_init_filter(&ld, capture_opts->iface, capture_opts->cfilter, errmsg, sizeof(errmsg))) {
goto error;
}
in other places as well - and I don't think that works all the
time in any case, due to libpcap bugs. */
- if (capture_child) {
+ if (capture_opts->capture_child) {
/* Well, we should be able to start capturing.
This is the child process for a sync mode capture, so sync out
if(show_info) {
capture_ui.callback_data = &ld;
capture_ui.counts = &ld.counts;
- capture_info_create(&capture_ui, cfile.iface);
+ capture_info_create(&capture_ui, capture_opts->iface);
}
/* init the time values */
main_window_update();
/* dispatch incoming packets */
- inpkts = capture_loop_dispatch(&ld, errmsg, sizeof(errmsg));
+ inpkts = capture_loop_dispatch(capture_opts, &ld, errmsg, sizeof(errmsg));
if (inpkts > 0) {
ld.packets_sync_pipe += inpkts;
}
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&cfile, &ld.wtap_pdh, &ld.err)) {
+ if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &capture_opts->save_file_fd, &ld.err)) {
/* File switch succeeded: reset the conditions */
cnd_reset(cnd_autostop_size);
if (cnd_file_duration) {
/* do sync here */
fflush(wtap_dump_file(ld.wtap_pdh));
- if (capture_child) {
+ if (capture_opts->capture_child) {
/* This is the child process for a sync mode capture, so send
our parent a message saying we've written out "ld.sync_packets"
packets to the capture file. */
}
/* Switch to the next ringbuffer file */
- if (ringbuf_switch_file(&cfile, &ld.wtap_pdh, &ld.err)) {
+ if (ringbuf_switch_file(&ld.wtap_pdh, &capture_opts->save_file, &capture_opts->save_file_fd, &ld.err)) {
/* file switch succeeded: reset the conditions */
cnd_reset(cnd_file_duration);
if(cnd_autostop_size)
if (ld.pcap_err) {
g_snprintf(errmsg, sizeof(errmsg), "Error while capturing packets: %s",
pcap_geterr(ld.pcap_h));
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
}
#ifndef _WIN32
else if (ld.from_cap_pipe && ld.cap_pipe_err == PIPERR)
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
#endif
/* did we had an error while capturing? */
if (ld.err == 0) {
write_ok = TRUE;
} else {
- capture_loop_get_errmsg(errmsg, sizeof(errmsg), cfile.save_file, ld.err,
+ capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, ld.err,
FALSE);
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
write_ok = FALSE;
}
/* If we've displayed a message about a write error, there's no point
in displaying another message about an error on close. */
if (!close_ok && write_ok) {
- capture_loop_get_errmsg(errmsg, sizeof(errmsg), cfile.save_file, err_close,
+ capture_loop_get_errmsg(errmsg, sizeof(errmsg), capture_opts->save_file, err_close,
TRUE);
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
}
/*
dropped. */
if (pcap_stats(ld.pcap_h, stats) >= 0) {
*stats_known = TRUE;
- if (capture_child) {
+ if (capture_opts->capture_child) {
/* Let the parent process know. */
sync_pipe_drops_to_parent(stats->ps_drop);
}
g_snprintf(errmsg, sizeof(errmsg),
"Can't get packet-drop statistics: %s",
pcap_geterr(ld.pcap_h));
- capture_loop_popup_errmsg(errmsg);
+ capture_loop_popup_errmsg(capture_opts, errmsg);
}
}
} 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(cfile.save_file_fd);
+ close(capture_opts->save_file_fd);
/* We couldn't even start the capture, so get rid of the capture
file. */
- unlink(cfile.save_file); /* silently ignore error */
- g_free(cfile.save_file);
+ unlink(capture_opts->save_file); /* silently ignore error */
+ g_free(capture_opts->save_file);
}
- cfile.save_file = NULL;
- capture_loop_popup_errmsg(errmsg);
+ capture_opts->save_file = NULL;
+ capture_loop_popup_errmsg(capture_opts, errmsg);
/* close the input file (pcap or cap_pipe) */
capture_loop_close_input(&ld);
}
static void
-capture_loop_popup_errmsg(const char *errmsg)
+capture_loop_popup_errmsg(capture_options *capture_opts, const char *errmsg)
{
- if (capture_child) {
+ if (capture_opts->capture_child) {
/* This is the child process for a sync mode capture.
Send the error message to our parent, so they can display a
dialog box containing it. */
int err;
/* if the user told us to stop after x packets, do we have enough? */
- if ((ld->packets_max > 0) && (++ld->counts.total >= ld->packets_max))
+ ld->counts.total++;
+ if ((ld->packets_max > 0) && (ld->counts.total >= ld->packets_max))
{
ld->go = FALSE;
}