/// <summary> /// Sends a set of ping packets, results are stores within /// Ping.Results of the called object /// /// Acts as a basic wrapper to SendICMP and feeds it a specific /// set of PingAttributes /// </summary> public PingResults Send(PingAttributes attrs, Action <PingResults> onResultsUpdate = null) { // Lookup host if specified if (attrs.InputtedAddress != "") { attrs.Address = Lookup.QueryDNS(attrs.InputtedAddress, attrs.ForceV4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6); } Display.PingIntroMsg(attrs); if (Display.UseResolvedAddress) { try { attrs.InputtedAddress = Helper.RunWithCancellationToken(() => Lookup.QueryHost(attrs.Address), m_CancellationToken); } catch (OperationCanceledException) { return(new PingResults()); } if (attrs.InputtedAddress == "") { // If reverse lookup fails just display whatever is in the address field attrs.InputtedAddress = attrs.Address; } } // Perform ping operation and store results PingResults results = SendICMP(attrs, onResultsUpdate); if (Display.ShowOutput) { Display.PingResults(attrs, results); } return(results); }
/// <summary> /// Display Initial ping message to screen, declaring simple info about the ping /// </summary> /// <param name="host">Resolved host address</param> /// <param name="ping">Ping object</param> public static void PingIntroMsg(PingAttributes attrs) { if (!Configuration.ShowOutput || !Configuration.ShowIntro) { return; } // TODO: I think this part is bullshit, check later if (Configuration.UseResolvedAddress) { try { attrs.InputtedAddress = Helper.RunWithCancellationToken(() => Lookup.QueryHost(attrs.ResolvedAddress), CancellationToken); } catch (OperationCanceledException) { } if (attrs.InputtedAddress == "") { // If reverse lookup fails just display whatever is in the address field attrs.InputtedAddress = attrs.ResolvedAddress; } } // Construct string Console.WriteLine(); Console.Write(ProgramStrings.INTRO_ADDR_TXT, attrs.InputtedAddress); if (!String.Equals(attrs.InputtedAddress, attrs.ResolvedAddress)) { // Only show resolved address if inputted address and resolved address are different Console.Write("[{0}] ", attrs.ResolvedAddress); } if (!Configuration.Short) { // Only show extra detail when not in Configuration.Short mode if (attrs.ArtificalMessageSize != -1) { // If custom packet size has been specified, show that Console.Write(ProgramStrings.INTRO_MSG, attrs.ArtificalMessageSize.ToString(), attrs.Type, attrs.Code, attrs.Ttl); } else { // Else show how big the string is in bytes Console.Write(ProgramStrings.INTRO_MSG, ASCIIEncoding.ASCII.GetByteCount(attrs.Message), attrs.Type, attrs.Code, attrs.Ttl); } } // Print string Console.WriteLine(":"); }
private void SendPacket() { byte[] receiveBuffer = new byte[m_PingAttributes.ReceiveBufferSize]; // Ipv4Header.length + IcmpHeader.length + attrs.recievebuffersize int bytesRead = 0; // Sending loop for (int index = 1; m_PingAttributes.Continous || index <= m_PingAttributes.Count; index++) { if (index != 1) { // Wait for set interval before sending again or cancel if requested if (m_CancellationToken.WaitHandle.WaitOne(m_PingAttributes.Interval)) { break; } // Generate random interval when RandomTiming flag is set if (m_PingAttributes.RandomTiming) { m_PingAttributes.Interval = Helper.RandomInt(5000, 100000); } } // Update packet before sending UpdatePacketSequenceNumber(index); if (m_PingAttributes.RandomMessage) { UpdatePacketMessage(Encoding.ASCII.GetBytes(Helper.RandomString())); } UpdatePacketChecksum(); try { // Show request packet if (Display.ShowRequests) { Display.RequestPacket(m_Packet, Display.UseInputtedAddress | Display.UseResolvedAddress ? m_PingAttributes.InputtedAddress : m_PingAttributes.ResolvedAddress, index); } // If there were extra responses from a prior request, ignore them while (m_Socket.Available != 0) { bytesRead = m_Socket.Receive(receiveBuffer); } // Send ping request m_Socket.SendTo(m_Packet.GetBytes(), m_PacketSize, SocketFlags.None, m_RemoteEndpoint); // Packet size = message field + 4 header bytes long requestTimestamp = Stopwatch.GetTimestamp(); m_PingResults.IncrementSentPackets(); // Just for artifically testing higher ping response times if (m_Debug) { Random rnd = new Random(); Thread.Sleep(rnd.Next(10, 400)); if (rnd.Next(3) == 1) { throw new SocketException(); } } // Try and recieve a packet ICMP response = null; EndPoint responseEP = m_RemoteEndpoint; TimeSpan replyTime = TimeSpan.Zero; ReceivePacket(ref response, ref responseEP, ref replyTime, ref bytesRead, requestTimestamp); if (Display.ShowReplies) { // Determine what form the response address is going to be displayed in string responseAddress = responseEP.ToString(); if (Display.UseResolvedAddress) { // Returned address normally have port at the end (eg 8.8.8.8:0) so we need to remove that before trying to query the DNS string responseIP = responseEP.ToString().Split(':')[0]; // Resolve the ip and store as the response address responseAddress = Helper.RunWithCancellationToken(() => Lookup.QueryHost(responseIP), m_CancellationToken); } else if (Display.UseInputtedAddress) { responseAddress = m_PingAttributes.InputtedAddress; } Display.ReplyPacket(response, responseAddress, index, replyTime, bytesRead); } // Store response info m_PingResults.IncrementReceivedPackets(); m_PingResults.CountPacketType(response.Type); m_PingResults.SaveResponseTime(replyTime.TotalMilliseconds); if (m_PingAttributes.BeepMode == 2) { try { Console.Beep(); } catch (Exception) { } // Silently continue if Console.Beep errors } } catch (IOException) { if (Display.ShowOutput) { Display.Error("General transmit error"); } m_PingResults.SaveResponseTime(-1); m_PingResults.IncrementLostPackets(); } catch (SocketException) { Display.Timeout(index); if (m_PingAttributes.BeepMode == 1) { try { Console.Beep(); } catch (Exception) { } } m_PingResults.SaveResponseTime(-1); m_PingResults.IncrementLostPackets(); } catch (OperationCanceledException) { m_PingResults.ScanWasCanceled = true; break; } catch (Exception) { if (Display.ShowOutput) { Display.Error("General error occured"); } m_PingResults.SaveResponseTime(-1); m_PingResults.IncrementLostPackets(); } // Run callback (if provided) to notify of updated results OnPingResultsUpdateCallback?.Invoke(m_PingResults); } }
public PingResults Send() { // Reset some properties so they are readyfor pinging Reset(); Display.PingIntroMsg(m_PingAttributes); // TODO: I think this part is bullshit, check later if (Display.UseResolvedAddress) { try { m_PingAttributes.InputtedAddress = Helper.RunWithCancellationToken(() => Lookup.QueryHost(m_PingAttributes.ResolvedAddress), m_CancellationToken); } catch (OperationCanceledException) { return(new PingResults()); } if (m_PingAttributes.InputtedAddress == "") { // If reverse lookup fails just display whatever is in the address field m_PingAttributes.InputtedAddress = m_PingAttributes.ResolvedAddress; } } // Peroform ping operation SendPacket(); return(m_PingResults); }
public static void Start(string range, CancellationToken cancellationToken) { Ping p = new Ping(cancellationToken); List <string> addresses = new List <string>(); List <HostInformation> activeHosts = new List <HostInformation>(); Stopwatch timer = new Stopwatch(); int scanned = 0; // Setup scan ping attributes PingAttributes attrs = new PingAttributes(); attrs.Timeout = 500; attrs.Interval = 0; attrs.Count = 1; Display.ShowOutput = false; // Get addresses to scan from range addresses = ParseRange(range); // TODO: In order to speed this up we need the following steps: /* * 1) Divide the address list by the number of threads we will us * 2) New thread method w/ mutable active hosts list * 3) Some way of updating the UI (resultsUpdateCallback?) */ timer.Start(); try { // Scan loop foreach (string host in addresses) { // Update host attrs.Address = host; // Send ping PingResults results = p.Send(attrs); if (results.ScanWasCanceled) { // Cancel was requested during scan throw new OperationCanceledException(); } scanned++; Display.ScanProgress(scanned, activeHosts.Count, addresses.Count, timer.Elapsed, range, attrs.Address); if (results.Lost == 0 && results.ErrorPackets != 1) { // If host is active, add to list activeHosts.Add(new HostInformation { Address = host, HostName = "", ResponseTime = results.CurrTime }); } } } catch (OperationCanceledException) { } // Lookup host's name Console.WriteLine(); Console.Write("Looking up host names, one sec..."); Console.CursorLeft = 0; foreach (HostInformation host in activeHosts) { string hostName = Helper.RunWithCancellationToken(() => Lookup.QueryHost(host.Address), cancellationToken); host.HostName = hostName; } Console.WriteLine(" "); Console.CursorTop--; Display.ScanResults(scanned, !cancellationToken.IsCancellationRequested, activeHosts); }
public static void Start(string range, CancellationToken cancellationToken) { List <string> addresses = new List <string>(); List <HostInformation> activeHosts = new List <HostInformation>(); Stopwatch timer = new Stopwatch(); // Get addresses to scan from range addresses = ParseRange(range); // Setup addresses and threads var splitAddresses = Helper.PartitionList(addresses, THREAD_COUNT); Thread[] threads = new Thread[THREAD_COUNT]; object lockObject = new object(); int scanned = 0; // Run the threads timer.Start(); for (int i = 0; i < THREAD_COUNT; i++) { List <string> addrs = splitAddresses[i]; threads[i] = new Thread(() => { PingAttributes attrs = new PingAttributes(); attrs.InputtedAddress = "127.0.0.1"; attrs.Timeout = 500; attrs.Interval = 0; attrs.Count = 1; Ping ping = new Ping(attrs, cancellationToken); try { foreach (string host in addrs) { // Send ping PingResults results = ping.Send(host); if (results.ScanWasCanceled) { // Cancel was requested during scan throw new OperationCanceledException(); } Interlocked.Increment(ref scanned); if (results.Lost == 0 && results.ErrorPackets != 1) { // If host is active, add to list lock (lockObject) { activeHosts.Add(new HostInformation { Address = host, HostName = "", ResponseTime = results.CurrTime }); } } } } catch (OperationCanceledException) { _cancelled = true; } }); threads[i].IsBackground = true; threads[i].Start(); } // Wait for all threads to exit int lastSent = 0, pingsPerSecond = 0; int lastSpeedCheck = 0; while (threads.Where(x => x.IsAlive).ToList().Count > 0) { int count = 0; lock (lockObject) { count = activeHosts.Count; } if (lastSpeedCheck == 5) { pingsPerSecond = Math.Abs((scanned - lastSent)); lastSent = scanned; lastSpeedCheck = 0; } ConsoleDisplay.ScanProgress( scanned, activeHosts.Count, addresses.Count, pingsPerSecond, timer.Elapsed, range); lastSpeedCheck++; Thread.Sleep(200); } // Display one last time so the bar actually completes // (scan could have completed while the main thread was sleeping) ConsoleDisplay.ScanProgress( scanned, activeHosts.Count, addresses.Count, pingsPerSecond, timer.Elapsed, range); // Exit out when the operation has been canceled if (_cancelled) { ConsoleDisplay.ScanResults(scanned, false, activeHosts); return; } // Lookup host's name Console.WriteLine(); Console.Write("Looking up host names, one sec..."); Console.CursorLeft = 0; foreach (HostInformation host in activeHosts) { string hostName = Helper.RunWithCancellationToken(() => Lookup.QueryHost(host.Address), cancellationToken); host.HostName = hostName; } Console.WriteLine(" "); Console.CursorTop--; ConsoleDisplay.ScanResults(scanned, !cancellationToken.IsCancellationRequested, activeHosts); }