/// <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); }
internal void OnStart(PingAttributes attributes) { _destinationAddress = attributes.InputtedAddress; string message = attributes.Message.Length > 50 ? $"{attributes.Message.Substring(0, 50)}...({attributes.Message.Length - 50} lines truncated)" : attributes.Message; _logFile.Append($"[{_destinationAddress}] " + $"[{DateTime.Now.ToString(DATETIME_STRING_FORMAT)}] " + $"[START] " + $"input_address={attributes.InputtedAddress} " + $"resolved_address={attributes.ResolvedAddress} " + $"source_address={attributes.SourceAddress} " + $"message={message} " + $"interval={attributes.Interval}ms " + $"timeout={attributes.Timeout}ms " + $"count={attributes.Count} " + $"TTL={attributes.Ttl} " + $"receive_buffer_size={attributes.ReceiveBufferSize} bytes " + $"artifical_message_size={attributes.ArtificalMessageSize} bytes " + $"type={attributes.Type} " + $"code={attributes.Code} " + $"beep_mode={attributes.BeepMode} " + $"continous_mode={attributes.Continous} " + $"ipv4={attributes.UseICMPv4} " + $"ipv6={attributes.UseICMPv6} " + $"random_message={attributes.RandomMessage} " + $"dont_fragment={attributes.DontFragment} " + $"random_timing={attributes.RandomTiming} " + $"enable_logging={attributes.EnableLogging} " + $"log_filename={attributes.LogFilePath}"); }
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> /// 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(String host, PingAttributes attrs) { if (!Display.ShowOutput) { return; } // Construct string Console.WriteLine(); Console.Write(INTRO_ADDR_TXT, host); if (!String.Equals(host, attrs.Address)) { // Only show resolved address if inputted address and resolved address are different Console.Write("[{0}] ", attrs.Address); } if (!Short) // Only show extra detail when not in Short mode { if (attrs.RandomMsg) { Console.Write(INTRO_RNG_MSG, attrs.Type, attrs.Code, attrs.Ttl); } else { Console.Write(INTRO_MSG, attrs.Message, attrs.Type, attrs.Code, attrs.Ttl); } } // Print string Console.WriteLine(":"); }
/// <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 void Send(PingAttributes attrs) { // Load user inputted attributes this.Attributes = attrs; // Lookup address Attributes.Address = PowerPing.Lookup.QueryDNS(Attributes.Host, Attributes.ForceV4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6); PowerPing.Display.PingIntroMsg(Attributes.Host, attrs); if (Display.UseResolvedAddress) { Attributes.Host = PowerPing.Lookup.QueryHost(Attributes.Address); if (Attributes.Host == "") { // If reverse lookup fails just display whatever is in the address field Attributes.Host = Attributes.Address; } } // Perform ping operation and store results this.SendICMP(Attributes); PowerPing.Display.PingResults(this); }
/// <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 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> /// Search for host can be IPv4 or URL, stores the results in the PingAttributes object /// </summary> /// <param name="args">Command line arguments</param> /// <param name="attributes">PingAttributes object to store propterties from arguments</param> /// <returns>Returns if the address was found or not</returns> public static bool FindAddress(string[] args, ref PingAttributes attributes) { // Skip first argument, if it's the name of the program // (this is a problematic line) if (args.First().ToLower() == "powerping") { args = args.Skip(1).ToArray(); } // Look for valid scan address (slightly different format than normal address) if (attributes.Operation == PingOperation.Scan) { if (Helper.IsValidScanRange(args.First())) { attributes.InputtedAddress = args.First(); return(true); } if (Helper.IsValidScanRange(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } // Didn't find one.. return(false); } // First check first and last arguments for IPv4 address if (Helper.IsIPv4Address(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } if (Helper.IsIPv4Address(args.First())) { attributes.InputtedAddress = args.First(); return(true); } // Then check for URLs if (Helper.IsURL(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } if (Helper.IsURL(args.First())) { attributes.InputtedAddress = args.First(); return(true); } return(false); }
public PingResults Send(PingAttributes attributes) { if (attributes != m_PingAttributes) { // Replace attributes if they are different m_PingAttributes = attributes; // Setup everything again Setup(); } return(Send()); }
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> /// Sends high volume of ping packets /// </summary> public void Flood(string address) { PingAttributes attrs = new PingAttributes(); Ping p = new Ping(); // Verify address attrs.Address = PowerPing.Lookup.QueryDNS(address, AddressFamily.InterNetwork); // Setup ping attributes attrs.Interval = 0; attrs.Timeout = 100; attrs.Message = "R U Dead Yet?"; attrs.Continous = true; // Disable output for faster speeds Display.ShowOutput = false; // Start flood thread var thread = new Thread(() => { p.Send(attrs); }); thread.IsBackground = true; thread.Start(); IsRunning = true; // Results loop while (IsRunning) { // Update results text Display.FloodProgress(p.Results, address); // Wait before updating (save our CPU load) and check for cancel event if (cancelEvent.WaitOne(1000)) { break; } } // Cleanup IsRunning = false; p.Dispose(); thread.Abort(); // Display results Display.PingResults(p); }
/// <summary> /// Search for host can be IPv4 or URL, stores the results in the PingAttributes object /// </summary> /// <param name="args">Command line arguments</param> /// <param name="attributes">PingAttributes object to store propterties from arguments</param> /// <returns>Returns if the address was found or not</returns> public static bool FindAddress(string[] args, ref PingAttributes attributes) { // Look for valid scan address (slightly different format than normal address) if (attributes.Operation == PingOperation.Scan) { if (Helper.IsValidScanRange(args.First())) { attributes.InputtedAddress = args.First(); return(true); } if (Helper.IsValidScanRange(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } // Didn't find one.. return(false); } // First check first and last arguments for IPv4 address if (Helper.IsIPv4Address(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } if (Helper.IsIPv4Address(args.First())) { attributes.InputtedAddress = args.First(); return(true); } // Then check for URLs if (Helper.IsURL(args.Last())) { attributes.InputtedAddress = args.Last(); return(true); } if (Helper.IsURL(args.First())) { attributes.InputtedAddress = args.First(); return(true); } return(false); }
/// <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 (!Display.ShowOutput || !Display.ShowIntro) { return; } // Construct string Console.WriteLine(); Console.Write(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 (!Short) // Only show extra detail when not in Short mode { if (attrs.ArtificalMessageSize != -1) { // If custom packet size has been specified, show that Console.Write(INTRO_MSG, attrs.ArtificalMessageSize.ToString(), attrs.Type, attrs.Code, attrs.Ttl); } else { // Else show how big the string is in bytes Console.Write(INTRO_MSG, ASCIIEncoding.ASCII.GetByteCount(attrs.Message), attrs.Type, attrs.Code, attrs.Ttl); } } // Print string Console.WriteLine(":"); }
/// <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); }
/// <summary> /// Main entry point of PowerPing /// Parses arguments and runs operations /// </summary> /// <param name="args">Program arguments</param> static void Main(string[] args) { // Local variables PingAttributes attributes = new PingAttributes(); attributes.Address = ""; // 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 attributes)) { Helper.ErrorAndExit("Problem parsing arguments, use \"PowerPing /help\" or \"PowerPing /?\" for help."); } // Find address/host in arguments if (attributes.Operation != PingOperation.Whoami && attributes.Operation != PingOperation.Listen) { if (!CommandLine.FindAddress(args, ref attributes)) { Helper.ErrorAndExit("Could not find correctly formatted address, please check and try again"); } } // Add Control C event handler if (attributes.Operation != PingOperation.Whoami && attributes.Operation != PingOperation.Location && attributes.Operation != PingOperation.Whois) { Console.CancelKeyPress += new ConsoleCancelEventHandler(ExitHandler); } // Select correct function using opMode Ping p = new Ping(m_CancellationTokenSource.Token); Graph g; switch (attributes.Operation) { case PingOperation.Listen: Listen.Start(m_CancellationTokenSource.Token); break; case PingOperation.Location: Console.WriteLine(Lookup.GetAddressLocationInfo(attributes.InputtedAddress, false)); Helper.WaitForUserInput(); break; case PingOperation.Whoami: Console.WriteLine(Lookup.GetAddressLocationInfo("", true)); Helper.WaitForUserInput(); break; case PingOperation.Whois: Lookup.QueryWhoIs(attributes.InputtedAddress); break; case PingOperation.Graph: g = new Graph(attributes.InputtedAddress, m_CancellationTokenSource.Token); g.Start(); break; case PingOperation.CompactGraph: g = new Graph(attributes.InputtedAddress, m_CancellationTokenSource.Token); g.CompactGraph = true; g.Start(); break; case PingOperation.Flood: Flood.Start(attributes.InputtedAddress, m_CancellationTokenSource.Token); break; case PingOperation.Scan: Scan.Start(attributes.InputtedAddress, m_CancellationTokenSource.Token); break; case PingOperation.Normal: // Send ping normally p.Send(attributes); break; default: Helper.ErrorAndExit("Could not determine ping operation"); break; } // Reset console colour Display.ResetColor(); Console.CursorVisible = true; }
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 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); }
/// <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(); } }
/// <summary> /// Core ICMP sending method (used by all other functions) /// Takes a set of attributes, performs operation and returns a set of results. /// /// Works specifically by creating a raw socket, creating a ICMP object and /// other socket properties (timeouts, interval etc) using the /// inputted properties (attrs), then performs ICMP operation /// before cleaning up and returning results. /// /// NOTE: There is a weird hack here, The set of PingAttributes used are /// those provided in the parameter as opposed to the ones stored /// in this class (Ping.Attributes) (similar case with PingResults). /// This is due to some functions (flood, scan) requiring to be run on seperate threads /// and needing us to pass specific attributes directly to the object /// trust me it works (I think..) /// </summary> /// <param name="attrs">Properties of pings to be sent</param> /// <returns>Set of ping results</returns> private PingResults SendICMP(PingAttributes attrs) { IPEndPoint iep = null; EndPoint ep = null; IPAddress ipAddr = null; ICMP packet = new ICMP(); Socket sock = null; byte[] receiveBuffer = new byte[attrs.RecieveBufferSize]; // Ipv4Header.length + IcmpHeader.length + attrs.recievebuffersize int bytesRead, packetSize, index = 1; // Convert to IPAddress ipAddr = IPAddress.Parse(attrs.Address); // Setup endpoint iep = new IPEndPoint(ipAddr, 0); ep = (EndPoint)iep; // Setup raw socket sock = CreateRawSocket(ipAddr.AddressFamily); // Set socket options sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, attrs.Timeout); // Socket timeout sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, attrs.Ttl); sock.DontFragment = attrs.DontFragment; // 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(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 while (attrs.Continous ? true : index <= attrs.Count) { // Exit loop if cancel event is set if (cancelEvent.WaitOne(0)) { break; } else { IsRunning = true; } // 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.Host : attrs.Address, index); } // If there were extra responses from a prior request, ignore them while (sock.Available != 0) { bytesRead = sock.ReceiveFrom(receiveBuffer, ref ep); } // 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 (debug) { // Induce random wait for debugging Random rnd = new Random(); Thread.Sleep(rnd.Next(700)); if (rnd.Next(20) == 1) { throw new SocketException(); } } ICMP response; TimeSpan replyTime; do { // Wait for response bytesRead = sock.ReceiveFrom(receiveBuffer, ref ep); replyTime = new TimeSpan(Helper.StopwatchToTimeSpanTicks(Stopwatch.GetTimestamp() - requestTimestamp)); // Store reply packet response = new ICMP(receiveBuffer, bytesRead); // Ignore unexpected echo responses if (packet.type == 8 && response.type == 0) { ushort responseSessionId = BitConverter.ToUInt16(response.message, 0); ushort responseSequenceNum = BitConverter.ToUInt16(response.message, 2); if (responseSessionId != sessionId || responseSequenceNum != sequenceNum) { if (replyTime.TotalMilliseconds >= attrs.Timeout) { throw new SocketException(); } response = null; } } } while (response == null); // Display reply packet if (Display.ShowReplies) { PowerPing.Display.ReplyPacket(response, Display.UseInputtedAddress | Display.UseResolvedAddress ? attrs.Host : ep.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) { PowerPing.Display.Error("General transmit error"); } Results.SaveResponseTime(-1); try { Results.Lost++; } catch (OverflowException) { Results.HasOverflowed = true; } } catch (SocketException) { PowerPing.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 (Exception) { if (Display.ShowOutput) { PowerPing.Display.Error("General error occured"); } Results.SaveResponseTime(-1); try { Results.Lost++; } catch (OverflowException) { Results.HasOverflowed = true; } } finally { // Increment seq and wait for interval index++; // Wait for set interval before sending again cancelEvent.WaitOne(attrs.Interval); // Generate random interval when RandomTimings flag is set if (attrs.RandomTiming) { attrs.Interval = Helper.RandomInt(5000, 100000); } } // Stop sending if flag is set if (!IsRunning) { break; } } // Clean up IsRunning = false; sock.Close(); return(Results); }
/// <summary> /// Pases command line arguments and store properties in attributes object /// </summary> /// <param name="args">Command line arguments</param> /// <param name="attributes">PingAttributes object to store propterties from arguments</param> /// <returns>bool based on if parsing was successful or not</returns> public static bool Parse(string[] args, ref PingAttributes attributes) { int curArg = 0; // Loop through arguments try { checked { for (int count = 0; count < args.Length; count++) { curArg = count; switch (args[count]) { case "/version": case "-version": case "--version": case "/v": case "-v": case "--v": Display.Version(true); Helper.CheckRecentVersion(); Helper.WaitForUserInput(); Environment.Exit(0); break; case "/beep": case "-beep": case "--beep": case "/b": case "-b": case "--b": int level = Convert.ToInt32(args[count + 1]); if (level > 2) { Display.Message("Invalid beep level, please use a number between 0 & 2"); throw new ArgumentFormatException(); } attributes.BeepLevel = level; break; case "/count": case "-count": case "--count": case "/c": case "-c": case "--c": // Ping count attributes.Count = Convert.ToInt32(args[count + 1]); break; case "/infinite": case "-infinite": case "--infinite": case "/t": case "-t": case "--t": // Infinitely send attributes.Continous = true; break; case "/timeout": case "-timeout": case "--timeout": case "/w": case "-w": case "--w": // Timeout attributes.Timeout = Convert.ToInt32(args[count + 1]); break; case "/message": case "-message": case "--message": case "/m": case "-m": case "--m": // Message if (args[count + 1].Contains("--") || args[count + 1].Contains('/') || args[count + 1].Contains("-")) { throw new ArgumentFormatException(); } attributes.Message = args[count + 1]; break; case "/ttl": case "-ttl": case "--ttl": case "/i": case "-i": case "--i": // Time To Live int ttl = Convert.ToInt16(args[count + 1]); if (ttl > 255) { Display.Message("TTL has to be between 0 and 255"); throw new ArgumentFormatException(); } attributes.Ttl = ttl; break; case "/interval": case "-interval": case "--interval": case "/in": case "-in": case "--in": // Interval attributes.Interval = Convert.ToInt32(args[count + 1]); if (attributes.Interval < 1) { Display.Message("Ping interval cannot be less than 1ms"); throw new ArgumentFormatException(); } break; case "/type": case "-type": case "--type": case "/pt": case "-pt": case "--pt": // Ping type var type = Convert.ToByte(args[count + 1]); if (type > 255) { throw new ArgumentFormatException(); } attributes.Type = type; break; case "/code": case "-code": case "--code": case "/pc": case "-pc": case "--pc": // Ping code attributes.Code = Convert.ToByte(args[count + 1]); break; case "/displaymsg": case "-displaymsg": case "--displaymsg": case "/dm": case "-dm": case "--dm": // Display packet message Display.ShowMessages = true; break; case "/ipv4": case "-ipv4": case "--ipv4": case "/4": case "-4": case "--4": // Force ping with IPv4 if (attributes.ForceV6) { // Reset IPv6 force if already set attributes.ForceV6 = false; } attributes.ForceV4 = true; break; case "/ipv6": case "-ipv6": case "--ipv6": case "/6": case "-6": case "--6": // Force ping with IPv6 if (attributes.ForceV4) { // Reset IPv4 force if already set attributes.ForceV4 = false; } attributes.ForceV6 = true; break; case "/help": case "-help": case "--help": case "/?": case "-?": case "--?": // Display help message Display.Help(); Helper.WaitForUserInput(); Environment.Exit(0); break; case "/examples": case "-examples": case "--examples": case "/ex": case "-ex": case "--ex": // Displays examples Display.Examples(); Environment.Exit(0); // Exit after displaying examples break; case "/shorthand": case "-shorthand": case "--shorthand": case "/sh": case "-sh": case "--sh": // Use short hand messages Display.Short = true; break; case "/nocolor": case "-nocolor": case "--nocolor": case "/nc": case "-nc": case "--nc": // No color mode Display.NoColor = true; break; case "/ni": case "-ni": case "--ni": case "/noinput": case "-noinput": case "--noinput": // No input mode Display.NoInput = true; if (Properties.Settings.Default.RequireInput != true) { Display.Message( "(RequireInput is now permenantly OFF, you will no longer be prompted for user input anytime PowerPing is finished)", ConsoleColor.Cyan); } Properties.Settings.Default.RequireInput = false; Properties.Settings.Default.Save(); break; case "/ri": case "-ri": case "--ri": case "/requireinput": case "-requireinput": case "--requireinput": Display.NoInput = false; if (Properties.Settings.Default.RequireInput != true) { Display.Message( "(RequireInput is now permenantly ON, from now on you will be prompted for user input whenever PowerPing is finished)", ConsoleColor.Cyan); } Properties.Settings.Default.RequireInput = true; Properties.Settings.Default.Save(); break; case "/decimals": case "-decimals": case "--decimals": case "/dp": case "-dp": case "--dp": // Decimal places if (Convert.ToInt32(args[count + 1]) > 3 || Convert.ToInt32(args[count + 1]) < 0) { throw new ArgumentFormatException(); } Display.DecimalPlaces = Convert.ToInt32(args[count + 1]); break; case "/symbols": case "-symbols": case "--symbols": case "/sym": case "-sym": case "--sym": Display.UseSymbols = true; Display.SetAsciiReplySymbolsTheme(0); // Change symbols theme if an argument is present if (args.Length < count + 1) { count++; continue; } if (args[count + 1].Contains("--") || args[count + 1].Contains('/') || args[count + 1].Contains("-") || args[count + 1].Contains(".")) { count++; continue; } int theme = Convert.ToInt32(args[count + 1]); Display.SetAsciiReplySymbolsTheme(theme); break; case "/random": case "-random": case "--random": case "/rng": case "-rng": case "--rng": attributes.RandomMsg = true; break; case "/limit": case "-limit": case "--limit": case "/l": case "-l": case "--l": if (Convert.ToInt32(args[count + 1]) == 1) { Display.ShowSummary = false; Display.ShowIntro = false; } else if (Convert.ToInt32(args[count + 1]) == 2) { Display.ShowSummary = false; Display.ShowIntro = false; Display.ShowReplies = false; Display.ShowRequests = true; } else if (Convert.ToInt32(args[count + 1]) == 3) { Display.ShowReplies = false; Display.ShowRequests = false; } else { throw new ArgumentFormatException(); } break; case "/notimeout": case "-notimeout": case "--notimeout": case "/nt": case "-nt": case "--nt": Display.ShowTimeouts = false; break; case "/timestamp": case "-timestamp": case "--timestamp": case "/ts": case "-ts": case "--ts": // Display timestamp if (args[count + 1].ToLower() == "utc") { Display.ShowtimeStampUTC = true; } else { Display.ShowTimeStamp = true; } break; case "/fulltimestamp": case "-fulltimestamp": case "--fulltimestamp": case "/fts": case "-fts": case "--fts": // Display timestamp with date if (count + 1 > args.Length) { Display.ShowFullTimeStamp = true; } else if (args[count + 1].ToLower() == "utc") { Display.ShowFullTimeStampUTC = true; } else { Display.ShowFullTimeStamp = true; } break; case "/timing": case "-timing": case "--timing": case "/ti": case "-ti": case "--ti": // Timing option switch (args[count + 1].ToLowerInvariant()) { case "0": case "paranoid": attributes.Timeout = 10000; attributes.Interval = 300000; break; case "1": case "sneaky": attributes.Timeout = 5000; attributes.Interval = 120000; break; case "2": case "quiet": attributes.Timeout = 5000; attributes.Interval = 30000; break; case "3": case "polite": attributes.Timeout = 3000; attributes.Interval = 3000; break; case "4": case "nimble": attributes.Timeout = 2000; attributes.Interval = 750; break; case "5": case "speedy": attributes.Timeout = 1500; attributes.Interval = 500; break; case "6": case "insane": attributes.Timeout = 750; attributes.Interval = 100; break; case "7": case "random": attributes.RandomTiming = true; attributes.RandomMsg = true; attributes.Interval = Helper.RandomInt(5000, 100000); attributes.Timeout = 15000; break; default: // Unknown timing type throw new ArgumentFormatException(); } break; case "/request": case "-request": case "--request": case "/requests": case "-requests": case "--requests": case "/r": case "-r": case "--r": Display.ShowRequests = true; break; case "/quiet": case "-quiet": case "--quiet": case "/q": case "-q": case "--q": Display.ShowOutput = false; break; case "/resolve": case "-resolve": case "--resolve": case "/res": case "-res": case "--res": Display.UseResolvedAddress = true; break; case "/inputaddr": case "-inputaddr": case "--inputaddr": case "/ia": case "-ia": case "--ia": Display.UseInputtedAddress = true; break; case "/buffer": case "-buffer": case "--buffer": case "/rb": case "-rb": case "--rb": int recvbuff = Convert.ToInt32(args[count + 1]); if (recvbuff < 65000) { attributes.RecieveBufferSize = recvbuff; } else { throw new ArgumentFormatException(); } break; case "/checksum": case "-checksum": case "--checksum": case "/chk": case "-chk": case "--chk": Display.ShowChecksum = true; break; case "/dontfrag": case "-dontfrag": case "--dontfrag": case "/df": case "-df": case "--df": attributes.DontFragment = true; break; case "/size": case "-size": case "--size": case "/s": case "-s": case "--s": int size = Convert.ToInt32(args[count + 1]); if (size < 100000) { attributes.Size = size; } else { throw new ArgumentFormatException(); } break; case "/whois": case "-whois": case "--whois": // Whois lookup attributes.Operation = PingOperation.Whois; break; case "/whoami": case "-whoami": case "--whoami": // Current computer location attributes.Operation = PingOperation.Whoami; break; case "/location": case "-location": case "--location": case "/loc": case "-loc": case "--loc": // Location lookup attributes.Operation = PingOperation.Location; break; case "/listen": case "-listen": case "--listen": case "/li": case "-li": case "--li": // Listen for ICMP packets attributes.Operation = PingOperation.Listen; break; case "/graph": case "-graph": case "--graph": case "/g": case "-g": case "--g": // Graph view attributes.Operation = PingOperation.Graph; break; case "/compact": case "-compact": case "--compact": case "/cg": case "-cg": case "--cg": // Compact graph view attributes.Operation = PingOperation.CompactGraph; break; case "/flood": case "-flood": case "--flood": case "/fl": case "-fl": case "--fl": // Flood attributes.Operation = PingOperation.Flood; break; case "/scan": case "-scan": case "--scan": case "/sc": case "-sc": case "--sc": // Scan attributes.Operation = PingOperation.Scan; break; default: // Check for invalid argument if ((args[count].Contains("--") || args[count].Contains("/") || args[count].Contains("-")) && attributes.Operation != PingOperation.Scan && // (ignore if scanning) // TODO: Change this (!Helper.IsURL(args[count]) && !Helper.IsIPv4Address(args[count]))) { throw new InvalidArgumentException(); } break; } } } } catch (IndexOutOfRangeException) { Display.Error($"Missing argument parameter @ \"PowerPing >>>{args[curArg]}<<<\""); return(false); } catch (OverflowException) { Display.Error($"Overflow while converting @ \"PowerPing {args[curArg]} >>>{args[curArg + 1]}<<<\""); return(false); } catch (InvalidArgumentException) { Display.Error($"Invalid argument @ \"PowerPing >>>{args[curArg]}<<<\""); return(false); } catch (ArgumentFormatException) { Display.Error($"Incorrect parameter for [{args[curArg]}] @ \"PowerPing {args[curArg]} >>>{args[curArg + 1]}<<<\""); return(false); } catch (Exception e) { Display.Error($"An {e.GetType().ToString().Split('.').Last()} exception occured @ \"PowerPing >>>{args[curArg]}<<<\""); return(false); } return(true); }
/// <summary> /// Main entry point of PowerPing /// Parses arguments and runs operations /// </summary> /// <param name="args">Program arguments</param> static void Main(string[] args) { // Local variables int curArg = 0; string opMode = ""; PingAttributes attributes = new PingAttributes(); attributes.Address = ""; // Setup console Display.DefaultForegroundColor = Console.ForegroundColor; Display.DefaultBackgroundColor = Console.BackgroundColor; // Show current version info //Display.Version(); // Check if no arguments if (args.Length == 0) { PowerPing.Display.Help(); return; } // Loop through arguments try { checked { for (int count = 0; count < args.Length; count++) { curArg = count; switch (args[count]) { case "/version": case "-version": case "--version": case "/v": case "-v": case "--v": Display.Version(true); Environment.Exit(0); break; case "/beep": case "-beep": case "--beep": case "/b": case "-b": case "--b": int level = Convert.ToInt32(args[count + 1]); if (level > 2) { PowerPing.Display.Error("Invalid beep level, please use a number between 0 & 2", true, true); } attributes.BeepLevel = level; break; case "/count": case "-count": case "--count": case "/c": case "-c": case "--c": // Ping count attributes.Count = Convert.ToInt32(args[count + 1]); break; case "/infinite": case "-infinite": case "--infinite": case "/t": case "-t": case "--t": // Infinitely send attributes.Continous = true; break; case "/timeout": case "-timeout": case "--timeout": case "/w": case "-w": case "--w": // Timeout attributes.Timeout = Convert.ToInt32(args[count + 1]); break; case "/message": case "-message": case "--message": case "/m": case "-m": case "--m": // Message if (args[count + 1].Contains("--") || args[count + 1].Contains("//") || args[count + 1].Contains("-")) { throw new ArgumentFormatException(); } attributes.Message = args[count + 1]; break; case "/ttl": case "-ttl": case "--ttl": case "/i": case "-i": case "--i": // Time To Live attributes.Ttl = Convert.ToInt16(args[count + 1]); break; case "/interval": case "-interval": case "--interval": case "/in": case "-in": case "--in": // Interval attributes.Interval = Convert.ToInt32(args[count + 1]); if (attributes.Interval < 1) { PowerPing.Display.Error("Ping interval cannot be less than 1ms", true, true); } break; case "/type": case "-type": case "--type": case "/pt": case "-pt": case "--pt": // Ping type var type = Convert.ToByte(args[count + 1]); if (type > 255) { throw new ArgumentFormatException(); } attributes.Type = type; break; case "/code": case "-code": case "--code": case "/pc": case "-pc": case "--pc": // Ping code attributes.Code = Convert.ToByte(args[count + 1]); break; case "/displaymsg": case "-displaymsg": case "--displaymsg": case "/dm": case "-dm": case "--dm": // Display packet message Display.ShowMessages = true; break; case "/ipv4": case "-ipv4": case "--ipv4": case "/4": case "-4": case "--4": // Force ping with IPv4 if (attributes.ForceV6) { // Reset IPv6 force if already set attributes.ForceV6 = false; } attributes.ForceV4 = true; break; case "/ipv6": case "-ipv6": case "--ipv6": case "/6": case "-6": case "--6": // Force ping with IPv6 if (attributes.ForceV4) { // Reset IPv4 force if already set attributes.ForceV4 = false; } attributes.ForceV6 = true; break; case "/help": case "-help": case "--help": case "/?": case "-?": case "--?": // Display help message PowerPing.Display.Help(); Environment.Exit(0); break; case "/examples": case "-examples": case "--examples": case "/ex": case "-ex": case "--ex": // Displays examples PowerPing.Display.Examples(); break; case "/shorthand": case "-shorthand": case "--shorthand": case "/sh": case "-sh": case "--sh": // Use short hand messages Display.Short = true; break; case "/nocolor": case "-nocolor": case "--nocolor": case "/nc": case "-nc": case "--nc": // No color mode Display.NoColor = true; break; case "/input": case "-input": case "--input": // No input mode Display.NoInput = false; break; case "/decimals": case "-decimals": case "--decimals": case "/dp": case "-dp": case "--dp": // Decimal places if (Convert.ToInt32(args[count + 1]) > 3 || Convert.ToInt32(args[count + 1]) < 0) { throw new ArgumentFormatException(); } Display.DecimalPlaces = Convert.ToInt32(args[count + 1]); break; case "/symbols": case "-symbols": case "--symbols": case "/sym": case "-sym": case "--sym": Display.UseSymbols = true; break; case "/random": case "-random": case "--random": case "/rng": case "-rng": case "--rng": attributes.RandomMsg = true; break; case "/limit": case "-limit": case "--limit": case "/l": case "-l": case "--l": if (Convert.ToInt32(args[count + 1]) == 0) { Display.ShowReplies = true; Display.ShowRequests = false; } else if (Convert.ToInt32(args[count + 1]) == 1) { Display.ShowReplies = false; Display.ShowRequests = true; } else { throw new ArgumentFormatException(); } break; case "/notimeout": case "-notimeout": case "--notimeout": case "/nt": case "-nt": case "--nt": Display.ShowTimeouts = false; break; case "/timestamp": case "-timestamp": case "--timestamp": case "/ts": case "-ts": case "--ts": // Display timestamp Display.ShowTimeStamp = true; break; case "/timing": case "-timing": case "--timing": case "/ti": case "-ti": case "--ti": // Timing option switch (args[count + 1].ToLowerInvariant()) { case "0": case "paranoid": attributes.Timeout = 10000; attributes.Interval = 300000; break; case "1": case "sneaky": attributes.Timeout = 5000; attributes.Interval = 120000; break; case "2": case "quiet": attributes.Timeout = 5000; attributes.Interval = 30000; break; case "3": case "polite": attributes.Timeout = 3000; attributes.Interval = 3000; break; case "4": case "nimble": attributes.Timeout = 2000; attributes.Interval = 750; break; case "5": case "speedy": attributes.Timeout = 1500; attributes.Interval = 500; break; case "6": case "insane": attributes.Timeout = 750; attributes.Interval = 100; break; case "7": case "random": attributes.RandomTiming = true; attributes.RandomMsg = true; attributes.Interval = Helper.RandomInt(5000, 100000); attributes.Timeout = 15000; break; default: // Unknown timing type throw new ArgumentFormatException(); } break; case "/request": case "-request": case "--request": case "/r": case "-r": case "--r": Display.ShowRequests = true; break; case "/quiet": case "-quiet": case "--quiet": case "/q": case "-q": case "--q": Display.ShowOutput = false; break; case "/resolve": case "-resolve": case "--resolve": case "/res": case "-res": case "--res": Display.UseResolvedAddress = true; break; case "/inputaddr": case "-inputaddr": case "--inputaddr": case "/ia": case "-ia": case "--ia": Display.UseInputtedAddress = true; break; case "/buffer": case "-buffer": case "--buffer": case "/rb": case "-rb": case "--rb": int recvbuff = Convert.ToInt32(args[count + 1]); if (recvbuff < 65000) { attributes.RecieveBufferSize = recvbuff; } else { throw new ArgumentFormatException(); } break; case "/checksum": case "-checksum": case "--checksum": case "/chk": case "-chk": case "--chk": Display.ShowChecksum = true; break; case "/dontfrag": case "-dontfrag": case "--dontfrag": case "/df": case "-df": case "--df": attributes.DontFragment = true; break; case "/size": case "-size": case "--size": case "/s": case "-s": case "--s": int size = Convert.ToInt32(args[count + 1]); if (size < 100000) { attributes.Size = size; } else { throw new ArgumentFormatException(); } break; case "/whois": case "-whois": case "--whois": opMode = "whois"; break; case "/whoami": case "-whoami": case "--whoami": // Current computer location opMode = "whoami"; break; case "/location": case "-location": case "--location": case "/loc": case "-loc": case "--loc": // Location lookup opMode = "location"; break; case "/listen": case "-listen": case "--listen": case "/li": case "-li": case "--li": // Listen for ICMP packets opMode = "listening"; break; case "/graph": case "-graph": case "--graph": case "/g": case "-g": case "--g": // Graph view opMode = "graphing"; break; case "/compact": case "-compact": case "--compact": case "/cg": case "-cg": case "--cg": // Compact graph view opMode = "compactgraph"; break; case "/flood": case "-flood": case "--flood": case "/fl": case "-fl": case "--fl": // Flood opMode = "flooding"; break; case "/scan": case "-scan": case "--scan": case "/sc": case "-sc": case "--sc": // Scan opMode = "scanning"; break; default: // Check for invalid argument if ((args[count].Contains("--") || args[count].Contains("/") || args[count].Contains("-")) && !opMode.Equals("scanning") && // (ignore if scanning) args[count].Length < 7) // Ignore args under 7 chars (assume they are an address) { throw new ArgumentFormatException(); } break; } } } } catch (IndexOutOfRangeException) { PowerPing.Display.Error("Missing argument parameter", false, false, false); PowerPing.Display.Message(" @ \"PowerPing >>>" + args[curArg] + "<<<\"", ConsoleColor.Red); PowerPing.Display.Message("Use \"PowerPing /help\" or \"PowerPing /?\" for help."); Helper.Pause(); return; } catch (OverflowException) { PowerPing.Display.Error("Overflow while converting", false, false, false); PowerPing.Display.Message(" @ \"PowerPing " + args[curArg] + ">>>" + args[curArg + 1] + "<<<\"", ConsoleColor.Red); PowerPing.Display.Message("Use \"PowerPing /help\" or \"PowerPing /?\" for help."); Helper.Pause(); return; } catch (ArgumentFormatException) { PowerPing.Display.Error("Invalid argument or incorrect parameter", false, false, false); PowerPing.Display.Message(" @ \"PowerPing >>>" + args[curArg] + "<<<\"", ConsoleColor.Red); PowerPing.Display.Message("Use \"PowerPing /help\" or \"PowerPing /?\" for help."); Helper.Pause(); return; } catch (Exception e) { PowerPing.Display.Error("A " + e.GetType().ToString().Split('.').Last() + " Exception Occured", false, false, false); PowerPing.Display.Message(" @ \"PowerPing >>>" + args[curArg] + "<<<\"", ConsoleColor.Red); PowerPing.Display.Message("Use \"PowerPing /help\" or \"PowerPing /?\" for more info."); Helper.Pause(); return; } // Find address if (opMode.Equals("") || opMode.Equals("flooding") || opMode.Equals("graphing") || opMode.Equals("compactGraph") || opMode.Equals("location") || opMode.Equals("whois")) { if (Uri.CheckHostName(args.First()) == UriHostNameType.Unknown && Uri.CheckHostName(args.Last()) == UriHostNameType.Unknown) { PowerPing.Display.Error("Unknown address format. \nIf address is a url do not include any trailing '/'s, for example use: google.com NOT google.com/test.html", true, true); } if (Uri.CheckHostName(args.First()) == UriHostNameType.Unknown) { attributes.Host = args.Last(); } else { attributes.Host = args.First(); } } // Add Control C event handler if (opMode.Equals("") || opMode.Equals("flooding") || opMode.Equals("graphing") || opMode.Equals("compactgraph")) { Console.CancelKeyPress += new ConsoleCancelEventHandler(ExitHandler); } // Select correct function using opMode Thread thread; switch (opMode) { case "listening": p.Listen(); break; case "location": PowerPing.Lookup.AddressLocation(attributes.Host, true); break; case "whoami": PowerPing.Lookup.AddressLocation("", true); break; case "whois": PowerPing.Lookup.QueryWhoIs(attributes.Host); break; case "graphing": g = new Graph(attributes.Host); g.Start(); break; case "compactgraph": g = new Graph(attributes.Host); g.CompactGraph = true; g.Start(); break; case "flooding": thread = new Thread(() => { p.Flood(attributes.Host); }); thread.Start(); break; case "scanning": p.Scan(args.Last()); break; default: // Send ping normally thread = new Thread(() => { p.Send(attributes); }); thread.Start(); break; } }
/// <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); } }