diff --git a/P8/L110-Prac8.c b/P8/L110-Prac8.c deleted file mode 100644 index 30d77d4edefc81f4de871ea9abedf8fabb8e5daa..0000000000000000000000000000000000000000 --- a/P8/L110-Prac8.c +++ /dev/null @@ -1,193 +0,0 @@ -/** - * Practica Tema 8: ICMP-TIMESTAMP - * - * Redondo Calleja, Daniel - * Jimenez Prieto, Roberto - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <netinet/in.h> -#include <sys/time.h> -#include "ip-icmp.h" - -#define ICMP_TIMESTAMP 13 -#define ICMP_TIMESTAMP_REPLY 14 -#define TIMEOUT 5 // Tiempo de espera en segundos - -void crearICMPRequest(TimeStamp *icmp_msg); -unsigned short checksum(void *b, int len); -void imprimeError(unsigned char type, unsigned char 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 = (argc == 3 && strcmp(argv[2], "-v") == 0); - const char *ip = argv[1]; - int sockfd; - struct sockaddr_in dest_addr; - - // Crear socket RAW para ICMP - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (sockfd < 0) { - perror("Error al crear el socket"); - exit(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 dirección IP"); - exit(EXIT_FAILURE); - } - - // Construir el mensaje ICMP - TimeStamp icmp_msg; - crearICMPRequest(&icmp_msg); - - // En modo verbose, imprime siempre los detalles del datagrama enviado - if (verbose) { - printf("-> Type: %d\n", icmp_msg.icmpHdr.type); - printf("-> Code: %d\n", icmp_msg.icmpHdr.code); - printf("-> PID : %d\n", ntohs(icmp_msg.pid)); - printf("-> Seq Numbr: %d\n", ntohs(icmp_msg.sequence)); - printf("-> Originate: %u ms\n", icmp_msg.originate); - printf("-> Receive: 0 ms\n"); // Los campos Receive y Transmit no están en icmp_msg - printf("-> Transmit: 0 ms\n"); - printf("-> Tamanyo del Datagrama: %ld bytes\n", sizeof(TimeStamp)); - } - - // Enviar mensaje ICMP - printf("-> Enviando Datagrama ICMP a Destino con IP: %s\n", ip); - if (sendto(sockfd, &icmp_msg, sizeof(icmp_msg), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) { - perror("Error al enviar el datagrama"); - exit(EXIT_FAILURE); - } - printf("-> Timestamp Request enviado correctamente...\n"); - - // Configurar timeout - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(sockfd, &readfds); - - struct timeval timeout = {TIMEOUT, 0}; - if (select(sockfd + 1, &readfds, NULL, NULL, &timeout) <= 0) { - printf("-> Tiempo de espera agotado para %s\n", ip); - exit(EXIT_FAILURE); - } - - // Recibir respuesta - TimeStampReply recv_reply; - socklen_t addr_len = sizeof(dest_addr); - if (recvfrom(sockfd, &recv_reply, sizeof(recv_reply), 0, (struct sockaddr *)&dest_addr, &addr_len) < 0) { - perror("Error al recibir el datagrama"); - exit(EXIT_FAILURE); - } - - // Verificar tipo de respuesta - printf("\n-> Timestamp Reply recibido desde %s\n", ip); - if (strcmp(ip, "127.0.0.1") == 0) { // Caso especial: Loopback - printf("-> ICMP Datagram Not Processed...\n"); - } else if (recv_reply.icmpMsg.icmpHdr.type == ICMP_TIMESTAMP_REPLY && recv_reply.icmpMsg.icmpHdr.code == 0) { - int originate = recv_reply.icmpMsg.originate; - int receive = recv_reply.icmpMsg.receive; - int transmit = recv_reply.icmpMsg.transmit; - - struct timeval end_time; - gettimeofday(&end_time, NULL); - int t4 = (end_time.tv_sec * 1000) + (end_time.tv_usec / 1000); - int rtt = (receive - originate) + (t4 - transmit); - - if (verbose) { - printf("-> Originate: %u ms\n", originate); - printf("-> Receive: %u ms\n", receive); - printf("-> Transmit: %u ms\n", transmit); - printf("-> RTT: %u ms\n", rtt); - printf("-> TTL: %d\n", recv_reply.ipHdr.TTL); - printf("-> Tamanyo del Datagrama: %ld bytes\n", sizeof(TimeStampReply)); - } - - printf("-> Respuesta Correcta (Type %d, Code %d)\n", recv_reply.icmpMsg.icmpHdr.type, recv_reply.icmpMsg.icmpHdr.code); - } else { - // Caso de error genérico o inesperado - imprimeError(recv_reply.icmpMsg.icmpHdr.type, recv_reply.icmpMsg.icmpHdr.code); - } - - close(sockfd); - return EXIT_SUCCESS; -} - -// Función para inicializar el mensaje ICMP -void crearICMPRequest(TimeStamp *icmp_msg) { - memset(icmp_msg, 0, sizeof(TimeStamp)); - icmp_msg->icmpHdr.type = ICMP_TIMESTAMP; - icmp_msg->icmpHdr.code = 0; - icmp_msg->pid = htons(getpid()); - icmp_msg->sequence = htons(0); - - struct timeval start_time; - gettimeofday(&start_time, NULL); - icmp_msg->originate = (start_time.tv_sec * 1000) + (start_time.tv_usec / 1000); - - icmp_msg->icmpHdr.checksum = checksum(icmp_msg, sizeof(TimeStamp)); -} - -// Función para calcular el checksum -unsigned short checksum(void *b, int len) { - // Paso 1: Inicializar el campo checksum a 0. - unsigned short *buf = b; - unsigned int sum = 0; // Paso 4: Acumulador inicializado a 0. - - // Paso 2: Calcular el número de palabras de 16 bits. - int half_words = len / 2; - - // Paso 5: Recorrer el datagrama sumando palabras de 16 bits. - for (int i = 0; i < half_words; i++) { - sum += *buf++; // Sumar la palabra actual al acumulador. - } - - // Si queda un byte adicional (longitud impar), procesarlo. - if (len % 2 == 1) { - sum += *(unsigned char *)buf; // Sumar el último byte como un short. - } - - // Sumar las partes alta y baja del acumulador (1ª vez). - sum = (sum >> 16) + (sum & 0xFFFF); - - // Sumar nuevamente las partes alta y baja del acumulador (2ª vez). - sum += (sum >> 16); - - // Complemento a uno. - return (unsigned short)(~sum); -} - -// Función para imprimir errores ICMP -void imprimeError(unsigned char type, unsigned char code) { - const char *mensaje = ""; // Variable para almacenar el mensaje a imprimir - - // Determinar el mensaje basado en el tipo y código - if (type == 3) { // Destination Unreachable - mensaje = "-> Destination Unreachable: "; - if (code == 0) mensaje = "-> Destination Unreachable: Net Unreachable"; - else if (code == 1) mensaje = "-> Destination Unreachable: Host Unreachable"; - else if (code == 2) mensaje = "-> Destination Unreachable: Protocol Unreachable"; - else if (code == 3) mensaje = "-> Destination Unreachable: Port Unreachable"; - else mensaje = "-> Destination Unreachable: Unknown Code"; - } else if (type == 11) { // Time Exceeded - mensaje = "-> Time Exceeded"; - } else { // Otros tipos de error ICMP - mensaje = "-> ICMP Error: "; - } - - // Imprimir el mensaje final - printf("%s (Type %d, Code %d)\n", mensaje, type, code); -} -