improvement
This commit is contained in:
parent
4fbe6ffd79
commit
b7bc20a027
@ -5,81 +5,61 @@ using System.Net.Http;
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Connectivity tester – fixed time‑outs + real HTTP/HTTPS endpoints
|
||||||
|
// ------------------------------------------------------------------
|
||||||
namespace winPEAS.Info.NetworkInfo
|
namespace winPEAS.Info.NetworkInfo
|
||||||
{
|
{
|
||||||
public class InternetConnectivityInfo
|
|
||||||
{
|
|
||||||
public bool HttpAccess { get; set; }
|
|
||||||
public bool HttpsAccess { get; set; }
|
|
||||||
public bool LambdaAccess { get; set; }
|
|
||||||
public bool DnsAccess { get; set; }
|
|
||||||
public bool IcmpAccess { get; set; }
|
|
||||||
public string HttpError { get; set; }
|
|
||||||
public string HttpsError { get; set; }
|
|
||||||
public string LambdaError { get; set; }
|
|
||||||
public string DnsError { get; set; }
|
|
||||||
public string IcmpError { get; set; }
|
|
||||||
public string SuccessfulHttpIp { get; set; }
|
|
||||||
public string SuccessfulHttpsIp { get; set; }
|
|
||||||
public string SuccessfulDnsIp { get; set; }
|
|
||||||
public string SuccessfulIcmpIp { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class InternetConnectivity
|
public static class InternetConnectivity
|
||||||
{
|
{
|
||||||
private const int HTTP_TIMEOUT = 5000; // 5 seconds
|
// 5 seconds expressed in *milliseconds* to avoid unit mistakes
|
||||||
private const int ICMP_TIMEOUT = 2000; // 2 seconds
|
private const int HTTP_TIMEOUT_MS = 5000;
|
||||||
private static readonly string[] TEST_IPS = new[] { "1.1.1.1", "8.8.8.8" }; // Cloudflare DNS, Google DNS
|
private const int ICMP_TIMEOUT_MS = 2000;
|
||||||
private const string LAMBDA_URL = "https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/";
|
|
||||||
|
|
||||||
private static bool TryHttpAccess(string ip, out string error)
|
// IPs that really listen on 80/443 (example.com + Fastly CDN)
|
||||||
|
private static readonly string[] WEB_TEST_IPS =
|
||||||
|
{ "93.184.216.34", "151.101.1.69" };
|
||||||
|
|
||||||
|
// DNS & ICMP targets stay the same – public resolvers
|
||||||
|
private static readonly string[] DNS_ICMP_IPS =
|
||||||
|
{ "1.1.1.1", "8.8.8.8" };
|
||||||
|
|
||||||
|
private const string LAMBDA_URL =
|
||||||
|
"https://2e6ppt7izvuv66qmx2r3et2ufi0mxwqs.lambda-url.us-east-1.on.aws/";
|
||||||
|
|
||||||
|
// Re‑use a single HttpClient to avoid socket exhaustion
|
||||||
|
private static readonly HttpClient http = new HttpClient
|
||||||
|
{
|
||||||
|
Timeout = TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS)
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// HTTP (port 80)
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
private static bool TryHttpAccess(string ip, out string error) =>
|
||||||
|
TryWebRequest($"http://{ip}", out error);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// HTTPS (port 443)
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
private static bool TryHttpsAccess(string ip, out string error) =>
|
||||||
|
TryWebRequest($"https://{ip}", out error);
|
||||||
|
|
||||||
|
// Common HTTP/HTTPS helper
|
||||||
|
private static bool TryWebRequest(string url, out string error)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
|
using var cts =
|
||||||
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
|
new CancellationTokenSource(TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS));
|
||||||
|
|
||||||
var resp = client.GetAsync($"http://{ip}", cts.Token)
|
var resp = http.GetAsync(url, cts.Token).GetAwaiter().GetResult();
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
if (resp.IsSuccessStatusCode)
|
// Any response indicates that we reached the server
|
||||||
{
|
error = null;
|
||||||
error = null;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = $"HTTP status {(int)resp.StatusCode}";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
error = ex.Message;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool TryHttpsAccess(string ip, out string error)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
|
|
||||||
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
|
|
||||||
|
|
||||||
var resp = client.GetAsync($"https://{ip}", cts.Token)
|
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
if (resp.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
error = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = $"HTTPS status {(int)resp.StatusCode}";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -88,28 +68,28 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// Lambda URL check (GET)
|
||||||
|
// ----------------------------------------------------------
|
||||||
private static bool TryLambdaAccess(out string error)
|
private static bool TryLambdaAccess(out string error)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(HTTP_TIMEOUT));
|
using var cts =
|
||||||
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(HTTP_TIMEOUT) };
|
new CancellationTokenSource(TimeSpan.FromMilliseconds(HTTP_TIMEOUT_MS));
|
||||||
|
|
||||||
var req = new HttpRequestMessage(HttpMethod.Get, LAMBDA_URL);
|
var req = new HttpRequestMessage(HttpMethod.Get, LAMBDA_URL);
|
||||||
req.Headers.UserAgent.ParseAdd("winpeas");
|
req.Headers.UserAgent.ParseAdd("winpeas");
|
||||||
req.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
req.Headers.Accept.Add(
|
||||||
|
new MediaTypeWithQualityHeaderValue("application/json"));
|
||||||
|
|
||||||
var resp = client.SendAsync(req, cts.Token)
|
var resp = http.SendAsync(req, cts.Token)
|
||||||
.GetAwaiter().GetResult();
|
.GetAwaiter().GetResult();
|
||||||
|
|
||||||
if (resp.IsSuccessStatusCode)
|
error = resp.IsSuccessStatusCode
|
||||||
{
|
? null
|
||||||
error = null;
|
: $"HTTP {(int)resp.StatusCode}";
|
||||||
return true;
|
return error == null;
|
||||||
}
|
|
||||||
|
|
||||||
error = $"Lambda status {(int)resp.StatusCode}";
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -118,167 +98,125 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// DNS test – simple UDP query
|
||||||
|
// ----------------------------------------------------------
|
||||||
private static bool TryDnsAccess(string ip, out string error)
|
private static bool TryDnsAccess(string ip, out string error)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var udpClient = new UdpClient())
|
using var udp = new UdpClient();
|
||||||
|
udp.Client.ReceiveTimeout = HTTP_TIMEOUT_MS;
|
||||||
|
udp.Client.SendTimeout = HTTP_TIMEOUT_MS;
|
||||||
|
|
||||||
|
var server = new IPEndPoint(IPAddress.Parse(ip), 53);
|
||||||
|
|
||||||
|
// Minimal “A record for google.com” query
|
||||||
|
byte[] query = new byte[]
|
||||||
{
|
{
|
||||||
// Set a timeout for the connection attempt
|
0x00,0x01, 0x01,0x00, 0x00,0x01, 0x00,0x00, 0x00,0x00, 0x00,0x00,
|
||||||
udpClient.Client.ReceiveTimeout = HTTP_TIMEOUT;
|
0x06,0x67,0x6f,0x6f,0x67,0x6c,0x65, 0x03,0x63,0x6f,0x6d, 0x00,
|
||||||
udpClient.Client.SendTimeout = HTTP_TIMEOUT;
|
0x00,0x01, 0x00,0x01
|
||||||
|
};
|
||||||
|
|
||||||
// Create DNS server endpoint
|
udp.Send(query, query.Length, server);
|
||||||
var dnsServer = new IPEndPoint(IPAddress.Parse(ip), 53);
|
|
||||||
|
|
||||||
// Create a simple DNS query for google.com (type A record)
|
IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0);
|
||||||
byte[] dnsQuery = new byte[] {
|
byte[] response = udp.Receive(ref remote);
|
||||||
0x00, 0x01, // Transaction ID
|
|
||||||
0x01, 0x00, // Flags (Standard query)
|
|
||||||
0x00, 0x01, // Questions: 1
|
|
||||||
0x00, 0x00, // Answer RRs: 0
|
|
||||||
0x00, 0x00, // Authority RRs: 0
|
|
||||||
0x00, 0x00, // Additional RRs: 0
|
|
||||||
// google.com
|
|
||||||
0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
|
|
||||||
0x00, 0x01, // Type: A
|
|
||||||
0x00, 0x01 // Class: IN
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send the DNS query
|
error = response?.Length > 0 ? null : "No DNS response";
|
||||||
udpClient.Send(dnsQuery, dnsQuery.Length, dnsServer);
|
return error == null;
|
||||||
|
|
||||||
// Try to receive a response
|
|
||||||
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
|
|
||||||
byte[] response = udpClient.Receive(ref remoteEP);
|
|
||||||
|
|
||||||
// If we got a response, the DNS server is reachable
|
|
||||||
if (response != null && response.Length > 0)
|
|
||||||
{
|
|
||||||
error = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = "No response received from DNS server";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SocketException ex)
|
|
||||||
{
|
|
||||||
error = $"Socket error: {ex.Message}";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
error = ex.Message;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
catch (SocketException ex) { error = ex.Message; return false; }
|
||||||
|
catch (Exception ex) { error = ex.Message; return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// ICMP (Ping)
|
||||||
|
// ----------------------------------------------------------
|
||||||
private static bool TryIcmpAccess(string ip, out string error)
|
private static bool TryIcmpAccess(string ip, out string error)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var ping = new Ping())
|
using var ping = new Ping();
|
||||||
{
|
var reply = ping.Send(ip, ICMP_TIMEOUT_MS);
|
||||||
var reply = ping.Send(ip, ICMP_TIMEOUT);
|
|
||||||
if (reply?.Status == IPStatus.Success)
|
error = reply?.Status == IPStatus.Success
|
||||||
{
|
? null
|
||||||
error = null;
|
: $"Ping failed: {reply?.Status}";
|
||||||
return true;
|
return error == null;
|
||||||
}
|
|
||||||
error = $"Ping failed with status: {reply?.Status}";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
error = ex.Message;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
catch (Exception ex) { error = ex.Message; return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// MAIN ENTRY
|
||||||
|
// ----------------------------------------------------------
|
||||||
public static InternetConnectivityInfo CheckConnectivity()
|
public static InternetConnectivityInfo CheckConnectivity()
|
||||||
{
|
{
|
||||||
var result = new InternetConnectivityInfo();
|
var info = new InternetConnectivityInfo();
|
||||||
|
|
||||||
// Test HTTP (port 80) on each IP until success
|
// --- HTTP / HTTPS -------------------------------------
|
||||||
foreach (var ip in TEST_IPS)
|
foreach (var ip in WEB_TEST_IPS)
|
||||||
{
|
{
|
||||||
if (TryHttpAccess(ip, out string error))
|
if (!info.HttpAccess &&
|
||||||
|
TryHttpAccess(ip, out string eHttp))
|
||||||
{
|
{
|
||||||
result.HttpAccess = true;
|
info.HttpAccess = true;
|
||||||
result.SuccessfulHttpIp = ip;
|
info.SuccessfulHttpIp = ip;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
|
else if (!info.HttpAccess)
|
||||||
{
|
{
|
||||||
result.HttpAccess = false;
|
info.HttpError = eHttp;
|
||||||
result.HttpError = error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!info.HttpsAccess &&
|
||||||
|
TryHttpsAccess(ip, out string eHttps))
|
||||||
|
{
|
||||||
|
info.HttpsAccess = true;
|
||||||
|
info.SuccessfulHttpsIp = ip;
|
||||||
|
}
|
||||||
|
else if (!info.HttpsAccess)
|
||||||
|
{
|
||||||
|
info.HttpsError = eHttps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.HttpAccess && info.HttpsAccess) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test HTTPS (port 443) on each IP until success
|
// --- Lambda ------------------------------------------
|
||||||
foreach (var ip in TEST_IPS)
|
info.LambdaAccess = TryLambdaAccess(out string eLambda);
|
||||||
|
if (!info.LambdaAccess) info.LambdaError = eLambda;
|
||||||
|
|
||||||
|
// --- DNS / ICMP --------------------------------------
|
||||||
|
foreach (var ip in DNS_ICMP_IPS)
|
||||||
{
|
{
|
||||||
if (TryHttpsAccess(ip, out string error))
|
if (!info.DnsAccess &&
|
||||||
|
TryDnsAccess(ip, out string eDns))
|
||||||
{
|
{
|
||||||
result.HttpsAccess = true;
|
info.DnsAccess = true;
|
||||||
result.SuccessfulHttpsIp = ip;
|
info.SuccessfulDnsIp = ip;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
|
else if (!info.DnsAccess)
|
||||||
{
|
{
|
||||||
result.HttpsAccess = false;
|
info.DnsError = eDns;
|
||||||
result.HttpsError = error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!info.IcmpAccess &&
|
||||||
|
TryIcmpAccess(ip, out string ePing))
|
||||||
|
{
|
||||||
|
info.IcmpAccess = true;
|
||||||
|
info.SuccessfulIcmpIp = ip;
|
||||||
|
}
|
||||||
|
else if (!info.IcmpAccess)
|
||||||
|
{
|
||||||
|
info.IcmpError = ePing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.DnsAccess && info.IcmpAccess) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test Lambda URL
|
return info;
|
||||||
result.LambdaAccess = TryLambdaAccess(out string lambdaError);
|
|
||||||
if (!result.LambdaAccess)
|
|
||||||
{
|
|
||||||
result.LambdaError = lambdaError;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result.HttpsAccess = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test DNS on each IP until success
|
|
||||||
foreach (var ip in TEST_IPS)
|
|
||||||
{
|
|
||||||
if (TryDnsAccess(ip, out string error))
|
|
||||||
{
|
|
||||||
result.DnsAccess = true;
|
|
||||||
result.SuccessfulDnsIp = ip;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
|
|
||||||
{
|
|
||||||
result.DnsAccess = false;
|
|
||||||
result.DnsError = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test ICMP (ping) on each IP until success
|
|
||||||
foreach (var ip in TEST_IPS)
|
|
||||||
{
|
|
||||||
if (TryIcmpAccess(ip, out string error))
|
|
||||||
{
|
|
||||||
result.IcmpAccess = true;
|
|
||||||
result.SuccessfulIcmpIp = ip;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (ip == TEST_IPS[TEST_IPS.Length - 1]) // Last IP
|
|
||||||
{
|
|
||||||
result.IcmpAccess = false;
|
|
||||||
result.IcmpError = error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user