Пример #1
0
/**
 * activate HTTP analysis from pcap file
 */
void analyzeHttpFromPcapFile(std::string pcapFileName)
{
	// open input file (pcap or pcapng file)
	IFileReaderDevice* reader = IFileReaderDevice::getReader(pcapFileName.c_str());

	if (!reader->open())
		EXIT_WITH_ERROR("Could not open input pcap file");

	// set a port 80 filter on the reader device to process only HTTP packets
	PortFilter httpPortFilter(80, SRC_OR_DST);
	reader->setFilter(httpPortFilter);

	// read the input file packet by packet and give it to the HttpStatsCollector for collecting stats
	HttpStatsCollector collector;
	RawPacket rawPacket;
	while(reader->getNextPacket(rawPacket))
	{
		Packet parsedPacket(&rawPacket);
		collector.collectStats(&parsedPacket);
	}

	// print stats summary
	printf("\n\n");
	printf("STATS SUMMARY\n");
	printf("=============\n");
	printStatsSummary(collector);

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

	// free reader memory
	delete reader;
}
Пример #2
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;
}