// This callback will run after each ping iteration // This is technically our main update loop for the graph void OnPingResultsUpdateCallback(PingResults r) { // Make sure we're not updating the display too frequently if (!displayUpdateLimiter.RequestRun()) { return; } int scalePrevious = m_Scale; // Reset position Console.CursorTop = m_PlotStartY; Console.CursorLeft = m_PlotStartX; // Update labels UpdateLegend(r); // Get results from ping and add to graph AddResponseToGraph(r.CurrTime); // Draw graph columns DrawColumns(); // Only draw the y axis labels if the scale has changed if (scalePrevious != m_Scale) { DrawYAxisLabels(); } Console.CursorTop = EndCursorPosY; }
/// <summary> /// Stores graph drawing loop /// </summary> private void Draw() { // The actual display update rate may be limited by the ping interval RateLimiter displayUpdateLimiter = new RateLimiter(TimeSpan.FromMilliseconds(500)); // This callback will run after each ping iteration void ResultsUpdateCallback(PingResults r) { // Make sure we're not updating the display too frequently //if (!displayUpdateLimiter.RequestRun()) { // return; //} // Reset position Console.CursorTop = m_PlotStartY; Console.CursorLeft = m_PlotStartX; // Update labels UpdateLegend(r); // Get results from ping and add to graph AddResponseToGraph(r.CurrTime); // Draw graph columns DrawGraphColumns(); DrawYAxisLabels(); Console.CursorTop = EndCursorPosY; } // Start pinging PingResults results = m_Ping.Send(m_PingAttributes, ResultsUpdateCallback); }
public static void Start(string address, CancellationToken cancellationToken) { PingAttributes attrs = new PingAttributes(); m_Address = address; // Verify address attrs.ResolvedAddress = Lookup.QueryDNS(address, AddressFamily.InterNetwork); // Setup ping attributes attrs.Interval = 0; attrs.Timeout = 100; attrs.Message = "R U Dead Yet?"; // TODO: Option for 'heavy' flood with bloated packet sizes attrs.Continous = true; Ping p = new Ping(attrs, cancellationToken, ResultsUpdateCallback); // Disable output for faster speeds Display.ShowOutput = false; // Start flooding PingResults results = p.Send(); // Display results Display.ShowOutput = true; Display.PingResults(attrs, results); }
public void Start(string address, CancellationToken cancellationToken) { PingAttributes attrs = new PingAttributes(); _address = address; // Verify address attrs.ResolvedAddress = Lookup.QueryDNS(address, AddressFamily.InterNetwork); // Setup ping attributes attrs.Interval = 0; attrs.Timeout = 100; attrs.Message = "R U Dead Yet?"; // TODO: Option for 'heavy' flood with bloated packet sizes attrs.Continous = true; // Setup ping object Ping p = new Ping(attrs, cancellationToken); p.OnResultsUpdate += OnResultsUpdate; // Start flooding PingResults results = p.Send(); ConsoleDisplay.PingResults(attrs, results); }
/// <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); }
private void Reset() { m_CurrentSequenceNumber = 0; m_CurrentReceiveTimeout = 0; // Wipe any previous results m_PingResults = new PingResults(); }
private void Cleanup() { // On deconstruction m_Socket.Close(); m_Packet = null; m_PingAttributes = null; m_PingResults = null; OnPingResultsUpdateCallback = null; }
public Ping(PingAttributes attributes, CancellationToken cancellationToken, Action <PingResults> resultsUpdateCallback = null) // On results update { m_PingAttributes = attributes; m_PingResults = new PingResults(); m_CancellationToken = cancellationToken; OnPingResultsUpdateCallback = resultsUpdateCallback; Setup(); }
/// <summary> /// Listens for all ICMPv4 activity on localhost. /// /// Does this by setting a raw socket to SV_IO_ALL which /// will recieve all packets and filters to just show /// ICMP packets. Runs until ctrl-c or exit /// </summary> /// <source>https://stackoverflow.com/a/9174392</source> public void Listen() { IPAddress localAddress = null; Socket listeningSocket = null; PingResults results = new PingResults(); // Find local address localAddress = IPAddress.Parse(PowerPing.Lookup.LocalAddress()); IsRunning = true; try { // Create listener socket listeningSocket = CreateRawSocket(AddressFamily.InterNetwork); listeningSocket.Bind(new IPEndPoint(localAddress, 0)); listeningSocket.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 }); // Set SIO_RCVALL flag to socket IO control PowerPing.Display.ListenIntroMsg(); // Listening loop while (true) { byte[] buffer = new byte[4096]; // TODO: could cause overflow? // Recieve any incoming ICMPv4 packets EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); int bytesRead = listeningSocket.ReceiveFrom(buffer, ref remoteEndPoint); ICMP response = new ICMP(buffer, bytesRead); // Display captured packet PowerPing.Display.CapturedPacket(response, remoteEndPoint.ToString(), DateTime.Now.ToString("h:mm:ss.ff tt"), bytesRead); // Store results results.CountPacketType(response.type); results.Received++; if (cancelEvent.WaitOne(0)) { break; } } } catch (SocketException) { PowerPing.Display.Error("Could not read packet from socket"); results.Lost++; } catch (Exception) { PowerPing.Display.Error("General exception occured", true); } // Clean up IsRunning = false; listeningSocket.Close(); Display.ListenResults(results); }
public static void ListenForICMPOnAddress(IPAddress address) { Socket listeningSocket = null; PingResults results = new PingResults(); int bufferSize = 4096; // Create listener socket try { listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); listeningSocket.Bind(new IPEndPoint(address, 0)); listeningSocket.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 }); // Set SIO_RCVALL flag to socket IO control listeningSocket.ReceiveBufferSize = bufferSize; } catch (Exception e) { ConsoleDisplay.Error($"Exception occured while trying to create listening socket for {address.ToString()} ({e.GetType().ToString().Split('.').Last()})"); return; } ConsoleDisplay.ListenIntroMsg(address.ToString()); // Listening loop while (true) { byte[] buffer = new byte[bufferSize]; try { // Recieve any incoming ICMPv4 packets EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); int bytesRead = listeningSocket.ReceiveFrom(buffer, ref remoteEndPoint); ICMP response = new ICMP(buffer, bytesRead); // Display captured packet ConsoleDisplay.CapturedPacket(address.ToString(), response, remoteEndPoint.ToString(), DateTime.Now.ToString("h:mm:ss.ff tt"), bytesRead); // Store results results.CountPacketType(response.Type); results.IncrementReceivedPackets(); } catch (OperationCanceledException) { } catch (SocketException) { ConsoleDisplay.Error("Could not read packet from socket"); } } listeningSocket.Close(); }
public static void Start(CancellationToken cancellationToken) { IPAddress localAddress = null; Socket listeningSocket = null; PingResults results = new PingResults(); int bufferSize = 4096; // Find local address localAddress = IPAddress.Parse(Lookup.GetLocalAddress()); try { // Create listener socket listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); listeningSocket.Bind(new IPEndPoint(localAddress, 0)); listeningSocket.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 }); // Set SIO_RCVALL flag to socket IO control listeningSocket.ReceiveBufferSize = bufferSize; Display.ListenIntroMsg(localAddress.ToString()); // Listening loop while (!cancellationToken.IsCancellationRequested) { byte[] buffer = new byte[bufferSize]; // Recieve any incoming ICMPv4 packets EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); int bytesRead = Helper.RunWithCancellationToken(() => listeningSocket.ReceiveFrom(buffer, ref remoteEndPoint), cancellationToken); ICMP response = new ICMP(buffer, bytesRead); // Display captured packet Display.CapturedPacket(response, remoteEndPoint.ToString(), DateTime.Now.ToString("h:mm:ss.ff tt"), bytesRead); // Store results results.CountPacketType(response.Type); results.Received++; } } catch (OperationCanceledException) { } catch (SocketException) { Display.Error("Could not read packet from socket"); } catch (Exception e) { Display.Error($"General exception occured while trying to create listening socket (Exception: {e.GetType().ToString().Split('.').Last()}"); } // Clean up listeningSocket.Close(); // TODO: Implement ListenResults method //Display.ListenResults(results); }
public static void Start(string address, CancellationToken cancellationToken) { PingAttributes attrs = new PingAttributes(); RateLimiter displayUpdateLimiter = new RateLimiter(TimeSpan.FromMilliseconds(500)); ulong previousPingsSent = 0; Ping p = new Ping(cancellationToken); // Verify address attrs.Address = Lookup.QueryDNS(address, AddressFamily.InterNetwork);; // Setup ping attributes attrs.Interval = 0; attrs.Timeout = 100; attrs.Message = "R U Dead Yet?"; // TODO: Option for 'heavy' flood with bloated packet sizes attrs.Continous = true; // Disable output for faster speeds Display.ShowOutput = false; // This callback will run after each ping iteration void ResultsUpdateCallback(PingResults r) { // Make sure we're not updating the display too frequently if (!displayUpdateLimiter.RequestRun()) { return; } // Calculate pings per second double pingsPerSecond = 0; if (displayUpdateLimiter.ElapsedSinceLastRun != TimeSpan.Zero) { pingsPerSecond = (r.Sent - previousPingsSent) / displayUpdateLimiter.ElapsedSinceLastRun.TotalSeconds; } previousPingsSent = r.Sent; // Update results text Display.FloodProgress(r.Sent, (ulong)Math.Round(pingsPerSecond), address); } // Start flooding PingResults results = p.Send(attrs, ResultsUpdateCallback); // Display results Display.ShowOutput = true; Display.PingResults(attrs, results); }
/// <summary> /// Update graph text labels /// </summary> /// <param name="results"></param> private void UpdateLabels(PingResults results) { // save cursor location int cursorPositionX = Console.CursorLeft; int cursorPositionY = Console.CursorTop; String blankLabel = new String(' ', 6); // Update sent label Console.SetCursorPosition(sentLabelX, sentLabelY); // Clear label first Console.Write(blankLabel); // Move cursor back Console.CursorLeft = Console.CursorLeft - 6; // Write label value Console.Write(results.Sent); // Update recieve label Console.SetCursorPosition(recLabelX, recLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 6; Console.Write(results.Received); // Update fail label Console.SetCursorPosition(failLabelX, failLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 6; Console.Write(results.Lost); // Update RTT label Console.SetCursorPosition(rttLabelX, rttLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 6; Console.Write("{0:0.0}ms", results.CurTime); // Update time label Console.SetCursorPosition(timeLabelX, timeLabelY); Console.Write(blankLabel + " "); Console.CursorLeft = Console.CursorLeft - 14; Console.Write("{0:hh\\:mm\\:ss}", results.TotalRunTime); // Reset cursor to starting position Console.SetCursorPosition(cursorPositionX, cursorPositionY); }
/// <summary> /// Update graph legend text labels /// </summary> /// <param name="results"></param> private void UpdateLegend(PingResults results) { // save cursor location int cursorPositionX = Console.CursorLeft; int cursorPositionY = Console.CursorTop; string blankLabel = new string(' ', 8); // Update sent label Console.SetCursorPosition(m_SentLabelX, m_SentLabelY); // Clear label first Console.Write(blankLabel); // Move cursor back Console.CursorLeft = Console.CursorLeft - 8; // Write label value Console.Write(results.Sent); // Update recieve label Console.SetCursorPosition(m_RecvLabelX, m_RecvLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write(results.Received); // Update fail label Console.SetCursorPosition(m_FailLabelX, m_FailLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write(results.Lost); // Update RTT label Console.SetCursorPosition(m_RttLabelX, m_RttLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write("{0:0.0}ms", results.CurrTime); // Update time label Console.SetCursorPosition(m_TimeLabelX, m_TimeLabelY); Console.Write(blankLabel + " "); Console.CursorLeft = Console.CursorLeft - 16; Console.Write("{0:hh\\:mm\\:ss}", results.TotalRunTime); // Reset cursor to starting position Console.SetCursorPosition(cursorPositionX, cursorPositionY); }
// This callback will run after each ping iteration public void OnResultsUpdate(PingResults r) { // Make sure we're not updating the display too frequently if (!_displayUpdateLimiter.RequestRun()) { return; } // Calculate pings per second double pingsPerSecond = 0; if (_displayUpdateLimiter.ElapsedSinceLastRun != TimeSpan.Zero) { pingsPerSecond = (r.Sent - _previousPingsSent) / _displayUpdateLimiter.ElapsedSinceLastRun.TotalSeconds; } _previousPingsSent = r.Sent; // Update results text ConsoleDisplay.FloodProgress(r.Sent, (ulong)Math.Round(pingsPerSecond), _address); }
// This callback will run after each ping iteration private static void ResultsUpdateCallback(PingResults r) { // Make sure we're not updating the display too frequently if (!displayUpdateLimiter.RequestRun()) { return; } // Calculate pings per second double pingsPerSecond = 0; if (displayUpdateLimiter.ElapsedSinceLastRun != TimeSpan.Zero) { pingsPerSecond = (r.Sent - previousPingsSent) / displayUpdateLimiter.ElapsedSinceLastRun.TotalSeconds; } previousPingsSent = r.Sent; // Update results text Display.FloodProgress(r.Sent, (ulong)Math.Round(pingsPerSecond), m_Address); }
/// <summary> /// Displays and updates results of an ICMP flood /// </summary> /// <param name="results"></param> public static void FloodProgress(PingResults results, string target) { // Check if labels have already been drawn if (sentPos.Left > 0) { // Store original cursor position CursorPosition originalPos = new CursorPosition(Console.CursorLeft, Console.CursorTop); Console.CursorVisible = false; // Update labels Console.SetCursorPosition(sentPos.Left, sentPos.Top); Console.Write(results.Sent); Console.SetCursorPosition(ppsPos.Left, ppsPos.Top); Console.Write(" "); // Blank first Console.SetCursorPosition(ppsPos.Left, ppsPos.Top); Console.Write(results.Sent - sentPings); // Reset to original cursor position Console.SetCursorPosition(originalPos.Left, originalPos.Top); Console.CursorVisible = true; } else { // Draw labels Console.WriteLine(FLOOD_INTO_TXT, target); Console.Write(FLOOD_SEND_TXT); sentPos.Left = Console.CursorLeft; sentPos.Top = Console.CursorTop; Console.WriteLine("0"); Console.Write(FLOOD_PPS_TXT); ppsPos.Left = Console.CursorLeft; ppsPos.Top = Console.CursorTop; Console.WriteLine(); Console.WriteLine(FLOOD_EXIT_TXT); } sentPings = results.Sent; }
internal void OnFinish(PingResults results) { _logFile.Append($"[{_destinationAddress}] " + $"[{results.EndTime.ToString(DATETIME_STRING_FORMAT)}] " + $"[FINISH] ellapsed={results.TotalRunTime} start_time={results.StartTime} "); _logFile.Append($"[{_destinationAddress}] " + $"[{results.EndTime.ToString(DATETIME_STRING_FORMAT)}] " + $"[STATISTICS] [PINGS] " + $"sent={results.Sent} " + $"received={results.Received} " + $"lost={results.Lost} "); _logFile.Append($"[{_destinationAddress}] " + $"[{results.EndTime.ToString(DATETIME_STRING_FORMAT)}] " + $"[STATISTICS] [PACKETS] " + $"good={results.GoodPackets} " + $"error={results.ErrorPackets} " + $"other={results.OtherPackets} "); _logFile.Append($"[{_destinationAddress}] " + $"[{results.EndTime.ToString(DATETIME_STRING_FORMAT)}] " + $"[STATISTICS] [TIME] " + $"max={results.MaxTime} " + $"min={results.MinTime} " + $"avg={results.AvgTime} "); }
/// <summary> /// Displays statistics for a ping object /// </summary> /// <param name="ping"> </param> public static void PingResults(PingAttributes attrs, PingResults results) { if (!Configuration.ShowOutput || !Configuration.ShowSummary) { return; } ResetColor(); // Display stats double percent = (double)results.Lost / results.Sent; percent = Math.Round(percent * 100, 2); Console.WriteLine(); Console.WriteLine(ProgramStrings.RESULTS_HEADER, attrs.ResolvedAddress); // General: Sent [ 0 ], Recieved [ 0 ], Lost [ 0 ] (0% loss) Console.Write(ProgramStrings.RESULTS_GENERAL_TAG + ProgramStrings.RESULTS_SENT_TXT); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Sent); } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Sent); ResetColor(); } Console.Write(ProgramStrings.RESULTS_RECV_TXT); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Received); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Received); ResetColor(); } Console.Write(ProgramStrings.RESULTS_LOST_TXT); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Lost); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.Lost); ResetColor(); } Console.WriteLine(ProgramStrings.RESULTS_PERCENT_LOST_TXT, percent); // Times: Min [ 0ms ] Max [ 0ms ] Avg [ 0ms ] Console.WriteLine(ProgramStrings.RESULTS_TIMES_TAG + ProgramStrings.RESULTS_TIME_TXT, results.MinTime, results.MaxTime, results.AvgTime); // Types: Good [ 0 ], Errors [ 0 ], Unknown [ 0 ] Console.Write(ProgramStrings.RESULTS_TYPES_TAG); Console.Write(ProgramStrings.RESULTS_PKT_GOOD); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.GoodPackets); ResetColor(); } Console.Write(ProgramStrings.RESULTS_PKT_ERR); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.ErrorPackets); ResetColor(); } Console.Write(ProgramStrings.RESULTS_PKT_UKN); if (Configuration.NoColor) { Console.Write(ProgramStrings.RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(ProgramStrings.RESULTS_INFO_BOX, results.OtherPackets); ResetColor(); } // Started at: 0:00:00 (local time) Console.WriteLine(ProgramStrings.RESULTS_START_TIME_TXT, results.StartTime); //Runtime: hh:mm:ss.f Console.WriteLine(ProgramStrings.RESULTS_RUNTIME_TXT, results.TotalRunTime); Console.WriteLine(); if (results.HasOverflowed) { Console.WriteLine(ProgramStrings.RESULTS_OVERFLOW_MSG); Console.WriteLine(); } if (Configuration.RequireInput) { Helper.WaitForUserInput(); } }
private PingResults SendICMP(PingAttributes attrs, Action <PingResults> resultsUpdateCallback = null) { PingResults results = new PingResults(); ICMP packet = new ICMP(); byte[] receiveBuffer = new byte[attrs.RecieveBufferSize]; // Ipv4Header.length + IcmpHeader.length + attrs.recievebuffersize int bytesRead, packetSize; // Convert to IPAddress IPAddress ipAddr = IPAddress.Parse(attrs.Address); // Setup endpoint IPEndPoint iep = new IPEndPoint(ipAddr, 0); // Setup raw socket Socket sock = CreateRawSocket(ipAddr.AddressFamily); // Helper function to set receive timeout (only if it's changing) int appliedReceiveTimeout = 0; void SetReceiveTimeout(int receiveTimeout) { if (receiveTimeout != appliedReceiveTimeout) { sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, receiveTimeout); appliedReceiveTimeout = receiveTimeout; } } // Set socket options sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, attrs.Ttl); sock.DontFragment = attrs.DontFragment; sock.ReceiveBufferSize = attrs.RecieveBufferSize; // Create packet message payload byte[] payload; if (attrs.Size != -1) { payload = Helper.GenerateByteArray(attrs.Size); } else { payload = Encoding.ASCII.GetBytes(attrs.Message); } // Construct our ICMP packet packet.Type = attrs.Type; packet.Code = attrs.Code; Buffer.BlockCopy(BitConverter.GetBytes(m_SessionId), 0, packet.Message, 0, 2); // Add identifier to ICMP message Buffer.BlockCopy(payload, 0, packet.Message, 4, payload.Length); // Add text into ICMP message packet.MessageSize = payload.Length + 4; packetSize = packet.MessageSize + 4; // Sending loop for (int index = 1; attrs.Continous || index <= attrs.Count; index++) { if (index != 1) { // Wait for set interval before sending again or cancel if requested if (m_CancellationToken.WaitHandle.WaitOne(attrs.Interval)) { break; } // Generate random interval when RandomTimings flag is set if (attrs.RandomTiming) { attrs.Interval = Helper.RandomInt(5000, 100000); } } // Include sequence number in ping message ushort sequenceNum = (ushort)index; Buffer.BlockCopy(BitConverter.GetBytes(sequenceNum), 0, packet.Message, 2, 2); // Fill ICMP message field if (attrs.RandomMsg) { payload = Encoding.ASCII.GetBytes(Helper.RandomString()); Buffer.BlockCopy(payload, 0, packet.Message, 4, payload.Length); } // Update packet checksum packet.Checksum = 0; UInt16 chksm = packet.GetChecksum(); packet.Checksum = chksm; try { // Show request packet if (Display.ShowRequests) { Display.RequestPacket(packet, Display.UseInputtedAddress | Display.UseResolvedAddress ? attrs.InputtedAddress : attrs.Address, index); } // If there were extra responses from a prior request, ignore them while (sock.Available != 0) { bytesRead = sock.Receive(receiveBuffer); } // Send ping request sock.SendTo(packet.GetBytes(), packetSize, SocketFlags.None, iep); // Packet size = message field + 4 header bytes long requestTimestamp = Stopwatch.GetTimestamp(); try { results.Sent++; } catch (OverflowException) { results.HasOverflowed = true; } if (m_Debug) { // Induce random wait for debugging Random rnd = new Random(); Thread.Sleep(scale);//rnd.Next(scale));//1500)); //Thread.Sleep(rnd.Next(100)); if (inverting) { scale -= 5; } else { scale += 5; } if (scale > 1100) { inverting = true; } else if (scale == 10) { inverting = false; } //if (rnd.Next(20) == 1) { throw new SocketException(); } } ICMP response; EndPoint responseEP = iep; TimeSpan replyTime = TimeSpan.Zero; do { // Cancel if requested m_CancellationToken.ThrowIfCancellationRequested(); // Set receive timeout, limited to 250ms so we don't block very long without checking for // cancellation. If the requested ping timeout is longer, we will wait some more in subsequent // loop iterations until the requested ping timeout is reached. int remainingTimeout = (int)Math.Ceiling(attrs.Timeout - replyTime.TotalMilliseconds); if (remainingTimeout <= 0) { throw new SocketException(); } SetReceiveTimeout(Math.Min(remainingTimeout, 250)); // Wait for response try { bytesRead = sock.ReceiveFrom(receiveBuffer, ref responseEP); } catch (SocketException) { bytesRead = 0; } replyTime = new TimeSpan(Helper.StopwatchToTimeSpanTicks(Stopwatch.GetTimestamp() - requestTimestamp)); if (bytesRead == 0) { response = null; } else { // Store reply packet response = new ICMP(receiveBuffer, bytesRead); // If we sent an echo and receive a response with a different identifier or sequence // number, ignore it (it could correspond to an older request that timed out) if (packet.Type == 8 && response.Type == 0) { ushort responseSessionId = BitConverter.ToUInt16(response.Message, 0); ushort responseSequenceNum = BitConverter.ToUInt16(response.Message, 2); if (responseSessionId != m_SessionId || responseSequenceNum != sequenceNum) { response = null; } } } } while (response == null); // Display reply packet if (Display.ShowReplies) { Display.ReplyPacket(response, Display.UseInputtedAddress | Display.UseResolvedAddress ? attrs.InputtedAddress : responseEP.ToString(), index, replyTime, bytesRead); } // Store response info try { results.Received++; } catch (OverflowException) { results.HasOverflowed = true; } results.CountPacketType(response.Type); results.SaveResponseTime(replyTime.TotalMilliseconds); if (attrs.BeepLevel == 2) { try { Console.Beep(); } catch (Exception) { } // Silently continue if Console.Beep errors } } catch (IOException) { if (Display.ShowOutput) { Display.Error("General transmit error"); } results.SaveResponseTime(-1); try { results.Lost++; } catch (OverflowException) { results.HasOverflowed = true; } } catch (SocketException) { Display.Timeout(index); if (attrs.BeepLevel == 1) { try { Console.Beep(); } catch (Exception) { results.HasOverflowed = true; } } results.SaveResponseTime(-1); try { results.Lost++; } catch (OverflowException) { results.HasOverflowed = true; } } catch (OperationCanceledException) { results.ScanWasCanceled = true; break; } catch (Exception) { if (Display.ShowOutput) { Display.Error("General error occured"); } results.SaveResponseTime(-1); try { results.Lost++; } catch (OverflowException) { results.HasOverflowed = true; } } // Run callback (if provided) to notify of updated results resultsUpdateCallback?.Invoke(results); } // Clean up sock.Close(); return(results); }
/// <summary> /// Main entry point of PowerPing /// Parses arguments and runs operations /// </summary> /// <param name="args">Program arguments</param> static void Main(string[] args) { // User inputted attributes PingAttributes inputtedAttributes = new PingAttributes(); // Setup console Display.DefaultForegroundColor = Console.ForegroundColor; Display.DefaultBackgroundColor = Console.BackgroundColor; // Show current version info //Display.Version(); // Check if no arguments if (args.Length == 0) { Display.Help(); Helper.WaitForUserInput(); return; } // Parse command line arguments if (!CommandLine.Parse(args, ref inputtedAttributes)) { Helper.ErrorAndExit("Problem parsing arguments, use \"PowerPing /help\" or \"PowerPing /?\" for help."); } // Find address/host in arguments if (inputtedAttributes.Operation != PingOperation.Whoami && inputtedAttributes.Operation != PingOperation.Listen) { if (!CommandLine.FindAddress(args, ref inputtedAttributes)) { Helper.ErrorAndExit("Could not find correctly formatted address, please check and try again"); } } // Perform DNS lookup on inputted address // inputtedAttributes.ResolvedAddress = Lookup.QueryDNS(inputtedAttributes.InputtedAddress, inputtedAttributes.UseICMPv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6); // Add Control C event handler if (inputtedAttributes.Operation != PingOperation.Whoami && inputtedAttributes.Operation != PingOperation.Location && inputtedAttributes.Operation != PingOperation.Whois) { Console.CancelKeyPress += new ConsoleCancelEventHandler(ExitHandler); } // Select correct function using opMode Ping p; Graph g; switch (inputtedAttributes.Operation) { case PingOperation.Listen: // If we find an address then pass it to listen, otherwise start it without one if (CommandLine.FindAddress(args, ref inputtedAttributes)) { Listen.Start(m_CancellationTokenSource.Token, inputtedAttributes.InputtedAddress); } else { Listen.Start(m_CancellationTokenSource.Token); } break; case PingOperation.Location: Console.WriteLine(Lookup.GetAddressLocationInfo(inputtedAttributes.InputtedAddress, false)); Helper.WaitForUserInput(); break; case PingOperation.Whoami: Console.WriteLine(Lookup.GetAddressLocationInfo("", true)); Helper.WaitForUserInput(); break; case PingOperation.Whois: Lookup.QueryWhoIs(inputtedAttributes.InputtedAddress); break; case PingOperation.Graph: g = new Graph(inputtedAttributes.InputtedAddress, m_CancellationTokenSource.Token); g.Start(); break; case PingOperation.CompactGraph: g = new Graph(inputtedAttributes.InputtedAddress, m_CancellationTokenSource.Token); g.CompactGraph = true; g.Start(); break; case PingOperation.Flood: Flood.Start(inputtedAttributes.InputtedAddress, m_CancellationTokenSource.Token); break; case PingOperation.Scan: Scan.Start(inputtedAttributes.InputtedAddress, m_CancellationTokenSource.Token); break; case PingOperation.Normal: // Send ping normally p = new Ping(inputtedAttributes, m_CancellationTokenSource.Token); PingResults results = p.Send(); Display.PingResults(inputtedAttributes, results); break; default: Helper.ErrorAndExit("Could not determine ping operation"); break; } // Reset console colour Display.ResetColor(); try { Console.CursorVisible = true; } catch (Exception) { } }
/// <summary> /// Displays statistics for a ping object /// </summary> /// <param name="ping"> </param> public static void PingResults(PingAttributes attrs, PingResults results) { if (!Display.ShowOutput || !Display.ShowSummary) { return; } ResetColor(); // Display stats double percent = (double)results.Lost / results.Sent; percent = Math.Round(percent * 100, 2); Console.WriteLine(); Console.WriteLine(RESULTS_HEADER, attrs.ResolvedAddress); // General: Sent [ 0 ], Recieved [ 0 ], Lost [ 0 ] (0% loss) Console.Write(RESULTS_GENERAL_TAG + RESULTS_SENT_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Sent); } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(RESULTS_INFO_BOX, results.Sent); ResetColor(); } Console.Write(RESULTS_RECV_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Received); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(RESULTS_INFO_BOX, results.Received); ResetColor(); } Console.Write(RESULTS_LOST_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Lost); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(RESULTS_INFO_BOX, results.Lost); ResetColor(); } Console.WriteLine(RESULTS_PERCENT_LOST_TXT, percent); // Times: Min [ 0ms ] Max [ 0ms ] Avg [ 0ms ] Console.WriteLine(RESULTS_TIMES_TAG + RESULTS_TIME_TXT, results.MinTime, results.MaxTime, results.AvgTime); // Types: Good [ 0 ], Errors [ 0 ], Unknown [ 0 ] Console.Write(RESULTS_TYPES_TAG); Console.Write(RESULTS_PKT_GOOD); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(RESULTS_INFO_BOX, results.GoodPackets); ResetColor(); } Console.Write(RESULTS_PKT_ERR); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(RESULTS_INFO_BOX, results.ErrorPackets); ResetColor(); } Console.Write(RESULTS_PKT_UKN); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(RESULTS_INFO_BOX, results.OtherPackets); ResetColor(); } // Started at: 0:00:00 (local time) Console.WriteLine(RESULTS_START_TIME_TXT, results.StartTime); //Runtime: hh:mm:ss.f Console.WriteLine(RESULTS_RUNTIME_TXT, results.TotalRunTime); Console.WriteLine(); if (results.HasOverflowed) { Console.WriteLine(RESULTS_OVERFLOW_MSG); Console.WriteLine(); } if (Properties.Settings.Default.ShownInputPrompt == false) { Display.Message( "(NOTE: To stop PowerPing from closing too quickly (when opening in a new Administrator console) PowerPing will\n" + "prompt for user input upon completion BY DEFAULT, you can disable this PERMENANTLY using the --noinput argument next time)\n", ConsoleColor.Cyan); Properties.Settings.Default.ShownInputPrompt = true; Properties.Settings.Default.Save(); } Helper.WaitForUserInput(); }
public static void ListenResults(PingResults results) { throw new NotImplementedException(); }
/// <summary> /// Update graph legend text labels /// </summary> /// <param name="results"></param> private void UpdateLegend(PingResults results) { // save cursor location int cursorPositionX = Console.CursorLeft; int cursorPositionY = Console.CursorTop; string blankLabel = new string(' ', 8); // Update sent label Console.SetCursorPosition(m_SentLabelX, m_SentLabelY); // Clear label first Console.Write(blankLabel); // Move cursor back Console.CursorLeft = Console.CursorLeft - 8; // Write label value Console.Write(results.Sent); // Update recieve label Console.SetCursorPosition(m_RecvLabelX, m_RecvLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write(results.Received); // Update average label Console.SetCursorPosition(m_AvgLabelX, m_AvgLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; double r = Math.Round(results.AvgTime, 1); if (lastAvg < r) { Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write("+"); if (results.CurrTime - lastRes > 20) { Console.Write("+"); } } else if (lastAvg > r) { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.Write("-"); if (lastRes - results.CurrTime > 20) { Console.Write("-"); } } else { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.Write("~"); } lastAvg = r; lastRes = results.CurrTime; Console.ResetColor(); Console.Write("{0:0.0}ms", results.AvgTime); // Update fail label Console.SetCursorPosition(m_FailLabelX, m_FailLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write(results.Lost); // Update RTT label Console.SetCursorPosition(m_RttLabelX, m_RttLabelY); Console.Write(blankLabel); Console.CursorLeft = Console.CursorLeft - 8; Console.Write("{0:0.0}ms", results.CurrTime); // Update time label Console.SetCursorPosition(m_TimeLabelX, m_TimeLabelY); Console.Write(blankLabel + " "); Console.CursorLeft = Console.CursorLeft - 16; Console.Write("{0:hh\\:mm\\:ss}", results.TotalRunTime); // Reset cursor to starting position Console.SetCursorPosition(cursorPositionX, cursorPositionY); }
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); }
/// <summary> /// Displays statistics for a ping object /// </summary> /// <param name="ping"> </param> public static void PingResults(Ping ping) { // Load attributes PingAttributes attrs = ping.Attributes; PingResults results = ping.Results; ResetColor(); // Display stats double percent = (double)results.Lost / results.Sent; percent = Math.Round(percent * 100, 2); Console.WriteLine(); Console.WriteLine(RESULTS_HEADER, attrs.Address); // General: Sent [ 0 ], Recieved [ 0 ], Lost [ 0 ] (0% loss) Console.Write(RESULTS_GENERAL_TAG + RESULTS_SENT_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Sent); } else { Console.ForegroundColor = ConsoleColor.Yellow; Console.Write(RESULTS_INFO_BOX, results.Sent); ResetColor(); } Console.Write(RESULTS_RECV_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Received); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(RESULTS_INFO_BOX, results.Received); ResetColor(); } Console.Write(RESULTS_LOST_TXT); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.Lost); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(RESULTS_INFO_BOX, results.Lost); ResetColor(); } Console.WriteLine(RESULTS_PERCENT_LOST_TXT, percent); // Times: Min [ 0ms ] Max [ 0ms ] Avg [ 0ms ] Console.WriteLine(RESULTS_TIMES_TAG + RESULTS_TIME_TXT, results.MinTime, results.MaxTime, results.AvgTime); // Types: Good [ 0 ], Errors [ 0 ], Unknown [ 0 ] Console.Write(RESULTS_TYPES_TAG); Console.Write(RESULTS_PKT_GOOD); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Green; Console.Write(RESULTS_INFO_BOX, results.GoodPackets); ResetColor(); } Console.Write(RESULTS_PKT_ERR); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Red; Console.Write(RESULTS_INFO_BOX, results.ErrorPackets); ResetColor(); } Console.Write(RESULTS_PKT_UKN); if (NoColor) { Console.Write(RESULTS_INFO_BOX, results.GoodPackets); } else { Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine(RESULTS_INFO_BOX, results.OtherPackets); ResetColor(); } // Started at: 0:00:00 (local time) Console.WriteLine(RESULTS_START_TIME_TXT, results.StartTime); //Runtime: hh:mm:ss.f Console.WriteLine(RESULTS_RUNTIME_TXT, results.TotalRunTime); Console.WriteLine(); if (results.HasOverflowed) { Console.WriteLine(RESULTS_OVERFLOW_MSG); Console.WriteLine(); } if (!NoInput) { // Confirm to exit PowerPing.Helper.Pause(true); } }
/// <summary> /// Network scanning method. /// /// Uses pings to scan a IP address range and identify hosts /// that are active. /// /// range should be in format 192.0.0.1-255, where - denotes the range /// This can be specified at any octlet of the address (192.0.1-100.1.255) /// </summary> /// <param name="range">Range of addresses to scan</param> public void Scan(string range, bool recursing = false) { List <string> scanList = new List <string>(); // List of addresses to scan String[] ipSegments = range.Split('.'); PingResults results = new PingResults(); List <string> activeHosts = new List <string>(); List <double> activeHostTimes = new List <double>(); Stopwatch scanTimer = 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; // Check format of address (for '-'s and disallow multipl '-'s in one segment) if (!range.Contains("-")) { Display.Error("Scan - No range specified, must be specified in format: 192.168.1.1-254", true, true); } // Holds the ranges for each ip segment int[] segLower = new int[4]; int[] segUpper = new int[4]; // Work out upper and lower ranges for each segment try{ for (int y = 0; y < 4; y++) { string[] ranges = ipSegments[y].Split('-'); segLower[y] = Convert.ToInt16(ranges[0]); segUpper[y] = (ranges.Length == 1) ? segLower[y] : Convert.ToInt16(ranges[1]); } } catch (FormatException) { Display.Error("Scan - Incorrect format [" + range + "], must be specified in format: 192.168.1.1-254", true, true); } // Build list of addresses from ranges for (int seg1 = segLower[0]; seg1 <= segUpper[0]; seg1++) { for (int seg2 = segLower[1]; seg2 <= segUpper[1]; seg2++) { for (int seg3 = segLower[2]; seg3 <= segUpper[2]; seg3++) { for (int seg4 = segLower[3]; seg4 <= segUpper[3]; seg4++) { scanList.Add(new IPAddress(new byte[] { (byte)seg1, (byte)seg2, (byte)seg3, (byte)seg4 }).ToString()); } } } } scanTimer.Start(); // Scan loop foreach (string host in scanList) { // Update host attrs.Address = host; scanned++; // Reset global results for accurate results // (results need to be set globally while running for graph but need to be semi local for scan // or results bleed through so active hosts can't be determined) this.Results = new PingResults(); // Send ping results = SendICMP(attrs); Display.ScanProgress(scanned, activeHosts.Count, scanList.Count, scanTimer.Elapsed, range, attrs.Address); if (results.Lost == 0 && results.ErrorPackets != 1) { // If host is active, add to list activeHosts.Add(host); activeHostTimes.Add(results.CurTime); } } scanTimer.Stop(); PowerPing.Display.ScanResults(scanList.Count, activeHosts, activeHostTimes); }
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); }