From 5c974d1f80d6bbbcbbe7138fec974a79379702b2 Mon Sep 17 00:00:00 2001 From: Franciszek Malinka Date: Tue, 16 Mar 2021 19:31:22 +0100 Subject: pracownia 1 z sieci --- Semestr 4/sieci/pracownia1/traceroute.c | 106 ++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Semestr 4/sieci/pracownia1/traceroute.c (limited to 'Semestr 4/sieci/pracownia1/traceroute.c') diff --git a/Semestr 4/sieci/pracownia1/traceroute.c b/Semestr 4/sieci/pracownia1/traceroute.c new file mode 100644 index 0000000..7918957 --- /dev/null +++ b/Semestr 4/sieci/pracownia1/traceroute.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_TTL 30 +#define MESSAGES_PER_TTL 3 + +void print_as_bytes (unsigned char* buff, ssize_t length) +{ + for (ssize_t i = 0; i < length; i++, buff++) + printf ("%.2x ", *buff); +} + +struct sockaddr_in get_sockaddr_from_ip(char *ip) { + struct sockaddr_in sock; + bzero(&sock, sizeof(sock)); + sock.sin_family = AF_INET; + if (!inet_pton(AF_INET, ip, &sock.sin_addr)) { + fprintf(stderr, "Given ip is invalid: %s\n", ip); + exit(EXIT_FAILURE); + } + return sock; +} + +int create_raw_icmp_socket() { + int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (sockfd < 0) { + fprintf(stderr, "socket error: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + return sockfd; +} + +uint16_t compute_icmp_checksum (const void *buff, int length) +{ + uint32_t sum; + const uint16_t* ptr = buff; + assert (length % 2 == 0); + for (sum = 0; length > 0; length -= 2) + sum += *ptr++; + sum = (sum >> 16) + (sum & 0xffff); + return (uint16_t)(~(sum + (sum >> 16))); +} + +struct icmp create_icmp_header() { + static uint16_t pid = 0; + static uint16_t seq = 0; + + struct icmp header; + header.icmp_type = ICMP_ECHO; + header.icmp_code = 0; + header.icmp_id = ++pid; + header.icmp_seq = ++seq; + header.icmp_cksum = 0; + header.icmp_cksum = compute_icmp_checksum( + (uint16_t*)&header, sizeof(header)); + + return header; +} + +void send_icmp_packet(int sockfd, struct sockaddr_in *destination, int ttl) { + struct icmp header = create_icmp_header(); + setsockopt(sockfd, IPPROTO_IP, IP_TTL, &ttl, sizeof(int)); + + printf("%ld %d\n", destination->sin_addr.s_addr, sockfd); + ssize_t bytes_sent = sendto( + sockfd, + &header, + sizeof(header), + 0, + (struct sockaddr*)destination, + sizeof(*destination) + ); + if (bytes_sent == -1) { + fprintf(stderr, "Error while sending ICMP packet: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(stdout, "Bytes sent: %ld\n", bytes_sent); +} + +int traceroute(struct sockaddr_in *destination) { + int sockfd = create_raw_icmp_socket(); + + struct sockaddr_in sender; + socklen_t sender_len = sizeof(sender); + uint8_t buffer[IP_MAXPACKET]; + for (int ttl = 1; ttl <= MAX_TTL; ++ttl) { + send_icmp_packet(sockfd, destination, ttl); + } +} + +int main(int argc, char * argv[]) { + if (argc < 2) { + fprintf(stderr, "Usage:\n\t%s [host ip]\n", argv[0]); + return 1; + } + + struct sockaddr_in destination = get_sockaddr_from_ip(argv[1]); + traceroute(&destination); +} \ No newline at end of file -- cgit v1.2.3