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

Delete icmp3.c

parent 7ce0ea07
No related branches found
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.
Finish editing this message first!
Please register or to comment