diff --git a/P8/icmp3.c b/P8/icmp3.c deleted file mode 100644 index 9735c2dbb900d07f1bb3b46f4165fc0faf03a03c..0000000000000000000000000000000000000000 --- a/P8/icmp3.c +++ /dev/null @@ -1,283 +0,0 @@ -/** - * Practica Tema 8: ICMP-TIMESTAMP - * - * Mata, David - * - * - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/ip.h> // Define sockaddr_in -#include <errno.h> // Para usar errno y perror() -#include <unistd.h> -#include <sys/time.h> -#include "ip-icmp.h" - -#define tiempo_max 5 - -// Funcion para calcular el checksum -unsigned short checksum(TimeStamp *ts) -{ - unsigned int acumulador = 0; - unsigned short *puntero = (unsigned short *)ts; - int i; - int len = sizeof(TimeStamp) / 2; - - // Inicializamos el checksum a 0 - ts->icmpHdr.checksum = 0; - - // Calculamos el checksum - for (i = 0; i < len; i++) - { - acumulador += (unsigned int)*puntero; - puntero++; - } - // Realizamos dos veces la operacion por el acarreo - acumulador = (acumulador >> 16) + (acumulador & 0x0000ffff); - acumulador = (acumulador >> 16) + (acumulador & 0x0000ffff); - - return (unsigned short)~acumulador; -} -// Función para manejar los errores de ICMP -void errores_ICMP(char type, char code) -{ - switch (type) - { - case 3: // Destination Unreachable - switch (code) - { - case 0: - printf("Destination Unreachable: Net Unreachable\n"); - break; - case 1: - printf("Destination Unreachable: Host Unreachable\n"); - break; - case 2: - printf("Destination Unreachable: Protocol Unreachable\n"); - break; - case 3: - printf("Destination Unreachable: Port Unreachable\n"); - break; - case 4: - printf("Destination Unreachable: Fragmentation Needed\n"); - break; - case 5: - printf("Destination Unreachable: Source Route Failed\n"); - break; - case 6: - printf("Destination Unreachable: Destination Network Unknown\n"); - break; - case 7: - printf("Destination Unreachable: Destination Host Unknown\n"); - break; - case 8: - printf("Destination Unreachable: Source Host Isolated\n"); - break; - case 11: - printf("Destination Unreachable: Destination Network Unreachable for Type of Service\n"); - break; - case 12: - printf("Destination Unreachable: Destination Host Unreachable for Type of Service\n"); - break; - case 13: - printf("Destination Unreachable: Communication Administratively Prohibited\n"); - break; - case 14: - printf("Destination Unreachable: Host Precedence Violation\n"); - break; - case 15: - printf("Destination Unreachable: Precedence Cutoff in Effect\n"); - break; - } - case 5: // Redirect - switch (code) - { - case 1: - printf("Redirect: Redirect for Destination Host\n"); - break; - case 3: - printf("Redirect: Redirect for Destination Host Based on Type-of-Service\n"); - break; - } - case 11: // Time Exceeded - switch (code) - { - case 0: - printf("Time Exceeded: Time-to-Live Exceeded in Transit\n"); - break; - case 1: - printf("Time Exceeded: Fragment Reassembly Time Exceeded\n"); - break; - } - case 12: // Parameter Problem - switch (code) - { - case 0: - printf("Parameter Problem: Pointer indicates the error\n"); - break; - case 1: - printf("Parameter Problem: Missing a Required Option\n"); - break; - case 2: - printf("Parameter Problem: Bad Length\n"); - break; - } - default: - printf("ICMP Error: Type %d, Code %d\n", type, code); - } -} -int main(int argc, char *argv[]) -{ - - struct sockaddr_in direccion; // Estructura para guardar la ip del servidor - int numero_socket; // numero del sockect - int v = 0; // Modo verbose(-v) - socklen_t tam; // Variable para la funcion rcvfrom - struct sockaddr_in myaddr; - - // Comprobamos que el numero de argumentos sea correcto - if (argc < 2 || argc > 3) - { - fprintf(stderr, "Error en el numero de argumentos"); - exit(EXIT_FAILURE); - } - - // Convertimos la dirección IP - if (inet_aton(argv[1], &direccion.sin_addr) == 0) - { - fprintf(stderr, "Error al transformar la direccion IP\n"); - exit(EXIT_FAILURE); - } - - // Creamos el socket UDP - numero_socket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (numero_socket < 0) - { - perror("Error al crear el socket"); - exit(EXIT_FAILURE); - } - // Asignamos la familia a la direccion - direccion.sin_family = AF_INET; - - // Comprobamos si el tercer argumento es modo verbose y inicializamos el flag - if (argc == 3 && strcmp(argv[2], "-v") == 0) - { - v = 1; - } - - printf("-> Enviando Datagrama ICMP a Destino con IP: %s\n", argv[1]); - - // Creamos el mensaje Timestamp - TimeStamp mensaje; - memset(&mensaje, 0, sizeof(mensaje)); - - // Inicializamos la cabecera ICMP - mensaje.icmpHdr.type = 13; - mensaje.icmpHdr.code = 0; - mensaje.pid = getpid(); - mensaje.sequence = 0; - - // Calculamos el tiempo de origen para el mensaje enviado - struct timeval tiempo_ori; - gettimeofday(&tiempo_ori, NULL); - mensaje.originate = tiempo_ori.tv_sec * 1000 + tiempo_ori.tv_usec / 1000; - - // Calculamos checksum y se lo asignamos al mensaje - mensaje.icmpHdr.checksum = 0; - mensaje.icmpHdr.checksum = checksum(&mensaje); - - // Informacion para el modo verbose - if (v) - { - printf("-> Type: %d\n", mensaje.icmpHdr.type); - printf("-> Code: %d\n", mensaje.icmpHdr.code); - printf("-> PID : %d\n", mensaje.pid); - printf("-> Seq Numbr: %d\n", mensaje.sequence); - printf("-> Originate: %u\n", mensaje.originate); - printf("-> Receive: %d\n", mensaje.receive); - printf("-> Transmit: %d\n", mensaje.transmit); - printf("-> Tamanyo del Datagrama: %lu bytes\n", sizeof(mensaje)); - printf("\n"); - } - - // Enviamos el mensaje - int bytes_enviados = sendto(numero_socket, &mensaje, sizeof(mensaje), 0, (struct sockaddr *)&direccion, sizeof(direccion)); - if (bytes_enviados < 0) - { - perror("Error al enviar mensaje"); - exit(EXIT_FAILURE); - } - - printf("-> Timestamp Request enviado correctamente...\n"); - - // Preparar select para tiempo_espera - fd_set sock_lec; - struct timeval tiempo_espera; - - FD_ZERO(&sock_lec); - FD_SET(numero_socket, &sock_lec); - tiempo_espera.tv_sec = tiempo_max; - - // Esperar respuesta con tiempo_espera - int ready = select(numero_socket + 1, &sock_lec, NULL, NULL, &tiempo_espera); - if (ready < 0) - { - perror("Error en select"); - exit(EXIT_FAILURE); - } - - // Recibimos la respuesta - TimeStampReply respuesta; - tam = sizeof(myaddr); - int bytes_recibidos = recvfrom(numero_socket, &respuesta, sizeof(respuesta), 0, (struct sockaddr *)&myaddr, &tam); - if (bytes_recibidos < 0) - { - perror("Error en los bytes recibidos"); - exit(EXIT_FAILURE); - } - - // Calculamos el tiempo de recibir para el mensaje recibido - struct timeval tiempo_rec; - gettimeofday(&tiempo_rec, NULL); - int tiempo_rec_ms = tiempo_rec.tv_sec * 1000 + tiempo_rec.tv_usec / 1000; - - printf("-> Timestamp Reply recibido desde %s\n", inet_ntoa(myaddr.sin_addr)); - // Procesamos la respuesta ICMP - if (respuesta.icmpMsg.icmpHdr.type == 14 && respuesta.icmpMsg.icmpHdr.code == 0) - { - // modo verbose - if (v) - { - printf("-> Originate: %d\n", respuesta.icmpMsg.originate); - printf("-> Receive: %u\n", respuesta.icmpMsg.receive); - printf("-> Transmit: %u\n", respuesta.icmpMsg.transmit); - - // Calcular RTT (RTT = (T2 − T1) + (T4 − T3)) - int rtt = (respuesta.icmpMsg.receive - mensaje.originate) + (tiempo_rec_ms - respuesta.icmpMsg.transmit); - printf("-> RTT: %d miliseconds\n", rtt); - - printf("-> TTL: %d\n", respuesta.ipHdr.TTL); - printf("-> Tamanyo del Datagrama: %lu bytes\n", sizeof(respuesta)); - } - - printf("-> Respuesta Correcta (Type 14, Code 0)\n"); - } - // Si hay errores en la respuesta del mensaje - else if (respuesta.icmpMsg.icmpHdr.type == 3 || respuesta.icmpMsg.icmpHdr.type == 5 || respuesta.icmpMsg.icmpHdr.type == 11 || respuesta.icmpMsg.icmpHdr.type == 12) - - { - errores_ICMP(respuesta.icmpMsg.icmpHdr.type, respuesta.icmpMsg.icmpHdr.code); - } - else - { - printf("-> ICMP Datagram Not Processed...\n"); - } - - return 0; -} \ No newline at end of file