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

📄 pcap-win32.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}pcap_t *pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,    char *ebuf){	register pcap_t *p;	NetType type;#ifdef HAVE_REMOTE	char host[PCAP_BUF_SIZE + 1];	char port[PCAP_BUF_SIZE + 1];	char name[PCAP_BUF_SIZE + 1];	int srctype;	/*		Retrofit; we have to make older applications compatible with the remote capture		So, we're calling the pcap_open_remote() from here, that is a very dirty thing.		Obviously, we cannot exploit all the new features; for instance, we cannot		send authentication, we cannot use a UDP data connection, and so on.	*/	if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) )		return NULL;	if (srctype == PCAP_SRC_IFREMOTE)	{		p= pcap_opensource_remote(device, NULL, ebuf);		if (p == NULL) 			return NULL;		p->snapshot= snaplen;		p->timeout= to_ms;		p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0;		return p;	}#endif	/* HAVE_REMOTE */	/* 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);		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;	}		/*get network type*/	if(PacketGetNetType (p->adapter,&type) == FALSE)	{		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror());		goto bad;	}		/*Set the linktype*/	switch (type.LinkType) 	{	case NdisMediumWan:		p->linktype = DLT_EN10MB;		break;			case NdisMedium802_3:		p->linktype = DLT_EN10MB;		/*		 * This is (presumably) a real Ethernet capture; give it a		 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so		 * that an application can let you choose it, in case you're		 * capturing DOCSIS traffic that a Cisco Cable Modem		 * Termination System is putting out onto an Ethernet (it		 * doesn't put an Ethernet header onto the wire, it puts raw		 * DOCSIS frames out on the wire inside the low-level		 * Ethernet framing).		 */		p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);		/*		 * If that fails, just leave the list empty.		 */		if (p->dlt_list != NULL) {			p->dlt_list[0] = DLT_EN10MB;			p->dlt_list[1] = DLT_DOCSIS;			p->dlt_count = 2;		}		break;			case NdisMediumFddi:		p->linktype = DLT_FDDI;		break;			case NdisMedium802_5:					p->linktype = DLT_IEEE802;			break;			case NdisMediumArcnetRaw:		p->linktype = DLT_ARCNET;		break;			case NdisMediumArcnet878_2:		p->linktype = DLT_ARCNET;		break;			case NdisMediumAtm:		p->linktype = DLT_ATM_RFC1483;		break;			case NdisMediumCHDLC:		p->linktype = DLT_CHDLC;		break;	case NdisMediumPPPSerial:		p->linktype = DLT_PPP_SERIAL;		break;	case NdisMediumNull:		p->linktype = DLT_NULL;		break;	case NdisMediumBare80211:		p->linktype = DLT_IEEE802_11;		break;	case NdisMediumRadio80211:		p->linktype = DLT_IEEE802_11_RADIO;		break;	default:		p->linktype = DLT_EN10MB;			/*an unknown adapter is assumed to be ethernet*/		break;	}	/* Set promisquous mode */	if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS);	 else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL);	/* Set the buffer size */	p->bufsize = PcapBufSize;	/* Store the timeout. Used by pcap_setnonblock() */	p->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");		goto bad;	}	if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD))	{	/* 	 * Traditional Adapter 	 */				p->buffer = (u_char *)malloc(PcapBufSize);		if (p->buffer == NULL) 		{			snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));			goto bad;		}				PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);				p->snapshot = snaplen;				/* 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");			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());			goto bad;		}	}	else#ifdef HAVE_DAG_API	{	/* 	 * Dag Card 	 */		LONG	status;		HKEY	dagkey;		DWORD	lptype;		DWORD	lpcbdata;		int		postype = 0;		char	keyname[512];				snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", 			"SYSTEM\\CurrentControlSet\\Services\\DAG",			strstr(_strlwr((char*)device), "dag"));		do		{			status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey);			if(status != ERROR_SUCCESS)				break;						status = RegQueryValueEx(dagkey,				"PosType",				NULL,				&lptype,				(char*)&postype,				&lpcbdata);						if(status != ERROR_SUCCESS)			{				postype = 0;			}						RegCloseKey(dagkey);		}		while(FALSE);						p->snapshot = PacketSetSnapLen(p->adapter, snaplen);				/* Set the length of the FCS associated to any packet. This value 		 * will be subtracted to the packet length */		p->md.dag_fcs_bits = p->adapter->DagFcsLen;	}#else	goto bad;#endif /* HAVE_DAG_API */		PacketSetReadTimeout(p->adapter, to_ms);	#ifdef HAVE_DAG_API	if(p->adapter->Flags & INFO_FLAG_DAG_CARD)	{		/* install dag specific handlers for read and setfilter */		p->read_op = pcap_read_win32_dag;		p->setfilter_op = pcap_setfilter_win32_dag;	}	else	{#endif /* HAVE_DAG_API */		/* install traditional npf handlers for read and setfilter */		p->read_op = pcap_read_win32_npf;		p->setfilter_op = pcap_setfilter_win32_npf;#ifdef HAVE_DAG_API	}#endif /* HAVE_DAG_API */	p->setdirection_op = NULL;	/* Not implemented. */	    /* XXX - can this be implemented on some versions of Windows? */	p->inject_op = pcap_inject_win32;	p->set_datalink_op = NULL;	/* can't change data link type */	p->getnonblock_op = pcap_getnonblock_win32;	p->setnonblock_op = pcap_setnonblock_win32;	p->stats_op = pcap_stats_win32;	p->close_op = pcap_close_win32;	return (p);bad:	if (p->adapter)	    PacketCloseAdapter(p->adapter);	if (p->buffer != NULL)		free(p->buffer);	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);}static intpcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp){	if(PacketSetBpf(p->adapter,fp)==FALSE){		/*		 * Kernel filter not installed.		 * XXX - fall back on userland filtering, as is done		 * on other platforms?		 */		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());		return (-1);	}	/*	 * Discard any previously-received packets, as they might have	 * passed whatever filter was formerly in effect, but might	 * not pass this filter (BIOCSETF discards packets buffered	 * in the kernel, so you can lose packets in any case).	 */	p->cc = 0;	return (0);}/* * We filter at user level, since the kernel driver does't process the packets */static int pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) {		if(!fp) 	{		strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf));		return -1;	}		/* Install a user level filter */	if (install_bpf_program(p, fp) < 0) 	{		snprintf(p->errbuf, sizeof(p->errbuf),			"setfilter, unable to install the filter: %s", pcap_strerror(errno));		return -1;	}		p->md.use_bpf = 0;		return (0);}static intpcap_getnonblock_win32(pcap_t *p, char *errbuf){	/*	 * XXX - if there were a PacketGetReadTimeout() call, we	 * would use it, and return 1 if the timeout is -1	 * and 0 otherwise.	 */	return (p->nonblock);}static intpcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf){	int newtimeout;	if (nonblock) {		/*		 * Set the read timeout to -1 for non-blocking mode.		 */		newtimeout = -1;	} else {		/*		 * Restore the timeout set when the device was opened.		 * (Note that this may be -1, in which case we're not		 * really leaving non-blocking mode.)		 */		newtimeout = p->timeout;	}	if (!PacketSetReadTimeout(p->adapter, newtimeout)) {		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,		    "PacketSetReadTimeout: %s", pcap_win32strerror());		return (-1);	}	p->nonblock = (newtimeout == -1);	return (0);}/* Set the driver working mode */int pcap_setmode(pcap_t *p, int mode){		if (p->adapter==NULL)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file");		return -1;	}	if(PacketSetMode(p->adapter,mode)==FALSE)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized");		return -1;	}	return 0;}/* Set the dimension of the kernel-level capture buffer */int pcap_setbuff(pcap_t *p, int dim){#ifdef HAVE_REMOTE	if (p->rmt_clientside)	{		/* Currently, this is a bug: the capture buffer cannot be set with remote capture */		return 0;	}#endif	/* HAVE_REMOTE */	if (p->adapter==NULL)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file");		return -1;	}		if(PacketSetBuff(p->adapter,dim)==FALSE)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer");		return -1;	}	return 0;}/*set the minimum amount of data that will release a read call*/int pcap_setmintocopy(pcap_t *p, int size){	if (p->adapter==NULL)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture");		return -1;	}		if(PacketSetMinToCopy(p->adapter, size)==FALSE)	{		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size");		return -1;	}	return 0;}

⌨️ 快捷键说明

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