Home | History | Annotate | Download | only in libpcap
      1 /*
      2  * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
      3  * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  * 1. Redistributions of source code must retain the above copyright
     11  * notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  * notice, this list of conditions and the following disclaimer in the
     14  * documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the Politecnico di Torino, CACE Technologies
     16  * nor the names of its contributors may be used to endorse or promote
     17  * products derived from this software without specific prior written
     18  * permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  *
     32  */
     33 
     34 #ifndef lint
     35 static const char rcsid[] _U_ =
     36     "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25.2.7 2007/06/14 22:07:14 gianluca Exp $ (LBL)";
     37 #endif
     38 
     39 #include <pcap-int.h>
     40 #include <Packet32.h>
     41 #include <Ntddndis.h>
     42 #ifdef HAVE_DAG_API
     43 #include <dagnew.h>
     44 #include <dagapi.h>
     45 #endif /* HAVE_DAG_API */
     46 #ifdef __MINGW32__
     47 int* _errno();
     48 #define errno (*_errno())
     49 #endif /* __MINGW32__ */
     50 
     51 static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);
     52 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);
     53 static int pcap_getnonblock_win32(pcap_t *, char *);
     54 static int pcap_setnonblock_win32(pcap_t *, int, char *);
     55 
     56 #define	PcapBufSize 256000	/*dimension of the buffer in the pcap_t structure*/
     57 #define	SIZE_BUF 1000000
     58 
     59 /* Equivalent to ntohs(), but a lot faster under Windows */
     60 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)
     61 
     62 /*
     63  * Header that the WinPcap driver associates to the packets.
     64  * Once was in bpf.h
     65  */
     66 struct bpf_hdr {
     67 	struct timeval	bh_tstamp;	/* time stamp */
     68 	bpf_u_int32	bh_caplen;	/* length of captured portion */
     69 	bpf_u_int32	bh_datalen;	/* original length of packet */
     70 	u_short		bh_hdrlen;	/* length of bpf header (this struct
     71 					   plus alignment padding) */
     72 };
     73 
     74 /* Start winsock */
     75 int
     76 wsockinit()
     77 {
     78 	WORD wVersionRequested;
     79 	WSADATA wsaData;
     80 	int err;
     81 	wVersionRequested = MAKEWORD( 1, 1);
     82 	err = WSAStartup( wVersionRequested, &wsaData );
     83 	if ( err != 0 )
     84 	{
     85 		return -1;
     86 	}
     87 	return 0;
     88 }
     89 
     90 
     91 static int
     92 pcap_stats_win32(pcap_t *p, struct pcap_stat *ps)
     93 {
     94 
     95 	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
     96 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
     97 		return -1;
     98 	}
     99 
    100 	return 0;
    101 }
    102 
    103 static int
    104 pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    105 {
    106 	int cc;
    107 	int n = 0;
    108 	register u_char *bp, *ep;
    109 
    110 	cc = p->cc;
    111 	if (p->cc == 0) {
    112 		/*
    113 		 * Has "pcap_breakloop()" been called?
    114 		 */
    115 		if (p->break_loop) {
    116 			/*
    117 			 * Yes - clear the flag that indicates that it
    118 			 * has, and return -2 to indicate that we were
    119 			 * told to break out of the loop.
    120 			 */
    121 			p->break_loop = 0;
    122 			return (-2);
    123 		}
    124 
    125 	    /* capture the packets */
    126 		if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){
    127 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    128 			return (-1);
    129 		}
    130 
    131 		cc = p->Packet->ulBytesReceived;
    132 
    133 		bp = p->Packet->Buffer;
    134 	}
    135 	else
    136 		bp = p->bp;
    137 
    138 	/*
    139 	 * Loop through each packet.
    140 	 */
    141 #define bhp ((struct bpf_hdr *)bp)
    142 	ep = bp + cc;
    143 	while (1) {
    144 		register int caplen, hdrlen;
    145 
    146 		/*
    147 		 * Has "pcap_breakloop()" been called?
    148 		 * If so, return immediately - if we haven't read any
    149 		 * packets, clear the flag and return -2 to indicate
    150 		 * that we were told to break out of the loop, otherwise
    151 		 * leave the flag set, so that the *next* call will break
    152 		 * out of the loop without having read any packets, and
    153 		 * return the number of packets we've processed so far.
    154 		 */
    155 		if (p->break_loop) {
    156 			if (n == 0) {
    157 				p->break_loop = 0;
    158 				return (-2);
    159 			} else {
    160 				p->bp = bp;
    161 				p->cc = ep - bp;
    162 				return (n);
    163 			}
    164 		}
    165 		if (bp >= ep)
    166 			break;
    167 
    168 		caplen = bhp->bh_caplen;
    169 		hdrlen = bhp->bh_hdrlen;
    170 
    171 		/*
    172 		 * XXX A bpf_hdr matches a pcap_pkthdr.
    173 		 */
    174 		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);
    175 		bp += BPF_WORDALIGN(caplen + hdrlen);
    176 		if (++n >= cnt && cnt > 0) {
    177 			p->bp = bp;
    178 			p->cc = ep - bp;
    179 			return (n);
    180 		}
    181 	}
    182 #undef bhp
    183 	p->cc = 0;
    184 	return (n);
    185 }
    186 
    187 #ifdef HAVE_DAG_API
    188 static int
    189 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
    190 {
    191 	u_char *dp = NULL;
    192 	int	packet_len = 0, caplen = 0;
    193 	struct pcap_pkthdr	pcap_header;
    194 	u_char *endofbuf;
    195 	int n = 0;
    196 	dag_record_t *header;
    197 	unsigned erf_record_len;
    198 	ULONGLONG ts;
    199 	int cc;
    200 	unsigned swt;
    201 	unsigned dfp = p->adapter->DagFastProcess;
    202 
    203 	cc = p->cc;
    204 	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */
    205 	{
    206 	    /* Get new packets from the network */
    207 		if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){
    208 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");
    209 			return (-1);
    210 		}
    211 
    212 		cc = p->Packet->ulBytesReceived;
    213 		if(cc == 0)
    214 			/* The timeout has expired but we no packets arrived */
    215 			return 0;
    216 		header = (dag_record_t*)p->adapter->DagBuffer;
    217 	}
    218 	else
    219 		header = (dag_record_t*)p->bp;
    220 
    221 	endofbuf = (char*)header + cc;
    222 
    223 	/*
    224 	 * Cycle through the packets
    225 	 */
    226 	do
    227 	{
    228 		erf_record_len = SWAPS(header->rlen);
    229 		if((char*)header + erf_record_len > endofbuf)
    230 			break;
    231 
    232 		/* Increase the number of captured packets */
    233 		p->md.stat.ps_recv++;
    234 
    235 		/* Find the beginning of the packet */
    236 		dp = ((u_char *)header) + dag_record_size;
    237 
    238 		/* Determine actual packet len */
    239 		switch(header->type)
    240 		{
    241 		case TYPE_ATM:
    242 			packet_len = ATM_SNAPLEN;
    243 			caplen = ATM_SNAPLEN;
    244 			dp += 4;
    245 
    246 			break;
    247 
    248 		case TYPE_ETH:
    249 			swt = SWAPS(header->wlen);
    250 			packet_len = swt - (p->md.dag_fcs_bits);
    251 			caplen = erf_record_len - dag_record_size - 2;
    252 			if (caplen > packet_len)
    253 			{
    254 				caplen = packet_len;
    255 			}
    256 			dp += 2;
    257 
    258 			break;
    259 
    260 		case TYPE_HDLC_POS:
    261 			swt = SWAPS(header->wlen);
    262 			packet_len = swt - (p->md.dag_fcs_bits);
    263 			caplen = erf_record_len - dag_record_size;
    264 			if (caplen > packet_len)
    265 			{
    266 				caplen = packet_len;
    267 			}
    268 
    269 			break;
    270 		}
    271 
    272 		if(caplen > p->snapshot)
    273 			caplen = p->snapshot;
    274 
    275 		/*
    276 		 * Has "pcap_breakloop()" been called?
    277 		 * If so, return immediately - if we haven't read any
    278 		 * packets, clear the flag and return -2 to indicate
    279 		 * that we were told to break out of the loop, otherwise
    280 		 * leave the flag set, so that the *next* call will break
    281 		 * out of the loop without having read any packets, and
    282 		 * return the number of packets we've processed so far.
    283 		 */
    284 		if (p->break_loop)
    285 		{
    286 			if (n == 0)
    287 			{
    288 				p->break_loop = 0;
    289 				return (-2);
    290 			}
    291 			else
    292 			{
    293 				p->bp = (char*)header;
    294 				p->cc = endofbuf - (char*)header;
    295 				return (n);
    296 			}
    297 		}
    298 
    299 		if(!dfp)
    300 		{
    301 			/* convert between timestamp formats */
    302 			ts = header->ts;
    303 			pcap_header.ts.tv_sec = (int)(ts >> 32);
    304 			ts = (ts & 0xffffffffi64) * 1000000;
    305 			ts += 0x80000000; /* rounding */
    306 			pcap_header.ts.tv_usec = (int)(ts >> 32);
    307 			if (pcap_header.ts.tv_usec >= 1000000) {
    308 				pcap_header.ts.tv_usec -= 1000000;
    309 				pcap_header.ts.tv_sec++;
    310 			}
    311 		}
    312 
    313 		/* No underlaying filtering system. We need to filter on our own */
    314 		if (p->fcode.bf_insns)
    315 		{
    316 			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0)
    317 			{
    318 				/* Move to next packet */
    319 				header = (dag_record_t*)((char*)header + erf_record_len);
    320 				continue;
    321 			}
    322 		}
    323 
    324 		/* Fill the header for the user suppplied callback function */
    325 		pcap_header.caplen = caplen;
    326 		pcap_header.len = packet_len;
    327 
    328 		/* Call the callback function */
    329 		(*callback)(user, &pcap_header, dp);
    330 
    331 		/* Move to next packet */
    332 		header = (dag_record_t*)((char*)header + erf_record_len);
    333 
    334 		/* Stop if the number of packets requested by user has been reached*/
    335 		if (++n >= cnt && cnt > 0)
    336 		{
    337 			p->bp = (char*)header;
    338 			p->cc = endofbuf - (char*)header;
    339 			return (n);
    340 		}
    341 	}
    342 	while((u_char*)header < endofbuf);
    343 
    344   return 1;
    345 }
    346 #endif /* HAVE_DAG_API */
    347 
    348 /* Send a packet to the network */
    349 static int
    350 pcap_inject_win32(pcap_t *p, const void *buf, size_t size){
    351 	LPPACKET PacketToSend;
    352 
    353 	PacketToSend=PacketAllocatePacket();
    354 
    355 	if (PacketToSend == NULL)
    356 	{
    357 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");
    358 		return -1;
    359 	}
    360 
    361 	PacketInitPacket(PacketToSend,(PVOID)buf,size);
    362 	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){
    363 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");
    364 		PacketFreePacket(PacketToSend);
    365 		return -1;
    366 	}
    367 
    368 	PacketFreePacket(PacketToSend);
    369 
    370 	/*
    371 	 * We assume it all got sent if "PacketSendPacket()" succeeded.
    372 	 * "pcap_inject()" is expected to return the number of bytes
    373 	 * sent.
    374 	 */
    375 	return size;
    376 }
    377 
    378 static void
    379 pcap_close_win32(pcap_t *p)
    380 {
    381 	pcap_close_common(p);
    382 	if (p->adapter != NULL) {
    383 		PacketCloseAdapter(p->adapter);
    384 		p->adapter = NULL;
    385 	}
    386 	if (p->Packet) {
    387 		PacketFreePacket(p->Packet);
    388 		p->Packet = NULL;
    389 	}
    390 }
    391 
    392 pcap_t *
    393 pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
    394     char *ebuf)
    395 {
    396 	register pcap_t *p;
    397 	NetType type;
    398 
    399 	/* Init WinSock */
    400 	wsockinit();
    401 
    402 	p = (pcap_t *)malloc(sizeof(*p));
    403 	if (p == NULL)
    404 	{
    405 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
    406 		return (NULL);
    407 	}
    408 	memset(p, 0, sizeof(*p));
    409 	p->adapter=NULL;
    410 
    411 	p->adapter = PacketOpenAdapter((char*)device);
    412 
    413 	if (p->adapter == NULL)
    414 	{
    415 		free(p);
    416 		/* Adapter detected but we are not able to open it. Return failure. */
    417 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror());
    418 		return NULL;
    419 	}
    420 
    421 	/*get network type*/
    422 	if(PacketGetNetType (p->adapter,&type) == FALSE)
    423 	{
    424 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());
    425 		goto bad;
    426 	}
    427 
    428 	/*Set the linktype*/
    429 	switch (type.LinkType)
    430 	{
    431 	case NdisMediumWan:
    432 		p->linktype = DLT_EN10MB;
    433 		break;
    434 
    435 	case NdisMedium802_3:
    436 		p->linktype = DLT_EN10MB;
    437 		/*
    438 		 * This is (presumably) a real Ethernet capture; give it a
    439 		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
    440 		 * that an application can let you choose it, in case you're
    441 		 * capturing DOCSIS traffic that a Cisco Cable Modem
    442 		 * Termination System is putting out onto an Ethernet (it
    443 		 * doesn't put an Ethernet header onto the wire, it puts raw
    444 		 * DOCSIS frames out on the wire inside the low-level
    445 		 * Ethernet framing).
    446 		 */
    447 		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
    448 		/*
    449 		 * If that fails, just leave the list empty.
    450 		 */
    451 		if (p->dlt_list != NULL) {
    452 			p->dlt_list[0] = DLT_EN10MB;
    453 			p->dlt_list[1] = DLT_DOCSIS;
    454 			p->dlt_count = 2;
    455 		}
    456 		break;
    457 
    458 	case NdisMediumFddi:
    459 		p->linktype = DLT_FDDI;
    460 		break;
    461 
    462 	case NdisMedium802_5:
    463 		p->linktype = DLT_IEEE802;
    464 		break;
    465 
    466 	case NdisMediumArcnetRaw:
    467 		p->linktype = DLT_ARCNET;
    468 		break;
    469 
    470 	case NdisMediumArcnet878_2:
    471 		p->linktype = DLT_ARCNET;
    472 		break;
    473 
    474 	case NdisMediumAtm:
    475 		p->linktype = DLT_ATM_RFC1483;
    476 		break;
    477 
    478 	case NdisMediumCHDLC:
    479 		p->linktype = DLT_CHDLC;
    480 		break;
    481 
    482 	case NdisMediumPPPSerial:
    483 		p->linktype = DLT_PPP_SERIAL;
    484 		break;
    485 
    486 	case NdisMediumNull:
    487 		p->linktype = DLT_NULL;
    488 		break;
    489 
    490 	case NdisMediumBare80211:
    491 		p->linktype = DLT_IEEE802_11;
    492 		break;
    493 
    494 	case NdisMediumRadio80211:
    495 		p->linktype = DLT_IEEE802_11_RADIO;
    496 		break;
    497 
    498 	case NdisMediumPpi:
    499 		p->linktype = DLT_PPI;
    500 		break;
    501 
    502 	default:
    503 		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/
    504 		break;
    505 	}
    506 
    507 	/* Set promiscuous mode */
    508 	if (promisc)
    509 	{
    510 
    511 		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE)
    512 		{
    513 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode");
    514 			goto bad;
    515 		}
    516 	}
    517 	else
    518 	{
    519 		if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE)
    520 		{
    521 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode");
    522 			goto bad;
    523 		}
    524 	}
    525 
    526 	/* Set the buffer size */
    527 	p->bufsize = PcapBufSize;
    528 
    529 	/* Store the timeout. Used by pcap_setnonblock() */
    530 	p->timeout= to_ms;
    531 
    532 	/* allocate Packet structure used during the capture */
    533 	if((p->Packet = PacketAllocatePacket())==NULL)
    534 	{
    535 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure");
    536 		goto bad;
    537 	}
    538 
    539 	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))
    540 	{
    541 	/*
    542 	 * Traditional Adapter
    543 	 */
    544 
    545 		p->buffer = (u_char *)malloc(PcapBufSize);
    546 		if (p->buffer == NULL)
    547 		{
    548 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
    549 			goto bad;
    550 		}
    551 
    552 		PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
    553 
    554 		p->snapshot = snaplen;
    555 
    556 		/* allocate the standard buffer in the driver */
    557 		if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE)
    558 		{
    559 			snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n");
    560 			goto bad;
    561 		}
    562 
    563 		/* tell the driver to copy the buffer only if it contains at least 16K */
    564 		if(PacketSetMinToCopy(p->adapter,16000)==FALSE)
    565 		{
    566 			snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
    567 			goto bad;
    568 		}
    569 	}
    570 	else
    571 #ifdef HAVE_DAG_API
    572 	{
    573 	/*
    574 	 * Dag Card
    575 	 */
    576 		LONG	status;
    577 		HKEY	dagkey;
    578 		DWORD	lptype;
    579 		DWORD	lpcbdata;
    580 		int		postype = 0;
    581 		char	keyname[512];
    582 
    583 		snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s",
    584 			"SYSTEM\\CurrentControlSet\\Services\\DAG",
    585 			strstr(_strlwr((char*)device), "dag"));
    586 		do
    587 		{
    588 			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);
    589 			if(status != ERROR_SUCCESS)
    590 				break;
    591 
    592 			status = RegQueryValueEx(dagkey,
    593 				"PosType",
    594 				NULL,
    595 				&lptype,
    596 				(char*)&postype,
    597 				&lpcbdata);
    598 
    599 			if(status != ERROR_SUCCESS)
    600 			{
    601 				postype = 0;
    602 			}
    603 
    604 			RegCloseKey(dagkey);
    605 		}
    606 		while(FALSE);
    607 
    608 
    609 		p->snapshot = PacketSetSnapLen(p->adapter, snaplen);
    610 
    611 		/* Set the length of the FCS associated to any packet. This value
    612 		 * will be subtracted to the packet length */
    613 		p->md.dag_fcs_bits = p->adapter->DagFcsLen;
    614 	}
    615 #else
    616 	goto bad;
    617 #endif /* HAVE_DAG_API */
    618 
    619 	PacketSetReadTimeout(p->adapter, to_ms);
    620 
    621 #ifdef HAVE_DAG_API
    622 	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)
    623 	{
    624 		/* install dag specific handlers for read and setfilter */
    625 		p->read_op = pcap_read_win32_dag;
    626 		p->setfilter_op = pcap_setfilter_win32_dag;
    627 	}
    628 	else
    629 	{
    630 #endif /* HAVE_DAG_API */
    631 		/* install traditional npf handlers for read and setfilter */
    632 		p->read_op = pcap_read_win32_npf;
    633 		p->setfilter_op = pcap_setfilter_win32_npf;
    634 #ifdef HAVE_DAG_API
    635 	}
    636 #endif /* HAVE_DAG_API */
    637 	p->setdirection_op = NULL;	/* Not implemented. */
    638 	    /* XXX - can this be implemented on some versions of Windows? */
    639 	p->inject_op = pcap_inject_win32;
    640 	p->set_datalink_op = NULL;	/* can't change data link type */
    641 	p->getnonblock_op = pcap_getnonblock_win32;
    642 	p->setnonblock_op = pcap_setnonblock_win32;
    643 	p->stats_op = pcap_stats_win32;
    644 	p->close_op = pcap_close_win32;
    645 
    646 	return (p);
    647 bad:
    648 	if (p->adapter)
    649 	    PacketCloseAdapter(p->adapter);
    650 	if (p->buffer != NULL)
    651 		free(p->buffer);
    652 	if(p->Packet)
    653 		PacketFreePacket(p->Packet);
    654 	/*
    655 	 * Get rid of any link-layer type list we allocated.
    656 	 */
    657 	if (p->dlt_list != NULL)
    658 		free(p->dlt_list);
    659 	free(p);
    660 	return (NULL);
    661 }
    662 
    663 
    664 static int
    665 pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp)
    666 {
    667 	if(PacketSetBpf(p->adapter,fp)==FALSE){
    668 		/*
    669 		 * Kernel filter not installed.
    670 		 * XXX - fall back on userland filtering, as is done
    671 		 * on other platforms?
    672 		 */
    673 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
    674 		return (-1);
    675 	}
    676 
    677 	/*
    678 	 * Discard any previously-received packets, as they might have
    679 	 * passed whatever filter was formerly in effect, but might
    680 	 * not pass this filter (BIOCSETF discards packets buffered
    681 	 * in the kernel, so you can lose packets in any case).
    682 	 */
    683 	p->cc = 0;
    684 	return (0);
    685 }
    686 
    687 /*
    688  * We filter at user level, since the kernel driver does't process the packets
    689  */
    690 static int
    691 pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {
    692 
    693 	if(!fp)
    694 	{
    695 		strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));
    696 		return -1;
    697 	}
    698 
    699 	/* Install a user level filter */
    700 	if (install_bpf_program(p, fp) < 0)
    701 	{
    702 		snprintf(p->errbuf, sizeof(p->errbuf),
    703 			"setfilter, unable to install the filter: %s", pcap_strerror(errno));
    704 		return -1;
    705 	}
    706 
    707 	p->md.use_bpf = 0;
    708 
    709 	return (0);
    710 }
    711 
    712 static int
    713 pcap_getnonblock_win32(pcap_t *p, char *errbuf)
    714 {
    715 	/*
    716 	 * XXX - if there were a PacketGetReadTimeout() call, we
    717 	 * would use it, and return 1 if the timeout is -1
    718 	 * and 0 otherwise.
    719 	 */
    720 	return (p->nonblock);
    721 }
    722 
    723 static int
    724 pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
    725 {
    726 	int newtimeout;
    727 
    728 	if (nonblock) {
    729 		/*
    730 		 * Set the read timeout to -1 for non-blocking mode.
    731 		 */
    732 		newtimeout = -1;
    733 	} else {
    734 		/*
    735 		 * Restore the timeout set when the device was opened.
    736 		 * (Note that this may be -1, in which case we're not
    737 		 * really leaving non-blocking mode.)
    738 		 */
    739 		newtimeout = p->timeout;
    740 	}
    741 	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
    742 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
    743 		    "PacketSetReadTimeout: %s", pcap_win32strerror());
    744 		return (-1);
    745 	}
    746 	p->nonblock = (newtimeout == -1);
    747 	return (0);
    748 }
    749 
    750 /* Set the driver working mode */
    751 int
    752 pcap_setmode(pcap_t *p, int mode){
    753 
    754 	if (p->adapter==NULL)
    755 	{
    756 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");
    757 		return -1;
    758 	}
    759 
    760 	if(PacketSetMode(p->adapter,mode)==FALSE)
    761 	{
    762 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");
    763 		return -1;
    764 	}
    765 
    766 	return 0;
    767 }
    768 
    769 /* Set the dimension of the kernel-level capture buffer */
    770 int
    771 pcap_setbuff(pcap_t *p, int dim)
    772 {
    773 	if (p->adapter==NULL)
    774 	{
    775 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");
    776 		return -1;
    777 	}
    778 
    779 	if(PacketSetBuff(p->adapter,dim)==FALSE)
    780 	{
    781 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");
    782 		return -1;
    783 	}
    784 	return 0;
    785 }
    786 
    787 /*set the minimum amount of data that will release a read call*/
    788 int
    789 pcap_setmintocopy(pcap_t *p, int size)
    790 {
    791 	if (p->adapter==NULL)
    792 	{
    793 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");
    794 		return -1;
    795 	}
    796 
    797 	if(PacketSetMinToCopy(p->adapter, size)==FALSE)
    798 	{
    799 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");
    800 		return -1;
    801 	}
    802 	return 0;
    803 }
    804