示例#1
0
int get_source_ipv4(int protocol, struct sockaddr_in * address)
{
    /* Voir la section NOTES du man(2) de gethostname pour la taille
     * du buffer.
     */
    char buffer[HOST_NAME_MAX+1];
    gethostname(buffer, HOST_NAME_MAX+1);

    int success = get_ipv4(buffer, protocol, address);

    /* Workaround pour obtenir une adresse de la machine.
     *
     * Sur certaines machines getaddrinfo retourne pour unique adresse 127.0.0.1
     * lorsqu'on donne le hostname de la machine...
     * Sur d'autres elle retourne bien les adresses des interfaces
     * de la machine.
     *
     * De même avec les « vrais » ping et traceroute:
     * `ping localhost` et `ping <hostname de la machine>` vont tous deux se faire sur
     * 127.0.0.1, mais sur d'autres machines se feront sur deux adresses différentes.
     * Configuration des machines ? Versions des logiciels ? ...?
     *
     * Avec ça, ça fonctionne partout :
     */
    const in_addr_t REFUSED_IPV4 = inet_addr("127.0.0.1");
    if (address->sin_addr.s_addr == REFUSED_IPV4)
        success = get_interface_ipv4(address);

    return success;
}
示例#2
0
文件: anna.c 项目: Harenome/Anna-Lise
int anna(const char * hostname)
{
    int success;
    struct sockaddr_in address;
    struct timeval wait_time = { 1, 0 };

    succeed_or_die(success, 0, get_ipv4(hostname, IPPROTO_ICMP, &address));

    int sockfd;
    succeed_or_die(success, 0, create_raw_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP, &sockfd));

    set_handler();

    int i;
    for (i = 0; fin_des_temps == 1; i++)
    {
        printf("Discovering new route:\n");
        printf("----------------------\n");
        succeed_or_die(success, 0, traceroute_icmp_v4(hostname, 64, 3, 64, &wait_time));
        printf("\n");
        printf("Pinging:\n");
        printf("--------\n");
        ping_v4(hostname);
        printf("\n");
    }
    printf("traceroute and pinging done %d time(s).\n", i);

    close(sockfd);

    return success;
}
示例#3
0
void set_interface(interface *inter, struct ifaddrs *ifa)
{
  get_name(inter,ifa->ifa_name);
  get_status(inter,ifa);
  if (ifa->ifa_addr->sa_family == AF_INET)
  {
    get_ipv4(inter,ifa);
    get_mask(inter,ifa);
  }

  if (ifa->ifa_addr->sa_family == AF_INET6)
    get_ipv6(inter,ifa);

  if (ifa->ifa_addr->sa_family == AF_PACKET)
    get_hwaddr(inter,ifa);
}
int main(int argc, char **argv) {
  int raw_mode = 0;
  struct GlobalHeader ghead;

  // parameter check
  if(argc == 1) {
    raw_mode = 0;
  } else if(argc == 2) {
    if(0 != strcmp(argv[1], "-r")) {
      usage();
      return 0;
    }
    raw_mode = 1;
  } else {
    usage();
    return 0;
  }

  // read global header
  if(!raw_mode) {
    // XXX Should check link type and record snapshot length.
    fread(&ghead, sizeof(unsigned char), sizeof(struct GlobalHeader), stdin);
    if(ghead.magic != MAGIC_NUMBER) {
      printf("invalid file format\n");
      return 0;
    }
    printf("PCAP format v%d.%d, ", ghead.majorver, ghead.minorver);
    if(ghead.linklayertype != 1) {
      printf("unsupported link layer type\n");
      return 0;
    }
    printf("link layer type: Ethernet.\n");
  }

  // read each packet
  while (1) {
    int i;
    struct PacketHeader phead;
    struct EthernetHeader ehead;

    printf("\n");

    // packet header
    if (!raw_mode) {
      // XXX Should use length information in decoding below.
      if(sizeof(struct PacketHeader) != fread(&phead, sizeof(unsigned char), sizeof(struct PacketHeader), stdin)) break;
      if(phead.packetsize > ghead.snapshotlength) {
	printf("wrong packet at 0x%08x\n", (int)ftell(stdin));
	return 0;
      }
      printf("<<<PCAP packet\n");
      printf("    packet size: %d\n", phead.packetsize);
      printf("    payload size: %d\n", phead.payloadsize);
    }

    // data captured from wire
    get_ether(&ehead);
    print_ether(&ehead);

    if (ehead.length_type <= 1500) {
      // old style packet
      printf("Old style packet, length = %d\n", ehead.length_type);
      printf("We don't support this packet now\n");
      if (!raw_mode) {
	dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else if (ehead.length_type == 0x0800) {
      // ASSIGNMENT: MODIFY THIS TO PRINT INFORMATION ABOUT ENCAPSULATED PAYLOAD.
      struct IPv4Header ipv4head;
      get_ipv4(&ipv4head);
      print_ipv4(&ipv4head);

      if(ipv4head.protocol == 4) {
	printf("IP packet\n");
	printf("Wedon't support this packet now\n");
	dump(ipv4head.datalen-sizeof(ipv4head), 1);
      } else if(ipv4head.protocol ==  6) {
	struct TCPHeader tcphead;
	get_tcp(&tcphead);
	print_tcp(&tcphead);

	// get payload in TCP packet
	//dump(ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead), 2);
	if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) {
	  dump(ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead), 0);
	} else {
	  dump((ipv4head.datalen-sizeof(ipv4head)-sizeof(tcphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0);
	}
      } else if(ipv4head.protocol == 17) {
	struct UDPHeader udphead;
	get_udp(&udphead);
	assert(udphead.size == ipv4head.datalen-sizeof(ipv4head));
	print_udp(&udphead);

	// get payload in UDP packet
	if(phead.packetsize >= sizeof(ehead)+ipv4head.datalen) {
	  dump(udphead.size-sizeof(udphead), 0);
	} else {
	  dump((udphead.size-sizeof(udphead))-(sizeof(ehead)+ipv4head.datalen-phead.packetsize), 0);
	}
      } else {
	printf("Unexpected IP packet\n");
	dump(ipv4head.datalen-sizeof(ipv4head), 1);
      }

      if(!raw_mode) {
	if(phead.packetsize > sizeof(ehead)+ipv4head.datalen) {
	  printf("pad:\n");
	  dump(phead.packetsize-sizeof(ehead)-ipv4head.datalen, 1);
	}
      }
    } else if(ehead.length_type == 0x0806) {
      printf("ARP packet\n");
      printf("We don't support this packet now\n");
      if (!raw_mode) {
	dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else if(ehead.length_type == 0x86DD) {
      printf("IPv6 packet\n");
      printf("We don't support this packet now\n");
      if (!raw_mode) {
	dump(phead.packetsize-sizeof(ehead), 1);
      }
    } else {
      printf("Unexpected Ethernet packet\n");
      if (!raw_mode) {
	dump(phead.packetsize-sizeof(ehead), 1);
      }
    }
  }
  return 0;
}
示例#5
0
int
do_recv (const char *answer)
{
	if (get_ipv4 () < 0)
	{
		fprintf (stderr, "ERROR on getting IPv4 address, exiting...\n");
		return -1;
	}
	
	struct sockaddr_in my_addr, peer_addr;
	
	unsigned int file_size = 0, total_bytes_read = 0, tmp_file_size;
	ssize_t nread = 0, tx = 0;
	size_t socket_len = 0;
	void *filebuffer = NULL;
	char *filename = NULL;
	char yes_or_no[2], hash[33];
	
	/* Info sul server locale */
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = 15000;
	my_addr.sin_addr.s_addr = INADDR_ANY;
	
	init_signals ();

	if ((fsd.sockd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
	{
		fprintf (stderr, "Error on socket creation\n");
		return -1;
	}

	if (bind (fsd.sockd, (struct sockaddr *) &my_addr, sizeof (struct sockaddr_in)) < 0)
	{
		fprintf (stderr, "Bind error\n");
		return -1;
	}
	
	if (listen (fsd.sockd, 10) < 0)
	{
		fprintf (stderr, "Error on listen");
		return -1;
	}
	
	new_conn:
	socket_len = sizeof (peer_addr);
	if ((fsd.newsockd = accept (fsd.sockd, (struct sockaddr *) &peer_addr, (socklen_t *) &socket_len)) < 0)
	{
		fprintf (stderr, "Connection error (accept)\n");
		return -1;
  	}
	
	file_size = total_bytes_read = nread = 0;
	memset( yes_or_no, 0, sizeof (yes_or_no));
	if (recv (fsd.newsockd, &file_size, sizeof (file_size), 0) < 0)
	{
		fprintf(stderr, "Error on receiving the file name length\n");
   		return -1;
	}
	
	filename = (char *) malloc (file_size);
	if (filename == NULL)
	{
		fprintf(stderr, "Error during filename memory allocation\n");
		return -1;
	}
	if (recv (fsd.newsockd, filename, file_size, 0) < 0)
	{
   		fprintf(stderr, "Error on receiving the file name\n");
   		free(filename);
   		return -1;
	}
	file_size = 0;
	if (recv (fsd.newsockd, &file_size, sizeof(file_size), 0) < 0)
	{
		fprintf (stderr, "Error on receiving the file size\n");
   		free (filename);
		return -1;
	}
    
	if (strcmp (answer, "y") == 0)
	{
		strcpy (yes_or_no, "Y");
		goto auto_accept;
	}

	printf ("Do you want to receive the file '%s' which size is '%"PRIu32"' bytes? (Y or N)\n", filename, file_size);
	
	another_yorn:
	if(scanf("%1s", yes_or_no) == EOF)
	{
	   	fprintf (stderr, "Scanf error\n");
		free (filename);
		return -1;
	}
	yes_or_no[0] = toupper (yes_or_no[0]);
	if (strcmp (yes_or_no, "Y") != 0)
	{
	   	if (strcmp (yes_or_no, "N") != 0)
	   	{
			printf ("You have to write Y or N, try again: ");
			memset (yes_or_no, 0, sizeof (yes_or_no));
			goto another_yorn;
		}
	}
	auto_accept:
	if (strcmp (yes_or_no, "N") == 0)
	{
	   	printf ("Transfer aborted\n");
		if (send (fsd.newsockd, yes_or_no, 2, 0) < 0)
		{
			printf ("Error on sending N\n");
			free (filename);
			return -1;   
		}
		close (fsd.newsockd);
		free (filename);
		goto new_conn;
	}
	else
	{
		if (send (fsd.newsockd, yes_or_no, 2, 0) < 0)
		{
			fprintf (stderr, "Error on sending Y\n");
			free (filename);
			return -1;
		}
	}
	
	tmp_file_size = file_size;
	filebuffer = malloc (file_size);
	if (filebuffer == NULL)
	{
		fprintf (stderr, "Error during filebuffer memory allocation\n");
		free (filename);
		return -1;
	}
	
	fsd.fd = open (filename, O_CREAT | O_WRONLY, 0644);
	if (fsd.fd  < 0)
	{
		fprintf (stderr, "Error during file opening\n");
		free (filename);
		free (filebuffer);
   	  	return -1;
	}
	tx = 0;
	while((total_bytes_read != file_size) && ((nread = read(fsd.newsockd, filebuffer, tmp_file_size)) > 0))
	{
		tx += nread;
		printf ("\r%zd%%", (tx * 100 / file_size));
   	  	if (write (fsd.fd, filebuffer, nread) != nread)
   	  	{
			fprintf (stderr, "Write error\n");
			free (filename);
  		  	free (filebuffer);
			return -1;
   		}
   	  	total_bytes_read += nread;
   	  	tmp_file_size -= nread;
	}
	char *file_md5 = check_md5 (filename);
	if (recv (fsd.newsockd, hash, 33, 0) < 0)
	{
		fprintf (stderr, "Error on receiving file md5\n");
		free (filename);
		free (file_md5);
		return -1;
	}
	if (strcmp (file_md5, hash) == 0)
	{
		memset (yes_or_no, 0, sizeof(yes_or_no));
		strcpy (yes_or_no, "Y");
		if (send (fsd.newsockd, yes_or_no, 2, 0) < 0)
		{
			free (filename);
			free (file_md5);
			return -1;
		}
		printf ("\n--> File successfully received\n");
	}
	else
	{
	  	memset (yes_or_no, 0, sizeof (yes_or_no));
		strcpy (yes_or_no, "N");
		if (send (fsd.newsockd, yes_or_no, 2, 0) < 0)
		{
			close (fsd.newsockd);
			close (fsd.fd);
			free (filename);
			free (file_md5);
			goto new_conn;
		}
		printf ("\n--> File transfer FAILED, md5sum doesn't match\n");
	}
	
	free (file_md5);
	close (fsd.fd);
	free (filename);
	free (filebuffer);
	close (fsd.newsockd);
	goto new_conn;
}
示例#6
0
文件: anna.c 项目: Harenome/Anna-Lise
static inline int ping_v4(const char * hostname)
{
    int sockfd;
    struct sockaddr_in address;
    icmp4_packet packet;

    int success = get_ipv4(hostname, IPPROTO_ICMP, &address);
    printf("ping ");
    print_host_v4(&address);
    printf("\n");
    succeed_or_die(success, 0, create_raw_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP, &sockfd));
    succeed_or_die(success, 0, icmp4_packet_init(&packet, extract_ipv4(&address)));
    succeed_or_die(success, 0, icmp4_packet_set_length(&packet, sizeof packet));

    int sent = 0;
    int i = 0;
    int gotten = 0;
    struct timeval wait_time = { 1, 0 };
    long double min = 0.;
    long double max = 0.;
    long double sum = .0;
    struct timeval ping_start = { 0, 0 };
    struct timeval ping_end = { 0, 0 };
    gettimeofday(&ping_start, NULL);
    while (success == 0 && fin_des_temps == 1)
    {
        struct timeval start = { 0, 0 };
        struct timeval end = { 0, 0 };

        succeed_or_die(success, 0, icmp4_packet_set_echo_seq(&packet, i));
        gettimeofday(&start, NULL);
        if (sendto(sockfd, &packet, sizeof packet, 0, (struct sockaddr *) &address, sizeof address) == sizeof packet)
        {
            sent++;
            icmp4_packet received;
            memset(&received, 0, sizeof received);
            int before = gotten;
            if (receive_icmp_v4(sockfd, &address, &wait_time, &received) == 0)
            {
                if (received.icmp_header.type == ICMP_ECHOREPLY
                    && received.icmp_header.un.echo.sequence == i
                    && received.icmp_header.un.echo.id == packet.icmp_header.un.echo.id
                    )
                {
                    gotten++;
                    gettimeofday(&end, NULL);
                    struct timeval diff = diff_timeval(start, end);
                    long double rtt = extract_time(diff);
                    update_statistics(&min, &max, &sum, rtt, gotten, before);
                    print_received(&received, &address, rtt);

                    if (rtt > sum / gotten * 2 || rtt < sum / gotten / 2)
                        success = -1;
                }
            }
            if ((float) gotten / sent < 0.7)
                success = -1;
        }
        i++;
        sleep(1);
    }
    gettimeofday(&ping_end, NULL);
    struct timeval total = diff_timeval(ping_start, ping_end);
    print_ping_statistics(sent, gotten, min, max, sum, total, &address);

    return success;

}