Example #1
0
		void Socket::bind(const IPv4Address &ip){
			sockaddr_in name;
			name.sin_family = AF_INET;
			name.sin_addr = *ip.address();
			if(::bind(_socket, (struct sockaddr *)&name, sizeof(sockaddr_in)) != 0){
				switch(errno){
					default:
						NetworkException(errno);
				}
			}
		}
Example #2
0
void IPForensics::update_host(std::set<Host>::iterator it, IPv4Address ipv4,
                              IPv6Address ipv6) {
  Host h = *it;
  if (h.ipv4().address().empty() && !ipv4.address().empty()) {
    h.set_ipv4(ipv4);
  }
  if (h.ipv6().address().empty() && !ipv6.address().empty()) {
    h.set_ipv6(ipv6);
  }
  // replace previous IPv6 address if it is link-local
  if (!h.ipv6().address().empty() && !ipv6.address().empty()) {
    if (h.ipv6().address()[0] == ipf::kLinkLocalIPv6[0] &&
        h.ipv6().address()[1] == ipf::kLinkLocalIPv6[1] &&
        ipv6.address()[0] != ipf::kLinkLocalIPv6[0] &&
        ipv6.address()[1] != ipf::kLinkLocalIPv6[1]) {
      h.set_ipv6(ipv6);
    }
  }
  hosts_.erase(it);
  hosts_.insert(h);
}
Example #3
0
		OldUDPSocket::OldUDPSocket(const IPv4Address &addr, int _port){
#ifdef USE_EMBEDDED_CLASSNAMES
			setClassName(__xvr2_Net_OldUDPSocket);
#endif
			flags = MSG_NOSIGNAL;
			port = _port;
			bzero(&ipv4addr, sizeof(struct ::sockaddr_in));
			ipv4addr.sin_family = AF_INET;
			ipv4addr.sin_port   = htons(_port);
			ipv4addr.sin_addr   = *addr.address();
			tsock = socket(ipv4addr.sin_family, SOCK_DGRAM, 0);
			if(tsock < 0){
				switch(errno){
					case EMFILE:
						throw ProcOutOfFileDescriptors();
					break;
					case ENFILE:
						throw SysOutOfFileDescriptors();
					break;
					default:
						throw IOException();
				}
			}
		}
Example #4
0
void CLogViewWindow::ProxyEvent(LogProxyEvent Event, const IPv4Address& addr)
{
	CString msg = GetTranslateMessage(ID_PROXYEVENTHEADER, addr.GetPortNumber()).c_str();
	switch (Event) {
	case kLogProxyNewRequest:
		msg += GetTranslateMessage(ID_PROXYNEWREQUEST).c_str();
		break;

	case kLogProxyEndRequest:
		msg += GetTranslateMessage(ID_PROXYENDREQUEST).c_str();
		break;

	default:
		ATLASSERT( FALSE );
		return ;
	}

	SetWindowText(GetTranslateMessage(IDD_LOGVIEW, CLog::GetActiveRequestCount()).c_str());

	if (m_bProxyEvent == false)
		return;

	_AppendText(msg, LOG_COLOR_PROXY);
}
Example #5
0
int ResolveUtil::getHostnameByAddress(bsl::string        *canonicalHostname,
                                      const IPv4Address&  address,
                                      int                *errorCode)
{
    BSLS_ASSERT(canonicalHostname);

    struct hostent *hp = NULL;
    unsigned int    addr = address.ipAddress();   // in network order

#if defined(BSLS_PLATFORM_OS_AIX)
    struct hostent      hent;
    struct hostent_data hdt;

    if (gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                        sizeof (struct in_addr),
                        AF_INET,
                        &hent,
                        &hdt)) {
        if (errorCode) {
            *errorCode = h_errno;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hent.h_name;

#elif defined(BSLS_PLATFORM_OS_SUNOS) || defined(BSLS_PLATFORM_OS_SOLARIS)
    struct hostent hent;
    char           hdt[2048];
    int            err;

    hp = gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                         sizeof (struct in_addr),
                         AF_INET,
                         &hent,
                         hdt,
                         sizeof(hdt),
                         &err);

    if (0 == hp) {
        if (errorCode) {
            *errorCode = err;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hp->h_name;

#elif defined(BSLS_PLATFORM_OS_LINUX) \
   || defined(BSLS_PLATFORM_OS_FREEBSD)
    struct hostent hent;
    char           hdt[2048];
    int            err;

    if (gethostbyaddr_r(reinterpret_cast<char *>(&addr),
                        sizeof (struct in_addr),
                        AF_INET,
                        &hent,
                        hdt,
                        sizeof(hdt),
                        &hp,
                        &err) || 0 == hp) {
        if (errorCode) {
            *errorCode = err;
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hp->h_name;

#elif defined(BSLS_PLATFORM_OS_UNIX)
    // Standard call cannot be assumed to be re-entrant (it often is not).
    {
        static bslmt::Mutex            mutex;
        bslmt::LockGuard<bslmt::Mutex> guard(&mutex);

        hp = gethostbyaddr(reinterpret_cast<char *>(&addr),
                           sizeof (struct in_addr),
                           AF_INET);

        if (0 == hp) {
            if (errorCode) {
#ifdef BSLS_PLATFORM_OS_HPUX
                *errorCode = h_errno;
#else
                *errorCode = errno;
#endif
            }
            return -1;                                                // RETURN
        }

        *canonicalHostname = hp->h_name;
    }

#elif defined(BSLS_PLATFORM_OS_WINDOWS)
    unsigned short port = address.portNumber();  // in host order

    struct sockaddr_in saGNI;
    char               hostName[NI_MAXHOST];
    char               servInfo[NI_MAXSERV];

    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = addr;
    saGNI.sin_port = htons(port);

    if (getnameinfo(reinterpret_cast<SOCKADDR *>(&saGNI),
                    sizeof(sockaddr),
                    hostName,
                    sizeof(hostName),
                    servInfo,
                    sizeof(servInfo),
                    NI_NUMERICSERV|NI_NAMEREQD)) {
        if (errorCode) {
            *errorCode = WSAGetLastError();
        }
        return -1;                                                    // RETURN
    }

    *canonicalHostname = hostName; // a Fully Qualified Domain Name (FQDN)

#else

#error getHostnameByAddress does not handle current platform type!

#endif

    return 0;
}
Example #6
0
IPv4Address::IPv4Address(const IPv4Address& _ip) : ipAddr(_ip.data()){}
Example #7
0
bool IPv4Address::operator>(const IPv4Address& _rhs) const{
    return ipAddr < _rhs.data();
}
Example #8
0
IPv4Address NetworkUtils::getIPv4Address(std::string hostname, PcapLiveDevice* device, double& dnsResponseTimeMS, uint32_t& dnsTTL,
		int dnsTimeout, IPv4Address dnsServerIP, IPv4Address gatewayIP)
{
	IPv4Address result = IPv4Address::Zero;

	// open the device if not already opened
	bool closeDeviceAtTheEnd = false;
	if (!device->isOpened())
	{
		closeDeviceAtTheEnd = true;
		if (!device->open())
		{
			LOG_ERROR("Cannot open device");
			return result;
		}
	}

	// first - resolve gateway MAC address

	// if gateway IP wasn't provided - try to find the default gateway
	if (gatewayIP == IPv4Address::Zero)
	{
		gatewayIP = device->getDefaultGateway();
	}

	if (!gatewayIP.isValid() || gatewayIP == IPv4Address::Zero)
	{
		LOG_ERROR("Gateway address isn't valid or couldn't find default gateway");
		return result;
	}

	// send the ARP request to find gateway MAC address
	double arpResTime;
	MacAddress gatewayMacAddress = getMacAddress(gatewayIP, device, arpResTime);

	if (gatewayMacAddress == MacAddress::Zero)
	{
		LOG_ERROR("Coulnd't resolve gateway MAC address");
		return result;
	}

	if (dnsTimeout <= 0)
		dnsTimeout = NetworkUtils::DefaultTimeout;

	// validate DNS server IP. If it wasn't provided - set the system-configured DNS server
	if (dnsServerIP == IPv4Address::Zero && device->getDnsServers().size() > 0)
	{
		dnsServerIP = device->getDnsServers().at(0);
	}

	if (!dnsServerIP.isValid())
	{
		LOG_ERROR("DNS server IP isn't valid");
		return result;
	}

	// create DNS request

	Packet dnsRequest(100);
	MacAddress sourceMac = device->getMacAddress();
	EthLayer ethLayer(sourceMac, gatewayMacAddress, PCPP_ETHERTYPE_IP);
	IPv4Layer ipLayer(device->getIPv4Address(), dnsServerIP);
	ipLayer.getIPv4Header()->timeToLive = 128;

	// randomize source port to a number >= 10000
	int srcPortLowest = 10000;
	int srcPortRange = (2^16) - srcPortLowest;
	uint16_t srcPort = (rand() % srcPortRange) + srcPortLowest;
	UdpLayer udpLayer(srcPort, DNS_PORT);

	// create the DNS request for the hostname
	DnsLayer dnsLayer;

	// randomize transaction ID
	uint16_t transactionID = rand() % (2^16);
	dnsLayer.getDnsHeader()->transactionID = htons(transactionID);
	dnsLayer.addQuery(hostname, DNS_TYPE_A, DNS_CLASS_IN);

	// add all layers to packet
	if (!dnsRequest.addLayer(&ethLayer) || !dnsRequest.addLayer(&ipLayer) || !dnsRequest.addLayer(&udpLayer) || !dnsRequest.addLayer(&dnsLayer))
	{
		LOG_ERROR("Couldn't construct DNS query");
		return result;
	}

	dnsRequest.computeCalculateFields();

	// set a DNS response filter on the device
	PortFilter dnsResponseFilter(53, SRC);
	if (!device->setFilter(dnsResponseFilter))
	{
		LOG_ERROR("Couldn't set DNS respnse filter");
		return result;
	}

	// since packet capture is done on another thread, I use a conditional mutex with timeout to synchronize between the capture
	// thread and the main thread. When the capture thread starts running the main thread is blocking on the conditional mutex.
	// When the DNS response are captured the capture thread signals the main thread and the main thread stops capturing and continues
	// to the next iteration. if a timeout passes and no DNS response is captured, the main thread stops capturing

	pthread_mutex_t mutex;
	pthread_cond_t cond;

	// init the conditonal mutex
	pthread_mutex_init(&mutex, 0);
	pthread_cond_init(&cond, 0);

	// this is the token that passes between the 2 threads
	DNSRecievedData data = {
			&mutex,
			&cond,
			hostname,
			transactionID,
			clock(),
			IPv4Address::Zero,
			0,
			0
	};


	struct timeval now;
	gettimeofday(&now,NULL);

	// create the timeout
	timespec timeout = {
			now.tv_sec + dnsTimeout,
			now.tv_usec
	};

	// start capturing. The capture is done on another thread, hence "dnsResponseRecieved" is running on that thread
	device->startCapture(dnsResponseRecieved, &data);

	// send the DNS request
	device->sendPacket(&dnsRequest);

	pthread_mutex_lock(&mutex);

	// block on the conditional mutex until capture thread signals or until timeout expires
	int res = pthread_cond_timedwait(&cond, &mutex, &timeout);

	// stop the capturing thread
	device->stopCapture();

	pthread_mutex_unlock(&mutex);

	// check if timeout expired
	if (res == ETIMEDOUT)
	{
		LOG_ERROR("DNS request time out");
		return result;
	}

	pthread_mutex_destroy(&mutex);
	pthread_cond_destroy(&cond);

	if (closeDeviceAtTheEnd)
		device->close();
	else
		device->clearFilter();

	result = data.result;
	dnsResponseTimeMS = data.dnsResponseTime;
	dnsTTL = data.ttl;

	return result;
}
Example #9
0
sockaddr_in toSockaddr(const IPv4Address & address) {
	return address.getData()->address;
}
Example #10
0
void CLogViewWindow::HttpEvent(LogHttpEvent Event, const IPv4Address& addr, int RequestNumber, const std::string& text)
{
	CString msg = GetTranslateMessage(ID_HTTPEVENTHEADER, addr.GetPortNumber(), RequestNumber).c_str();
	switch (Event) {
	case kLogHttpNewRequest:
		{
			CString url = text.c_str();
			CString temp;
			temp.Format(_T("#%d %s"), RequestNumber, (LPCWSTR)url);
			int nSel = m_cmbRequest.AddString(temp);
			m_cmbRequest.SetItemData(nSel, RequestNumber);
			return;
		}
		break;
		
	case kLogHttpRecvOut:	if (!m_bBrowserToProxy)	return ;
		msg += GetTranslateMessage(ID_HTTPRECVOUT).c_str();
		break;

	case kLogHttpSendOut:	if (!m_bProxyToWeb)	return ;
		msg += GetTranslateMessage(ID_HTTPSENDOUT).c_str();
		break;

	case kLogHttpRecvIn:	if (!m_bProxyFromWeb)	return ;
		msg += GetTranslateMessage(ID_HTTPRECVIN).c_str();
		break;

	case kLogHttpSendIn:	if (!m_bBrowserFromProxy)	return ;
		msg += GetTranslateMessage(ID_HTTPSENDIN).c_str();
		break;

	case kLogHttpPostOut:	if (!m_bViewPostData)	return ;
		msg += L"PostData";
		break;

	default:
		return ;
	}
	msg += _T("\n");
	msg += UTF16fromUTF8(text).c_str();
	msg += _T("\n");

    // Colors depends on Outgoing or Incoming
	COLORREF color = LOG_COLOR_REQUEST;
	if (Event == kLogHttpRecvIn || Event == kLogHttpSendIn) {
		color = LOG_COLOR_RESPONSE;
	} else if (Event == kLogHttpPostOut) {
		color = LOG_COLOR_DEFAULT;

		std::string unescText = CUtil::UESC(text);
		std::string charaCode = DetectCharaCode(unescText);
		if (charaCode.length()) {
			UErrorCode err = UErrorCode::U_ZERO_ERROR;
			auto pConverter = ucnv_open(charaCode.c_str(), &err);
			if (pConverter) {
				std::wstring utf16PostData = UTF16fromConverter(unescText, pConverter);
				msg.AppendFormat(_T(">> Decode Data [%s]\n%s\n"), UTF16fromUTF8(charaCode).c_str(), utf16PostData.c_str());
				ucnv_close(pConverter);
			}
		}
		msg += _T("\n");
	}
	
	{
		CCritSecLock	lock(m_csRequestLog);
		bool bFound = false;
		for (auto& reqLog : m_vecRquestLog) {
			if (reqLog->RequestNumber == RequestNumber) {
				reqLog->vecLog.emplace_back(new TextLog(msg, color));
				lock.Unlock();
				int nCurSel = m_cmbRequest.GetCurSel();
				if (nCurSel > 0 && m_cmbRequest.GetItemData(nCurSel) == RequestNumber) {
					_AppendRequestLogText(msg, color);
				}
				bFound = true;
				break;
			}
		}
		if (bFound == false) {
			m_vecRquestLog.emplace_back(new RequestLog(RequestNumber));
			m_vecRquestLog.back()->vecLog.emplace_back(new TextLog(msg, color));
		}
	}
	_AppendText(msg, color);
}
Example #11
0
/**
 * main method of the application. Responsible for parsing user args, preparing worker thread configuration, creating the worker threads and activate them.
 * At program termination worker threads are stopped, statistics are collected from them and printed to console
 */
int main(int argc, char* argv[])
{
	std::vector<int> dpdkPortVec;

	bool writePacketsToDisk = false;

	string packetFilePath = "";

	CoreMask coreMaskToUse = getCoreMaskForAllMachineCores();

	int sendPacketsToPort = -1;

	int optionIndex = 0;
	char opt = 0;

	uint32_t mBufPoolSize = DEFAULT_MBUF_POOL_SIZE;

	IPv4Address 	srcIPToMatch = IPv4Address::Zero;
	IPv4Address 	dstIPToMatch = IPv4Address::Zero;
	uint16_t 		srcPortToMatch = 0;
	uint16_t 		dstPortToMatch = 0;
	ProtocolType	protocolToMatch = Unknown;

	while((opt = getopt_long (argc, argv, "d:c:s:f:m:i:I:p:P:r:hl", FilterTrafficOptions, &optionIndex)) != -1)
	{
		switch (opt)
		{
			case 0:
			{
				break;
			}
			case 'd':
			{
				string portListAsString = string(optarg);
				stringstream stream(portListAsString);
				string portAsString;
				int port;
				// break comma-separated string into string list
				while(getline(stream, portAsString, ','))
				{
					char c;
					std::stringstream stream2(portAsString);
					stream2 >> port;
					if (stream2.fail() || stream2.get(c))
					{
						// not an integer
						EXIT_WITH_ERROR_AND_PRINT_USAGE("DPDK ports list is invalid");
					}
					dpdkPortVec.push_back(port);
				}

				// verify list is not empty
				if (dpdkPortVec.empty())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("DPDK ports list is empty");
				}
				break;
			}
			case 's':
			{
				sendPacketsToPort = atoi(optarg);
				break;
			}
			case 'c':
			{
				coreMaskToUse = atoi(optarg);
				break;
			}
			case 'f':
			{
				packetFilePath = string(optarg);
				writePacketsToDisk = true;
				if (packetFilePath.empty())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Filename to write packets is empty");
				}
				break;
			}
			case 'm':
			{
				mBufPoolSize = atoi(optarg);
				break;
			}
			case 'i':
			{
				srcIPToMatch = IPv4Address(optarg);
				if (!srcIPToMatch.isValid())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Source IP to match isn't a valid IP address");
				}
				break;
			}
			case 'I':
			{
				dstIPToMatch = IPv4Address(optarg);
				if (!dstIPToMatch.isValid())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Destination IP to match isn't a valid IP address");
				}
				break;
			}
			case 'p':
			{
				srcPortToMatch = atoi(optarg);
				if (srcPortToMatch <= 0)
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Source port to match isn't a valid TCP/UDP port");
				}
				break;
			}
			case 'P':
			{
				dstPortToMatch = atoi(optarg);
				if (dstPortToMatch <= 0)
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Destination port to match isn't a valid TCP/UDP port");
				}
				break;
			}
			case 'r':
			{
				string protocol = string(optarg);
				if (protocol == "TCP")
					protocolToMatch = TCP;
				else if (protocol == "UDP")
					protocolToMatch = UDP;
				else
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Protocol to match isn't TCP or UDP");
				}
				break;
			}
			case 'h':
			{
				printUsage();
				exit(0);
			}
			case 'l':
			{
				listDpdkPorts();
				exit(0);
			}
			default:
			{
				printUsage();
				exit(0);
			}
		}
	}

	// verify list is not empty
	if (dpdkPortVec.empty())
	{
		EXIT_WITH_ERROR_AND_PRINT_USAGE("DPDK ports list is empty. Please use the -d switch");
	}

	// initialize DPDK
	if (!DpdkDeviceList::initDpdk(coreMaskToUse, mBufPoolSize))
	{
		EXIT_WITH_ERROR("couldn't initialize DPDK");
	}

	// removing DPDK master core from core mask because DPDK worker threads cannot run on master core
	coreMaskToUse = coreMaskToUse & ~(DpdkDeviceList::getInstance().getDpdkMasterCore().Mask);

	// extract core vector from core mask
	vector<SystemCore> coresToUse;
	createCoreVectorFromCoreMask(coreMaskToUse, coresToUse);

	// collect the list of DPDK devices
	vector<DpdkDevice*> dpdkDevicesToUse;
	for (vector<int>::iterator iter = dpdkPortVec.begin(); iter != dpdkPortVec.end(); iter++)
	{
		DpdkDevice* dev = DpdkDeviceList::getInstance().getDeviceByPort(*iter);
		if (dev == NULL)
		{
			EXIT_WITH_ERROR("DPDK device for port %d doesn't exist", *iter);
		}
		dpdkDevicesToUse.push_back(dev);
	}

	// get DPDK device to send packets to (or NULL if doesn't exist)
	DpdkDevice* sendPacketsTo = DpdkDeviceList::getInstance().getDeviceByPort(sendPacketsToPort);
	if (sendPacketsTo != NULL && !sendPacketsTo->open())
	{
		EXIT_WITH_ERROR("Could not open port#%d for sending matched packets", sendPacketsToPort);
	}

	// go over all devices and open them
	for (vector<DpdkDevice*>::iterator iter = dpdkDevicesToUse.begin(); iter != dpdkDevicesToUse.end(); iter++)
	{
		if (!(*iter)->openMultiQueues((*iter)->getTotalNumOfRxQueues(), (*iter)->getTotalNumOfTxQueues()))
		{
			EXIT_WITH_ERROR("Couldn't open DPDK device #%d, PMD '%s'", (*iter)->getDeviceId(), (*iter)->getPMDName().c_str());
		}
	}

	// prepare configuration for every core
	AppWorkerConfig workerConfigArr[coresToUse.size()];
	prepareCoreConfiguration(dpdkDevicesToUse, coresToUse, writePacketsToDisk, packetFilePath, sendPacketsTo, workerConfigArr, coresToUse.size());

	PacketMatchingEngine matchingEngine(srcIPToMatch, dstIPToMatch, srcPortToMatch, dstPortToMatch, protocolToMatch);

	// create worker thread for every core
	vector<DpdkWorkerThread*> workerThreadVec;
	int i = 0;
	for (vector<SystemCore>::iterator iter = coresToUse.begin(); iter != coresToUse.end(); iter++)
	{
		AppWorkerThread* newWorker = new AppWorkerThread(workerConfigArr[i], matchingEngine);
		workerThreadVec.push_back(newWorker);
		i++;
	}

	// start all worker threads
	if (!DpdkDeviceList::getInstance().startDpdkWorkerThreads(coreMaskToUse, workerThreadVec))
	{
		EXIT_WITH_ERROR("Couldn't start worker threads");
	}

	// register the on app close event to print summary stats on app termination
	FiltetTrafficArgs args;
	args.workerThreadsVector = &workerThreadVec;
	ApplicationEventHandler::getInstance().onApplicationInterrupted(onApplicationInterrupted, &args);

	// infinite loop (until program is terminated)
	while (!args.shouldStop)
	{
		sleep(5);
	}
}
/**
 * Send a file to the pitcher
 */
void sendFile(std::string filePath, IPv4Address pitcherIP, IPv4Address catcherIP, size_t blockSize)
{
	// identify the interface to listen and send packets to
	PcapLiveDevice* dev = PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(&catcherIP);
	if (dev == NULL)
		EXIT_WITH_ERROR("Cannot find network interface with IP '%s'", catcherIP.toString().c_str());

	// try to open the interface (device)
	if (!dev->open())
		EXIT_WITH_ERROR("Cannot open network interface");

	// set an ICMP protocol filter so it'll capture only ICMP packets
	ProtoFilter protocolFilter(ICMP);
	if (!dev->setFilter(protocolFilter))
		EXIT_WITH_ERROR("Can't set ICMP filter on device");

	// try the open the file for reading
	std::ifstream file(filePath.c_str(), std::ios::in|std::ios::binary);

	if (file.is_open())
	{
		// extract file size
		file.seekg(0, std::ios_base::end);
	    uint32_t fileSize = file.tellg();

	    // go back to the beginning of the file
		file.seekg(0, std::ios::beg);

		// remove the path and keep just the file name. This is the name that will be delivered to the pitcher
		std::string fileName = getFileNameFromPath(filePath);

		printf("Waiting for pitcher to send a keep-alive signal...\n");

		IcmpFileTransferStart icmpFTStart = {
				pitcherIP,
				catcherIP,
				fileName,
				0
		};

		// first, establish a connection with the pitcher and send it the file name. This method waits for the pitcher to send an ICMP
		// request which indicates it's alive. The response to the request will contain the file name in the ICMP response data
		int res  = dev->startCaptureBlockingMode(startFileTransfer, &icmpFTStart, -1);
		// if an error occurred
		if (!res)
			EXIT_WITH_ERROR("Cannot start capturing packets");

		printf("Sending file '%s' ", fileName.c_str());


		IcmpFileContentDataSend icmpFileContentData = {
				pitcherIP,
				catcherIP,
				&file,
				true,
				0,
				blockSize,
				NULL
		};

		// create the memory block that will contain the file data chunks that will be transferred to the pitcher
		icmpFileContentData.memblock = new char[blockSize];

		// wait for ICMP requests coming from the pitcher and send file data chunks as a reply in the ICMP response data
		// this method returns when all file was transferred to the pitcher
		res = dev->startCaptureBlockingMode(sendContent, &icmpFileContentData, -1);

		// free the memory block data and close the file
		delete [] icmpFileContentData.memblock;
		file.close();

		// if capture failed, exit the program
		if (!res)
			EXIT_WITH_ERROR("Cannot start capturing packets");

		printf("\n\nFinished sending '%s' [sent %d bytes]\n", fileName.c_str(), fileSize);
	}
	else // if file couldn't be opened
		EXIT_WITH_ERROR("Cannot open file '%s'", filePath.c_str());

	// close the device
	dev->close();
}
/**
 * Receive a file from the pitcher
 */
void receiveFile(IPv4Address pitcherIP, IPv4Address catcherIP)
{
	// identify the interface to listen and send packets to
	PcapLiveDevice* dev = PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(&catcherIP);
	if (dev == NULL)
		EXIT_WITH_ERROR("Cannot find network interface with IP '%s'", catcherIP.toString().c_str());

	// try to open the interface (device)
	if (!dev->open())
		EXIT_WITH_ERROR("Cannot open network interface");

	// set an ICMP protocol filter so it'll capture only ICMP packets
	ProtoFilter protocolFilter(ICMP);
	if (!dev->setFilter(protocolFilter))
		EXIT_WITH_ERROR("Can't set ICMP filter on device");

	printf("Waiting for pitcher to send a file...\n");

	IcmpFileTransferStart icmpFTStart = {
			pitcherIP,
			catcherIP,
			"",
			0
	};

	// wait until the pitcher sends an ICMP request with the file name in its data
	int res = dev->startCaptureBlockingMode(waitForFileTransferStart, &icmpFTStart, -1);
	if (!res)
		EXIT_WITH_ERROR("Cannot start capturing packets");

	// create a new file with the name provided by the pitcher
	std::ofstream file(icmpFTStart.fileName.c_str(), std::ios::out|std::ios::binary);

	if (file.is_open())
	{
		printf("Getting file from pitcher: '%s' ", icmpFTStart.fileName.c_str());

		IcmpFileContentDataRecv icmpFileContentData = {
				pitcherIP,
				catcherIP,
				&file,
				icmpFTStart.fileName,
				(uint16_t)(icmpFTStart.icmpId+1),
				0,
				0
		};

		// get all file data from the pitcher. This method blocks until all file is received
		res = dev->startCaptureBlockingMode(getFileContent, &icmpFileContentData, -1);
		if (!res)
		{
			file.close();
			EXIT_WITH_ERROR_AND_RUN_COMMAND("Cannot start capturing packets", std::remove(icmpFTStart.fileName.c_str()));
		}

		printf("\n\nFinished getting file '%s' [received %d bytes]\n", icmpFTStart.fileName.c_str(), icmpFileContentData.fileSize);
	}
	else
		EXIT_WITH_ERROR("Cannot create file");

	// remove the filter and close the device (interface)
	dev->clearFilter();
	dev->close();
}
Example #14
0
int main(int argc, char* argv[])
{
	PfRingDevice* dev = NULL;

	int totalNumOfCores = getNumOfCores();
	int numOfCaptureThreads = totalNumOfCores-1;

	PfRingDevice* sendPacketsToIface = NULL;

	std::string packetFilePath = "";
	bool writePacketsToDisk = true;

	IPv4Address 	srcIPToMatch = IPv4Address::Zero;
	IPv4Address 	dstIPToMatch = IPv4Address::Zero;
	uint16_t 		srcPortToMatch = 0;
	uint16_t 		dstPortToMatch = 0;
	ProtocolType	protocolToMatch = Unknown;

	int optionIndex = 0;
	char opt = 0;

	while((opt = getopt_long (argc, argv, "n:s:t:f:i:I:p:P:r:hl", PfFilterTrafficOptions, &optionIndex)) != -1)
	{
		switch (opt)
		{
			case 0:
			{
				break;
			}
			case 'n':
			{
				std::string ifaceName = std::string(optarg);
				dev = PfRingDeviceList::getInstance().getPfRingDeviceByName(ifaceName);
				if (dev == NULL)
					EXIT_WITH_ERROR("Could not find PF_RING device '%s'", ifaceName.c_str());
				break;
			}
			case 's':
			{
				std::string sendPacketsToIfaceName = std::string(optarg);
				sendPacketsToIface = PfRingDeviceList::getInstance().getPfRingDeviceByName(sendPacketsToIfaceName);
				if (sendPacketsToIface == NULL)
					EXIT_WITH_ERROR("Could not find PF_RING device '%s'", sendPacketsToIfaceName.c_str());

				break;
			}
			case 't':
			{
				numOfCaptureThreads = atoi(optarg);
				if (numOfCaptureThreads < 1 || numOfCaptureThreads > totalNumOfCores-1)
					EXIT_WITH_ERROR("Number of capture threads must be in the range of 1 to %d", totalNumOfCores-1);
				break;
			}
			case 'f':
			{
				packetFilePath = string(optarg);
				// make sure the path ends with '/'
				if (packetFilePath.length() > 1 && (0 != packetFilePath.compare(packetFilePath.length()-1, 1, "/")))
					packetFilePath += "/";

				writePacketsToDisk = true;
				break;
			}
			case 'i':
			{
				srcIPToMatch = IPv4Address(optarg);
				if (!srcIPToMatch.isValid())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Source IP to match isn't a valid IP address");
				}
				break;
			}
			case 'I':
			{
				dstIPToMatch = IPv4Address(optarg);
				if (!dstIPToMatch.isValid())
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Destination IP to match isn't a valid IP address");
				}
				break;
			}
			case 'p':
			{
				srcPortToMatch = atoi(optarg);
				if (srcPortToMatch <= 0)
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Source port to match isn't a valid TCP/UDP port");
				}
				break;
			}
			case 'P':
			{
				dstPortToMatch = atoi(optarg);
				if (dstPortToMatch <= 0)
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Destination port to match isn't a valid TCP/UDP port");
				}
				break;
			}
			case 'r':
			{
				string protocol = string(optarg);
				if (protocol == "TCP")
					protocolToMatch = TCP;
				else if (protocol == "UDP")
					protocolToMatch = UDP;
				else
				{
					EXIT_WITH_ERROR_AND_PRINT_USAGE("Protocol to match isn't TCP or UDP");
				}
				break;
			}
			case 'h':
			{
				printUsage();
				exit(0);
			}
			case 'l':
			{
				listPfRingDevices();
				exit(0);
			}
			default:
			{
				printUsage();
				exit(0);
			}
		}
	}

	if (dev == NULL)
		EXIT_WITH_ERROR_AND_PRINT_USAGE("Interface name was not provided");

	// open the PF_RING device in multi-thread mode. Distribution of packets between threads will be done per-flow (as opposed to
	// round-robin)
	if (!dev->openMultiRxChannels(numOfCaptureThreads, PfRingDevice::PerFlow))
		EXIT_WITH_ERROR("Couldn't open %d RX channels on interface '%s'", numOfCaptureThreads, dev->getDeviceName().c_str());

	if (sendPacketsToIface != NULL && !sendPacketsToIface->open())
		EXIT_WITH_ERROR("Couldn't open PF_RING device '%s' for sending matched packets", sendPacketsToIface->getDeviceName().c_str());

	CoreMask coreMask = 0;
	int threadId = 0;
	int threadCount = 0;

	// create an array of packet stats with the size of all machine cores
	PacketStats packetStatsArr[totalNumOfCores];

	// init each packet stats instance with an illegal core ID
	for (int coreId = 0; coreId < totalNumOfCores; coreId++)
		packetStatsArr[coreId].ThreadId = MAX_NUM_OF_CORES+1;

	// mark only relevant cores by adding them to core mask
	// mark only relevant packet stats instances by setting their core ID
	while (threadCount < numOfCaptureThreads)
	{
		if (SystemCores::IdToSystemCore[threadId].Id != dev->getCurrentCoreId().Id)
		{
			coreMask |= SystemCores::IdToSystemCore[threadId].Mask;
			packetStatsArr[threadId].ThreadId = SystemCores::IdToSystemCore[threadId].Id;
			threadCount++;
		}

		threadId++;
	}

	// create the matching engine instance
	PacketMatchingEngine matchingEngine(srcIPToMatch, dstIPToMatch, srcPortToMatch, dstPortToMatch, protocolToMatch);

	// create a flow table for each core
	map<uint32_t, bool> flowTables[totalNumOfCores];

	PcapFileWriterDevice** pcapWriters = NULL;

	// if needed, prepare pcap writers for all capturing threads
	if (writePacketsToDisk)
	{
		pcapWriters = new PcapFileWriterDevice*[totalNumOfCores];

		for (int coreId = 0; coreId < totalNumOfCores; coreId++)
		{
			// if core doesn't participate in capturing, skip it
			if ((coreMask & SystemCores::IdToSystemCore[coreId].Mask) == 0)
			{
				pcapWriters[coreId] = NULL;
				continue;
			}

			std::stringstream packetFileName;
			packetFileName << packetFilePath << "Thread" << coreId << ".pcap";
			pcapWriters[coreId] = new PcapFileWriterDevice(packetFileName.str().c_str());
			if (!pcapWriters[coreId]->open())
			{
				EXIT_WITH_ERROR("Couldn't open pcap writer device for core %d", coreId);
			}
		}
	}


	printf("Start capturing on %d threads core mask = 0x%X\n", numOfCaptureThreads, coreMask);

	// prepare packet capture configuration
	CaptureThreadArgs args;
	args.packetStatArr = packetStatsArr;
	args.matchingEngine = &matchingEngine;
	args.flowTables = flowTables;
	args.sendPacketsTo = sendPacketsToIface;
	args.pcapWriters = pcapWriters;

	// start capturing packets on all threads
	if (!dev->startCaptureMultiThread(packetArrived, &args, coreMask))
		EXIT_WITH_ERROR("Couldn't start capturing on core mask %X on interface '%s'", coreMask, dev->getDeviceName().c_str());

	bool shouldStop = false;

	// register the on app close event to print summary stats on app termination
	ApplicationEventHandler::getInstance().onApplicationInterrupted(onApplicationInterrupted, &shouldStop);

	// infinite loop (until program is terminated)
	while (!shouldStop)
	{
		sleep(5);
	}

	// stop capturing packets, close the device
	dev->stopCapture();
	dev->close();

	// close and delete pcap writers
	if (writePacketsToDisk)
	{
		for (int coreId = 0; coreId < totalNumOfCores; coreId++)
		{
			if ((coreMask & SystemCores::IdToSystemCore[coreId].Mask) == 0)
				continue;

			pcapWriters[coreId]->close();
			delete pcapWriters[coreId];
		}
	}

	printf("\n\nApplication stopped\n");

	// print final stats for every capture thread plus sum of all threads and free worker threads memory
	PacketStats aggregatedStats;
	bool printedStatsHeadline = false;
	for (int i = 0; i < totalNumOfCores; i++)
	{
		if (packetStatsArr[i].ThreadId == MAX_NUM_OF_CORES+1)
			continue;

		aggregatedStats.collectStats(packetStatsArr[i]);
		if (!printedStatsHeadline)
		{
			packetStatsArr[i].printStatsHeadline();
			printedStatsHeadline = true;
		}
		packetStatsArr[i].printStats();
	}
	aggregatedStats.printStats();
}
Example #15
0
void UDPNetworkSocket::addTarget(const IPv4Address & address) {
	if (address.isValid())
		data->targets.insert(address);
}
Example #16
0
static int daemonMain(int argc, char *argv[])
{
    try {
        std::string macAddressString = g_macAddress->val();
        replace(macAddressString, "-", "");
        if (macAddressString.size() != 12u) {
            std::cerr << "MAC address must be 12 characters" << std::endl;
            return -1;
        }
        std::string macAddress = dataFromHexstring(macAddressString);

        std::set<Address::ptr> blacklistedAddresses;
        std::vector<std::string> blacklistedAddressesString = split(
            g_blacklist->val(), ";, ");
        for(std::vector<std::string>::const_iterator it(
            blacklistedAddressesString.begin());
            it != blacklistedAddressesString.end();
            ++it) {
            if(it->empty())
                continue;
            blacklistedAddresses.insert(IPAddress::create(it->c_str()));
        }

        std::vector<std::pair<Address::ptr, unsigned int> > addresses =
            Address::getInterfaceAddresses(g_interface->val(), AF_INET);
        if (addresses.empty()) {
            std::cerr << "Couldn't find interface " << g_interface->val()
                << std::endl;
            return -1;
        }

        IPAddress::ptr localAddress = boost::static_pointer_cast<IPAddress>(
            addresses.front().first);
        IPAddress::ptr broadcastAddress = localAddress->broadcastAddress(
            addresses.front().second);
        broadcastAddress->port(9u);
        IPv4Address multicastAddress("239.255.255.250", 1900);

        IOManager ioManager;

        Socket::ptr broadcastSocket(broadcastAddress->createSocket(ioManager,
            SOCK_DGRAM));
        broadcastSocket->setOption(SOL_SOCKET, SO_BROADCAST, 1);
        broadcastSocket->connect(broadcastAddress);

        Socket::ptr listenSocket(multicastAddress.createSocket(ioManager,
            SOCK_DGRAM));
        listenSocket->setOption(SOL_SOCKET, SO_REUSEADDR, 1);
        listenSocket->bind(IPv4Address(0u, 1900u));
        // TODO: listenSocket->joinGroup(multicastAddress, addresses.front().first);
        struct ip_mreq multicastGroup;
        memcpy(&multicastGroup.imr_multiaddr, &((sockaddr_in *)multicastAddress.name())->sin_addr, sizeof(struct in_addr));
        memcpy(&multicastGroup.imr_interface, &((sockaddr_in *)addresses.front().first->name())->sin_addr, sizeof(struct in_addr));
        listenSocket->setOption(IPPROTO_IP, IP_ADD_MEMBERSHIP, multicastGroup);

        Daemon::onTerminate.connect(boost::bind(&Socket::cancelReceive,
            listenSocket));

        try {
            IPv4Address sender;
            char buffer[4096];
            size_t size;
            while((size = listenSocket->receiveFrom(buffer, 4096, sender))) {
                IPAddress::ptr senderDuplicate = sender.clone();
                senderDuplicate->port(0u);
                if (blacklistedAddresses.find(senderDuplicate) !=
                    blacklistedAddresses.end()) {
                    MORDOR_LOG_VERBOSE(Log::root())
                        << "Skipping broadcast from " << sender;
                    continue;
                }

                HTTP::Request request;
                HTTP::RequestParser parser(request);
                parser.run(buffer, size);
                if (parser.complete() && !parser.error()) {
                    if (request.requestLine.method == "M-SEARCH") {
                        MORDOR_LOG_INFO(Log::root()) << "Relaying M-SEARCH to WOL from "
                            << sender;
                        wol(broadcastSocket, macAddress);
                    }
                } else {
                    MORDOR_LOG_WARNING(Log::root()) << "Unable to parse HTTP request from "
                        << sender << ": " << charslice(buffer, size);
                }
            }
        } catch (OperationAbortedException &) {
        } catch (...) {
            MORDOR_LOG_FATAL(Log::root())
                << boost::current_exception_diagnostic_information();
            return -1;
        }
    } catch (...) {
        std::cerr << boost::current_exception_diagnostic_information() << std::endl;
        return -1;
    }
    return 0;
}
Example #17
0
void icmp_router_address_structure::setRouterAddress(IPv4Address addr, uint32_t preference)
{
	routerAddress = addr.toInt();
	preferenceLevel = htonl(preference);
}
Example #18
0
/**
 * main method of the application
 */
int main(int argc, char* argv[])
{
	std::string hostname;
	bool hostnameProvided = false;
	std::string interfaceNameOrIP;
	bool interfaceNameOrIPProvided = false;
	IPv4Address dnsServerIP = IPv4Address::Zero;
	IPv4Address gatewayIP = IPv4Address::Zero;
	int timeoutSec = -1;

	int optionIndex = 0;
	char opt = 0;

	while((opt = getopt_long (argc, argv, "i:d:g:s:t:hl", DNSResolverOptions, &optionIndex)) != -1)
	{
		switch (opt)
		{
			case 0:
			{
				break;
			}
			case 'h':
			{
				printUsage();
				exit(0);
			}
			case 'l':
			{
				listInterfaces();
				exit(0);
			}
			case 'i':
			{
				interfaceNameOrIP = optarg;
				interfaceNameOrIPProvided = true;
				break;
			}
			case 'd':
			{
				dnsServerIP = IPv4Address(optarg);
				break;
			}
			case 'g':
			{
				gatewayIP = IPv4Address(optarg);
				break;
			}
			case 's':
			{
				hostname = optarg;
				hostnameProvided = true;
				break;
			}
			case 't':
			{
				timeoutSec = atoi(optarg);
				break;
			}
			default:
			{
				printUsage();
				exit(1);
			}
		}
	}

	// make sure that hostname is provided
	if (!hostnameProvided)
		EXIT_WITH_ERROR("Hostname not provided");

	// find the interface to send the DNS request from
	PcapLiveDevice* dev = NULL;

	// if interface name or IP was provided - find the device accordingly
	if (interfaceNameOrIPProvided)
	{
		IPv4Address interfaceIP(interfaceNameOrIP);
		if (interfaceIP.isValid())
		{
			dev = PcapLiveDeviceList::getInstance().getPcapLiveDeviceByIp(interfaceIP);
			if (dev == NULL)
				EXIT_WITH_ERROR("Couldn't find interface by provided IP");
		}
		else
		{
			dev = PcapLiveDeviceList::getInstance().getPcapLiveDeviceByName(interfaceNameOrIP);
			if (dev == NULL)
				EXIT_WITH_ERROR("Couldn't find interface by provided name");
		}
	}
	// if interface name or IP was not provided - find a device that has a default gateway
	else
	{
		const std::vector<PcapLiveDevice*>& devList = PcapLiveDeviceList::getInstance().getPcapLiveDevicesList();

		for (std::vector<PcapLiveDevice*>::const_iterator iter = devList.begin(); iter != devList.end(); iter++)
		{
			if ((*iter)->getDefaultGateway() != IPv4Address::Zero)
			{
				dev = *iter;
				break;
			}
		}

		if (dev == NULL)
			EXIT_WITH_ERROR("Couldn't find an interface with a default gateway");
	}

	printf("Using interface '%s'\n", dev->getIPv4Address().toString().c_str());

	// find the IPv4 address for provided hostname
	double responseTime = 0;
	uint32_t dnsTTL = 0;
	IPv4Address resultIP = NetworkUtils::getInstance().getIPv4Address(hostname, dev, responseTime, dnsTTL, timeoutSec, dnsServerIP, gatewayIP);

	// print resolved IPv4 address if found
	if (resultIP == IPv4Address::Zero)
		printf("\nCould not resolve hostname [%s]\n", hostname.c_str());
	else
		printf("\nIP address of [%s] is: %s  DNS-TTL=%d  time=%dms\n", hostname.c_str(), resultIP.toString().c_str(), dnsTTL, (int)responseTime);

}