private void CreateRawSocket() { // Determine what address family we are using AddressFamily family; ProtocolType protocol; if (m_PingAttributes.UseICMPv4) { family = AddressFamily.InterNetwork; protocol = ProtocolType.Icmp; } else { family = AddressFamily.InterNetworkV6; protocol = ProtocolType.IcmpV6; } // Create the raw socket try { m_Socket = new Socket(family, SocketType.Raw, protocol); } catch (SocketException) { Display.Message("PowerPing uses raw sockets which require Administrative rights to create." + Environment.NewLine + "(You can find more info at https://github.com/Killeroo/PowerPing/issues/110)", ConsoleColor.Cyan); Helper.ErrorAndExit("Socket cannot be created, make sure you are running as an Administrator and try again."); } }
/// <summary> /// Creates a raw socket for ping operations. /// /// We have to use raw sockets here as we are using our own /// implementation of ICMP and only raw sockets will allow us /// to send whatever data we want through it. /// /// The downside is this is why we need to run as administrator /// but it allows us the greater degree of control over the packets /// that we need /// </summary> /// <param name="family">AddressFamily to use (IP4 or IP6)</param> /// <returns>A raw socket</returns> private static Socket CreateRawSocket(AddressFamily family) { Socket s = null; try { s = new Socket(family, SocketType.Raw, family == AddressFamily.InterNetwork ? ProtocolType.Icmp : ProtocolType.IcmpV6); } catch (SocketException) { Display.Message("PowerPing uses raw sockets which require Administrative rights to create." + Environment.NewLine + "(You can find more info at https://github.com/Killeroo/PowerPing/issues/110)", ConsoleColor.Cyan); Helper.ErrorAndExit("Socket cannot be created, make sure you are running as an Administrator and try again."); } return(s); }
/// <summary> /// Internal whois function for recursive lookup /// </summary> /// <param name="address"></param> /// <returns></returns> public static void QueryWhoIs(string address, bool full = true) { // Trim the inputted address address = address.Split('/')[0]; string keyword = address.Split('.')[0]; string tld = address.Split('.').Last(); // Quick sanity check before we proceed if (keyword == "" || tld == "") { Helper.ErrorAndExit("Incorrectly formatted address, please check format and try again"); } Display.Message("WHOIS [" + address + "]:", ConsoleColor.Yellow); // Find appropriate whois for the tld Display.Message("QUERYING [" + ROOT_WHOIS_SERVER + "] FOR TLD [" + tld + "]:", ConsoleColor.Yellow, false); string whoisRoot = PerformWhoIsLookup(ROOT_WHOIS_SERVER, tld); Display.Message(" DONE", ConsoleColor.Yellow); if (full) { Console.WriteLine(whoisRoot); } whoisRoot = whoisRoot.Remove(0, whoisRoot.IndexOf("whois:", StringComparison.Ordinal) + 6).TrimStart(); whoisRoot = whoisRoot.Substring(0, whoisRoot.IndexOf('\r')); Display.Message("QUERYING [" + whoisRoot + "] FOR DOMAIN [" + address + "]:", ConsoleColor.Yellow, false); // Next query resulting whois for the domain string result = PerformWhoIsLookup(whoisRoot, address); Display.Message(" DONE", ConsoleColor.Yellow); Console.WriteLine(result); Display.Message("WHOIS LOOKUP FOR [" + address + "] COMPLETE.", ConsoleColor.Yellow); Helper.WaitForUserInput(); }
/// <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(); }
/// <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); }