Exemple #1
0
void TcpScanner::init() {
	src_port = getFirstPID();
	port_count = 0;
	resolve_service_names = 1;

	/* craft template packet */
	template_packet.ip.ihl = 5;
	template_packet.ip.version = 4;
	template_packet.ip.tos = 0;
	template_packet.ip.tot_len = htons(sizeof(template_packet));
	template_packet.ip.frag_off = 0;
	template_packet.ip.ttl = getTTL(); // TODO need to update template after change TTL
	template_packet.ip.protocol = IPPROTO_TCP;
	template_packet.ip.check = 0;
	template_packet.tcp.ack_seq = 0;
	template_packet.tcp.res1 = 0;
	template_packet.tcp.doff = 5;
	template_packet.tcp.fin = 0;  // All TCP flags off by default
	template_packet.tcp.syn = 0;
	template_packet.tcp.rst = 0;
	template_packet.tcp.psh = 0;
	template_packet.tcp.ack = 0;
	template_packet.tcp.urg = 0;
	template_packet.tcp.res2 = 0;
	// template_packet.tcp.ece = 0;
	// template_packet.tcp.cwr = 0;
	template_packet.tcp.window = htons(512);
	template_packet.tcp.check = 0;
	template_packet.tcp.urg_ptr = 0;

	syn_flag = 0;
	rst_flag = 0;
	fin_flag = 0;
	psh_flag = 0;
	ack_flag = 0;
	urg_flag = 0;
	ece_flag = 0;
	cwr_flag = 0;
}
Exemple #2
0
// TODO
// - Return 0 ONLY when there is no packet to send (not on the last packet)
// - Make a hardcoded template packet to prevent having to craft it each time
int TcpScanner::sendPacket() {
	if (debug > 3) printf("TcpScanner::sendPacket: Called\n");
	// dumpPortList();

	// TODO findNextScannablePort(); // Updates pcurrent_host_element
	// First check if there's anything left to scan.  Return 0 if not.
	//
	// This involves moving onto the next host/port and checking if we've found
	// something that can be scanned.  It's a bit untidy, but it's important that
	// this func can be called even if nothing needs scanning.

#ifdef DEBUG
	if (!pcurrent_host_element) {
		printf("DEBUG WARNING: TcpScanner::sendPacket called with pcurrent_host_element = null\n");
	}
#endif

	// If all host elements have been deleted, we're done.
	if (!pcurrent_host_element) return 0;

#ifdef DEBUG
	if (!pcurrent_host_element->pcurrent_port) {
		printf("DEBUG WARNING: TcpScanner::sendPacket called with pcurrent_host_element->pcurrent_port = null\n");
	}
#endif
	// Note the current port element
	// We need to note this so we can tell we've been completely round the port list
	struct port_element *pstart_port_element = pcurrent_host_element->pcurrent_port;
	
	// Increment the port pointer on this host
	pcurrent_host_element->pcurrent_port = pcurrent_host_element->pcurrent_port->pnext;
	int more_ports = 0;

	// Move onto next host
	pcurrent_host_element = pcurrent_host_element->pnext;

	// optimisation to avoid too much pointer defrerencing.  Hardly worth it.
	struct port_element *pcurhost_curport = pcurrent_host_element->pcurrent_port;

	while (!more_ports and pcurhost_curport != pstart_port_element) {
		// can we send to the current port in this portlist?
		if (pcurhost_curport->send_count < tries) {
			// we can send to this
			more_ports = 1;
		} else {
			// we can't send.  increment the port pointer on this host
			pcurrent_host_element->pcurrent_port = pcurhost_curport->pnext;

			// change to next host 
			pcurrent_host_element = pcurrent_host_element->pnext;
			pcurhost_curport = pcurrent_host_element->pcurrent_port;
		}
	}

	// Return 0 if there is nothing left to scan
	if (!(more_ports or pcurhost_curport->send_count < tries)) {
		return 0;
	}

	/* vars for sending */
	struct sockaddr_in sin;
	int send_socket;

	// Make a new packet based on the template packet
	struct send_tcp packet;
	memcpy(&packet, &template_packet, sizeof(packet));

	// Fill in dynamic fields in new packet
	memcpy(&packet.ip.saddr, &src_ip, sizeof(src_ip));
	packet.tcp.source = htons(getNextSourcePort());
	packet.ip.daddr = pcurrent_host_element->ip.s_addr;
	packet.tcp.dest = htons(pcurrent_host_element->pcurrent_port->port);
	packet.tcp.seq = htonl(syncookie(packet.ip.saddr, packet.ip.daddr, packet.tcp.source, packet.tcp.dest));
	packet.tcp.fin = fin_flag;
	packet.tcp.syn = syn_flag;
	packet.tcp.rst = rst_flag;
	packet.tcp.psh = psh_flag;
	packet.tcp.ack = ack_flag;
	packet.tcp.urg = urg_flag;
	packet.tcp.res2 = ece_flag;
	// packet.tcp.ece = ece_flag;
	// packet.tcp.cwr = cwr_flag;
	packet.ip.ttl = getTTL();

	// Now open the raw socket for sending
	sin.sin_family = AF_INET;
	sin.sin_port = packet.tcp.source;
	sin.sin_addr.s_addr = packet.ip.daddr;
	send_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	
	int options;
	options = O_NONBLOCK | fcntl(send_socket, F_GETFL);
	if(fcntl(send_socket, F_SETFL, options) < 0) {
		perror("FCNTL");
		exit(1);
	}

	int one = 1;
	int *oneptr = &one;

	// TODO Note what these socket options actually do
	if (setsockopt(send_socket, IPPROTO_IP, IP_HDRINCL, oneptr, sizeof(one)) == -1) {
		printf("setsockopt: set IP_HDRINCL failed\n");
	}

	if (setsockopt(send_socket, SOL_SOCKET, SO_BROADCAST, oneptr, sizeof(one)) == -1) {
		printf("libnet_open_raw_sock: set SO_BROADCAST failed\n");
	}

	// From synhose.c by knight
	pseudo_hdr_tcp.source_address = packet.ip.saddr;
	pseudo_hdr_tcp.dest_address = packet.ip.daddr;
	pseudo_hdr_tcp.placeholder = 0;
	pseudo_hdr_tcp.protocol = IPPROTO_TCP;
	pseudo_hdr_tcp.tcp_length = htons(sizeof(packet.tcp));

	// recalc checksum
	packet.ip.check = 0;
	packet.tcp.check = 0;
	packet.ip.check = in_cksum((unsigned short *)&packet.ip, sizeof(packet.ip));
	memcpy((char *)&pseudo_hdr_tcp.tcp, (char *)&packet.tcp, sizeof(pseudo_hdr_tcp.tcp));
	packet.tcp.check = in_cksum((unsigned short *)&pseudo_hdr_tcp, sizeof(pseudo_hdr_tcp));

	// send packet
	if (verbose > 1) printf("Sending packet to %s:%d\n", inet_ntoa(pcurrent_host_element->ip), pcurrent_host_element->pcurrent_port->port);
	sendto(send_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&sin, sizeof(sin));
	close(send_socket);

	// Increment number of times this port has been scanned
	pcurrent_host_element->pcurrent_port->send_count++;

	// Delete from list if unless we're going to scan it again
	// TODO This is elegant, but REALLY hurts performance.
	//if (pcurrent_host_element->pcurrent_port->send_count >= tries) {
	//	deletePort(pcurrent_host_element, pcurrent_host_element->pcurrent_port);
	//}

	// Return the length of the packet we sent
	return sizeof(packet);
}
Exemple #3
0
/*******************************************************************
* Function Name: externalFunction
* Description: the Network gets input from outside
********************************************************************/
Model &LTSNetwork::externalFunction( const ExternalMessage &msg ){

	if (msg.port() == peer_online)
	{

		thegraph->online(msg.value());   //adds a node to the graph with the given value
		if(VERBOSE) cout<<"node "<<msg.value()<<" inserted\n";
		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == peer_offline){
		int inpeer = msg.value();

		//get all the connected nodes a disconnect them, plus let them know they've been disconnected
		set<int> connected = thegraph->getConnectedNodes(inpeer);
		set<int>::iterator sit;
		for ( sit=connected.begin() ; sit != connected.end(); sit++ ){
			thegraph->disconnect(inpeer, *sit); //disconnect them
			DisconnectionQueue.push(buildMessage(*sit, inpeer)); //enqueue a message saying peer "inpeer" disconnects from "*sit"
		}

		thegraph->offline(inpeer);

		if(VERBOSE) cout<<"node "<<msg.value()<<" removed\n";
		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == peer_connect){
		int twonumbers, from, to;
		twonumbers = msg.value();
		from = getPeerId(twonumbers); //first and second field encoding of the peers
		to = getMessageId(twonumbers);
		if(VERBOSE) cout<<"connecting "<<from<<" to "<< to<<"\n";

		if(thegraph->connect(from,to))
			ConnectionQueue.push(buildMessage(to, from, 1)); // enqueue a connection message : adding the TTL makes it different from a disconnect message, further down the road

		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == peer_disconnect){
		int twonumbers, from, to;
		twonumbers = msg.value();
		from = getPeerId(twonumbers); //first and second field encoding of the peers
		to = getMessageId(twonumbers);
		if(VERBOSE) cout<<"disconnecting "<<from<<" and "<< to<<"\n";

		if(thegraph->disconnect(from, to))
			DisconnectionQueue.push(twonumbers); // enqueue the original message to be re-output as confirmation that connection took place

		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == inroute){
		//routing=true;
		int inpeer, TTL, messageId;
		inpeer = getPeerId(msg.value());
		TTL= getTTL(msg.value());
		messageId = getMessageId(msg.value());

		if(VERBOSE) cout<<"about to route a message from"<<inpeer<<"\n";

		//get all the connected nodes and enqueue the "arrival of the message" event for all these new nodes
		//find the nodes connected to this one
		set<int> connected = thegraph->getConnectedNodes(inpeer);

		//if(VERBOSE) cout<<"loop for enqueuing nodes :"<<connected.size()<<" nodes to enqueue";
		set<int>::iterator sit;

		//if(VERBOSE) cout << "connected nodes contains:";
		for ( sit=connected.begin() ; sit != connected.end(); sit++ ){
			//    if(VERBOSE) cout<<"bang!  "<<*sit<<"\n";
			EvQ.push(makeNetworkEvent(messageId, *sit, TTL, 0.0f)); //enqueue a network event with the "*sit" peer (the other parts are not used for now)

			//holdIn( active, Time(0.01f));
		}
	}

	// TEST : no external transition unless we're passive
	if (this->state()==passive){
		holdIn( active, Time(0,0,0,120)); //wait 120ms before doing something
	}

	return *this ;
}
Exemple #4
0
/*******************************************************************
* Function Name: externalFunction
* Description: the Network gets input from outside
********************************************************************/
Model &LTSNetwork::externalFunction( const ExternalMessage &msg ){
		//advance my internal time
	if(VERBOSE) cout<<"External Transition :"<<endl<<"time: "<<msg.time().asMsecs()<<endl;
	currenttimefloat = msg.time().asMsecs();

	if (msg.port() == peer_online)
	{
		thegraph->online(msg.value());   //adds a node to the graph with the given value
		if(VERBOSE) cout<<"node "<<msg.value()<<" inserted\n";

	}
	else if (msg.port() == peer_offline){
		int inpeer = msg.value();

		//get all the connected nodes a disconnect them, plus let them know they've been disconnected
		set<int> connected = thegraph->getConnectedNodes(inpeer);
		set<int>::iterator sit;
		int count = 0;
		for ( sit=connected.begin() ; sit != connected.end(); sit++ ){
			count++;
			thegraph->disconnect(inpeer, *sit); //disconnect them
			EvQ.push(makeDisConnectEvent(inpeer, *sit,currenttimefloat+count)); // enqueue messages to be output with just 1 millisecond delay
			//DisconnectionQueue.push(buildMessage(*sit, inpeer)); //enqueue a message saying peer "inpeer" disconnects from "*sit"
		}

		thegraph->offline(inpeer);

		if(VERBOSE) cout<<"node "<<msg.value()<<" removed\n";
		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == peer_connect){
		int twonumbers, from, to;
		twonumbers = msg.value();
		from = getPeerId(twonumbers); //first and second field encoding of the peers
		to = getMessageId(twonumbers);
		if(VERBOSE) cout<<"connecting "<<from<<" to "<< to<<"\n";

		if(thegraph->connect(from,to))
			EvQ.push(makeConnectEvent(from, to,currenttimefloat+1)); // enqueue message to be output with just 1 millisecond delay
			//ConnectionQueue.push(buildMessage(to, from, 1)); // enqueue a connection message : adding the TTL makes it different from a disconnect message, further down the road

		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == peer_disconnect){
		int twonumbers, from, to;
		twonumbers = msg.value();
		from = getPeerId(twonumbers); //first and second field encoding of the peers
		to = getMessageId(twonumbers);
		if(VERBOSE) cout<<"disconnecting "<<from<<" and "<< to<<"\n";

		if(thegraph->disconnect(from, to))
			EvQ.push(makeDisConnectEvent(from, to,currenttimefloat+1));//DisconnectionQueue.push(twonumbers); // enqueue the original message to be re-output as confirmation that connection took place

		//holdIn( active, Time(0.00f));
	}
	else if (msg.port() == inroute){
		//routing=true;
		int inpeer, TTL, messageId;
		inpeer = getPeerId(msg.value());
		TTL= getTTL(msg.value());
		messageId = getMessageId(msg.value());

		if(VERBOSE) cout<<"about to route a message from"<<inpeer<<"\n";

		//get all the connected nodes and enqueue the "arrival of the message" event for all these new nodes
		//find the nodes connected to this one
		set<int> connected = thegraph->getConnectedNodes(inpeer);

		//if(VERBOSE) cout<<"loop for enqueuing nodes :"<<connected.size()<<" nodes to enqueue";
		set<int>::iterator sit;

		//if(VERBOSE) cout << "connected nodes contains:";
		for ( sit=connected.begin() ; sit != connected.end(); sit++ ){

			//generate a random network delay:
			float delay = static_cast<float>(distribution().get());
			if(VERBOSE) cout<<"enqueueing event for time = "<<currenttimefloat +delay*1000<<"\n";  //delay in milliseconds !
			EvQ.push(makeNetworkEvent(messageId, *sit, TTL, currenttimefloat + (delay*1000))); //enqueue a network event with the "*sit" peer (the other parts are not used for now)


			//holdIn( active, Time(0.01f));
		}

	}



	if (EvQ.empty()){ // this transition didn't enqueue anything
		if(VERBOSE) cout<<"LTS:Event queue is empty. Passivating."<<endl;
		passivate();
	} else {
	//calculate time until next scheduled change :

	float remainingdelay = EvQ.top().time - currenttimefloat; //EvQ.top() is the next NetworkEvent to be output

	if(VERBOSE) cout<<"next change at (ms):"<<EvQ.top().time<<"time until next change (s):"<<remainingdelay/1000<<endl;
	// hold until then
	holdIn(active, Time(remainingdelay/1000)); // time remaining until next scheduled change
	//then it will be time for an internal transition...
	}

	/*/ TEST : no external transition unless we're passive
	if (this->state()==passive){
		holdIn( active, Time(0,0,0,120)); //wait 120ms before doing something
	}*/

	return *this ;
}
Exemple #5
0
/*******************************************************************
* Function Name: externalFunction
* Description: the Network gets input from outside
********************************************************************/
Model &LTSNetwork::externalFunction( const ExternalMessage &msg ){
	//if(VERBOSE) cout<<"coucou\n";
 // if ( this->state() == passive) // in fact all this should happen whatever the state ! TODO !!
 // {
    if (msg.port() == peer_online)
     {

       thegraph->online(msg.value());   //adds a node to the graph with the given value
       if(VERBOSE) cout<<"node "<<msg.value()<<" inserted\n";
       //holdIn( active, Time(0.00f));
     }
    else if (msg.port() == peer_offline){
    	thegraph->offline(msg.value());

    	if(VERBOSE) cout<<"node "<<msg.value()<<" removed\n";
    	//holdIn( active, Time(0.00f));
    }
    else if (msg.port() == peer_connect){
        	int twonumbers, from, to;
        	twonumbers = msg.value();
        	from = floor(twonumbers /1000);
        	to = twonumbers%1000;
        	if(VERBOSE) cout<<"connecting "<<from<<" to "<< to<<"\n";

        	thegraph->connect(from,to);

        	//holdIn( active, Time(0.00f));
        }
    else if (msg.port() == peer_disconnect){
            	int twonumbers, from, to;
            	twonumbers = msg.value();
            	from = floor(twonumbers /1000);
            	to = twonumbers%1000;
            	if(VERBOSE) cout<<"disconnecting "<<from<<" and "<< to<<"\n";

            	thegraph->disconnect(from, to);

            	//holdIn( active, Time(0.00f));
            }
    else if (msg.port() == inroute){
    	//routing=true;
    	int inpeer, TTL, messageId;
    	inpeer = getPeerId(msg.value());
    	TTL= getTTL(msg.value());
    	messageId = getMessageId(msg.value());

    	if(VERBOSE) cout<<"LTS --- about to route a message from "<<inpeer<<"\n";

    	//get all the connected nodes and enqueue the "arrival of the message" event for all these new nodes
    	//find the nodes connected to this one
    	cout<<"LTS --- about to get Connected peers  : \n";

    	/*thegraph->getConnectedNodes(inpeer);
    	cout<<"getConnectedpeers (1) passed\n about to declare another intbag\n";*/
    	set<int> connected;
    	//cout<<"ok--Intbag Declared----------------\nabout to get connected peers again";
    	connected = thegraph->getConnectedNodes(inpeer);
    	//cout<<"ok--after connected peers----------------\n";


    	if(VERBOSE) cout<<"LTS --- loop for enqueuing nodes :"<<connected.size()<<" nodes to enqueue\n";
    	set<int>::iterator sit;

    	  if(VERBOSE) cout << "LTS --- connected nodes contains:";
    	  for ( sit=connected.begin() ; sit != connected.end(); sit++ ){
    	    if(VERBOSE) cout<<*sit<<";";
    		EvQ.push(makeNetworkEvent(messageId, *sit, TTL, 0.0f)); //enqueue a network event with the "*sit" peer (the other parts are not used for now)

    	//holdIn( active, Time(0.01f));
			}
    	  if(VERBOSE) cout<<endl;

  //}

  if (!EvQ.empty()) { // if we were or now are in the process of routing messages

    	holdIn( active, Time(0.03f)); // we wait 0.03s to dequeue

   } else {
    	holdIn( active, Time(0.00f)); // we just passivate immediately
   }



	return *this ;
 }
}
Exemple #6
0
/*******************************************************************
* Function Name: externalFunction
* Description: the router gets input from either the "outside" (a new messgae to route) or from the router (next step for routing)
********************************************************************/
Model &Gnutella::externalFunction( const ExternalMessage &msg ){

	if ( this->state() == passive)
	{
		if (msg.port() == route_in) //new message to route
		{
			//expecting float values looking like 6,123 meaning route from peer 6 with msg id 123 (id<1000)
			//get the peerid, message id, generate new TTL, then put in "to output" variable // not a list ! [id, TTL, peer]
			if(VERBOSE) cout<<"Gnutella : new routing message : "<<msg.value()<<endl;
			int peerid = getPeerId(msg.value());// get originating peer (from value of external msg)
			if(VERBOSE)cout<<" peerid:"<<peerid<<endl;
			int id = getMessageId(msg.value()); // get message id
			if(VERBOSE)cout<<"  message id:"<<id<<endl;



			//create "seen" list. The message ids are float values (that way we can generate them using a random function)
			// to create an empty list I use the default constructor, throught the shortcut of calling the [] operator.
			routingTable[id]; //creates empty set mapped to id
			routingTable[id].insert(peerid); // the new peer has now been visited (because the first thing will be to send himself the message !)

			// we need to propagate this message to the DB and route it in the network (separate issues)
			hitting = true;
			routing = true;
			//set the output values
			// from right, digits 1-3 are id, digits 4-6 are peerid, digit 7 is TTL exampel value : 6005123 = TTL=6, peerid 5, id = 123
			nextOutputDB =  buildMessage(id, peerid);
			nextOutputR =buildMessage(id, peerid, STANDARDTTL); //standardTTL is a constant defined in the h, should be a model parameter

			//if(VERBOSE) cout<<"next output:"<<nextOutputR<<endl;

		}

		else if (msg.port() ==  in_n){
			//expecting value = TTL * 100 + peerid + id, where id is the decimal part (<1)
			if(VERBOSE) cout<<"Gnutella : message from the network routing loop... "<<msg.value()<<"\n";

			long inval = msg.value();

			//extract our 3 values using static functions from complexmessages.h
			int OldTTL = getTTL(inval);
			//if(VERBOSE)cout<<"old ttl:"<<OldTTL<<endl;
			int peerid = getPeerId(inval);
			//if(VERBOSE)cout<<" peerid:"<<peerid<<endl;
			int id = getMessageId(inval);
			//if(VERBOSE)cout<<"  message id:"<<id<<endl;

			//check for already visited peer : search for "peerid" in set mapped to id in routing table
			set<long>::iterator finder = routingTable[id].find(peerid);
			if(finder==routingTable[id].end()){ //it's NOT in there
				//the unseen peer must get the message
				if(VERBOSE)cout<<" peerid:"<<peerid<<"unseen by msg id ="<<id<< endl;
				hitting = true;
				nextOutputDB = buildMessage(id, peerid); // we don't put in a TTL
				// the new peer has now been visited : we add him to the set of seen peers
				routingTable[id].insert(peerid);

				if(OldTTL>0){ // the unseen peer will also propagate the message because it still has some TTL
					routing=true;
					nextOutputR = buildMessage(id, peerid, OldTTL-1); //add the TTL for the routing msg
					if(VERBOSE)cout<<" message will be re-cycled TTL >0 "<< endl;
				}
				else {
					routing = false;
				}
			} else {
				if(VERBOSE)cout<<" peerid:"<<peerid<<"already visited by msg id ="<<id<< endl;
				hitting = false;
				routing = false;
			}

		}

	} //end if state is passive
	else{
		cout<<"error: message received while in active state"<<endl;
	}
	// we have an instantaneous change back to the passive state (will output the next output values where relevant)
	holdIn( active, Time(0.01f));

	return *this ;
}