示例#1
0
NetSend::Result NetSend::initialize()
{
    DEBUG("");

    for (HashIterator<String, Argument *> it(m_arguments.getFlags());
         it.hasCurrent(); it++)
    {
        printf("key = '%s' value = '%s'\n",
                *it.key(), *it.current()->getName());
    }
        
    for (Size i = 0; i < m_arguments.getPositionals().count(); i++)
    {
        printf("pos[%d]: %s = %s\n", i, *m_arguments.getPositionals()[i]->getName(),
                                        *m_arguments.getPositionals()[i]->getValue());
    }

    //const String *dev = m_arguments.get("device");
    //if (dev)
    //    DEBUG("sending on device: " << **dev);

    IPV4::Address ipAddr = (192 << 24) | (168 << 16) | (1 << 8) | (123);
    Ethernet::Address etherAddr;

    arpRequest(ipAddr, &etherAddr);

    return Success;
}
示例#2
0
/*
The handle_arpreq() function is a function you should write, and it should
handle sending ARP requests if necessary:

function handle_arpreq(request):
    if difftime(now, request->sent) > 1.0
        if request->times_sent >= 5:
            send icmp host unreachable to source addr of all pkts waiting
              on this request
            arpreq_destroy(request)
        else:
            send arp request
            request->sent = now
            request->times_sent++

*/
void handle_arpreq(struct sr_instance *sr, struct sr_arpreq *request){
    //assert(sr);
    //assert(request);

	// If time since last sent is more than 1 second
    if (difftime(time(NULL), request->sent) >= 1.0) {

		/* If an ARP request has been sent 5 times with no response,
		a destination host unreachable should go back to all the sender of packets that were waiting on
		a reply to this ARP request. */
        if (request->times_sent >= 5) {

			// Iniitalize variables for the loop
            struct sr_packet *packetPointer = NULL;
            sr_ethernet_hdr_t *ethernetHeader = NULL;
            struct sr_if *interface = NULL;

			// get a pointer to a array of all packets waiting
            packetPointer = request->packets;

			// For every xender of packets waiting, send host unreachable
            while (packetPointer != NULL) {
                ethernetHeader = (sr_ethernet_hdr_t *)(packetPointer->buf);
                interface = getAddressInterface(sr, ethernetHeader->ether_dhost);

                /* do not send an ICMP message for an ICMP message */
				// If we got an interface of a waiting sender, send the ICMP host unreachable
                if (interface) {
                    sendICMP(sr, packetPointer->buf, packetPointer->len, DESTINATION_UNREACHABLE, HOST_UNREACHABLE_CODE);
                }

				// Go to the next exisiting packet
                packetPointer = packetPointer->next;
            }
            sr_arpreq_destroy(&(sr->cache), request);
        }

		// Otherwise, just send arp request with its sent time = now and increment times sent
		else {
            struct sr_if *sendingInterface = sr_get_interface(sr, request->packets->iface);
            arpRequest(sr, sendingInterface, request->ip);

			// Set sent time to NOW
            request->sent = time(NULL); // time(NULL) = NOW

			// Increment # of times sent
            request->times_sent = request->times_sent + 1;
        }
    }
}
示例#3
0
MacAddress NetworkUtils::getMacAddress(IPv4Address ipAddr, PcapLiveDevice* device, double& arpResponseTimeMS,
		MacAddress sourceMac, IPv4Address sourceIP, int arpTimeout)
{
	MacAddress result = MacAddress::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;
		}
	}

	if (sourceMac == MacAddress::Zero)
		sourceMac = device->getMacAddress();

	if (sourceIP == IPv4Address::Zero)
		sourceIP = device->getIPv4Address();

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

	// create an ARP request from sourceMac and sourceIP and ask for target IP

	Packet arpRequest(100);

	MacAddress destMac(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
	EthLayer ethLayer(sourceMac, destMac);

	ArpLayer arpLayer(ARP_REQUEST, sourceMac, destMac, sourceIP, ipAddr);

	if (!arpRequest.addLayer(&ethLayer))
	{
		LOG_ERROR("Couldn't build Eth layer for ARP request");
		return result;
	}

	if (!arpRequest.addLayer(&arpLayer))
	{
		LOG_ERROR("Couldn't build ARP layer for ARP request");
		return result;
	}

	arpRequest.computeCalculateFields();

	// set a filter for the interface to intercept only ARP response packets
	ArpFilter arpFilter(ARP_REPLY);
	if (!device->setFilter(arpFilter))
	{
		LOG_ERROR("Couldn't set ARP filter for device");
		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 ARP response is 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 ARP 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. It contains pointers to the conditional mutex, the target IP for identifying
	// the ARP response, the iteration index and a timestamp to calculate the response time
	ArpingRecievedData data = {
			&mutex,
			&cond,
			ipAddr,
			clock(),
			MacAddress::Zero,
			0
	};

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

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

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

	// send the ARP request
	device->sendPacket(&arpRequest);

	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("ARP request time out");
		return result;
	}

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

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

	result = data.result;
	arpResponseTimeMS = data.arpResponseTime;

	return result;
}