This commit is contained in:
EonaCat 2023-02-24 13:25:01 +01:00
parent 0a9a3c23e6
commit 2ba9705b66
5 changed files with 478 additions and 534 deletions

View File

@ -1,99 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CAA93B33-C1F4-46AE-ABD8-3802BCB6CB5F}</ProjectGuid>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>EonaCat.DnsTester</RootNamespace> <RootNamespace>EonaCat.DnsTester</RootNamespace>
<AssemblyName>EonaCat.DnsTester</AssemblyName> <AssemblyName>EonaCat.DnsTester</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>EonaCat.ico</ApplicationIcon> <ApplicationIcon>EonaCat.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Design" />
<Reference Include="System.Runtime.Serialization.Formatters.Soap" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="UIAutomationProvider" />
<Reference Include="UIAutomationTypes" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="EonaCat.ico" /> <Content Include="EonaCat.ico" />
<Content Include="Servers.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@ -0,0 +1,118 @@
using Microsoft.VisualBasic.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace EonaCat.DnsTester.Helpers
{
internal class DnsHelper
{
public static event EventHandler<string> Log;
public static void ProcessDns(string startOfUrl, string domain, int urlsTotal, Socket dnsSocket, byte[] bytesSend,
long startTime, int totalDnsToUse, ListView result)
{
var bytesReceived = new byte[512];
var totalReceived = 0;
// wait for a response up to timeout
while (totalReceived < urlsTotal * totalDnsToUse)
{
dnsSocket.Receive(bytesReceived);
// Check if the error is ours
if ((bytesReceived[0] != bytesSend[0] || bytesReceived[1] != 0x31) &&
bytesReceived[1] != 0x32)
continue;
if (bytesReceived[2] != 0x81 || bytesReceived[3] != 0x80) continue;
// Get the time now
var stopTime = DateTime.Now.Ticks;
var deltaTime = Convert.ToString((double)(stopTime - startTime) / 10000000);
// Decode the answers
// Find the URL that was returned
int dnsId = bytesReceived[1];
var receiveString = Encoding.ASCII.GetString(bytesReceived);
var index = 12;
int startOfUrlLength = bytesReceived[index];
index++;
startOfUrl = receiveString.Substring(index, startOfUrlLength);
index += startOfUrlLength;
int domainLength = bytesReceived[index];
index++;
domain = receiveString.Substring(index, domainLength);
index += domainLength;
index += 8;
// Get the record type
int ResponseType = bytesReceived[index];
index += 9;
// Get the IP address if applicable
var ipResponse = "";
switch (ResponseType)
{
case 1:
ipResponse =
$"{Convert.ToString(bytesReceived[index])}.{Convert.ToString(bytesReceived[index + 1])}.{Convert.ToString(bytesReceived[index + 2])}.{Convert.ToString(bytesReceived[index + 3])}";
break;
case 5:
ipResponse = "CNAME";
break;
case 6:
ipResponse = "SOA";
break;
}
SetStatus($"Answer: {startOfUrl}.{domain} : {ipResponse}");
// Find the url in the list
for (int i = 0; i < result.Items.Count; i++)
{
if (result.Items[i].Text != $"{startOfUrl}.{domain}") continue;
string sDeltaTime;
switch (dnsId)
{
case 49:
result.Items[i].SubItems[1].Text = Convert.ToString(ipResponse);
sDeltaTime = Convert.ToString(deltaTime);
result.Items[i].SubItems[2].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
result.Items[i].ForeColor = System.Drawing.Color.Red;
result.EnsureVisible(i);
result.Update();
Application.DoEvents();
result.Items[i].ForeColor = System.Drawing.Color.Black;
break;
case 50:
result.Items[i].SubItems[3].Text = Convert.ToString(ipResponse);
sDeltaTime = Convert.ToString(deltaTime);
result.Items[i].SubItems[4].Text =
sDeltaTime.Length > 5 ? sDeltaTime.Substring(0, 5) : sDeltaTime;
result.Items[i].ForeColor = System.Drawing.Color.Red;
result.EnsureVisible(i);
result.Update();
Application.DoEvents();
result.Items[i].ForeColor = System.Drawing.Color.Black;
break;
}
totalReceived++;
}
}
}
private static void SetStatus(string text)
{
Log?.Invoke(null, text);
}
}
}

View File

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace EonaCat.DnsTester.Helpers
{
internal class UrlHelper
{
private static readonly RandomNumberGenerator _randomNumberGenerator = RandomNumberGenerator.Create();
public static event EventHandler<string> Log;
public static void GetRandomUrls(ref List<string> urlList, int totalUrls)
{
// Generate a cryptographically strong random string
byte[] randomBytes = new byte[32];
_randomNumberGenerator.GetBytes(randomBytes);
string letters = Convert.ToBase64String(randomBytes);
Dictionary<string, string> searchEngineUrls = new Dictionary<string, string>
{
{ "Yahoo", "https://search.yahoo.com/search?p=" },
{ "Bing", "https://www.bing.com/search?q=" },
{ "Google", "https://www.google.com/search?q=" },
{ "Ask", "https://www.ask.com/web?q=" },
{ "WolframAlpha", "https://www.wolframalpha.com/input/?i=" },
{ "StartPage", "https://www.startpage.com/do/dsearch?query=" },
{ "Yandex", "https://www.yandex.com/search/?text=" },
{ "Qwant", "https://www.qwant.com/?q=" }
};
Random rand = new Random();
List<string> localCleanNames = urlList;
while (localCleanNames.Count < totalUrls)
{
int index = rand.Next(searchEngineUrls.Count);
KeyValuePair<string, string> searchEngine = searchEngineUrls.ElementAt(index);
string url = searchEngine.Value + letters;
try
{
using (var client = new WebClient())
{
string responseString = client.DownloadString(url);
// find all .xxx.com addresses
MatchCollection hostNames = Regex.Matches(responseString, @"[.](\w+[.]com)");
// Loop through the match collection to retrieve all matches and delete the leading "."
HashSet<string> uniqueNames = new HashSet<string>();
foreach (Match match in hostNames)
{
string name = match.Groups[1].Value;
if (name != $"{searchEngine.Key.ToLower()}.com")
{
uniqueNames.Add(name);
}
}
// Add the names to the list
foreach (string name in uniqueNames)
{
if (localCleanNames.Count >= totalUrls)
{
break;
}
if (!localCleanNames.Contains(name))
{
localCleanNames.Add(name);
}
}
}
}
catch (Exception ex)
{
SetStatus($"{searchEngine.Key}: {ex.Message}");
}
}
urlList = localCleanNames; // Update the reference to the list
SetStatus($"{urlList.Count} Random URL's found");
}
private static void SetStatus(string text)
{
Log?.Invoke(null, text);
}
}
}

View File

@ -38,8 +38,8 @@
this.RunTest = new System.Windows.Forms.Button(); this.RunTest = new System.Windows.Forms.Button();
this.lblDns1 = new System.Windows.Forms.Label(); this.lblDns1 = new System.Windows.Forms.Label();
this.lblDns2 = new System.Windows.Forms.Label(); this.lblDns2 = new System.Windows.Forms.Label();
this.DnsList1 = new System.Windows.Forms.ComboBox(); this.dnsList1 = new System.Windows.Forms.ComboBox();
this.DnsList2 = new System.Windows.Forms.ComboBox(); this.dnsList2 = new System.Windows.Forms.ComboBox();
this.UseCustomServers = new System.Windows.Forms.CheckBox(); this.UseCustomServers = new System.Windows.Forms.CheckBox();
this.lblCustom1 = new System.Windows.Forms.Label(); this.lblCustom1 = new System.Windows.Forms.Label();
this.lblCustom2 = new System.Windows.Forms.Label(); this.lblCustom2 = new System.Windows.Forms.Label();
@ -139,25 +139,25 @@
this.lblDns2.TabIndex = 14; this.lblDns2.TabIndex = 14;
this.lblDns2.Text = "Dns 2:"; this.lblDns2.Text = "Dns 2:";
// //
// DnsList1 // dnsList1
// //
this.DnsList1.FormattingEnabled = true; this.dnsList1.FormattingEnabled = true;
this.DnsList1.ItemHeight = 31; this.dnsList1.ItemHeight = 31;
this.DnsList1.Location = new System.Drawing.Point(277, 155); this.dnsList1.Location = new System.Drawing.Point(277, 155);
this.DnsList1.Margin = new System.Windows.Forms.Padding(8, 7, 8, 7); this.dnsList1.Margin = new System.Windows.Forms.Padding(8, 7, 8, 7);
this.DnsList1.Name = "DnsList1"; this.dnsList1.Name = "dnsList1";
this.DnsList1.Size = new System.Drawing.Size(756, 39); this.dnsList1.Size = new System.Drawing.Size(756, 39);
this.DnsList1.TabIndex = 15; this.dnsList1.TabIndex = 15;
// //
// DnsList2 // dnsList2
// //
this.DnsList2.FormattingEnabled = true; this.dnsList2.FormattingEnabled = true;
this.DnsList2.ItemHeight = 31; this.dnsList2.ItemHeight = 31;
this.DnsList2.Location = new System.Drawing.Point(1229, 155); this.dnsList2.Location = new System.Drawing.Point(1229, 155);
this.DnsList2.Margin = new System.Windows.Forms.Padding(8, 7, 8, 7); this.dnsList2.Margin = new System.Windows.Forms.Padding(8, 7, 8, 7);
this.DnsList2.Name = "DnsList2"; this.dnsList2.Name = "dnsList2";
this.DnsList2.Size = new System.Drawing.Size(788, 39); this.dnsList2.Size = new System.Drawing.Size(788, 39);
this.DnsList2.TabIndex = 16; this.dnsList2.TabIndex = 16;
// //
// UseCustomServers // UseCustomServers
// //
@ -366,8 +366,8 @@
this.Controls.Add(this.lblCustom2); this.Controls.Add(this.lblCustom2);
this.Controls.Add(this.lblCustom1); this.Controls.Add(this.lblCustom1);
this.Controls.Add(this.UseCustomServers); this.Controls.Add(this.UseCustomServers);
this.Controls.Add(this.DnsList2); this.Controls.Add(this.dnsList2);
this.Controls.Add(this.DnsList1); this.Controls.Add(this.dnsList1);
this.Controls.Add(this.lblDns2); this.Controls.Add(this.lblDns2);
this.Controls.Add(this.lblDns1); this.Controls.Add(this.lblDns1);
this.Controls.Add(this.RunTest); this.Controls.Add(this.RunTest);
@ -396,8 +396,8 @@
private System.Windows.Forms.Button RunTest; private System.Windows.Forms.Button RunTest;
private System.Windows.Forms.Label lblDns1; private System.Windows.Forms.Label lblDns1;
private System.Windows.Forms.Label lblDns2; private System.Windows.Forms.Label lblDns2;
private System.Windows.Forms.ComboBox DnsList1; private System.Windows.Forms.ComboBox dnsList1;
private System.Windows.Forms.ComboBox DnsList2; private System.Windows.Forms.ComboBox dnsList2;
private System.Windows.Forms.CheckBox UseCustomServers; private System.Windows.Forms.CheckBox UseCustomServers;
private System.Windows.Forms.Label lblCustom1; private System.Windows.Forms.Label lblCustom1;
private System.Windows.Forms.Label lblCustom2; private System.Windows.Forms.Label lblCustom2;

View File

@ -6,18 +6,20 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Security.Policy;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Threading; using EonaCat.DnsTester.Helpers;
namespace EonaCat.DnsTester namespace EonaCat.DnsTester
{ {
public partial class MainForm : Form public partial class MainForm : Form
{ {
private bool UseCustomDnsServers = false; private bool useCustomDnsServers;
public string DNS1, DNS2; private string _dnsServer1, _dnsServer2;
private int _dnsTotalChecked;
public bool IsRunning { get; private set; } public bool IsRunning { get; private set; }
@ -28,460 +30,269 @@ namespace EonaCat.DnsTester
private void RunTest_Click(object sender, EventArgs e) private void RunTest_Click(object sender, EventArgs e)
{ {
int i; List<string> urls = new List<string>();
List<string> CleanNames = new List<string>(); SetupUrls(urls);
if (this.UseCustomDnsServers) if (IsRunning)
{ {
if (chkDns1.Checked) return;
{ }
DNS1 = CustomDns1.Text;
}
if (chkDns2.Checked) IsRunning = true;
{ Process(urls.ToArray(), _dnsServer1, _dnsServer2);
DNS2 = CustomDns2.Text; IsRunning = false;
} }
private void SetupUrls(List<string> urls)
{
if (useCustomDnsServers)
{
_dnsTotalChecked = 0;
if (chkDns1.Checked)
{
_dnsTotalChecked++;
_dnsServer1 = CustomDns1.Text;
}
if (chkDns2.Checked)
{
_dnsTotalChecked++;
_dnsServer2 = CustomDns2.Text;
}
} }
else else
{ {
if (chkDns1.Checked) _dnsTotalChecked = 0;
{ if (chkDns1.Checked)
DNS1 = DnsList1.SelectedValue.ToString(); {
} _dnsTotalChecked++;
_dnsServer1 = dnsList1.SelectedValue.ToString();
}
if (chkDns2.Checked) if (chkDns2.Checked)
{ {
DNS2 = DnsList2.SelectedValue.ToString(); _dnsTotalChecked++;
} _dnsServer2 = dnsList2.SelectedValue.ToString();
}
} }
ResultView.Items.Clear(); ResultView.Items.Clear();
ResultView.Update(); ResultView.Update();
Application.DoEvents(); Application.DoEvents();
GetWebAddresses(ref CleanNames, (int)numericUpDown1.Value); UrlHelper.Log += UrlHelper_Log;
UrlHelper.GetRandomUrls(ref urls, (int)numericUpDown1.Value);
for (i = 0; i < CleanNames.Count; i++) AddUrlToView(urls);
{
ListViewItem listURL = new ListViewItem(CleanNames[i]);
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
ResultView.Items.Add(listURL);
}
if (ResultView.Items.Count > 1)
{
ResultView.EnsureVisible(ResultView.Items.Count - 1);
}
ResultView.Update();
Application.DoEvents();
if (IsRunning)
{
return;
}
IsRunning = true;
CheckDNS(CleanNames.ToArray(), CleanNames.Count, DNS1, DNS2);
IsRunning = false;
}
private void TesterUI_Load(object sender, EventArgs e)
{
FillDnsList();
} }
private void FillDnsList() private void UrlHelper_Log(object sender, string e)
{ {
DnsList1.ValueMember = "ip"; SetStatus(e);
DnsList1.DisplayMember = "name"; }
DnsList2.ValueMember = "ip"; private void AddUrlToView(List<string> urls)
DnsList2.DisplayMember = "name"; {
foreach (var currentUrl in urls)
{
ListViewItem listURL = new ListViewItem(currentUrl);
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
listURL.SubItems.Add(" ");
ResultView.Items.Add(listURL);
}
if (ResultView.Items.Count > 1)
{
ResultView.EnsureVisible(ResultView.Items.Count - 1);
}
ResultView.Update();
Application.DoEvents();
}
private void TesterUI_Load(object sender, EventArgs e)
{
PopulateDnsLists();
}
private void PopulateDnsLists()
{
dnsList1.ValueMember = "ip";
dnsList1.DisplayMember = "name";
dnsList2.ValueMember = "ip";
dnsList2.DisplayMember = "name";
var serverList = Path.Combine(Application.StartupPath, "Servers.xml");
DataSet servers1 = new DataSet(); DataSet servers1 = new DataSet();
DataSet servers2 = new DataSet(); DataSet servers2 = new DataSet();
servers1.ReadXml(Path.Combine(Application.StartupPath, "Servers.xml")); servers1.ReadXml(serverList);
servers2.ReadXml(Path.Combine(Application.StartupPath, "Servers.xml")); servers2.ReadXml(serverList);
DataTable ns1 = servers1.Tables[0];
DataTable ns2 = servers2.Tables[0];
DnsList1.DataSource = ns1;
DnsList2.DataSource = ns2;
DataTable dataTable1 = servers1.Tables[0];
DataTable dataTable2 = servers2.Tables[0];
dnsList1.DataSource = dataTable1;
dnsList2.DataSource = dataTable2;
} }
private void UseCustomServers_CheckedChanged(object sender, EventArgs e) private void UseCustomServers_CheckedChanged(object sender, EventArgs e)
{ {
this.UseCustomDnsServers = UseCustomServers.Checked; useCustomDnsServers = UseCustomServers.Checked;
SetUI(); SetUI();
} }
private void SetUI() private void SetUI()
{ {
if (this.UseCustomDnsServers) if (useCustomDnsServers)
{ {
this.DnsList1.Enabled = false; dnsList1.Enabled = false;
this.DnsList2.Enabled = false; dnsList2.Enabled = false;
this.CustomDns1.Enabled = true; CustomDns1.Enabled = true;
this.CustomDns2.Enabled = true; CustomDns2.Enabled = true;
this.CustomDns1.Visible = true; CustomDns1.Visible = true;
this.CustomDns2.Visible = true; CustomDns2.Visible = true;
this.lblCustom1.Visible = true; lblCustom1.Visible = true;
this.lblCustom2.Visible = true; lblCustom2.Visible = true;
} }
else else
{ {
this.DnsList1.Enabled = true; dnsList1.Enabled = true;
this.DnsList2.Enabled = true; dnsList2.Enabled = true;
this.CustomDns1.Enabled = false; ; CustomDns1.Enabled = false;
this.CustomDns2.Enabled = false; CustomDns2.Enabled = false;
this.CustomDns1.Visible = false; CustomDns1.Visible = false;
this.CustomDns2.Visible = false; CustomDns2.Visible = false;
this.lblCustom1.Visible = false; lblCustom1.Visible = false;
this.lblCustom2.Visible = false; lblCustom2.Visible = false;
} }
} }
private void Process(string[] urls, string dnsAddress1, string dnsAddress2)
private void GetWebAddresses(ref List<string> CleanNames, int totalUrls)
{
int i, j;
byte[] random = new Byte[256];
string Letters = "";
// Make a 3 letter random string
//RNGCryptoServiceProvider is an implementation of a random number generator.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(random); // The array is now filled with cryptographically strong random bytes.
for (i = 1; i < 256; i++)
{
// Just take the first three letters
if (random[i] > 0x40 && random[i] < 0x5b) Letters = Letters + Convert.ToChar(random[i]);
if (Letters.Length == 3) break;
}
KeyValuePair<string, string> searchEngine = new KeyValuePair<string, string>();
Random rand = new Random();
// Create a list of search engine URLs to query
Dictionary<string, string> searchEngineUrls = new Dictionary<string, string>
{
{ "DuckDuckGo", "https://duckduckgo.com/html/?q=" },
{ "Yahoo", "https://search.yahoo.com/search?p=" },
{ "Bing", "https://www.bing.com/search?q=" },
{ "Google", "https://www.google.com/search?q=" },
{ "Ask", "https://www.ask.com/web?q=" },
{ "AOL", "https://www.aol.com/search?q=" },
{ "WolframAlpha", "https://www.wolframalpha.com/input/?i=" },
{ "StartPage", "https://www.startpage.com/do/dsearch?query=" },
{ "Yandex", "https://www.yandex.com/search/?text=" },
{ "Qwant", "https://www.qwant.com/?q=" }
};
try
{
while (CleanNames.Count < totalUrls)
{
int index = rand.Next(searchEngineUrls.Count);
searchEngine = searchEngineUrls.ElementAt(index);
WebRequest Request = WebRequest.Create(searchEngine.Value + Letters); //Letters);
WebResponse Response = Request.GetResponse();
Application.DoEvents();
// Get the response stream.
Stream Stream = Response.GetResponseStream();
StatusBoxPrint(searchEngine.Key + " response received");
StreamReader StreamReader = new StreamReader(Stream, Encoding.ASCII);
string ResponseString = StreamReader.ReadToEnd();
// Close the response stream and response to free resources.
Stream.Close();
Response.Close();
Application.DoEvents();
// find all .xxx.com addresses
MatchCollection HostNames;
string[] Names = new string[totalUrls + 1000];
// Create a new Regex object and define the regular expression.
Regex Dotcom = new Regex("[.]([A-Za-z]*)[.]com");
// Use the Matches method to find all matches in the input string.
HostNames = Dotcom.Matches(ResponseString);
Application.DoEvents();
// Loop through the match collection to retrieve all
// matches and delete the leading "."
for (i = 0; i < HostNames.Count; i++)
{
Names[i] = HostNames[i].Value.Remove(0, 1);
}
// eliminate its own search engine names and repeated entries
for (i = 0; i < HostNames.Count - 1; i++)
{
if (Names[i] == searchEngine.Key.ToLower() + ".com") Names[i] = "";
for (j = i + 1; j < HostNames.Count; j++)
{
if (Names[i] == Names[j]) Names[j] = "";
}
}
Shuffle(Names);
// Add the names to the list
for (i = 0; i < HostNames.Count; i++)
{
if (CleanNames.Count >= totalUrls)
{
break;
}
if (!string.IsNullOrEmpty(Names[i]) && !CleanNames.Contains(Names[i]))
{
CleanNames.Add(Names[i]);
}
}
}
StatusBoxPrint(CleanNames.Count + " Random URL's found");
}
catch(Exception exception)
{
StatusBoxPrint(searchEngine.Key + ": " ?? string.Empty + exception.Message);
}
}
public static void Shuffle<T>(T[] array)
{ {
Random rng = new Random(); int i;
int n = array.Length; int urlsTotal = urls.Length;
while (n > 1) const int ipPort = 53;
const string transactionId1 = "Q1";
const string transactionId2 = "Q2";
const string typeString = "\u0001" + "\u0000" + "\u0000" + "\u0001" + "\u0000" + "\u0000" + "\u0000" + "\u0000" + "\u0000" + "\u0000";
const string trailerString = "\u0000" + "\u0000" + "\u0001" + "\u0000" + "\u0001";
const int dnsReceiveTimeout = 5000;
string startOfUrl = string.Empty;
string domain = string.Empty;
byte[] bytesSend = new byte[256];
Socket dnsSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
dnsSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, dnsReceiveTimeout);
SetupDnsServers(dnsAddress1, dnsAddress2, ipPort, out var dnsEndpoint1, out var dnsEndpoint2);
// Start the clock
var startTime = DateTime.Now.Ticks;
for (i = 0; i < urlsTotal; i++)
{ {
n--; var currentUrl = urls[i];
int k = rng.Next(n + 1); startOfUrl = currentUrl.Substring(0, currentUrl.IndexOf("."));
T value = array[k]; domain = currentUrl.Substring(currentUrl.IndexOf(".") + 1,
array[k] = array[n]; currentUrl.Length - currentUrl.IndexOf(".") - 1);
array[n] = value; var dnsQuery = typeString + (char)startOfUrl.Length + startOfUrl + (char)domain.Length + domain +
trailerString;
string queryString;
if (chkDns1.Checked)
{
queryString = transactionId1 + dnsQuery;
bytesSend = Encoding.ASCII.GetBytes(queryString);
if (dnsEndpoint1 != null)
dnsSocket.SendTo(bytesSend, bytesSend.Length, SocketFlags.None, dnsEndpoint1);
}
if (!chkDns2.Checked) continue;
queryString = transactionId2 + dnsQuery;
bytesSend = Encoding.ASCII.GetBytes(queryString);
if (dnsEndpoint2 != null) dnsSocket.SendTo(bytesSend, bytesSend.Length, SocketFlags.None, dnsEndpoint2);
}
try
{
DnsHelper.Log += DnsHelper_Log;
DnsHelper.ProcessDns(startOfUrl, domain, urlsTotal, dnsSocket, bytesSend, startTime, _dnsTotalChecked, ResultView);
}
catch (SocketException socketException)
{
SetStatus(
Convert.ToString(socketException).IndexOf("time", StringComparison.Ordinal) > 0
? $"Timeout - No response received for {Convert.ToString(dnsReceiveTimeout / 1000)} seconds"
: Convert.ToString(socketException));
}
finally
{
// close the socket
dnsSocket.Close();
} }
} }
private void CheckDNS(string[] URLNames, int URLNamescount, string DNSAddress1, string DNSAddress2) private void DnsHelper_Log(object sender, string e)
{ {
int i; SetStatus(e);
const int IPPort = 53; }
const string TransactionID1 = "Q1"; // Use transaction ID of Q1 and Q2 to identify our packet and DNS
const string TransactionID2 = "Q2";
const string TypeString = "\u0001" + "\u0000" + "\u0000" + "\u0001" + "\u0000" + "\u0000" + "\u0000" + "\u0000" + "\u0000" + "\u0000";
const string TrailerString = "\u0000" + "\u0000" + "\u0001" + "\u0000" + "\u0001";
const int DNSReceiveTimeout = 5000;
string URLNameStart, DomainName, QueryString, ReceiveString, IPResponse, sDeltaTime;
int URLNameStartLength, DomainNameLength, index, TransactionDNS;
byte[] Sendbytes = new byte[256];
long StartTime, StopTime;
string DeltaTime;
Socket DNSsocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
DNSsocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, DNSReceiveTimeout);
IPEndPoint dnsEP1 = null; private void SetupDnsServers(string dnsAddress1, string dnsAddress2, int ipPort, out IPEndPoint dnsEndpoint1,
if (chkDns1.Checked && !string.IsNullOrWhiteSpace(DNSAddress1)) out IPEndPoint dnsEndpoint2)
{ {
dnsEP1 = new IPEndPoint(IPAddress.Parse(DNSAddress1), IPPort); dnsEndpoint1 = null;
} if (chkDns1.Checked && !string.IsNullOrWhiteSpace(dnsAddress1))
{
dnsEndpoint1 = new IPEndPoint(IPAddress.Parse(dnsAddress1), ipPort);
}
IPEndPoint dnsEP2 = null; dnsEndpoint2 = null;
if (chkDns2.Checked && !string.IsNullOrWhiteSpace(DNSAddress2)) if (chkDns2.Checked && !string.IsNullOrWhiteSpace(dnsAddress2))
{ {
dnsEP2 = new IPEndPoint(IPAddress.Parse(DNSAddress2), IPPort); dnsEndpoint2 = new IPEndPoint(IPAddress.Parse(dnsAddress2), ipPort);
} }
}
// Start the clock
StartTime = DateTime.Now.Ticks;
for (i = 0; i < URLNamescount; i++)
{
URLNameStart = URLNames[i].Substring(0, URLNames[i].IndexOf("."));
DomainName = URLNames[i].Substring(URLNames[i].IndexOf(".") + 1, URLNames[i].Length - URLNames[i].IndexOf(".") - 1);
if (chkDns1.Checked)
{
QueryString = TransactionID1 + TypeString + (char)URLNameStart.Length + URLNameStart + (char)DomainName.Length + DomainName + TrailerString;
Sendbytes = Encoding.ASCII.GetBytes(QueryString);
if (dnsEP1 != null)
{
DNSsocket.SendTo(Sendbytes, Sendbytes.Length, SocketFlags.None, dnsEP1);
}
}
if (chkDns2.Checked)
{
QueryString = TransactionID2 + TypeString + (char)URLNameStart.Length + URLNameStart + (char)DomainName.Length + DomainName + TrailerString;
Sendbytes = Encoding.ASCII.GetBytes(QueryString);
if (dnsEP2 != null)
{
DNSsocket.SendTo(Sendbytes, Sendbytes.Length, SocketFlags.None, dnsEP2);
}
}
}
byte[] Receivebytes = new byte[512];
int totalReceived = 0;
try
{
// wait for a response up to timeout
more:
DNSsocket.Receive(Receivebytes);
// make sure the message returned is ours
if (Receivebytes[0] == Sendbytes[0] && (Receivebytes[1] == 0x31) || (Receivebytes[1] == 0x32))
{
if (Receivebytes[2] == 0x81 && Receivebytes[3] == 0x80)
{
// Get the time now
StopTime = DateTime.Now.Ticks;
DeltaTime = Convert.ToString((double)(StopTime - StartTime) / 10000000);
// Decode the answers
// Find the URL that was returned
TransactionDNS = Receivebytes[1];
ReceiveString = Encoding.ASCII.GetString(Receivebytes);
index = 12;
URLNameStartLength = Receivebytes[index];
index++;
URLNameStart = ReceiveString.Substring(index, URLNameStartLength);
index = index + URLNameStartLength;
DomainNameLength = Receivebytes[index];
index++;
DomainName = ReceiveString.Substring(index, DomainNameLength);
index = index + DomainNameLength;
index = index + 8;
// Get the record type
int ResponseType = Receivebytes[index];
index = index + 9;
// Get the IP address if applicable
IPResponse = "";
switch (ResponseType)
{
case 1:
IPResponse = Convert.ToString(Receivebytes[index]) + "."
+ Convert.ToString(Receivebytes[index + 1]) + "."
+ Convert.ToString(Receivebytes[index + 2]) + "."
+ Convert.ToString(Receivebytes[index + 3]); break;
case 5: IPResponse = "CNAME"; break;
case 6: IPResponse = "SOA"; break;
}
StatusBoxPrint("DNS Answer: " + URLNameStart + "." + DomainName + " = " + IPResponse);
// Find the URL entry in the list
for (i = 0; i < ResultView.Items.Count; i++)
{
if (ResultView.Items[i].Text == URLNameStart + "." + DomainName)
{
switch (TransactionDNS)
{
case 0x31:
ResultView.Items[i].SubItems[1].Text = Convert.ToString(IPResponse);
sDeltaTime = Convert.ToString(DeltaTime);
if (sDeltaTime.Length > 5) ResultView.Items[i].SubItems[2].Text = sDeltaTime.Substring(0, 5);
else ResultView.Items[i].SubItems[2].Text = sDeltaTime;
ResultView.Items[i].ForeColor = System.Drawing.Color.Red;
ResultView.EnsureVisible(i);
ResultView.Update();
Application.DoEvents();
ResultView.Items[i].ForeColor = System.Drawing.Color.Black;
break;
case 0x32:
ResultView.Items[i].SubItems[3].Text = Convert.ToString(IPResponse);
sDeltaTime = Convert.ToString(DeltaTime);
if (sDeltaTime.Length > 5) ResultView.Items[i].SubItems[4].Text = sDeltaTime.Substring(0, 5);
else ResultView.Items[i].SubItems[4].Text = sDeltaTime;
ResultView.Items[i].ForeColor = System.Drawing.Color.Red;
ResultView.EnsureVisible(i);
ResultView.Update();
Application.DoEvents();
ResultView.Items[i].ForeColor = System.Drawing.Color.Black;
break;
}
totalReceived++;
}
}
}
if (totalReceived < URLNamescount)
{
goto more;
}
}
}
catch (SocketException e)
{
if (Convert.ToString(e).IndexOf("time") > 0)
{
StatusBoxPrint("Timeout - No response received for " + Convert.ToString(DNSReceiveTimeout / 1000) + " seconds");
}
else
{
StatusBoxPrint(Convert.ToString(e)); // for testing
}
}
finally
{
// close the socket
DNSsocket.Close();
}
}
private async void btnResolveIP_Click(object sender, EventArgs e) private async void btnResolveIP_Click(object sender, EventArgs e)
{ {
if (string.IsNullOrWhiteSpace(txtResolveIP.Text)) if (string.IsNullOrWhiteSpace(txtResolveIP.Text))
{ {
MessageBox.Show("Please enter an IP address to resolve"); MessageBox.Show("Please enter an IP address to resolve");
return; return;
}
if (!IPAddress.TryParse(txtResolveIP.Text , out IPAddress iPAddress))
{
MessageBox.Show("Please enter a valid IP address");
return;
} }
try if (!IPAddress.TryParse(txtResolveIP.Text, out IPAddress iPAddress))
{ {
await Task.Run(() => MessageBox.Show("Please enter a valid IP address");
{ return;
var dnsEntry = Dns.GetHostEntry(iPAddress); }
Dispatcher.CurrentDispatcher.Invoke(() =>
{ try
txtResolveHost.Text = dnsEntry.HostName; {
}); await Task.Run(() =>
{
var dnsEntry = Dns.GetHostEntry(iPAddress);
txtResolveHost.Invoke(() =>
{
txtResolveHost.Text = dnsEntry.HostName;
});
}); });
} }
catch (Exception) catch (Exception)
{ {
MessageBox.Show($"Could not get hostname for IP address '{txtResolveIP.Text}'"); MessageBox.Show($"Could not get hostname for IP address '{txtResolveIP.Text}'");
} }
} }
private async void btnResolveHost_Click(object sender, EventArgs e) private async void btnResolveHost_Click(object sender, EventArgs e)
@ -494,15 +305,15 @@ namespace EonaCat.DnsTester
try try
{ {
await Task.Run(() => await Task.Run(() =>
{ {
var dnsEntry = Dns.GetHostEntry(txtResolveHost.Text); var dnsEntry = Dns.GetHostEntry(txtResolveHost.Text);
Dispatcher.CurrentDispatcher.Invoke(() => txtResolveHost.Invoke(() =>
{ {
txtResolveIP.Text = dnsEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault().Address.ToString(); txtResolveIP.Text = dnsEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork).FirstOrDefault().Address.ToString();
}); });
}); });
} }
catch (Exception) catch (Exception)
{ {
@ -510,17 +321,17 @@ namespace EonaCat.DnsTester
} }
} }
private void StatusBoxPrint(string LogText) private void SetStatus(string text)
{ {
StatusBox.Items.Add(DateTime.Now + " " + LogText); StatusBox.Items.Add($"{DateTime.Now} {text}");
StatusBox.TopIndex = StatusBox.Items.Count - 1; StatusBox.TopIndex = StatusBox.Items.Count - 1;
if (StatusBox.Items.Count > 5000) if (StatusBox.Items.Count > STATUS_BAR_SIZE)
{ {
StatusBox.Items.RemoveAt(0); StatusBox.Items.RemoveAt(0);
} }
StatusBox.Update(); StatusBox.Update();
} }
const int STATUS_BAR_SIZE = 5000;
} }
} }