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
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
danredo
ARS
Commits
e9213c69
Commit
e9213c69
authored
5 months ago
by
danredo
Browse files
Options
Downloads
Patches
Plain Diff
Delete icmp3.c
parent
7ce0ea07
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
P8/icmp3.c
+0
-283
0 additions, 283 deletions
P8/icmp3.c
with
0 additions
and
283 deletions
P8/icmp3.c
deleted
100644 → 0
+
0
−
283
View file @
7ce0ea07
/**
* 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
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