⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcap-win32.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Politecnico di Torino, CACE Technologies  * nor the names of its contributors may be used to endorse or promote  * products derived from this software without specific prior written  * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#ifndef lintstatic const char rcsid[] _U_ =    "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.25.2.5 2006/08/09 19:18:41 gianluca Exp $ (LBL)";#endif#include <pcap-int.h>#include <Packet32.h>#include <Ntddndis.h>#ifdef HAVE_DAG_API#include <dagnew.h>#include <dagapi.h>#endif /* HAVE_DAG_API */#ifdef __MINGW32__int* _errno();#define errno (*_errno())#endif /* __MINGW32__ */#ifdef HAVE_REMOTE#include <pcap-remote.h>#endif	/* HAVE_REMOTE */static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *);static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *);static int pcap_getnonblock_win32(pcap_t *, char *);static int pcap_setnonblock_win32(pcap_t *, int, char *);#define	PcapBufSize 256000	/*dimension of the buffer in the pcap_t structure*/#define	SIZE_BUF 1000000/* Equivalent to ntohs(), but a lot faster under Windows */#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8)/* * Header that the WinPcap driver associates to the packets. * Once was in bpf.h */struct bpf_hdr {	struct timeval	bh_tstamp;	/* time stamp */	bpf_u_int32	bh_caplen;	/* length of captured portion */	bpf_u_int32	bh_datalen;	/* original length of packet */	u_short		bh_hdrlen;	/* length of bpf header (this struct					   plus alignment padding) */};/* Start winsock */int wsockinit(){	WORD wVersionRequested;	WSADATA wsaData;	int err;	wVersionRequested = MAKEWORD( 1, 1); 	err = WSAStartup( wVersionRequested, &wsaData );	if ( err != 0 )	{		return -1;	}	return 0;}static intpcap_stats_win32(pcap_t *p, struct pcap_stat *ps){	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());		return -1;	}	return 0;}static intpcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user){	int cc;	int n = 0;	register u_char *bp, *ep;#ifdef HAVE_REMOTE	static int samp_npkt;				// parameter needed for sampling, with '1 out of N' method has been requested	static struct timeval samp_time;	// parameter needed for sampling, with '1 every N ms' method has been requested#endif	/* HAVE_REMOTE */	cc = p->cc;	if (p->cc == 0) {		/*		 * Has "pcap_breakloop()" been called?		 */		if (p->break_loop) {			/*			 * Yes - clear the flag that indicates that it			 * has, and return -2 to indicate that we were			 * told to break out of the loop.			 */			p->break_loop = 0;			return (-2);		}	    /* capture the packets */		if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");			return (-1);		}					cc = p->Packet->ulBytesReceived;		bp = p->Packet->Buffer;	} 	else		bp = p->bp;	/*	 * Loop through each packet.	 */#define bhp ((struct bpf_hdr *)bp)	ep = bp + cc;	while (1) {		register int caplen, hdrlen;		/*		 * Has "pcap_breakloop()" been called?		 * If so, return immediately - if we haven't read any		 * packets, clear the flag and return -2 to indicate		 * that we were told to break out of the loop, otherwise		 * leave the flag set, so that the *next* call will break		 * out of the loop without having read any packets, and		 * return the number of packets we've processed so far.		 */		if (p->break_loop) {			if (n == 0) {				p->break_loop = 0;				return (-2);			} else {				p->bp = bp;				p->cc = ep - bp;				return (n);			}		}		if (bp >= ep)			break;		caplen = bhp->bh_caplen;		hdrlen = bhp->bh_hdrlen;#ifdef HAVE_REMOTE		if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N)		{			samp_npkt= (samp_npkt + 1) % p->rmt_samp.value;			// Discard all packets that are not '1 out of N'			if (samp_npkt != 0)			{				bp += BPF_WORDALIGN(caplen + hdrlen);				continue;			}		}		if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS)		{		struct pcap_pkthdr *pkt_header= (struct pcap_pkthdr*) bp;			// Check if the timestamp of the arrived packet is smaller than our target time			if ( (pkt_header->ts.tv_sec < samp_time.tv_sec) ||					( (pkt_header->ts.tv_sec == samp_time.tv_sec) && (pkt_header->ts.tv_usec < samp_time.tv_usec) ) )			{				bp += BPF_WORDALIGN(caplen + hdrlen);				continue;			}			// The arrived packet is suitable for being sent to the remote host			// So, let's update the target time			samp_time.tv_usec= pkt_header->ts.tv_usec + p->rmt_samp.value * 1000;			if (samp_time.tv_usec > 1000000)			{				samp_time.tv_sec= pkt_header->ts.tv_sec + samp_time.tv_usec / 1000000;				samp_time.tv_usec= samp_time.tv_usec % 1000000;			}		}#endif	/* HAVE_REMOTE */		/*		 * XXX A bpf_hdr matches a pcap_pkthdr.		 */		(*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen);		bp += BPF_WORDALIGN(caplen + hdrlen);		if (++n >= cnt && cnt > 0) {			p->bp = bp;			p->cc = ep - bp;			return (n);		}	}#undef bhp	p->cc = 0;	return (n);}#ifdef HAVE_DAG_APIstatic intpcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user){	u_char *dp = NULL;	int	packet_len = 0, caplen = 0;	struct pcap_pkthdr	pcap_header;	u_char *endofbuf;	int n = 0;	dag_record_t *header;	unsigned erf_record_len;	ULONGLONG ts;	int cc;	unsigned swt;	unsigned dfp = p->adapter->DagFastProcess;	cc = p->cc;	if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */	{	    /* Get new packets from the network */		if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed");			return (-1);		}		cc = p->Packet->ulBytesReceived;		if(cc == 0)			/* The timeout has expired but we no packets arrived */			return 0;		header = (dag_record_t*)p->adapter->DagBuffer;	} 	else		header = (dag_record_t*)p->bp;		endofbuf = (char*)header + cc;		/* 	 * Cycle through the packets 	 */	do	{		erf_record_len = SWAPS(header->rlen);		if((char*)header + erf_record_len > endofbuf)			break;		/* Increase the number of captured packets */		p->md.stat.ps_recv++;				/* Find the beginning of the packet */		dp = ((u_char *)header) + dag_record_size;		/* Determine actual packet len */		switch(header->type) 		{		case TYPE_ATM:			packet_len = ATM_SNAPLEN;			caplen = ATM_SNAPLEN;			dp += 4;			break;		case TYPE_ETH:			swt = SWAPS(header->wlen);			packet_len = swt - (p->md.dag_fcs_bits);			caplen = erf_record_len - dag_record_size - 2;			if (caplen > packet_len)			{				caplen = packet_len;			}			dp += 2;						break;				case TYPE_HDLC_POS:			swt = SWAPS(header->wlen);			packet_len = swt - (p->md.dag_fcs_bits);			caplen = erf_record_len - dag_record_size;			if (caplen > packet_len)			{				caplen = packet_len;			}						break;		}				if(caplen > p->snapshot)			caplen = p->snapshot;		/*		 * Has "pcap_breakloop()" been called?		 * If so, return immediately - if we haven't read any		 * packets, clear the flag and return -2 to indicate		 * that we were told to break out of the loop, otherwise		 * leave the flag set, so that the *next* call will break		 * out of the loop without having read any packets, and		 * return the number of packets we've processed so far.		 */		if (p->break_loop) 		{			if (n == 0) 			{				p->break_loop = 0;				return (-2);			} 			else 			{				p->bp = (char*)header;				p->cc = endofbuf - (char*)header;				return (n);			}		}		if(!dfp)		{			/* convert between timestamp formats */			ts = header->ts;			pcap_header.ts.tv_sec = (int)(ts >> 32);			ts = (ts & 0xffffffffi64) * 1000000;			ts += 0x80000000; /* rounding */			pcap_header.ts.tv_usec = (int)(ts >> 32);			if (pcap_header.ts.tv_usec >= 1000000) {				pcap_header.ts.tv_usec -= 1000000;				pcap_header.ts.tv_sec++;			}		}				/* No underlaying filtering system. We need to filter on our own */		if (p->fcode.bf_insns) 		{			if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) 			{				/* Move to next packet */				header = (dag_record_t*)((char*)header + erf_record_len);				continue;			}		}				/* Fill the header for the user suppplied callback function */		pcap_header.caplen = caplen;		pcap_header.len = packet_len;				/* Call the callback function */		(*callback)(user, &pcap_header, dp);				/* Move to next packet */		header = (dag_record_t*)((char*)header + erf_record_len);		/* Stop if the number of packets requested by user has been reached*/		if (++n >= cnt && cnt > 0) 		{			p->bp = (char*)header;			p->cc = endofbuf - (char*)header;			return (n);		}	}	while((u_char*)header < endofbuf);	  return 1;}#endif /* HAVE_DAG_API *//* Send a packet to the network */static int pcap_inject_win32(pcap_t *p, const void *buf, size_t size){	LPPACKET PacketToSend;	PacketToSend=PacketAllocatePacket();		if (PacketToSend == NULL)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed");		return -1;	}		PacketInitPacket(PacketToSend,(PVOID)buf,size);	if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed");		PacketFreePacket(PacketToSend);		return -1;	}	PacketFreePacket(PacketToSend);	/*	 * We assume it all got sent if "PacketSendPacket()" succeeded.	 * "pcap_inject()" is expected to return the number of bytes	 * sent.	 */	return size;}static voidpcap_close_win32(pcap_t *p){	pcap_close_common(p);	if (p->adapter != NULL) {		PacketCloseAdapter(p->adapter);		p->adapter = NULL;	}	if (p->Packet) {		PacketFreePacket(p->Packet);		p->Packet = NULL;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -