Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
ARS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
danredo
ARS
Commits
ccf91b38
Commit
ccf91b38
authored
8 months ago
by
danredo
Browse files
Options
Downloads
Patches
Plain Diff
Delete icmp-timestamp.c
parent
49136983
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
P8/icmp-timestamp.c
+0
-195
0 additions, 195 deletions
P8/icmp-timestamp.c
with
0 additions
and
195 deletions
P8/icmp-timestamp.c
deleted
100644 → 0
+
0
−
195
View file @
49136983
/**
* Practica Tema 8: ICMP-TIMESTAMP
*
* Apellido, Nombre
* Apellido, Nombre
*
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<unistd.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<arpa/inet.h>
#include
<sys/time.h>
#include
<errno.h>
#include
"ip-icmp.h"
// Usa las estructuras definidas en este archivo
#define ICMP_TIMESTAMP 13
#define ICMP_TIMESTAMP_REPLY 14
#define TIMEOUT 5 // Tiempo de espera en segundos
unsigned
short
checksum
(
void
*
b
,
int
len
)
{
unsigned
short
*
buf
=
b
;
unsigned
int
sum
=
0
;
unsigned
short
result
;
for
(
sum
=
0
;
len
>
1
;
len
-=
2
)
{
sum
+=
*
buf
++
;
}
if
(
len
==
1
)
{
sum
+=
*
(
unsigned
char
*
)
buf
;
}
sum
=
(
sum
>>
16
)
+
(
sum
&
0xFFFF
);
sum
+=
(
sum
>>
16
);
result
=
~
sum
;
return
result
;
}
void
print_icmp_error
(
int
type
,
int
code
)
{
switch
(
type
)
{
case
3
:
printf
(
"-> Destination Unreachable: "
);
switch
(
code
)
{
case
0
:
printf
(
"Net Unreachable
\n
"
);
break
;
case
1
:
printf
(
"Host Unreachable
\n
"
);
break
;
default:
printf
(
"Unknown Code
\n
"
);
break
;
}
break
;
default:
printf
(
"-> ICMP Error: Type %d, Code %d
\n
"
,
type
,
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
=
0
;
const
char
*
ip
=
argv
[
1
];
if
(
argc
==
3
&&
strcmp
(
argv
[
2
],
"-v"
)
==
0
)
{
verbose
=
1
;
}
int
sockfd
;
struct
sockaddr_in
dest_addr
;
struct
timeval
start_time
,
end_time
;
unsigned
char
buffer
[
1024
];
sockfd
=
socket
(
AF_INET
,
SOCK_RAW
,
IPPROTO_ICMP
);
if
(
sockfd
<
0
)
{
perror
(
"Error al crear el socket"
);
return
EXIT_FAILURE
;
}
memset
(
&
dest_addr
,
0
,
sizeof
(
dest_addr
));
dest_addr
.
sin_family
=
AF_INET
;
if
(
inet_pton
(
AF_INET
,
ip
,
&
dest_addr
.
sin_addr
)
<=
0
)
{
perror
(
"Error al convertir la direccion IP"
);
return
EXIT_FAILURE
;
}
// Construccion del mensaje ICMP
TimeStamp
icmp_msg
;
memset
(
&
icmp_msg
,
0
,
sizeof
(
icmp_msg
));
icmp_msg
.
icmpHdr
.
type
=
ICMP_TIMESTAMP
;
icmp_msg
.
icmpHdr
.
code
=
0
;
icmp_msg
.
pid
=
htons
(
getpid
());
icmp_msg
.
sequence
=
htons
(
0
);
gettimeofday
(
&
start_time
,
NULL
);
icmp_msg
.
originate
=
htonl
((
start_time
.
tv_sec
*
1000
)
+
(
start_time
.
tv_usec
/
1000
));
icmp_msg
.
receive
=
0
;
// Inicializar campo Receive a 0
icmp_msg
.
transmit
=
0
;
// Inicializar campo Transmit a 0
int
icmp_length
=
sizeof
(
icmp_msg
);
// Tamaño dinámico en caso de relleno
icmp_msg
.
icmpHdr
.
checksum
=
checksum
(
&
icmp_msg
,
icmp_length
);
// Calculo y asignacion del checksum
// Enviar el mensaje
if
(
sendto
(
sockfd
,
&
icmp_msg
,
sizeof
(
icmp_msg
),
0
,
(
struct
sockaddr
*
)
&
dest_addr
,
sizeof
(
dest_addr
))
<
0
)
{
perror
(
"Error al enviar el datagrama"
);
return
EXIT_FAILURE
;
}
if
(
verbose
)
{
printf
(
"-> Enviando Datagrama ICMP a Destino con IP: %s
\n
"
,
ip
);
}
// Configuracion del tiempo de espera
fd_set
readfds
;
FD_ZERO
(
&
readfds
);
FD_SET
(
sockfd
,
&
readfds
);
struct
timeval
timeout
;
timeout
.
tv_sec
=
TIMEOUT
;
timeout
.
tv_usec
=
0
;
int
sel
=
select
(
sockfd
+
1
,
&
readfds
,
NULL
,
NULL
,
&
timeout
);
if
(
sel
==
-
1
)
{
perror
(
"Error en select"
);
return
EXIT_FAILURE
;
}
else
if
(
sel
==
0
)
{
printf
(
"-> Tiempo de espera agotado para el destino %s.
\n
"
,
ip
);
return
EXIT_FAILURE
;
}
// Recibir la respuesta
socklen_t
addr_len
=
sizeof
(
dest_addr
);
if
(
recvfrom
(
sockfd
,
buffer
,
sizeof
(
buffer
),
0
,
(
struct
sockaddr
*
)
&
dest_addr
,
&
addr_len
)
<
0
)
{
perror
(
"Error al recibir el datagrama"
);
return
EXIT_FAILURE
;
}
gettimeofday
(
&
end_time
,
NULL
);
// Excluir cabecera IP
struct
iphdr
*
ip_hdr
=
(
struct
iphdr
*
)
buffer
;
int
ip_header_length
=
ip_hdr
->
ihl
*
4
;
TimeStamp
*
recv_reply
=
(
TimeStamp
*
)(
buffer
+
ip_header_length
);
// Verificar el checksum del datagrama recibido
unsigned
short
recv_checksum
=
recv_reply
->
icmpHdr
.
checksum
;
recv_reply
->
icmpHdr
.
checksum
=
0
;
// Temporalmente establece a 0 para recalcular
int
icmp_length
=
sizeof
(
buffer
)
-
ip_header_length
;
// Tamanno real del ICMP
if
(
checksum
(
recv_reply
,
icmp_length
)
!=
0
)
{
fprintf
(
stderr
,
"Error: Checksum invalido en el datagrama recibido.
\n
"
);
return
EXIT_FAILURE
;
}
recv_reply
->
icmpHdr
.
checksum
=
recv_checksum
;
// Restaurar el valor original
if
(
recv_reply
->
icmpHdr
.
type
==
ICMP_TIMESTAMP_REPLY
)
{
unsigned
long
originate
=
ntohl
(
recv_reply
->
originate
);
unsigned
long
receive
=
ntohl
(
recv_reply
->
receive
);
unsigned
long
transmit
=
ntohl
(
recv_reply
->
transmit
);
unsigned
long
t4
=
(
end_time
.
tv_sec
*
1000
)
+
(
end_time
.
tv_usec
/
1000
);
unsigned
long
rtt
=
(
receive
-
originate
)
+
(
t4
-
transmit
);
// Mensajes que se imprimen siempre
printf
(
"-> Timestamp Reply recibido desde %s
\n
"
,
ip
);
printf
(
"-> Respuesta Correcta (Type %d, Code %d)
\n
"
,
recv_reply
->
icmpHdr
.
type
,
recv_reply
->
icmpHdr
.
code
);
// Mensajes que solo se imprimen con -v
if
(
verbose
)
{
printf
(
"-> Originate (recibido): %lu
\n
"
,
originate
);
printf
(
"-> Receive (recibido): %lu
\n
"
,
receive
);
printf
(
"-> Transmit (recibido): %lu
\n
"
,
transmit
);
printf
(
"-> T4 (local): %lu
\n
"
,
t4
);
printf
(
"-> RTT: %lu ms
\n
"
,
rtt
);
printf
(
"-> TTL: %d
\n
"
,
ip_hdr
->
ttl
);
printf
(
"-> Tamanyo del Datagrama: %zu bytes
\n
"
,
sizeof
(
buffer
));
}
// Si algun tiempo es 0, el destino no ha procesado los campos
if
(
receive
==
0
||
transmit
==
0
)
{
fprintf
(
stderr
,
"Error: El destino no procesa correctamente los campos Receive (%lu) o Transmit (%lu).
\n
"
,
receive
,
transmit
);
return
EXIT_FAILURE
;
}
// Error si: el tiempo en que se recibio el mensaje es menor al tiempo en que se envio,
// el tiempo en que se transmitio la respuesta es menor que el tiempo en que se recibio,
// o el tiempo en que se recibio la respuesta del origen (t4) es menor al tiempo de transmision de la respuesta
if
(
receive
<
originate
||
transmit
<
receive
||
t4
<
transmit
)
{
fprintf
(
stderr
,
"Error: Valores de marcas de tiempo inconsistentes.
\n
"
);
return
EXIT_FAILURE
;
}
}
else
{
print_icmp_error
(
recv_reply
->
icmpHdr
.
type
,
recv_reply
->
icmpHdr
.
code
);
}
close
(
sockfd
);
return
EXIT_SUCCESS
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment