* Private data for capturing on WinPcap devices.
*/
struct pcap_win {
+ ADAPTER *adapter; /* the packet32 ADAPTER for the device */
int nonblock;
int rfmon_selfstart; /* a flag tells whether the monitor mode is set by itself */
int filtering_in_kernel; /* using kernel filter */
static int
pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
{
+ struct pcap_win *pw = p->priv;
struct bpf_stat bstats;
char errbuf[PCAP_ERRBUF_SIZE+1];
* in would stomp on whatever comes after the structure passed
* to us.
*/
- if (!PacketGetStats(p->adapter, &bstats)) {
+ if (!PacketGetStats(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketGetStats error: %s", errbuf);
struct pcap_stat *
pcap_stats_ex_win32(pcap_t *p, int *pcap_stat_size)
{
+ struct pcap_win *pw = p->priv;
struct bpf_stat bstats;
char errbuf[PCAP_ERRBUF_SIZE+1];
* WinPcap's "struct bpf_stat". It might currently have the
* same layout, but let's not cheat.)
*/
- if (!PacketGetStatsEx(p->adapter, &bstats)) {
+ if (!PacketGetStatsEx(pw->adapter, &bstats)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketGetStatsEx error: %s", errbuf);
static int
pcap_setbuff_win32(pcap_t *p, int dim)
{
- if(PacketSetBuff(p->adapter,dim)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetBuff(pw->adapter,dim)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
return (-1);
static int
pcap_setmode_win32(pcap_t *p, int mode)
{
- if(PacketSetMode(p->adapter,mode)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetMode(pw->adapter,mode)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
return (-1);
static int
pcap_setmintocopy_win32(pcap_t *p, int size)
{
- if(PacketSetMinToCopy(p->adapter, size)==FALSE)
+ struct pcap_win *pw = p->priv;
+
+ if(PacketSetMinToCopy(pw->adapter, size)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
return (-1);
static HANDLE
pcap_getevent_win32(pcap_t *p)
{
- return (PacketGetReadEvent(p->adapter));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketGetReadEvent(pw->adapter));
}
static int
pcap_oid_get_request_win32(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp)
{
+ struct pcap_win *pw = p->priv;
PACKET_OID_DATA *oid_data_arg;
char errbuf[PCAP_ERRBUF_SIZE+1];
*/
oid_data_arg->Oid = oid;
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
- if (!PacketRequest(p->adapter, FALSE, oid_data_arg)) {
+ if (!PacketRequest(pw->adapter, FALSE, oid_data_arg)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error calling PacketRequest: %s", errbuf);
pcap_oid_set_request_win32(pcap_t *p, bpf_u_int32 oid, const void *data,
size_t *lenp)
{
+ struct pcap_win *pw = p->priv;
PACKET_OID_DATA *oid_data_arg;
char errbuf[PCAP_ERRBUF_SIZE+1];
oid_data_arg->Oid = oid;
oid_data_arg->Length = (ULONG)(*lenp); /* XXX - check for ridiculously large value? */
memcpy(oid_data_arg->Data, data, *lenp);
- if (!PacketRequest(p->adapter, TRUE, oid_data_arg)) {
+ if (!PacketRequest(pw->adapter, TRUE, oid_data_arg)) {
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error calling PacketRequest: %s", errbuf);
static u_int
pcap_sendqueue_transmit_win32(pcap_t *p, pcap_send_queue *queue, int sync)
{
+ struct pcap_win *pw = p->priv;
u_int res;
char errbuf[PCAP_ERRBUF_SIZE+1];
- if (p->adapter==NULL) {
+ if (2->adapter==NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Cannot transmit a queue to an offline capture or to a TurboCap port");
return (0);
}
- res = PacketSendPackets(p->adapter,
+ res = PacketSendPackets(pw->adapter,
queue->buffer,
queue->len,
(BOOLEAN)sync);
static int
pcap_live_dump_win32(pcap_t *p, char *filename, int maxsize, int maxpacks)
{
+ struct pcap_win *pw = p->priv;
BOOLEAN res;
/* Set the packet driver in dump mode */
- res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
+ res = PacketSetMode(pw->adapter, PACKET_MODE_DUMP);
if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting dump mode");
}
/* Set the name of the dump file */
- res = PacketSetDumpName(p->adapter, filename, (int)strlen(filename));
+ res = PacketSetDumpName(pw->adapter, filename, (int)strlen(filename));
if(res == FALSE){
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting kernel dump file name");
}
/* Set the limits of the dump file */
- res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
+ res = PacketSetDumpLimits(pw->adapter, maxsize, maxpacks);
if(res == FALSE) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"Error setting dump limit");
static int
pcap_live_dump_ended_win32(pcap_t *p, int sync)
{
- return (PacketIsDumpEnded(p->adapter, (BOOLEAN)sync));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketIsDumpEnded(pw->adapter, (BOOLEAN)sync));
}
static PAirpcapHandle
pcap_get_airpcap_handle_win32(pcap_t *p)
{
#ifdef HAVE_AIRPCAP_API
- return (PacketGetAirPcapHandle(p->adapter));
+ struct pcap_win *pw = p->priv;
+
+ return (PacketGetAirPcapHandle(pw->adapter));
#else
return (NULL);
#endif /* HAVE_AIRPCAP_API */
* the stack.
*/
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
- if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
+ if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (PCAP_ERROR);
}
ULONGLONG ts;
int cc;
unsigned swt;
- unsigned dfp = p->adapter->DagFastProcess;
+ unsigned dfp = pw->adapter->DagFastProcess;
cc = p->cc;
if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
* the stack.
*/
PacketInitPacket(&Packet, (BYTE *)p->buffer, p->bufsize);
- if (!PacketReceivePacket(p->adapter, &Packet, TRUE)) {
+ if (!PacketReceivePacket(pw->adapter, &Packet, TRUE)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
return (-1);
}
if(cc == 0)
/* The timeout has expired but we no packets arrived */
return (0);
- header = (dag_record_t*)p->adapter->DagBuffer;
+ header = (dag_record_t*)pw->adapter->DagBuffer;
}
else
header = (dag_record_t*)p->bp;
static int
pcap_inject_win32(pcap_t *p, const void *buf, size_t size)
{
+ struct pcap_win *pw = p->priv;
PACKET pkt;
PacketInitPacket(&pkt, (PVOID)buf, size);
- if(PacketSendPacket(p->adapter,&pkt,TRUE) == FALSE) {
+ if(PacketSendPacket(pw->adapter,&pkt,TRUE) == FALSE) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
return (-1);
}
pcap_cleanup_win32(pcap_t *p)
{
struct pcap_win *pw = p->priv;
- if (p->adapter != NULL) {
- PacketCloseAdapter(p->adapter);
- p->adapter = NULL;
+
+ if (pw->adapter != NULL) {
+ PacketCloseAdapter(pw->adapter);
+ pw->adapter = NULL;
}
if (pw->rfmon_selfstart)
{
/* Init WinSock */
wsockinit();
- p->adapter = PacketOpenAdapter(p->opt.device);
+ pw->adapter = PacketOpenAdapter(p->opt.device);
- if (p->adapter == NULL)
+ if (pw->adapter == NULL)
{
/* Adapter detected but we are not able to open it. Return failure. */
pcap_win32_err_to_str(GetLastError(), errbuf);
}
/*get network type*/
- if(PacketGetNetType (p->adapter,&type) == FALSE)
+ if(PacketGetNetType (pw->adapter,&type) == FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
if (p->opt.promisc)
{
- if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
+ if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
goto bad;
}
else
{
- if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
+ if (PacketSetHwFilter(pw->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
goto bad;
/* Set the buffer size */
p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE;
- if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
+ if(!(pw->adapter->Flags & INFO_FLAG_DAG_CARD))
{
/*
* Traditional Adapter
if (p->opt.buffer_size == 0)
p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE;
- if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE)
+ if(PacketSetBuff(pw->adapter,p->opt.buffer_size)==FALSE)
{
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
goto bad;
if (p->opt.immediate)
{
/* tell the driver to copy the buffer as soon as data arrives */
- if(PacketSetMinToCopy(p->adapter,0)==FALSE)
+ if(PacketSetMinToCopy(pw->adapter,0)==FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
else
{
/* tell the driver to copy the buffer only if it contains at least 16K */
- if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
+ if(PacketSetMinToCopy(pw->adapter,16000)==FALSE)
{
pcap_win32_err_to_str(GetLastError(), errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
while(FALSE);
- p->snapshot = PacketSetSnapLen(p->adapter, p->snapshot);
+ p->snapshot = PacketSetSnapLen(pw->adapter, p->snapshot);
/* Set the length of the FCS associated to any packet. This value
* will be subtracted to the packet length */
- pw->dag_fcs_bits = p->adapter->DagFcsLen;
+ pw->dag_fcs_bits = pw->adapter->DagFcsLen;
#else /* HAVE_DAG_API */
/*
* No DAG support.
#endif /* HAVE_DAG_API */
}
- PacketSetReadTimeout(p->adapter, p->opt.timeout);
+ PacketSetReadTimeout(pw->adapter, p->opt.timeout);
+
+ /* disable loopback capture if requested */
+ if (p->opt.nocapture_local)
+ {
+ if (!PacketSetLoopbackBehavior(pw->adapter, NPF_DISABLE_LOOPBACK))
+ {
+ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Unable to disable the capture of loopback packets.");
+ goto bad;
+ }
+ }
#ifdef HAVE_DAG_API
- if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
+ if(pw->adapter->Flags & INFO_FLAG_DAG_CARD)
{
/* install dag specific handlers for read and setfilter */
p->read_op = pcap_read_win32_dag;
p->get_airpcap_handle_op = pcap_get_airpcap_handle_win32;
p->cleanup_op = pcap_cleanup_win32;
+ /*
+ * XXX - this is only done because WinPcap supported
+ * pcap_fileno() returning the hFile HANDLE from the
+ * ADAPTER structure. We make no general guarantees
+ * that the caller can do anything useful with it.
+ *
+ * (Not that we make any general guarantee of that
+ * sort on UN*X, either, any more, given that not
+ * all capture devices are regular OS network
+ * interfaces.)
+ */
+ p->handle = adapter->hFile;
+
return (0);
bad:
pcap_cleanup_win32(p);
{
struct pcap_win *pw = p->priv;
- if(PacketSetBpf(p->adapter,fp)==FALSE){
+ if(PacketSetBpf(pw->adapter,fp)==FALSE){
/*
* Kernel filter not installed.
*
*/
newtimeout = p->opt.timeout;
}
- if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
+ if (!PacketSetReadTimeout(pw->adapter, newtimeout)) {
pcap_win32_err_to_str(GetLastError(), win_errbuf);
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", win_errbuf);