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