bool PcapFileReaderDevice::getNextPacket(RawPacket& rawPacket)
{
	rawPacket.clear();
	if (m_PcapDescriptor == NULL)
	{
		LOG_ERROR("File device '%s' not opened", m_FileName);
		return false;
	}
	pcap_pkthdr pkthdr;
	const uint8_t* pPacketData = pcap_next(m_PcapDescriptor, &pkthdr);
	if (pPacketData == NULL)
	{
		LOG_DEBUG("Packet could not be read. Probably end-of-file");
		return false;
	}

	uint8_t* pMyPacketData = new uint8_t[pkthdr.caplen];
	memcpy(pMyPacketData, pPacketData, pkthdr.caplen);
	if (!rawPacket.setRawData(pMyPacketData, pkthdr.caplen, pkthdr.ts, static_cast<LinkLayerType>(m_PcapLinkLayerType)))
	{
		LOG_ERROR("Couldn't set data to raw packet");
		return false;
	}
	m_NumOfPacketsRead++;
	return true;
}
示例#2
0
RawSocketDevice::RecvPacketResult RawSocketDevice::receivePacket(RawPacket& rawPacket, bool blocking, int timeout)
{
#if defined(WIN32) || defined(WINx64) || defined(PCAPPP_MINGW_ENV)

	if (!isOpened())
	{
		LOG_ERROR("Device is not open");
		return RecvError;
	}

	SOCKET fd = ((SocketContainer*)m_Socket)->fd;
	char* buffer = new char[RAW_SOCKET_BUFFER_LEN];
	memset(buffer, 0, RAW_SOCKET_BUFFER_LEN);

	// value of 0 timeout means disabling timeout
	if (timeout < 0)
		timeout = 0;

	u_long blockingMode = (blocking? 0 : 1);
	ioctlsocket(fd, FIONBIO, &blockingMode);

	DWORD timeoutVal = timeout * 1000;
	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeoutVal, sizeof(timeoutVal));

	//recvfrom(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0, (struct sockaddr*)&sockAddr,(socklen_t*)&sockAddrLen);
	int bufferLen = recv(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0);
	if (bufferLen < 0)
	{
		delete [] buffer;
		int errorCode = 0;
		RecvPacketResult error = getError(errorCode);

		if (error == RecvError)
			LOG_ERROR("Error reading from recvfrom. Error code is %d", errorCode);

		return error;
	}

	if (bufferLen > 0)
	{
		timeval time;
		gettimeofday(&time, NULL);
		rawPacket.setRawData((const uint8_t*)buffer, bufferLen, time, LINKTYPE_DLT_RAW1);
		return RecvSuccess;
	}

	LOG_ERROR("Buffer length is zero");
	delete [] buffer;
	return RecvError;

#elif LINUX

	if (!isOpened())
	{
		LOG_ERROR("Device is not open");
		return RecvError;
	}

	int fd = ((SocketContainer*)m_Socket)->fd;
	char* buffer = new char[RAW_SOCKET_BUFFER_LEN];
	memset(buffer, 0, RAW_SOCKET_BUFFER_LEN);

	// value of 0 timeout means disabling timeout
	if (timeout < 0)
		timeout = 0;

	// set blocking or non-blocking flag
	int flags = fcntl(fd, F_GETFL, 0);
	if (flags == -1)
	{
		LOG_ERROR("Cannot get socket flags");
		return RecvError;
	} 
	flags = (blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK));
	if (fcntl(fd, F_SETFL, flags) != 0)
	{
		LOG_ERROR("Cannot set socket non-blocking flag");
		return RecvError;
	}

	// set timeout on socket
	struct timeval timeoutVal;
	timeoutVal.tv_sec = timeout;
	timeoutVal.tv_usec = 0;
	setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeoutVal, sizeof(timeoutVal));

	int bufferLen = recv(fd, buffer, RAW_SOCKET_BUFFER_LEN, 0);
	if (bufferLen < 0)
	{
		delete [] buffer;
		int errorCode = errno;
		RecvPacketResult error = getError(errorCode);

		if (error == RecvError)
			LOG_ERROR("Error reading from recvfrom. Error code is %d", errorCode);

		return error;
	}

	if (bufferLen > 0)
	{
		timeval time;
		gettimeofday(&time, NULL);
		rawPacket.setRawData((const uint8_t*)buffer, bufferLen, time, LINKTYPE_ETHERNET);
		return RecvSuccess;
	}

	LOG_ERROR("Buffer length is zero");
	delete [] buffer;
	return RecvError;

#else

	LOG_ERROR("Raw socket are not supported on this platform");
	return RecvError;

#endif
}