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; }
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(); }
//-------------------------------------------------------------------------------------------------------------// 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; } }
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(); } }
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; }
bool PfRingDevice::sendPacket(const RawPacket& rawPacket) { return sendData(rawPacket.getRawDataReadOnly(), rawPacket.getRawDataLen(), true); }
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 }
/** * 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; }