#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.36 2007-11-13 21:55:51 gianluca Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.37 2008-04-04 19:37:45 guy Exp $ (LBL)";
#endif
#include <pcap-int.h>
}
}
-pcap_t *
-pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
- char *ebuf)
+static int
+pcap_activate_win32(pcap_t *p)
{
- register pcap_t *p;
NetType type;
+ if (p->opt.rfmon) {
+ /*
+ * No monitor mode on Windows. It could be done on
+ * Vista with drivers that support the native 802.11
+ * mechanism and monitor mode.
+ */
+ return (PCAP_ERROR_RFMON_NOTSUP);
+ }
+
/* Init WinSock */
wsockinit();
- p = (pcap_t *)malloc(sizeof(*p));
- if (p == NULL)
- {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
- return (NULL);
- }
- memset(p, 0, sizeof(*p));
- p->adapter=NULL;
-
- p->adapter = PacketOpenAdapter((char*)device);
+ p->adapter = PacketOpenAdapter(p->opt.source);
if (p->adapter == NULL)
{
- free(p);
/* Adapter detected but we are not able to open it. Return failure. */
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
- return NULL;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
+ return PCAP_ERROR;
}
/*get network type*/
if(PacketGetNetType (p->adapter,&type) == FALSE)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
goto bad;
}
}
/* Set promiscuous mode */
- if (promisc)
+ if (p->opt.promisc)
{
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
goto bad;
}
}
{
if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
goto bad;
}
}
p->bufsize = PcapBufSize;
/* Store the timeout. Used by pcap_setnonblock() */
- p->timeout= to_ms;
+ p->md.timeout= to_ms;
/* allocate Packet structure used during the capture */
if((p->Packet = PacketAllocatePacket())==NULL)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
goto bad;
}
/*
* Traditional Adapter
*/
+ /*
+ * If the buffer size wasn't explicitly set, default to
+ * SIZE_BUF.
+ */
+ if (p->opt.buffer_size == 0)
+ p->opt.buffer_size = SIZE_BUF;
+ if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
+ {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
+ goto bad;
+ }
p->buffer = (u_char *)malloc(PcapBufSize);
if (p->buffer == NULL)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
goto bad;
}
/* allocate the standard buffer in the driver */
if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
goto bad;
}
/* tell the driver to copy the buffer only if it contains at least 16K */
if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
{
- snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
goto bad;
}
}
snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
"SYSTEM\\CurrentControlSet\\Services\\DAG",
- strstr(_strlwr((char*)device), "dag"));
+ strstr(_strlwr(p->opt.source), "dag"));
do
{
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
p->setmintocopy_op = pcap_setmintocopy_win32;
p->close_op = pcap_close_win32;
- return (p);
+ return (0);
bad:
if (p->adapter)
PacketCloseAdapter(p->adapter);
- if (p->buffer != NULL)
+ if (p->buffer != NULL) {
free(p->buffer);
+ p->buffer = NULL;
+ }
if(p->Packet)
PacketFreePacket(p->Packet);
- /*
- * Get rid of any link-layer type list we allocated.
- */
- if (p->dlt_list != NULL)
- free(p->dlt_list);
- free(p);
- return (NULL);
+ return (PCAP_ERROR);
}
+pcap_t *
+pcap_create(const char *device, char *ebuf)
+{
+ pcap_t *p;
+
+ p = pcap_create_common(device, ebuf);
+ if (p == NULL)
+ return (NULL);
+
+ p->activate_op = pcap_activate_win32;
+ return (p);
+}
static int
pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
* (Note that this may be -1, in which case we're not
* really leaving non-blocking mode.)
*/
- newtimeout = p->timeout;
+ newtimeout = p->md.timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,