WrenchmanDE

Untitled

Jun 22nd, 2018
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.89 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Threading;
  7. using System.Net.NetworkInformation;
  8. using System.Collections;
  9. using System.Windows.Forms;
  10.  
  11. namespace WrenchMTR
  12. {
  13. /// <summary>
  14. ///
  15. /// </summary>
  16. public class RouteEntry
  17. {
  18. public IPAddress Address { get; set; }
  19. public bool IsNull { get; set; }
  20. public int TTL { get; set; }
  21. public string HostName { get; set; }
  22. public string Text { get; set; }
  23. public long LastRoundTrip { get; set; }
  24. public long AvgRoundTrip { get; set; }
  25. public long BestRoundTrip { get; set; }
  26. public long WorstRoundTrip { get; set; }
  27. public long SentPings { get; set; }
  28. public long RecvPings { get; set; }
  29. public float Loss { get; set; }
  30.  
  31. public RouteEntry()
  32. {
  33. BestRoundTrip = Int64.MaxValue;
  34. WorstRoundTrip = 0;
  35. }
  36. }
  37.  
  38. /// <summary>
  39. ///
  40. /// </summary>
  41. public class RouteCollection : Dictionary<IPAddress, RouteEntry>
  42. {
  43.  
  44. }
  45.  
  46. /// <summary>
  47. ///
  48. /// </summary>
  49. public enum TraceEventType
  50. {
  51. PingSend,
  52. PingRecv,
  53. PingStopped
  54. }
  55.  
  56. /// <summary>
  57. ///
  58. /// </summary>
  59. public class TraceEventArgs : EventArgs
  60. {
  61. public TraceEventType TraceEventType { get; private set; }
  62. public TraceEventArgs(TraceEventType traceEventType)
  63. {
  64. TraceEventType = traceEventType;
  65. }
  66.  
  67. }
  68.  
  69. public class Trace : IDisposable
  70. {
  71. public class TracePingRun
  72. {
  73. public Trace Trace { get; private set; }
  74. public IPAddress Address { get; private set; }
  75. public IPHostEntry IPHostEntry { get; set; }
  76.  
  77. public TracePingRun(Trace trace, IPAddress address)
  78. {
  79. Trace = trace;
  80. Address = address;
  81. }
  82. }
  83.  
  84. public delegate void TraceEventHandler(object sender, TraceEventArgs e);
  85. public event TraceEventHandler TraceEvent;
  86.  
  87. private Trace()
  88. {
  89.  
  90. }
  91.  
  92. //public RouteCollection Route { get; private set; }
  93. public List<RouteEntry> Route { get; private set; }
  94. public IPAddress Address { get; private set; }
  95. public int PingTimeout { get; private set; }
  96. public int PingTimeFrame { get; private set; }
  97. public bool ResolveNames { get; private set; }
  98. public int PingSize { get; private set; }
  99. public int MaxHops{ get; private set; }
  100.  
  101.  
  102.  
  103. private Stack RunningThreads = new Stack();
  104.  
  105.  
  106. public Trace(IPAddress address)
  107. : this(address, 100, 1000, false, 64, 30)
  108. {
  109.  
  110. }
  111.  
  112. public Trace(IPAddress address, int pingTimeout, int pingTimeFrame, bool resolveNames, int pingSize, int maxHops)
  113. {
  114. Address = address;
  115. PingTimeout = pingTimeout;
  116. PingTimeFrame = pingTimeFrame;
  117. Route = new List<RouteEntry>();
  118. ResolveNames = resolveNames;
  119. PingSize = pingSize;
  120. MaxHops = maxHops;
  121. }
  122.  
  123. public static byte[] MakeByteArray(int length)
  124. {
  125. byte[] byteData = new byte[length];
  126. for (int i = 0; i < byteData.Length; i++)
  127. {
  128. byteData[i] = 0x65;
  129. }
  130. return byteData;
  131. }
  132.  
  133. public void Start()
  134. {
  135. run = true;
  136. new Thread(TraceRun).Start(this);
  137. }
  138.  
  139. public void Stop()
  140. {
  141. run = false;
  142. }
  143.  
  144. public void OnTraceEvent(TraceEventType tet)
  145. {
  146. if (TraceEvent != null)
  147. {
  148. TraceEvent(this, new TraceEventArgs(tet));
  149. }
  150.  
  151. }
  152.  
  153. volatile bool run = false;
  154.  
  155. /// <summary>
  156. ///
  157. /// </summary>
  158. /// <param name="data"></param>
  159. public static void TraceRun(object data)
  160. {
  161. if (!(data is Trace))
  162. return;
  163. Trace trace = (Trace)data;
  164.  
  165. byte[] byteData = MakeByteArray(trace.PingSize);
  166.  
  167. PingOptions pingOptions = new PingOptions(1, false);
  168. Ping ping = new Ping();
  169. bool run = true;
  170. int lastTtl = 1;
  171.  
  172.  
  173. while (run && trace.run && lastTtl <= trace.MaxHops)
  174. {
  175.  
  176. pingOptions = new PingOptions(lastTtl, false);
  177. PingReply pingReply = ping.Send(trace.Address, trace.PingTimeout, byteData, pingOptions);
  178.  
  179.  
  180.  
  181. if (pingReply.Address != null)
  182. {
  183. run = !pingReply.Address.Equals(trace.Address);
  184. lock (trace.Route)
  185. {
  186.  
  187. if (null == trace.Route.Find(delegate(RouteEntry re_) { return re_.Address.ToString() == pingReply.Address.ToString(); }))
  188. {
  189. RouteEntry re = new RouteEntry();
  190. re.Address = pingReply.Address;
  191. re.IsNull = false;
  192. re.TTL = lastTtl;
  193. trace.Route.Add(re);
  194. }
  195. //t.OnTraceEvent(TraceEventType.PingSend);
  196. }
  197. trace.PingHost(pingReply.Address);
  198. Thread.Sleep(1);
  199.  
  200. lastTtl++;
  201. }
  202. else
  203. {
  204. if (pingReply.Status == IPStatus.TimedOut )
  205. {
  206. lastTtl++;
  207.  
  208. lock (trace.Route)
  209. {
  210.  
  211.  
  212. //if (!trace.Route.ContainsKey(trace.Address))
  213. if (trace.Route.Count < lastTtl)
  214. {
  215. RouteEntry re = new RouteEntry();
  216. re.Loss = 1;
  217. re.Text = "N/A";
  218. re.Address = IPAddress.Any;
  219. re.TTL = lastTtl - 1;
  220. re.IsNull = true;
  221. trace.Route.Add(re);
  222.  
  223. }
  224. }
  225.  
  226. }
  227. //Console.WriteLine("Tracing reply status {0}", pingReply.Status);
  228. }
  229.  
  230. }
  231.  
  232. }
  233.  
  234. public void PingHost(IPAddress address)
  235. {
  236. Thread pingRunThread = new Thread(PingRun);
  237. RunningThreads.Push(pingRunThread);
  238. pingRunThread.Start(new TracePingRun(this, address));
  239.  
  240. }
  241.  
  242. private volatile int numThreads;
  243. private int NumThreads
  244. {
  245. get { return numThreads; }
  246. set
  247. {
  248. numThreads = value;
  249. if (numThreads == 0)
  250. OnTraceEvent(TraceEventType.PingStopped);
  251. }
  252. }
  253.  
  254. public static void PingRun(object data)
  255. {
  256.  
  257. if (!(data is TracePingRun))
  258. return;
  259. TracePingRun tracePingRun = (TracePingRun)data;
  260. tracePingRun.Trace.numThreads++;
  261. byte[] byteData = MakeByteArray(tracePingRun.Trace.PingSize);
  262.  
  263.  
  264. if (tracePingRun.Trace.ResolveNames)
  265. Dns.BeginGetHostEntry(tracePingRun.Address, ReverseCallback, tracePingRun);
  266.  
  267.  
  268.  
  269. PingOptions pingOptions = new PingOptions(1, false);
  270. Ping ping = new Ping();
  271. while (tracePingRun.Trace.run)
  272. {
  273. lock (tracePingRun.Trace.Route)
  274. {
  275. //if (tracePingRun.Trace.Route.ContainsKey(tracePingRun.Address))
  276. {
  277. //RouteEntry re = tracePingRun.Trace.Route[tracePingRun.Address];
  278. RouteEntry re = tracePingRun.Trace.Route.Find(delegate(RouteEntry re_) { return re_.Address == tracePingRun.Address; });
  279. if (re != null)
  280. {
  281. re.SentPings++;
  282. }
  283. }
  284. }
  285.  
  286. if (!tracePingRun.Trace.run)
  287. return;
  288.  
  289.  
  290. PingReply pingReply = ping.Send(tracePingRun.Address, tracePingRun.Trace.PingTimeout);
  291.  
  292. lock (tracePingRun.Trace.Route)
  293. {
  294. //if (tracePingRun.Trace.Route.ContainsKey(tracePingRun.Address))
  295. {
  296. //RouteEntry routeEntry = tracePingRun.Trace.Route[tracePingRun.Address];
  297. RouteEntry routeEntry = tracePingRun.Trace.Route.Find(delegate(RouteEntry re_) { return re_.Address.ToString() == tracePingRun.Address.ToString(); });
  298. routeEntry.AvgRoundTrip = (routeEntry.AvgRoundTrip + pingReply.RoundtripTime) / 2;
  299. routeEntry.LastRoundTrip = pingReply.RoundtripTime;
  300. if (pingReply.Status == IPStatus.Success)
  301. {
  302. routeEntry.BestRoundTrip = Math.Min(routeEntry.LastRoundTrip, routeEntry.BestRoundTrip);
  303. routeEntry.WorstRoundTrip = Math.Max(routeEntry.LastRoundTrip, routeEntry.WorstRoundTrip);
  304. routeEntry.RecvPings++;
  305.  
  306. if (tracePingRun.IPHostEntry != null)
  307. routeEntry.HostName = tracePingRun.IPHostEntry.HostName;
  308. }
  309. if (routeEntry.SentPings < routeEntry.RecvPings)
  310. {
  311. //localhost?
  312. routeEntry.Loss = 0;
  313. routeEntry.RecvPings = routeEntry.SentPings;
  314. }
  315. else
  316. {
  317. routeEntry.Loss = ((float)(routeEntry.SentPings - routeEntry.RecvPings) / routeEntry.SentPings);
  318. }
  319. tracePingRun.Trace.OnTraceEvent(TraceEventType.PingRecv);
  320. }
  321. }
  322. Thread.Sleep(tracePingRun.Trace.PingTimeFrame);
  323. }
  324.  
  325. tracePingRun.Trace.numThreads--;
  326. }
  327.  
  328. private static void ReverseCallback(IAsyncResult r)
  329. {
  330. try
  331. {
  332. IPHostEntry ihe = Dns.EndGetHostEntry(r);
  333. TracePingRun tpr = (TracePingRun)r.AsyncState;
  334. tpr.IPHostEntry = ihe;
  335.  
  336. }
  337. catch { }
  338. }
  339.  
  340. #region IDisposable Members
  341.  
  342. public void Dispose()
  343. {
  344. run = false;
  345.  
  346. }
  347.  
  348.  
  349.  
  350. #endregion
  351. }
  352. }
Advertisement
Add Comment
Please, Sign In to add comment