Exemplo n.º 1
0
void Router::forward_incoming_data_packet(Packet* p){
	if( p == NULL){ //check for null packet
		std::cout << "Rxed packet is NULL !\n";
		exit(1);
	}
	std::cout << "Rxed data packet which ll be forwarded is:\n";
	print_data_packet(p);
	//Correct packets will be sent to correct ports
	send_data_packet(p);
}
Exemplo n.º 2
0
void Router::send_data_packet(Packet* p){
	//std::cout << "The following packet ll be sent:" << std::endl;
	//print_data_packet(p);
			
	PacketHdr *hdr = p->accessHeader();
	char num_addr = hdr->getOctet(NUM_ADDR_INDEX);
	int int_num_addr = (int)(num_addr-'0');
	
	
	if(int_num_addr == 1 && hdr->getOctet(NUM_ADDR_INDEX+1) == id){ //if the packet is uni and targeted to me
		std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
		std::cout << "DATA PACKET TARGETED TO ME IS RXED: \n";
		print_data_packet(p);
		std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
		return;
	}
	int* f_ports = forward_rxed_data_packet_to_port(p);
	//Use the "goodness" of at most 3 MC receivers
	std::vector <int> ports_done;
	std::vector <char> temp_dests;
	
	for(int i=0; i<int_num_addr; i++){
		int curr_port = f_ports[i];
		temp_dests.clear();
		if(std::find(ports_done.begin(), ports_done.end(), curr_port) == ports_done.end()){ //not contained
			temp_dests.push_back(hdr->getOctet(NUM_ADDR_INDEX+i+1));
			for(int j=i+1; j<int_num_addr; j++){
				if(curr_port == f_ports[j])
					temp_dests.push_back(hdr->getOctet(NUM_ADDR_INDEX+j+1));
			}
			char* dest_addrs = new char[temp_dests.size()+1];
			for(int k=0; k<temp_dests.size(); k++){
				dest_addrs[k] = temp_dests.at(k);
			}
			dest_addrs[temp_dests.size()] = (char)'\0';
			//hdr->getOctet(PAYLOAD_SIZE_INDEX(temp_dests.size()))
			int payload_size = strlen(p->getPayload());
			char* payload = new char[payload_size];
			strcpy(payload, p->getPayload());
			Packet* new_p = create_data_packet('m', (char)((int)(hdr->getOctet(TTL_INDEX)-'0')-1), 
																			hdr->getOctet(SRC_ADDR_INDEX),
																			'0'+temp_dests.size(), dest_addrs,
																			payload_size,	payload);
			send_packet_over_port(new_p, curr_port);
			//std::cout << "The following packet ll be sent over port:" << curr_port << std::endl;
			//print_data_packet(p);
			//
			ports_done.push_back(curr_port);
		}
	}
	
}
Exemplo n.º 3
0
void Router::send_packet_over_port(Packet* p, int port){
	
	char correspoding_nhop = port_nhop.find(port)->second;
	for(int i=0; i<num_neighbors; i++){
		if(nbr_tbl.at(i).id[0] == correspoding_nhop){ //corresponding port index -> i
			//send disc message
			try{
				std::cout << "==================================\n";
				std::cout << "The following packet is being sent over TxP:" << nbr_tbl.at(i).TxP
								  << "_DstP:" << nbr_tbl.at(i).DstP << std::endl;
				print_data_packet(p);
				std::cout << "==================================\n";
				txing_ports[i]->sendPacket(p);
			}catch(const char *reason){
				cerr << "Exception:" << reason << endl;
			}
		}
	}
}
Exemplo n.º 4
0
int arp_hijack(struct conn_info *ci, char *src_fake_mac, char *dst_fake_mac,
	       int input_mode)
{
	struct iphdr *iph;
	struct tcphdr *tcph;
	struct tcp_spec ts;
	struct ifunc_item ifunc_dst, ifunc_src;
	struct packet *p;
	int count_dst = 0, count_src = 0;
	pthread_t thr_tty;
	struct watch_tty_data wtd;

	asi_src = asi_dst = NULL;
	
	dont_relay = arp_dont_relay_insert(ci->src_addr, ci->dst_addr,
	 	 		           ci->src_port, ci->dst_port);
	if (src_fake_mac) {
		if (!(asi_src = start_arp_spoof(ci->src_addr, ci->dst_addr, NULL, NULL, NULL, 0, 0, 0))) {
			asi_src = start_arp_spoof(ci->src_addr, ci->dst_addr,
			  		      ci->src.src_mac, ci->dst.src_mac,
					      src_fake_mac, 0, 0, 0);
		}
	} else
		asi_src = get_arp_spoof(ci->src_addr, ci->dst_addr);
	if (asi_src && user_arpspoof_test(asi_src)) {
		if (user_run_arpspoof_until_successed(asi_src)) {
			set_tty_color(COLOR_BRIGHTRED);
			printf("ARP spoof of %s in host %s FAILED\n",
			       host_lookup(asi_src->src_addr, hl_mode),
			       host_lookup(asi_src->dst_addr, hl_mode));
			set_tty_color(COLOR_LIGHTGRAY);
			fflush(stdout);
			if (src_fake_mac)
				stop_arp_spoof(asi_src);
			asi_src = NULL;
		}
	}
	if (dst_fake_mac) {
		if (!(asi_dst = start_arp_spoof(ci->dst_addr, ci->src_addr, NULL, NULL, NULL, 0, 0, 0))) {
			asi_dst = start_arp_spoof(ci->dst_addr, ci->src_addr,
					      ci->dst.src_mac, ci->src.src_mac,
					      dst_fake_mac, 0, 0, 0);
		}
	} else
		asi_dst = get_arp_spoof(ci->dst_addr, ci->src_addr);
	
	if (asi_dst && user_arpspoof_test(asi_dst)) {
		if (user_run_arpspoof_until_successed(asi_dst)) {
			set_tty_color(COLOR_BRIGHTRED);
			printf("ARP spoof of %s in host %s FAILED\n",
			       host_lookup(asi_dst->src_addr, hl_mode),
			       host_lookup(asi_dst->dst_addr, hl_mode));
			set_tty_color(COLOR_LIGHTGRAY);
			fflush(stdout);
			if (dst_fake_mac)
				stop_arp_spoof(asi_dst);
			asi_dst = NULL;
		}
	}
	set_tty_color(COLOR_WHITE);
	printf("you took over the connection\n");
	set_tty_color(COLOR_BRIGHTRED);
	printf("CTRL-] to break\n");
	set_tty_color(COLOR_LIGHTGRAY);
	fflush(stdout);

	wtd.src_fake_mac = asi_src ? asi_src->src_fake_mac : ci->src.src_mac;
	wtd.ci = ci;
	wtd.input_mode = input_mode;
	
	list_produce_start(&l_hijack_conn);
	pthread_create(&thr_tty, NULL, (void *(*)(void *)) watch_tty, &wtd);
	
	ifunc_dst.func = (void(*)(struct packet *, void *)) func_hijack_dst;
	ifunc_dst.arg = ci;
	list_enqueue(&l_ifunc_tcp, &ifunc_dst);
	ifunc_src.func = (void(*)(struct packet *, void *)) func_hijack_src;
	ifunc_src.arg = ci;
	list_enqueue(&l_ifunc_tcp, &ifunc_src);
	
	while ((p = list_consume(&l_hijack_conn, NULL))) {
		iph = p->p_iph;
		tcph = p->p_hdr.p_tcph;
		if (iph->saddr == ci->dst_addr &&
		    iph->daddr == ci->src_addr &&
		    tcph->source == ci->dst_port &&
		    tcph->dest == ci->src_port) {
			/* packet from dest */
			if (p->p_data_len) {
				print_data_packet(p, p->p_data_len, ++count_dst, 1);
				packet_free(p);
				/* send ACK */
				memset(&ts, 0, sizeof(ts));
				ts.saddr = ci->src_addr;
				ts.daddr = ci->dst_addr;
				ts.sport = ci->src_port;
				ts.dport = ci->dst_port;
				ts.src_mac = asi_src ? asi_src->src_fake_mac :
						ci->src.src_mac;
				ts.dst_mac = ci->dst.src_mac;
				ts.seq = ci->dst.next_d_seq;
				ts.ack_seq = ci->dst.next_seq;
				ts.window = ci->src.window ? ci->src.window : htons(242);
				ts.id = htons(ntohs(ci->src.id) + 1);
				ts.ack = 1;
				ts.psh = 1;
				ts.rst = 0;
				ts.data = NULL;
				ts.data_len = 0;
				send_tcp_packet(&ts);
			} else
				packet_free(p);
		} else {
			if (p->p_data_len) {
				/* packet from source */
				print_data_packet(p, p->p_data_len, ++count_src, 0);
				memset(&ts, 0, sizeof(ts));
				ts.saddr = ci->dst_addr;
				ts.daddr = ci->src_addr;
				ts.sport = ci->dst_port;
				ts.dport = ci->src_port;
				ts.src_mac = asi_dst ? asi_dst->src_fake_mac : 
							ci->dst.src_mac;
				ts.dst_mac = ci->src.src_mac;
				ts.seq = ci->src.next_d_seq;
				ts.ack_seq = ci->src.next_seq;
				ts.window = ci->dst.window ? ci->dst.window : 
							htons(242);
				ts.id = htons(ntohs(ci->dst.id) + 1);
				ts.ack = 1;
				ts.psh = 1;
				ts.rst = 0;
				if (p->p_data[0] == '\r' || p->p_data[0] == '\n') {
					ts.data = "\r\n$ ";
					ts.data_len = 4;
				} else {
					ts.data = p->p_data;
					ts.data_len = p->p_data_len;
				}
				send_tcp_packet(&ts);
			}
			packet_free(p);
		}
	}
	list_remove(&l_ifunc_tcp, &ifunc_dst);
	list_remove(&l_ifunc_tcp, &ifunc_src);
	packet_flush(&l_hijack_conn);
	pthread_join(thr_tty, NULL);

	return 0;
}
void process_inbound_udp(int sock) {
    struct sockaddr_in from;
    socklen_t fromlen;
    char buf[MAX_PACKET_LENGTH];

    fromlen = sizeof(from);
    int read_result = spiffy_recvfrom(sock, buf, MAX_PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlen);
    printf("read %d bytes\n", read_result);
    //printf("incoming message from %s:%d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port));

    /* we just assume we got one packet everytime
     * if there are multiple packets in the buffer (whichi is rare), we just ignore them,
     * and everything will just work fine.
     */
    struct network_packet_s* network_packet = (struct network_packet_s*)buf;
    net_to_host_header(& network_packet->header);
    print_packet_header(&network_packet->header);
    if(validate_packet(& network_packet->header) < 0){
        printf("packet is invalid, skip\n");
        return;
    }
    int packet_type = get_packet_type(& network_packet->header);
    /* get the peer who send this packet*/
    bt_peer_t* peer = search_bt_peer(&config, (struct sockaddr *)&from);
    switch(packet_type) {
        case TYPE_WHOHAS: {
            struct network_packet_s* ihave_packet = malloc_ihave_packet(network_packet);
            /* this node has no such chunk */
            if(ihave_packet == NULL){
                return;
            }
            else{
                //print_ihave_packet(ihave_packet);
                send_packet(ihave_packet, global_socket, (struct sockaddr *) &from);
                free(ihave_packet);
            }
            break;
        }
        case TYPE_IHAVE: {
            if(current_job == NULL){
                return;
            }
            /* receiving a new IHAVE packet */
            /* check whether there is alreay a connection with this peer */
            struct receiver_connection_s* existing_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            if(existing_connection != NULL){
            /* there is alreay a connection */
                add_ihave_to_receiver_connection(existing_connection, network_packet);
            }
            /* there is no such connection */
            else{
                /* check if the number of connection reached the maximum */
                if(get_receiver_connection_number(receiver_connection_head) >=
                        max_receiver_connection){
                    return;
                }
                /* add add the hash whose chunk is in a CHUNK_STATUS_NOT_FOUND status 
                 * to a new connection
                 */
                else{
                    struct receiver_connection_s*  new_connection = 
                        malloc_receiver_connection(network_packet, peer);
                    /* if every chunk has a provider, the new_connection is NULL */
                    if(new_connection != NULL){
                        add_receiver_connection(new_connection);
                        /* start the new connection */
                        struct network_packet_s* get_packet = start_connection(new_connection);
                        //print_get_packet(get_packet);
                        free(get_packet);
                    }   
                }
            }
            //print_receiver_connection_list(receiver_connection_head);
            break;
        }
        case TYPE_GET: {
            //print_get_packet(network_packet);
            /* check whether there is alreay a connection with this peer */
            if(search_provider_connection(provider_connection_head, peer) != NULL){
                printf("Provider connection already exists with peer %d , ignore GET\n", peer->id);
                return;
            }
            /* do nothing is the number of connection reached the maximum*/
            if(get_provider_connection_number(provider_connection_head) >=
                    max_provider_connection){
                printf("Provider connection reached maximum with peer %d \n", peer->id);
                return;
            }
            struct provider_connection_s* new_connection = 
                    malloc_provider_connection(network_packet, peer);
            if(new_connection != NULL){
                printf("Add new provider connection with peer %d \n", peer->id);
                add_provider_connection(new_connection);
                //print_provider_connection(new_connection);
            }
            //print_provider_connection_list(provider_connection_head);
            break;
        }
        case TYPE_DATA: {
            print_data_packet(network_packet);
            printf("received data packet, seq: %d, ack: %d\n ",
                network_packet->header.seq_number,
                network_packet->header.ack_number);

            /* check whether there is a connection with this peer */
            struct receiver_connection_s* receiver_connection = 
                    search_receiver_connection(receiver_connection_head, peer);
            /* connection does not exist, ignore the data packet */
            if(receiver_connection == NULL){
                return;
            }
            int existing_seq_num = receiver_connection->chunk_list_head->chunk->received_seq_num;
            printf("expected data packet, seq: %d \n", 1 + existing_seq_num);
            int packet_seq_num = network_packet->header.seq_number;
            /* sequence number is illegal */
            if(packet_seq_num < 0){
                return;
            }
            /* old packet arrived, do nothing */
            else if(packet_seq_num  < (existing_seq_num + 1)){
                return;
            } 
            /* latter packet arrived first, send duplicate ACK */
            else if(packet_seq_num  > (existing_seq_num + 1)){
                struct network_packet_s* ack_packet = malloc_ack_packet(existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                return;
            }
            /* the packet expected */
            else{
                gettimeofday(&receiver_connection->last_data_time, NULL);
                receiver_connection->status = RECEIVER_STATUS_RECEIVED_DATA;

                struct network_packet_s* ack_packet = malloc_ack_packet(1 + existing_seq_num);
                send_packet(ack_packet, global_socket, (struct sockaddr *) &from);
                free(ack_packet);
                
                /* save_data_packet */
                save_data_packet(network_packet, receiver_connection);
                /* save the downloading chunk of the connnection, if it finihsed */
                save_chunk(receiver_connection);
                /* continue to download next chunk, if finished first one */
                reset_receiver_connection(receiver_connection);
            } 
            break;
        }
        case TYPE_ACK: {
            //print_ack_packet(network_packet);
            struct provider_connection_s* provider_connection = 
                    search_provider_connection(provider_connection_head, peer);
            if(provider_connection == NULL){
                return;
            }
            provider_control_by_ack(provider_connection, 
                    network_packet->header.ack_number);
            /* check if the data has been all send to a receiver */
            if(provider_connection->last_packet_acked == CHUNK_DATA_NUM){
                /* download finished */
                finish_provider_connection(provider_connection);
            }
            break;
        }
        case TYPE_DENIED: {
            break;
        }
        default:{
            break;
        }
    }
}