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

Delete prueba.c

parent fb480611
No related branches found
No related tags found
No related merge requests found
/**
* 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, local_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;
dest_addr.sin_port = 0; // Inicializar sin_port
if (inet_pton(AF_INET, ip, &dest_addr.sin_addr) <= 0) {
perror("Error al convertir la dirección IP");
close(sockfd);
exit(EXIT_FAILURE);
}
// Asociar socket a la dirección local
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = INADDR_ANY;
local_addr.sin_port = 0;
if (bind(sockfd, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
perror("Error al asociar el socket a la dirección local");
close(sockfd);
exit(EXIT_FAILURE);
}
// Construir el mensaje ICMP
TimeStamp icmp_msg;
crearICMPRequest(&icmp_msg);
// En modo verbose, imprime 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", icmp_msg.pid);
printf("-> Seq Numbr: %d\n", ntohs(icmp_msg.sequence));
printf("-> Originate: %u ms\n", icmp_msg.originate);
printf("-> Receive: %u ms\n", icmp_msg.receive);
printf("-> Transmit: %u ms\n", icmp_msg.transmit);
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");
close(sockfd);
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};
int sel = select(sockfd + 1, &readfds, NULL, NULL, &timeout);
if (sel < 0) {
perror("Error en select");
close(sockfd);
exit(EXIT_FAILURE);
} else if (sel == 0) {
printf("-> Tiempo de espera agotado para %s\n", ip);
close(sockfd);
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");
close(sockfd);
exit(EXIT_FAILURE);
}
// Verificar tipo de respuesta
printf("\n-> Timestamp Reply recibido desde %s\n", ip);
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 if (recv_reply.icmpMsg.icmpHdr.type == 3){
imprimeError(recv_reply.icmpMsg.icmpHdr.type, recv_reply.icmpMsg.icmpHdr.code);
}else {
printf("-> ICMP Datagram Not Processed...\n");
}
close(sockfd);
return EXIT_SUCCESS;
}
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 = 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 = 0; // Inicializar el campo checksum a 0.
icmp_msg->icmpHdr.checksum = checksum(icmp_msg, sizeof(TimeStamp));
}
// Función para calcular el checksum
unsigned short checksum(void *b, int len) {
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 palabras = len / 2;
// Paso 5: Recorrer el datagrama sumando palabras de 16 bits.
while (palabras > 0) {
sum += *buf++; // Sumar la palabra actual al acumulador.
palabras--; // Reducir el contador de palabras.
}
// 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
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 if (code == 4) mensaje = "-> Destination Unreachable: Fragmentation Needed";
else if (code == 5) mensaje = "-> Destination Unreachable: Source Route Failed";
else if (code == 6) mensaje = "-> Destination Unreachable: Destination Network Unknown";
else if (code == 7) mensaje = "-> Destination Unreachable: Destination Host Unknown";
else if (code == 8) mensaje = "-> Destination Unreachable: Source Host Isolated";
else if (code == 11) mensaje = "-> Destination Unreachable: Destination Network Unreachable for Type of Service";
else if (code == 12) mensaje = "-> Destination Unreachable: Destination Host Unreachable for Type of Service";
else if (code == 13) mensaje = "-> Destination Unreachable: Communication Administratively Prohibited";
else if (code == 14) mensaje = "-> Destination Unreachable: Host Precedence Violation";
else if (code == 15) mensaje = "-> Destination Unreachable: Precedence Cutoff in Effect";
else mensaje = "-> Destination Unreachable: Unknown Code";
} else if (type == 5) { // Redirect
if (code == 1) mensaje = "-> Redirect: Redirect for Destination Host";
else if (code == 3) mensaje = "-> Redirect: Redirect for Destination Host Based on Type-of-Service";
else mensaje = "-> Redirect: Unknown Code";
} else if (type == 11) { // Time Exceeded
if (code == 0) mensaje = "-> Time Exceeded: Time-to-Live Exceeded in Transit";
else if (code == 1) mensaje = "-> Time Exceeded: Fragment Reassembly Time Exceeded";
else mensaje = "-> Time Exceeded: Unknown Code";
} else if (type == 12) { // Parameter Problem
if (code == 0) mensaje = "-> Parameter Problem: Pointer indicates the error";
else if (code == 1) mensaje = "-> Parameter Problem: Missing a Required Option";
else if (code == 2) mensaje = "-> Parameter Problem: Bad Length";
else mensaje = "-> Parameter Problem: Unknown Code";
} else { // Otros tipos de error ICMP
mensaje = "-> ICMP Error: ";
}
// Imprimir el mensaje final
printf("%s (Type %d, Code %d)\n", mensaje, type, code);
}
\ 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