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

Delete prueba.c

parent b7921416
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: 0 ms\n");
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");
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;
icmp_msg->icmpHdr.checksum = checksum(icmp_msg, sizeof(TimeStamp));
}
unsigned short checksum(void *b, int len) {
unsigned short *buf = b;
unsigned int sum = 0;
for (; len > 1; len -= 2) {
sum += *buf++;
}
if (len == 1) {
sum += *(unsigned char *)buf;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return ~sum;
}
void imprimeError(unsigned char type, unsigned char code) {
const char *mensaje = "";
if (type == 3) {
switch (code) {
case 0: mensaje = "Net Unreachable"; break;
case 1: mensaje = "Host Unreachable"; break;
case 2: mensaje = "Protocol Unreachable"; break;
case 3: mensaje = "Port Unreachable"; break;
case 4: mensaje = "Fragmentation Needed"; break;
case 5: mensaje = "Source Route Failed"; break;
case 6: mensaje = "Destination Network Unknown"; break;
case 7: mensaje = "Destination Host Unknown"; break;
case 8: mensaje = "Source Host Isolated"; break;
case 11: mensaje = "Destination Network Unreachable for Type of Service"; break;
case 12: mensaje = "Destination Host Unreachable for Type of Service"; break;
case 13: mensaje = "Communication Administratively Prohibited"; break;
case 14: mensaje = "Host Precedence Violation"; break;
case 15: mensaje = "Precedence Cutoff in Effect"; break;
default: mensaje = "Unknown Code"; break;
}
} else if (type == 5) {
switch (code) {
case 1: mensaje = "Redirect for Destination Host"; break;
case 3: mensaje = "Redirect for Destination Host Based on Type-of-Service"; break;
default: mensaje = "Unknown Code"; break;
}
} else if (type == 11) {
switch (code) {
case 0: mensaje = "Time-to-Live Exceeded in Transit"; break;
case 1: mensaje = "Fragment Reassembly Time Exceeded"; break;
default: mensaje = "Unknown Code"; break;
}
} else if (type == 12) {
switch (code) {
case 0: mensaje = "Pointer indicates the error"; break;
case 1: mensaje = "Missing a Required Option"; break;
case 2: mensaje = "Bad Length"; break;
default: mensaje = "Unknown Code"; break;
}
} else {
mensaje = "ICMP Error";
}
printf("-> %s (Type %d, Code %d)\n", mensaje, type, code);
}
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