Examples/IcmpFileTransfer/IcmpFileTransfer-pitcher.cpp
/**
 * Send a file to the catcher
 */
Send a file to the catcher
Send a file to the catcher
void sendFile(std::string filePath, pcpp::IPv4Address pitcherIP, pcpp::IPv4Address catcherIP, size_t blockSize, int packetPerSec)
{
	pcpp::PcapLiveDevice* dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(pitcherIP);
	if (dev == NULL)
		EXIT_WITH_ERROR("Cannot find network interface with IP '" << pitcherIP << "'");
	if (!dev->open())
		EXIT_WITH_ERROR("Cannot open network interface ");
	pcpp::MacAddress pitcherMacAddr = dev->getMacAddress();
	if (pitcherMacAddr == pcpp::MacAddress::Zero)
		EXIT_WITH_ERROR("Cannot find pitcher MAC address");
	double arpResTO = 0;
	pcpp::MacAddress catcherMacAddr = pcpp::NetworkUtils::getInstance().getMacAddress(catcherIP, dev, arpResTO, pitcherMacAddr, pitcherIP, 10);
	if (catcherMacAddr == pcpp::MacAddress::Zero)
		EXIT_WITH_ERROR("Cannot find catcher MAC address");
	uint8_t* memblock = new uint8_t[blockSize];
	memset(memblock, 0, blockSize);
	std::ifstream file(filePath.c_str(), std::ios::in|std::ios::binary);
	if (file.is_open())
	{
		std::string fileName = getFileNameFromPath(filePath);
		file.seekg(0, std::ios::beg);
		uint16_t icmpId = 1;
		strcpy((char*)memblock, fileName.c_str());
		IcmpFileTransferStartSend ftStartData = {
				icmpId,
				pitcherIP,
				catcherIP
		};
		std::cout << "Waiting for catcher..." << std::endl;
		while (1)
		{
			if (!sendIcmpRequest(dev,
					pitcherMacAddr, catcherMacAddr,
					pitcherIP, catcherIP,
					icmpId, ICMP_FT_START,
					memblock, fileName.length() + 1))
				EXIT_WITH_ERROR("Cannot send file transfer start message");
			int res = dev->startCaptureBlockingMode(waitForFileTransferStartAck, &ftStartData, SEND_TIMEOUT_BEFORE_FT_START);
			if (!res)
				EXIT_WITH_ERROR("Cannot start capturing packets");
			if (res == 1)
				break;
			icmpId++;
			ftStartData.icmpMsgId++;
		}
		std::cout << "Sending file '" << fileName << "' ";
		icmpId++;
		uint32_t bytesSentSoFar = 0;
		uint32_t MBSent = 0;
		uint32_t sleepBetweenPackets = 0;
		if (packetPerSec > 1)
			sleepBetweenPackets = (uint32_t)(1000000UL / packetPerSec);
		while (file.read((char*)memblock, blockSize))
		{
			if (!sendIcmpRequest(dev, pitcherMacAddr, catcherMacAddr, pitcherIP, catcherIP, icmpId, ICMP_FT_DATA, memblock, blockSize))
				EXIT_WITH_ERROR("Cannot send file data message");
			if (packetPerSec > 1)
				usleep(sleepBetweenPackets);
			else if (packetPerSec == 1)
				pcpp::multiPlatformSleep(1);
			bytesSentSoFar += blockSize;
			MBSent += blockSize;
			if (MBSent > ONE_MBYTE)
			{
				MBSent -= ONE_MBYTE;
				std::cout << ".";
			}
			icmpId++;
		}
		if (file.gcount() > 0)
		{
			if (!sendIcmpRequest(dev, pitcherMacAddr, catcherMacAddr, pitcherIP, catcherIP, icmpId, ICMP_FT_DATA, memblock, file.gcount()))
				EXIT_WITH_ERROR("Cannot send file data message");
			bytesSentSoFar += file.gcount();
			std::cout << ".";
		}
		if (!sendIcmpRequest(dev, pitcherMacAddr, catcherMacAddr, pitcherIP, catcherIP, icmpId, ICMP_FT_END, NULL, 0))
			EXIT_WITH_ERROR("Cannot send file transfer end message");
		std::cout << std::endl << std::endl
			<< "Finished sending '" << fileName << "' "
			<< "[sent " << bytesSentSoFar << " bytes]"
			<< std::endl;
	}
	else
		EXIT_WITH_ERROR("Cannot open file '" << filePath << "'");
	file.close();
	dev->close();
	delete [] memblock;
}
void sendFile ( std :: string filePath , pcpp :: IPv4Address pitcherIP , pcpp :: IPv4Address catcherIP , size_t blockSize , int packetPerSec ) { pcpp :: PcapLiveDevice * dev = pcpp :: PcapLiveDeviceList :: getInstance ( ) . getPcapLiveDeviceByIp ( pitcherIP ) ; if ( dev == NULL ) EXIT_WITH_ERROR ( " " << pitcherIP << " " ) ; if ( ! dev -> open ( ) ) EXIT_WITH_ERROR ( " " ) ; pcpp :: MacAddress pitcherMacAddr = dev -> getMacAddress ( ) ; if ( pitcherMacAddr == pcpp :: MacAddress :: Zero ) EXIT_WITH_ERROR ( " " ) ; double arpResTO = 0 ; pcpp :: MacAddress catcherMacAddr = pcpp :: NetworkUtils :: getInstance ( ) . getMacAddress ( catcherIP , dev , arpResTO , pitcherMacAddr , pitcherIP , 10 ) ; if ( catcherMacAddr == pcpp :: MacAddress :: Zero ) EXIT_WITH_ERROR ( " " ) ; uint8_t * memblock = new uint8_t [ blockSize ] ; memset ( memblock , 0 , blockSize ) ; std :: ifstream file ( filePath . c_str ( ) , std :: ios :: in | std :: ios :: binary ) ; if ( file . is_open ( ) ) { std :: string fileName = getFileNameFromPath ( filePath ) ; file . seekg ( 0 , std :: ios :: beg ) ; uint16_t icmpId = 1 ; strcpy ( ( char * ) memblock , fileName . c_str ( ) ) ; IcmpFileTransferStartSend ftStartData = { icmpId , pitcherIP , catcherIP } ; std :: cout << " " << std :: endl ; while ( 1 ) { if ( ! sendIcmpRequest ( dev , pitcherMacAddr , catcherMacAddr , pitcherIP , catcherIP , icmpId , ICMP_FT_START , memblock , fileName . length ( ) + 1 ) ) EXIT_WITH_ERROR ( " " ) ; int res = dev -> startCaptureBlockingMode ( waitForFileTransferStartAck , & ftStartData , SEND_TIMEOUT_BEFORE_FT_START ) ; if ( ! res ) EXIT_WITH_ERROR ( " " ) ; if ( res == 1 ) break ; icmpId ++ ; ftStartData . icmpMsgId ++ ; } std :: cout << " " << fileName << " " ; icmpId ++ ; uint32_t bytesSentSoFar = 0 ; uint32_t MBSent = 0 ; uint32_t sleepBetweenPackets = 0 ; if ( packetPerSec > 1 ) sleepBetweenPackets = ( uint32_t ) ( 1000000UL / packetPerSec ) ; while ( file . read ( ( char * ) memblock , blockSize ) ) { if ( ! sendIcmpRequest ( dev , pitcherMacAddr , catcherMacAddr , pitcherIP , catcherIP , icmpId , ICMP_FT_DATA , memblock , blockSize ) ) EXIT_WITH_ERROR ( " " ) ; if ( packetPerSec > 1 ) usleep ( sleepBetweenPackets ) ; else if ( packetPerSec == 1 ) pcpp :: multiPlatformSleep ( 1 ) ; bytesSentSoFar += blockSize ; MBSent += blockSize ; if ( MBSent > ONE_MBYTE ) { MBSent -= ONE_MBYTE ; std :: cout << " " ; } icmpId ++ ; } if ( file . gcount ( ) > 0 ) { if ( ! sendIcmpRequest ( dev , pitcherMacAddr , catcherMacAddr , pitcherIP , catcherIP , icmpId , ICMP_FT_DATA , memblock , file . gcount ( ) ) ) EXIT_WITH_ERROR ( " " ) ; bytesSentSoFar += file . gcount ( ) ; std :: cout << " " ; } if ( ! sendIcmpRequest ( dev , pitcherMacAddr , catcherMacAddr , pitcherIP , catcherIP , icmpId , ICMP_FT_END , NULL , 0 ) ) EXIT_WITH_ERROR ( " " ) ; std :: cout << std :: endl << std :: endl << " " << fileName << " " << " " << bytesSentSoFar << " " << std :: endl ; } else EXIT_WITH_ERROR ( " " << filePath << " " ) ; file . close ( ) ; dev -> close ( ) ; delete [ ] memblock ; }
Send a file to the catcher
Send a file to the catcher
// identify the interface to listen and send packets to
 // try to open the interface (device)
 // get the MAC address of the interface
 // discover the MAC address of the catcher by sending an ARP ping to it
 // create a buffer that will be used to send data chunks of the file
 // try the open the file for reading
 // remove the path and keep just the file name. This is the name that will be delivered to the catcher
 // go back to the beginning of the file
 // copy the file name to the buffer
 // establish connection with the catcher by sending it ICMP requests that contains the file name and wait for a response
 // keep sending these requests until the catcher answers or until the program is stopped
 // send the catcher an ICMP request that includes an special ICMP_FT_START message in the timestamp field and the filename
 // in the request data. The catcher should intercept this message and send an ICMP response with an ICMP_FT_ACK message in
 // the timestamp field
 // now wait for the catcher to answer. The timeout is SEND_TIMEOUT_BEFORE_FT_START. After that another ICMP request will be sent
 // res == 1 means we got the catcher response so we can break the endless loop
 // increase ICMP ID so we won't send the same ICMP ID again
 // calculate how many microseconds (usec) the pitcher needs to sleep between sending each file data chunk (calculated from user defined
 // packetPerSec parameter).
 // The calculation is done in usec as in most cases the pitcher needs to sleep less than 1 second between chunks. However if packetPerSec
 // equals to 1 it means sleeping for 1 second and in this case we can't use usleep (as it's not working for 1 sec or more) and we use
 // sleep instead
 // read one chunk of the file and send it to catcher. This loop breaks when it is reaching the end of the file and can't read a block
 // of size blockSize from the file
 // send an ICMP request to the catcher containing the data chunk.The message type (set in the timestamp field) is ICMP_FT_DATA
 // so the catcher knows it's a data chunk
 // use usleep or sleep (see comment a few lines below)
 // print a dot ('.') on every 1MB sent
 // after the loop above breaks there may be one more block to read (of size less than blockSize). Read it and send it to the catcher
 // done sending the file to the catcher, send an ICMP request with message type ICMP_FT_END (in the timestamp field) to the catcher
 // to indicate all file was sent
 // close the file and the device. Free the memory for memblock
