Estos días estaba revisando un proyecto personal, y vi una clase que había hecho hace tiempo, y bastante interezante, es una implementacion de Traceroute/Tracert en .Net (C Sharp).
¿Cómo funciona un Traceroute?
No es tan complicado como pudiésemos llegar a pensar. Para explicarlo imaginémos el siguiente esquema de red:
A-----B-----C-----D-----E
Donde A es el equipo host local, y E el host remoto. El funcionamiendo de la aplicacion es la siguiente. Se hace un ping hacia el remoto pero con una opcion diferente, TTL = 1, es decir Time To Live = 1. Esto quiere decir que apenas el paquete salga hacia E, éste nada más va a poder pasar por un Nodo, Router, Modem, etc y el resultado del ping nos va a retornar la Dirección IP de dicho Nodo, en éste caso de B.
De ésta manera vamos aumentando el TTL de cada intento y vamos guardando la informacion hasta que el status de la respuesta del Ping sea satisfactoria (IPStatus.Success).
Ahora veamos el código:
1: using System;
2: using System.Collections.Generic;
3: using System.Text;
4: using System.Net.NetworkInformation;
5:
6: namespace NetworkSupervisor.ComponentModel
7: {
8: //Delegado para los eventos del Traceroute
9: public delegate void TracertEventHandler(object sender, TracertEventArgs e);
10:
11: public class Tracert
12: {
13: int m_timeout = 0;
14: string m_host = "";
15: int m_maxHops = 0;
16:
17: public event TracertEventHandler EchoReceived;
18: public event TracertEventHandler ErrorReceived;
19: public event TracertEventHandler TracertCompleted;
20:
21: public Tracert(string host, int TimeOut, int maxHops)
22: {
23: m_host = host;
24: m_timeout = TimeOut;
25: m_maxHops = maxHops;
26: }
27: public void Start()
28: {
29: PingReply reply;
30: Ping pinger = new Ping();
31: PingOptions options = new PingOptions();
32:
33: //Con esto le decimos al paquete que nada más salte un equipo.
34: options.Ttl = 1;
35:
36: options.DontFragment = true;
37:
38: byte[] buffer = Encoding.ASCII.GetBytes("Algo de datos");
39: try
40: {
41: do
42: {
43: //Tiempo antes del comando
44: DateTime start = DateTime.Now;
45:
46: //Mandamos el ping
47: reply = pinger.Send(m_host,
48: m_timeout,
49: buffer,
50: options);
51:
52: //Restamos la diferencia de tiempo para conocer la latencia.
53: long milliseconds = DateTime.Now.Subtract(start).Milliseconds;
54: if ((reply.Status == IPStatus.TtlExpired)
55: || (reply.Status == IPStatus.Success))
56: {
57: //Damos respuesta en caso de que encontremos un host
58: //o que se haya finalizado el proceso.
59: OnEchoReceived(reply, milliseconds, options.Ttl);
60: }
61: else
62: {
63: OnErrorReceived(reply, milliseconds);
64: }
65: options.Ttl++;
66:
67: //Mientras no haya terminado, es decir, no sea Success
68: //seguimos mandando ping con un TTL aumentado.
69:
70: // Notemos que cuando la resuesta es Success
71: //es porque el paquete llego al destino
72: } while ((reply.Status != IPStatus.Success)
73: && (options.Ttl < m_maxHops));
74: }
75: catch (PingException pex)
76: {
77: //Acá pueden implementar algo en caso de algun error.
78: throw pex.InnerException;
79: }
80: finally
81: {
82: if (TracertCompleted != null)
83: TracertCompleted(this, new TracertEventArgs(null, 0, 0));
84: }
85: }
86:
87:
88: //Manejo de los eventos.
89: private void OnErrorReceived(PingReply reply, long milliseconds)
90: {
91: InvokeErrorReceived(reply, milliseconds);
92: }
93:
94: private void OnEchoReceived(PingReply reply, long milliseconds, int ttl)
95: {
96: InvokeEchoReceived(reply, milliseconds, ttl);
97: }
98: public void InvokeEchoReceived(PingReply reply, long milliseconds, int ttl)
99: {
100: if (EchoReceived != null)
101: EchoReceived(this, new TracertEventArgs(reply, milliseconds,ttl));
102: }
103: public void InvokeErrorReceived(PingReply reply, long milliseconds)
104: {
105: if (ErrorReceived != null)
106: ErrorReceived(this, new TracertEventArgs(reply, milliseconds,0));
107: }
108: }
109: }
Espero les sea de ayuda!
Gracias por leer!
No hay comentarios:
Publicar un comentario