Esempio n. 1
0
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;
}
Esempio n. 2
0
        void onVideoEncoded(void* sender, RawPacket& packet)
        {
            DebugL << "########### On packet: " << closed << ":" << packet.size() << endl;
            frames++;
            //assert(!closed);
            assert(packet.data());
            assert(packet.size());

            // Do not call stream::close from inside callback
            //ofile.write(packet.data(), packet.size());
            //assert(frames <= 3);
            //if (frames == 20)
            //    close();
        }
Esempio n. 3
0
//-------------------------------------------------------------------------------------------------------------//
void EngineServer::on_received_packet( const RawPacket& packet, void* clientData, UINT clientIndex )
{
	__super::on_received_packet(packet,clientData,clientIndex);

	switch(packet.Id())
	{
	case NET_Command:
		{
			const NetCmdId* cmd = cast(const NetCmdId*) packet.data;
			ExecuteCommand( cmd,  packet.MsgSize(), clientData );
		}
		break;

	default:
		Fallthrough;
	}
}
Esempio n. 4
0
 void onFrame(void* sender, RawPacket& packet)
 {
     DebugL << "On packet: " << packet.size() << endl;
     assert(!closed);
     try
     {
         encoder.process(packet);
     }
     catch (std::exception& exc)
     {
         ErrorL << "Capture Recorder Error: " << exc.what() << endl;
         stop();
     }
 }
Esempio n. 5
0
bool PcapFileWriterDevice::writePacket(RawPacket const& packet)
{
	if ((!m_AppendMode && m_PcapDescriptor == NULL) || (m_PcapDumpHandler == NULL))
	{
		LOG_ERROR("Device not opened");
		m_NumOfPacketsNotWritten++;
		return false;
	}

	if (packet.getLinkLayerType() != m_PcapLinkLayerType)
	{
		LOG_ERROR("Cannot write a packet with a different link layer type");
		m_NumOfPacketsNotWritten++;
		return false;
	}

	pcap_pkthdr pktHdr;
	pktHdr.caplen = ((RawPacket&)packet).getRawDataLen();
	pktHdr.len = ((RawPacket&)packet).getRawDataLen();
	pktHdr.ts = ((RawPacket&)packet).getPacketTimeStamp();
	if (!m_AppendMode)
		pcap_dump((uint8_t*)m_PcapDumpHandler, &pktHdr, ((RawPacket&)packet).getRawData());
	else
	{
		// Below are actually the lines run by pcap_dump. The reason I had to put them instead pcap_dump is that on Windows using WinPcap
		// you can't pass pointers between libraries compiled with different compilers. In this case - PcapPlusPlus and WinPcap weren't
		// compiled with the same compiler so it's impossible to fopen a file in PcapPlusPlus, pass the pointer to WinPcap and use the
		// FILE* pointer there. Doing this throws an exception. So the only option when implementing append to pcap is to write all relevant
		// WinPcap code that handles opening/closing/writing to pcap files inside PcapPlusPlus code
		fwrite(&pktHdr, sizeof(pktHdr), 1, m_File);
		fwrite(((RawPacket&)packet).getRawData(), pktHdr.caplen, 1, m_File);
	}
	LOG_DEBUG("Packet written successfully to '%s'", m_FileName);
	m_NumOfPacketsWritten++;
	return true;
}
//This copies the data at requestHeader, so you can free the memory after this has been called
int RequestCommon(char * sourceIP, char * destinationIP, char * dstHostName, request_hdr_t * requestHeader, unsigned int requestSize, me_t * outboundPendingME, char * parentFuncName){
	int ret;
	unsigned short sourcePort = 0xDEAD;
	unsigned short destinationPort = 0xBEEF;
	unsigned char dstMac[6] = {0,0,0,0,0,0};
	ULONG dstMacLong[2] = {0,0};
	ULONG MACSize = 6;
	RawPacket RP;
	IPAddr srcIPAddr, dstIPAddr;

	srcIPAddr = inet_addr(sourceIP);
	dstIPAddr = inet_addr(destinationIP);

	//This is a quick hack to make it server be a bit smarter 
	//about what dst MAC is uses - gateway if the dst IP is non-local, 
	//otherwise the MAC specifically for the dst host
	//ASSUMPTION: that all hosts on the same /24 are on the same ethernet segment
	if(memcmp(&srcIPAddr, &dstIPAddr, 3) == 0){
		//send to a local host on the same ethernet segment directly
		ret = SendARP(dstIPAddr, srcIPAddr, &dstMacLong, &MACSize);
		if(ret != NO_ERROR){
			if(gUseBroadcastMAC){
				printf("%s: RequestCommon: Failed to get the MAC address for the destination host on the same local network. Defaulting to broadcast MAC\n", parentFuncName);
				memset(&dstMac, 0xFF, 6);
			}
			else{
				printf("%s: RequestCommon: Failed to get the MAC address for the destination host on the same local network. Broadcast MAC disabled, erroring out\n", parentFuncName);
				//UpdateReadinessByHostID(hostID, ARP_FAIL);
				//If we're going to error out and not send the packet, we need to delete the pending events
				//We will not delete the null measurement because it will have actually been sent
				if(strcmp("BuildNullSelfMeasurementRequestPacket", parentFuncName) != 0){
					if(strcmp("BuildSelfMeasurementRequestPacket", parentFuncName) != 0){
						ret = SelectPreviousPendingIDFromPendingME(outboundPendingME->id,outboundPendingME->nonce, &outboundPendingME->previousPendingID);
						if(ret != GENERIC_SUCCESS){
							printf("RequestCommon: SelectPreviousPendingIDFromPendingMEByID failed\n");
							return ret;
						}
						if(!gQuiet) printf("Deleting PendingMeasurementEvent id = %u\n", outboundPendingME->previousPendingID);
						DeleteFromTableByID("PendingMeasurementEvents", outboundPendingME->previousPendingID);
					}
					if(!gQuiet) printf("Deleting PendingMeasurementEvent id = %u\n", outboundPendingME->id);
					DeleteFromTableByID("PendingMeasurementEvents", outboundPendingME->id);
				
					return GENERIC_ERROR;
				}
			}
		}
		else{
			memcpy(&dstMac, &dstMacLong, 6);
		}
		RP.CreatePacket(globDeviceInfoPtr->PhysicalAddress, dstMac,
						inet_addr(sourceIP),inet_addr(destinationIP),sourcePort,destinationPort,
						(UCHAR*)requestHeader, requestSize);
	}
	else{
		//send to a non-local host, by way of the gateway
		RP.CreatePacket(globDeviceInfoPtr->PhysicalAddress, globDeviceInfoPtr->GatewayPhysicalAddress,
						inet_addr(sourceIP),inet_addr(destinationIP),sourcePort,destinationPort,
						(UCHAR*)requestHeader, requestSize);
	}

	RP.SendPacket(globDevice);

	return GENERIC_SUCCESS;
}
Esempio n. 7
0
bool PfRingDevice::sendPacket(const RawPacket& rawPacket)
{
	return sendData(rawPacket.getRawDataReadOnly(), rawPacket.getRawDataLen(), true);
}
Esempio n. 8
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
}
Esempio n. 9
0
/**
 * main method of this utility
 */
int main(int argc, char* argv[])
{
	AppName::init(argc, argv);

	std::string inputPcapFileName = "";
	std::string outputPcapDir = "";

	std::string filter = "";

	std::string method = "";

	char param[1000];
	memset(param, 0, 1000);

	bool paramWasSet = false;

	int optionIndex = 0;
	char opt = 0;

	while((opt = getopt_long (argc, argv, "f:o:m:p:i:vh", PcapSplitterOptions, &optionIndex)) != -1)
	{
		switch (opt)
		{
			case 0:
				break;
			case 'f':
				inputPcapFileName = optarg;
				break;
			case 'o':
				outputPcapDir = optarg;
				break;
			case 'm':
				method = optarg;
				break;
			case 'p':
				strncpy(param, optarg, 999);
				paramWasSet = true;
				break;
			case 'i':
				filter = optarg;
				break;
			case 'h':
				printUsage();
				break;
			case 'v':
				printAppVersion();
				break;
			default:
				printUsage();
				exit(-1);
		}
	}

	if (inputPcapFileName == "")
	{
		EXIT_WITH_ERROR("Input file name was not given");
	}

	if (outputPcapDir == "")
	{
		EXIT_WITH_ERROR("Output directory name was not given");
	}

	if (!pcpp::directoryExists(outputPcapDir))
	{
		EXIT_WITH_ERROR("Output directory doesn't exist");
	}

	if (method == "")
	{
		EXIT_WITH_ERROR("Split method was not given");
	}

	Splitter* splitter = NULL;

	// decide of the splitter to use, according to the user's choice
	if (method == SPLIT_BY_FILE_SIZE)
	{
		uint64_t paramAsUint64 = (paramWasSet ? strtoull(param, NULL, 10) : 0);
		splitter = new FileSizeSplitter(paramAsUint64);
	}
	else if (method == SPLIT_BY_PACKET_COUNT)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : 0);
		splitter = new PacketCountSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_IP_CLIENT)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : SplitterWithMaxFiles::UNLIMITED_FILES_MAGIC_NUMBER);
		splitter = new ClientIPSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_IP_SERVER)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : SplitterWithMaxFiles::UNLIMITED_FILES_MAGIC_NUMBER);
		splitter = new ServerIPSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_SERVER_PORT)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : SplitterWithMaxFiles::UNLIMITED_FILES_MAGIC_NUMBER);
		splitter = new ServerPortSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_2_TUPLE)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : SplitterWithMaxFiles::UNLIMITED_FILES_MAGIC_NUMBER);
		splitter = new TwoTupleSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_5_TUPLE)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : SplitterWithMaxFiles::UNLIMITED_FILES_MAGIC_NUMBER);
		splitter = new FiveTupleSplitter(paramAsInt);
	}
	else if (method == SPLIT_BY_BPF_FILTER)
	{
		splitter = new BpfCriteriaSplitter(std::string(param));
	}
	else if (method == SPLIT_BY_ROUND_ROBIN)
	{
		int paramAsInt = (paramWasSet ? atoi(param) : 0);
		splitter = new RoundRobinSplitter(paramAsInt);
	}
	else
		EXIT_WITH_ERROR("Unknown method '%s'", method.c_str());


	// verify splitter param is legal, otherwise return an error
	std::string errorStr;
	if (!splitter->isSplitterParamLegal(errorStr))
	{
		EXIT_WITH_ERROR("%s", errorStr.c_str());
	}

	// prepare the output file format: /requested-path/original-file-name-[4-digit-number-starting-at-0000].pcap
	std::string outputPcapFileName = outputPcapDir + std::string(1, SEPARATOR) + getFileNameWithoutExtension(inputPcapFileName) + "-";

	// open a pcap file for reading
	IFileReaderDevice* reader = IFileReaderDevice::getReader(inputPcapFileName.c_str());
	bool isReaderPcapng = (dynamic_cast<PcapNgFileReaderDevice*>(reader) != NULL);

	if (reader == NULL || !reader->open())
	{
		EXIT_WITH_ERROR("Error opening input pcap file\n");
	}

	// set a filter if provided
	if (filter != "")
	{
		if (!reader->setFilter(filter))
			EXIT_WITH_ERROR("Couldn't set filter '%s'", filter.c_str());
	}

	printf("Started...\n");

	// determine output file extension
	std::string outputFileExtenison = (isReaderPcapng ? ".pcapng" : ".pcap");

	int packetCountSoFar = 0;
	int numOfFiles = 0;
	RawPacket rawPacket;

	// prepare a map of file number to IFileWriterDevice
	std::map<int, IFileWriterDevice*> outputFiles;

	// read all packets from input file, for each packet do:
	while (reader->getNextPacket(rawPacket))
	{
		// parse the raw packet into a parsed packet
		Packet parsedPacket(&rawPacket);

		std::vector<int> filesToClose;

		// call the splitter to get the file number to write the current packet to
		int fileNum = splitter->getFileNumber(parsedPacket, filesToClose);

		// if file number is seen for the first time (meaning it's the first packet written to it)
		if (outputFiles.find(fileNum) == outputFiles.end())
		{
			// get file name from the splitter and add the .pcap extension
			std::string fileName = splitter->getFileName(parsedPacket, outputPcapFileName, fileNum) + outputFileExtenison;

			// create a new IFileWriterDevice for this file
			if (isReaderPcapng)
			{
				// if reader is pcapng, create a pcapng writer
				outputFiles[fileNum] = new PcapNgFileWriterDevice(fileName.c_str());
			}
			else
			{
				// if reader is pcap, create a pcap writer
				outputFiles[fileNum] = new PcapFileWriterDevice(fileName.c_str(), rawPacket.getLinkLayerType());
			}

			// open the writer
			if (!outputFiles[fileNum]->open())
				break;

			numOfFiles++;
		}

		// if file number exists in the map but PcapFileWriterDevice is null it means this file was open once and
		// then closed. In this case we need to re-open the PcapFileWriterDevice in append mode
		else if (outputFiles[fileNum] == NULL)
		{
			// get file name from the splitter and add the .pcap extension
			std::string fileName = splitter->getFileName(parsedPacket, outputPcapFileName, fileNum) + outputFileExtenison;

			// re-create the IFileWriterDevice object
			if (isReaderPcapng)
			{
				// if reader is pcapng, create a pcapng writer
				outputFiles[fileNum] = new PcapNgFileWriterDevice(fileName.c_str());
			}
			else
			{
				// if reader is pcap, create a pcap writer
				outputFiles[fileNum] = new PcapFileWriterDevice(fileName.c_str(), rawPacket.getLinkLayerType());
			}

			// open the writer in __append__ mode
			if (!outputFiles[fileNum]->open(true))
				break;
		}

		// write the packet to the writer
		outputFiles[fileNum]->writePacket(*parsedPacket.getRawPacket());

		// if splitter wants us to close files - go over the file numbers and close them
		for (std::vector<int>::iterator it = filesToClose.begin(); it != filesToClose.end(); it++)
		{
			// check if that file number is in the map
			if (outputFiles.find(*it) != outputFiles.end())
			{
				// close the writer
				outputFiles[*it]->close();

				// free the writer memory and put null in the map record
				delete outputFiles[*it];
				outputFiles[*it] = NULL;
			}
		}

		packetCountSoFar++;
	}

	std::cout << "Finished. Read and written " << packetCountSoFar << " packets to " << numOfFiles << " files" << std::endl;

	// close the reader file
	reader->close();

	// free reader memory
	delete reader;

	// close the writer files which are still open
	for(std::map<int, IFileWriterDevice*>::iterator it = outputFiles.begin(); it != outputFiles.end(); ++it)
	{
		if (it->second != NULL)
			it->second->close();
	}

	return 0;
}