Merge remote-tracking branch 'goog/tcpdump'
* goog/tcpdump: (1872 commits)
Remove old version. Getting ready for new libpcap 1.5
Remove commas from clauses in a comma-separated list.
Fix typo.
Describe all NFLOG TLV types and define structures for some of them.
Check caplen in the NFLOG TLV loop.
Have nflog_tlv_t include only the TLV header.
Byte-swap the T and L in TLVs as necessary when reading an NFLOG file.
Don't support D-Bus sniffing on OS X.
Add post-1.5.2 bug fixes.
Tag some changes with a bug identifier.
Add items for 1.5.1 and 1.5.2.
Formatting tweak.
Count *ring buffer blocks*, not *packets* to be filtered in userland.
Add a PACKET_COUNT_IS_UNLIMITED() to test for a packet count <= 0.
Use HAVE_TPACKET3 rather than TPACKET_V3 to test for TPACKET_V3 support.
Fix builds on systems without TPACKET_V3.
tweak manpages formatting
Fix pcap_loop() with a count of 0 and TPACKET_V3.
Discourage the use of a zero timeout.
We can't use TPACKET_V3 in immediate mode, so fall back on TPACKET_V2.
...
Change-Id: I2aa9bd87673c56aee439e1154b96a14026ca7985
diff --git a/pcap-dos.c b/pcap-dos.c
index 0700d6b..cecc73c 100644
--- a/pcap-dos.c
+++ b/pcap-dos.c
@@ -1,11 +1,11 @@
/*
* This file is part of DOS-libpcap
- * Ported to DOS/DOSX by G. Vanem <giva@bgnett.no>
+ * Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no>
*
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers.
*
- * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.1.2.1 2005/05/03 18:54:35 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.7 2008-04-22 17:16:30 guy Exp $ (LBL)
*/
#include <stdio.h>
@@ -97,9 +97,10 @@
static struct device *handle_to_device [20];
+static int pcap_activate_dos (pcap_t *p);
static int pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
u_char *data);
-static void pcap_close_dos (pcap_t *p);
+static void pcap_cleanup_dos (pcap_t *p);
static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps);
static int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len);
static int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp);
@@ -143,58 +144,73 @@
}
/*
+ * Private data for capturing on MS-DOS.
+ */
+struct pcap_dos {
+ void (*wait_proc)(void); /* call proc while waiting */
+ struct pcap_stat stat;
+};
+
+pcap_t *pcap_create_interface (const char *device, char *ebuf)
+{
+ pcap_t *p;
+
+ p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos));
+ if (p == NULL)
+ return (NULL);
+
+ p->activate_op = pcap_activate_dos;
+ return (p);
+}
+
+/*
* Open MAC-driver with name 'device_name' for live capture of
* network packets.
*/
-pcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
- int timeout_ms, char *errbuf)
+static int pcap_activate_dos (pcap_t *pcap)
{
- struct pcap *pcap;
+ struct pcap_dos *pcapd = pcap->priv;
- if (snaplen < ETH_MIN)
- snaplen = ETH_MIN;
-
- if (snaplen > ETH_MAX) /* silently accept and truncate large MTUs */
- snaplen = ETH_MAX;
-
- pcap = calloc (sizeof(*pcap), 1);
- if (!pcap)
- {
- strcpy (errbuf, "Not enough memory (pcap)");
- return (NULL);
+ if (pcap->opt.rfmon) {
+ /*
+ * No monitor mode on DOS.
+ */
+ return (PCAP_ERROR_RFMON_NOTSUP);
}
- pcap->snapshot = max (ETH_MIN+8, snaplen);
+ if (pcap->snapshot < ETH_MIN+8)
+ pcap->snapshot = ETH_MIN+8;
+
+ if (pcap->snapshot > ETH_MAX) /* silently accept and truncate large MTUs */
+ pcap->snapshot = ETH_MAX;
+
pcap->linktype = DLT_EN10MB; /* !! */
- pcap->inter_packet_wait = timeout_ms;
- pcap->close_op = pcap_close_dos;
+ pcap->cleanup_op = pcap_cleanup_dos;
pcap->read_op = pcap_read_dos;
pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos;
pcap->setfilter_op = pcap_setfilter_dos;
- pcap->setdirection_op = NULL; /* Not implemented.*/
+ pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count;
if (pcap->fd == 1) /* first time we're called */
{
- if (!init_watt32(pcap, device_name, errbuf) ||
- !first_init(device_name, errbuf, promisc))
+ if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
+ !first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
{
- free (pcap);
- return (NULL);
+ return (PCAP_ERROR);
}
atexit (close_driver);
}
- else if (stricmp(active_dev->name,device_name))
+ else if (stricmp(active_dev->name,pcap->opt.source))
{
- snprintf (errbuf, PCAP_ERRBUF_SIZE,
+ snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
"Cannot use different devices simultaneously "
- "(`%s' vs. `%s')", active_dev->name, device_name);
- free (pcap);
- pcap = NULL;
+ "(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
+ return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
- return (pcap);
+ return (0);
}
/*
@@ -204,16 +220,16 @@
static int
pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
{
+ struct pcap_dos *pd = p->priv;
struct pcap_pkthdr pcap;
- struct bpf_insn *fcode = p->fcode.bf_insns;
- struct timeval now, expiry;
+ struct timeval now, expiry = { 0,0 };
BYTE *rx_buf;
int rx_len = 0;
- if (p->inter_packet_wait > 0)
+ if (p->opt.timeout > 0)
{
gettimeofday2 (&now, NULL);
- expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait;
+ expiry.tv_usec = now.tv_usec + 1000UL * p->opt.timeout;
expiry.tv_sec = now.tv_sec;
while (expiry.tv_usec >= 1000000L)
{
@@ -258,7 +274,7 @@
pcap.len = rx_len;
if (callback &&
- (!fcode || bpf_filter(fcode, rx_buf, pcap.len, pcap.caplen)))
+ (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen)))
{
filter_count++;
@@ -282,10 +298,10 @@
return (1);
}
- /* If not to wait for a packet or pcap_close() called from
+ /* If not to wait for a packet or pcap_cleanup_dos() called from
* e.g. SIGINT handler, exit loop now.
*/
- if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0)
+ if (p->opt.timeout <= 0 || (volatile int)p->fd <= 0)
break;
gettimeofday2 (&now, NULL);
@@ -303,7 +319,7 @@
if (rx_len < 0) /* receive error */
{
- p->md.stat.ps_drop++;
+ pd->stat.ps_drop++;
#ifdef USE_32BIT_DRIVERS
if (pcap_pkt_debug > 1)
printk ("pkt-err %s\n", pktInfo.error);
@@ -316,9 +332,10 @@
static int
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
{
+ struct pcap_dos *pd = p->priv;
int rc, num = 0;
- while (num <= cnt || (cnt < 0))
+ while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
{
if (p->fd <= 0)
return (-1);
@@ -338,6 +355,7 @@
static int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps)
{
struct net_device_stats *stats;
+ struct pcap_dos *pd;
struct device *dev = p ? get_device(p->fd) : NULL;
if (!dev)
@@ -354,12 +372,13 @@
FLUSHK();
- p->md.stat.ps_recv = stats->rx_packets;
- p->md.stat.ps_drop += stats->rx_missed_errors;
- p->md.stat.ps_ifdrop = stats->rx_dropped + /* queue full */
+ pd = p->priv;
+ pd->stat.ps_recv = stats->rx_packets;
+ pd->stat.ps_drop += stats->rx_missed_errors;
+ pd->stat.ps_ifdrop = stats->rx_dropped + /* queue full */
stats->rx_errors; /* HW errors */
if (ps)
- *ps = p->md.stat;
+ *ps = pd->stat;
return (0);
}
@@ -421,12 +440,15 @@
/*
* Close pcap device. Not called for offline captures.
*/
-static void pcap_close_dos (pcap_t *p)
+static void pcap_cleanup_dos (pcap_t *p)
{
+ struct pcap_dos *pd;
+
if (p && !exc_occured)
{
+ pd = p->priv;
if (pcap_stats(p,NULL) < 0)
- p->md.stat.ps_drop = 0;
+ pd->stat.ps_drop = 0;
if (!get_device(p->fd))
return;
@@ -477,7 +499,7 @@
{
if (!_watt_is_init)
{
- strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be "
+ strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
"called first");
return (-1);
}
@@ -585,10 +607,12 @@
*/
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
{
+ struct pcap_dos *pd;
if (p)
{
- p->wait_proc = yield;
- p->inter_packet_wait = wait;
+ pd = p->priv;
+ pd->wait_proc = yield;
+ p->opt.timeout = wait;
}
}
@@ -734,13 +758,13 @@
fprintf (stderr, "Catching signal %d.\n", sig);
}
exc_occured = 1;
- pcap_close_dos (NULL);
+ pcap_cleanup_dos (NULL);
}
#endif /* __DJGPP__ */
/*
- * Open the pcap device for the first client calling pcap_open_live()
+ * Open the pcap device for the first client calling pcap_activate()
*/
static int first_init (const char *name, char *ebuf, int promisc)
{
@@ -991,7 +1015,7 @@
* Application config hooks to set various driver parameters.
*/
-static struct config_table debug_tab[] = {
+static const struct config_table debug_tab[] = {
{ "PKT.DEBUG", ARG_ATOI, &pcap_pkt_debug },
{ "PKT.VECTOR", ARG_ATOX_W, NULL },
{ "NDIS.DEBUG", ARG_ATOI, NULL },