Ejemplo n.º 1
0
/*
This way is definitely safer than passing the pcap_stat * from the userland. In fact, there could
happen than the user allocates a variable which is not big enough for the new structure, and the
library will write in a zone which is not allocated to this variable.
In this way, we're pretty sure we are writing on memory allocated to this variable.
*/
struct pcap_stat *
pcap_stats_ex(pcap_t *p, int *pcap_stat_size)
{
	*pcap_stat_size= sizeof (struct pcap_stat);

#ifdef HAVE_REMOTE
	if (p->rmt_clientside)
	{
		/* We are on an remote capture */
		return pcap_stats_ex_remote(p);
	}
#endif

	if (p->adapter == NULL)
	{
		sprintf(p->errbuf, "Cannot retrieve the extended statistics from a file or a TurboCap port");
		return NULL;
	}

	if(PacketGetStatsEx(p->adapter, (struct bpf_stat*) (&p->md.stat) ) != TRUE){
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStatsEx error: %s", pcap_win32strerror());
		return NULL;
	}
	return (&p->md.stat);
}
Ejemplo n.º 2
0
static int
pcap_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;
}
Ejemplo n.º 3
0
int
pcap_stats(pcap_t *p, struct pcap_stat *ps)
{
#ifdef REMOTE
	if (p->rmt_clientside)
	{
		/* We are on an remote capture */
		return pcap_stats_remote(p, ps);
	}
#endif

	if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror());
		return -1;
	}

	return 0;
}
Ejemplo n.º 4
0
int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{
#ifdef REMOTE
	if (p->rmt_clientside)
	{
		/* We are on an remote capture */
		return pcap_setfilter_remote(p, fp);
	}
#endif

	if(p->adapter==NULL){
		/* Offline capture: make our own copy of the filter */
		if (install_bpf_program(p, fp) < 0)
			return (-1);
	}
	else if(PacketSetBpf(p->adapter,fp)==FALSE){
		/* kernel filter not installed. */
		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
		return (-1);
	}
	return (0);
}
Ejemplo n.º 5
0
/*
 * Get a list of all interfaces that are up and that we can open.
 * Returns -1 on error, 0 otherwise.
 * The list, as returned through "alldevsp", may be null if no interfaces
 * were up and could be opened.
 *
 * Win32 implementation, based on WinPcap
 */
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
	pcap_if_t *devlist = NULL;
	int ret = 0;
	const char *desc;
	char *AdaptersName;
	ULONG NameLength;
	char *name;
	
	PacketGetAdapterNames(NULL, &NameLength);

	if (NameLength > 0)
		AdaptersName = (char*) malloc(NameLength);
	else
	{
		*alldevsp = NULL;
		return 0;
	}
	if (AdaptersName == NULL)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
		return (-1);
	}			

	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
			"PacketGetAdapterNames: %s",
			pcap_win32strerror());
		free(AdaptersName);
		return (-1);
	}
	
	/*
	 * "PacketGetAdapterNames()" returned a list of
	 * null-terminated ASCII interface name strings,
	 * terminated by a null string, followed by a list
	 * of null-terminated ASCII interface description
	 * strings, terminated by a null string.
	 * This means there are two ASCII nulls at the end
	 * of the first list.
	 *
	 * Find the end of the first list; that's the
	 * beginning of the second list.
	 */
	desc = &AdaptersName[0];
	while (*desc != '\0' || *(desc + 1) != '\0')
		desc++;
	
	/*
 	 * Found it - "desc" points to the first of the two
	 * nulls at the end of the list of names, so the
	 * first byte of the list of descriptions is two bytes
	 * after it.
	 */
	desc += 2;
	
	/*
	 * Loop over the elements in the first list.
	 */
	name = &AdaptersName[0];
	while (*name != '\0') {
	/*
	 * Add an entry for this interface.
	 */
	if (pcap_add_if_win32(&devlist, name, desc,
			errbuf) == -1) {
			/*
			* Failure.
			*/
			ret = -1;
			break;
		}
		name += strlen(name) + 1;
		desc += strlen(desc) + 1;
	}
	
	if (ret == -1) {
	/*
	 * We had an error; free the list we've been constructing.
	 */
	if (devlist != NULL) {
			pcap_freealldevs(devlist);
			devlist = NULL;
		}
	}
	
	*alldevsp = devlist;
	free(AdaptersName);
	return (ret);
}
Ejemplo n.º 6
0
/*
 * Get a list of all interfaces that are up and that we can open.
 * Returns -1 on error, 0 otherwise.
 * The list, as returned through "alldevsp", may be null if no interfaces
 * were up and could be opened.
 *
 * Win32 implementation, based on WinPcap
 */
int
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
{
	pcap_if_t *devlist = NULL;
	int ret = 0;
	const char *desc;
	char *AdaptersName;
	ULONG NameLength;
	char *name;

	/*
	 * Find out how big a buffer we need.
	 *
	 * This call should always return FALSE; if the error is
	 * ERROR_INSUFFICIENT_BUFFER, NameLength will be set to
	 * the size of the buffer we need, otherwise there's a
	 * problem, and NameLength should be set to 0.
	 *
	 * It shouldn't require NameLength to be set, but,
	 * at least as of WinPcap 4.1.3, it checks whether
	 * NameLength is big enough before it checks for a
	 * NULL buffer argument, so, while it'll still do
	 * the right thing if NameLength is uninitialized and
	 * whatever junk happens to be there is big enough
	 * (because the pointer argument will be null), it's
	 * still reading an uninitialized variable.
	 */
	NameLength = 0;
	if (!PacketGetAdapterNames(NULL, &NameLength))
	{
		DWORD last_error = GetLastError();

		if (last_error != ERROR_INSUFFICIENT_BUFFER)
		{
			snprintf(errbuf, PCAP_ERRBUF_SIZE,
				"PacketGetAdapterNames: %s",
				pcap_win32strerror());
			return (-1);
		}
	}

	if (NameLength > 0)
		AdaptersName = (char*) malloc(NameLength);
	else
	{
		*alldevsp = NULL;
		return 0;
	}
	if (AdaptersName == NULL)
	{
		snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters.");
		return (-1);
	}

	if (!PacketGetAdapterNames(AdaptersName, &NameLength)) {
		snprintf(errbuf, PCAP_ERRBUF_SIZE,
			"PacketGetAdapterNames: %s",
			pcap_win32strerror());
		free(AdaptersName);
		return (-1);
	}

	/*
	 * "PacketGetAdapterNames()" returned a list of
	 * null-terminated ASCII interface name strings,
	 * terminated by a null string, followed by a list
	 * of null-terminated ASCII interface description
	 * strings, terminated by a null string.
	 * This means there are two ASCII nulls at the end
	 * of the first list.
	 *
	 * Find the end of the first list; that's the
	 * beginning of the second list.
	 */
	desc = &AdaptersName[0];
	while (*desc != '\0' || *(desc + 1) != '\0')
		desc++;

	/*
 	 * Found it - "desc" points to the first of the two
	 * nulls at the end of the list of names, so the
	 * first byte of the list of descriptions is two bytes
	 * after it.
	 */
	desc += 2;

	/*
	 * Loop over the elements in the first list.
	 */
	name = &AdaptersName[0];
	while (*name != '\0') {
		/*
		 * Add an entry for this interface.
		 */
		if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {
			/*
			 * Failure.
			 */
			ret = -1;
			break;
		}
		name += strlen(name) + 1;
		desc += strlen(desc) + 1;
	}

	if (ret != -1) {
		/*
		 * We haven't had any errors yet; do any platform-specific
		 * operations to add devices.
		 */
		if (pcap_platform_finddevs(&devlist, errbuf) < 0)
			ret = -1;
	}

	if (ret == -1) {
		/*
		 * We had an error; free the list we've been constructing.
		 */
		if (devlist != NULL) {
			pcap_freealldevs(devlist);
			devlist = NULL;
		}
	}

	*alldevsp = devlist;
	free(AdaptersName);
	return (ret);
}
Ejemplo n.º 7
0
pcap_t *
pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
    char *ebuf)
{
	register pcap_t *p;
	NetType type;

#ifdef REMOTE
	/*
		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.
	*/

	char host[PCAP_BUF_SIZE + 1];
	char port[PCAP_BUF_SIZE + 1];
	char name[PCAP_BUF_SIZE + 1];
	int srctype;

	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

	/* 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(device);
	if (p->adapter==NULL) {
		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;
	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;

	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;

	p->buffer = (u_char *)malloc(PcapBufSize);
	if (p->buffer == NULL) {
		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
		goto bad;
	}

	p->snapshot = snaplen;

	/* 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;
	}

	PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);

	/* 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;
	}

	PacketSetReadTimeout(p->adapter, to_ms);

	return (p);
bad:
	if (p->adapter)
	    PacketCloseAdapter(p->adapter);
	if (p->buffer != NULL)
		free(p->buffer);
	free(p);
	return (NULL);
}