diff --git a/P8/icmp-timestamp.c b/P8/icmp-timestamp.c deleted file mode 100644 index 34e263e5c1aaa1dda6230b0035c5bca885478b6d..0000000000000000000000000000000000000000 --- a/P8/icmp-timestamp.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - * Practica Tema 8: ICMP-TIMESTAMP - * - * Apellido, Nombre - * Apellido, Nombre - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/time.h> -#include <errno.h> -#include "ip-icmp.h" // Usa las estructuras definidas en este archivo - -#define ICMP_TIMESTAMP 13 -#define ICMP_TIMESTAMP_REPLY 14 -#define TIMEOUT 5 // Tiempo de espera en segundos - -unsigned short checksum(void *b, int len) { - unsigned short *buf = b; - unsigned int sum = 0; - unsigned short result; - - for (sum = 0; len > 1; len -= 2) { - sum += *buf++; - } - if (len == 1) { - sum += *(unsigned char *)buf; - } - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - result = ~sum; - return result; -} - -void print_icmp_error(int type, int code) { - switch (type) { - case 3: - printf("-> Destination Unreachable: "); - switch (code) { - case 0: printf("Net Unreachable\n"); break; - case 1: printf("Host Unreachable\n"); break; - default: printf("Unknown Code\n"); break; - } - break; - default: - printf("-> ICMP Error: Type %d, Code %d\n", type, code); - } -} - -int main(int argc, char *argv[]) { - if (argc < 2 || argc > 3) { - fprintf(stderr, "Uso: %s ip [-v]\n", argv[0]); - exit(EXIT_FAILURE); - } - - int verbose = 0; - const char *ip = argv[1]; - if (argc == 3 && strcmp(argv[2], "-v") == 0) { - verbose = 1; - } - - int sockfd; - struct sockaddr_in dest_addr; - struct timeval start_time, end_time; - unsigned char buffer[1024]; - - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (sockfd < 0) { - perror("Error al crear el socket"); - return EXIT_FAILURE; - } - - memset(&dest_addr, 0, sizeof(dest_addr)); - dest_addr.sin_family = AF_INET; - if (inet_pton(AF_INET, ip, &dest_addr.sin_addr) <= 0) { - perror("Error al convertir la direccion IP"); - return EXIT_FAILURE; - } - - // Construccion del mensaje ICMP - TimeStamp icmp_msg; - memset(&icmp_msg, 0, sizeof(icmp_msg)); - icmp_msg.icmpHdr.type = ICMP_TIMESTAMP; - icmp_msg.icmpHdr.code = 0; - icmp_msg.pid = htons(getpid()); - icmp_msg.sequence = htons(0); - gettimeofday(&start_time, NULL); - icmp_msg.originate = htonl((start_time.tv_sec * 1000) + (start_time.tv_usec / 1000)); - icmp_msg.receive = 0; // Inicializar campo Receive a 0 - icmp_msg.transmit = 0; // Inicializar campo Transmit a 0 - int icmp_length = sizeof(icmp_msg); // Tamaño dinámico en caso de relleno - icmp_msg.icmpHdr.checksum = checksum(&icmp_msg, icmp_length); // Calculo y asignacion del checksum - - - // Enviar el mensaje - if (sendto(sockfd, &icmp_msg, sizeof(icmp_msg), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { - perror("Error al enviar el datagrama"); - return EXIT_FAILURE; - } - if (verbose) { - printf("-> Enviando Datagrama ICMP a Destino con IP: %s\n", ip); - } - - // Configuracion del tiempo de espera - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(sockfd, &readfds); - - struct timeval timeout; - timeout.tv_sec = TIMEOUT; - timeout.tv_usec = 0; - - int sel = select(sockfd + 1, &readfds, NULL, NULL, &timeout); - if (sel == -1) { - perror("Error en select"); - return EXIT_FAILURE; - } else if (sel == 0) { - printf("-> Tiempo de espera agotado para el destino %s.\n", ip); - return EXIT_FAILURE; - } - - // Recibir la respuesta - socklen_t addr_len = sizeof(dest_addr); - if (recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&dest_addr, &addr_len) < 0) { - perror("Error al recibir el datagrama"); - return EXIT_FAILURE; - } - gettimeofday(&end_time, NULL); - - // Excluir cabecera IP - struct iphdr *ip_hdr = (struct iphdr *)buffer; - int ip_header_length = ip_hdr->ihl * 4; - TimeStamp *recv_reply = (TimeStamp *)(buffer + ip_header_length); - - // Verificar el checksum del datagrama recibido - unsigned short recv_checksum = recv_reply->icmpHdr.checksum; - recv_reply->icmpHdr.checksum = 0; // Temporalmente establece a 0 para recalcular - - int recv_len = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&dest_addr, &addr_len); - if (recv_len < 0) { - perror("Error al recibir el datagrama"); - return EXIT_FAILURE; - } - - icmp_length = recv_len - ip_header_length; - if (checksum(recv_reply, icmp_length) != 0) { - fprintf(stderr, "Error: Checksum invalido en el datagrama recibido.\n"); - return EXIT_FAILURE; - } - recv_reply->icmpHdr.checksum = recv_checksum; // Restaurar el valor original - - - if (recv_reply->icmpHdr.type == ICMP_TIMESTAMP_REPLY) { - unsigned long originate = ntohl(recv_reply->originate); - unsigned long receive = ntohl(recv_reply->receive); - unsigned long transmit = ntohl(recv_reply->transmit); - unsigned long t4 = (end_time.tv_sec * 1000) + (end_time.tv_usec / 1000); - unsigned long rtt = (receive - originate) + (t4 - transmit); - - // Mensajes que se imprimen siempre - printf("-> Timestamp Reply recibido desde %s\n", ip); - printf("-> Respuesta Correcta (Type %d, Code %d)\n", recv_reply->icmpHdr.type, recv_reply->icmpHdr.code); - - // Mensajes que solo se imprimen con -v - if (verbose) { - printf("-> Originate (recibido): %lu\n", originate); - printf("-> Receive (recibido): %lu\n", receive); - printf("-> Transmit (recibido): %lu\n", transmit); - printf("-> T4 (local): %lu\n", t4); - printf("-> RTT: %lu ms\n", rtt); - printf("-> TTL: %d\n", ip_hdr->ttl); - printf("-> Tamanyo del Datagrama: %zu bytes\n", sizeof(buffer)); - } - - // Si algun tiempo es 0, el destino no ha procesado los campos - if (receive == 0 || transmit == 0) { - fprintf(stderr, "Error: El destino no procesa correctamente los campos Receive (%lu) o Transmit (%lu).\n", receive, transmit); - return EXIT_FAILURE; - } - - // Error si: el tiempo en que se recibio el mensaje es menor al tiempo en que se envio, - // el tiempo en que se transmitio la respuesta es menor que el tiempo en que se recibio, - // o el tiempo en que se recibio la respuesta del origen (t4) es menor al tiempo de transmision de la respuesta - if (receive < originate || transmit < receive || t4 < transmit) { - fprintf(stderr, "Error: Valores de marcas de tiempo inconsistentes.\n"); - return EXIT_FAILURE; - } - - } else { - print_icmp_error(recv_reply->icmpHdr.type, recv_reply->icmpHdr.code); - } - - - close(sockfd); - return EXIT_SUCCESS; -}