Skip to content
Snippets Groups Projects
Commit e9213c69 authored by danredo's avatar danredo
Browse files

Delete icmp3.c

parent 7ce0ea07
Branches
No related tags found
No related merge requests found
/**
* 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment