Skip to content

Instantly share code, notes, and snippets.

@andreaskueffel
Created March 27, 2026 07:40
Show Gist options
  • Select an option

  • Save andreaskueffel/6d04bdddf3e2df8f1e59e3bc40fa397b to your computer and use it in GitHub Desktop.

Select an option

Save andreaskueffel/6d04bdddf3e2df8f1e59e3bc40fa397b to your computer and use it in GitHub Desktop.
Subnet Portscanner for Port 80 as Filebased C# App; run with 'dotnet Port80Scanner.cs 192.168.0.0'
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Text;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
// ----------------- MAIN -----------------
Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine("Starting network scan...");
// Subnetz ermitteln
string subnet = args.Length > 0
? string.Join('.', args[0].Split('.').Take(3))
: Scanner.GetLocalSubnet();
Console.WriteLine($"Subnet: {subnet}.0/24");
var found = new ConcurrentBag<(IPAddress IP, string? Host, string? MAC, string? Server)>();
var oui = await Scanner.LoadOuiAsync();
var tasks = Enumerable.Range(1, 254).Select(async i =>
{
var ip = IPAddress.Parse($"{subnet}.{i}");
if (!await Scanner.IsPortOpenAsync(ip))
return;
found.Add((
ip,
Scanner.TryResolveHostname(ip),
Scanner.GetMacAddress(ip),
await Scanner.GetHttpServerHeader(ip)
));
});
await Task.WhenAll(tasks);
// Ausgabe
Console.WriteLine("\n--- Results ---");
foreach (var f in found.OrderBy(x => x.IP.ToString()))
{
string vendor = Scanner.LookupVendor(f.MAC, oui);
vendor = vendor.Length > 20 ? vendor[..20] : vendor;
Console.WriteLine(
$"{f.IP,-15} Host: {f.Host ?? "-", -15} " +
$"MAC: {f.MAC ?? "-", -17} {vendor,-20} Server: {f.Server ?? "-"}"
);
}
Console.WriteLine("\nScan done.");
// ----------------- STATISCHE HILFSKLASSE -----------------
static class Scanner
{
[DllImport("iphlpapi.dll", ExactSpelling = true)]
private static extern int SendARP(int destIp, int srcIp, byte[] pMacAddr, ref uint phyAddrLen);
public static string? GetMacAddress(IPAddress ip)
{
try
{
byte[] mac = new byte[6];
uint len = 6;
int r = SendARP(BitConverter.ToInt32(ip.GetAddressBytes(), 0), 0, mac, ref len);
return r == 0 ? BitConverter.ToString(mac, 0, (int)len) : null;
}
catch { return null; }
}
public static async Task<bool> IsPortOpenAsync(IPAddress ip, int timeout = 200)
{
using var client = new TcpClient();
var task = client.ConnectAsync(ip, 80);
return await Task.WhenAny(task, Task.Delay(timeout)) == task;
}
public static async Task<string?> GetHttpServerHeader(IPAddress ip)
{
try
{
using var handler = new SocketsHttpHandler
{
ConnectTimeout = TimeSpan.FromMilliseconds(300)
};
using var http = new HttpClient(handler)
{
Timeout = TimeSpan.FromMilliseconds(500)
};
var resp = await http.SendAsync(new HttpRequestMessage(HttpMethod.Head, $"http://{ip}/"));
return resp.Headers.TryGetValues("Server", out var v) ? string.Join(", ", v) : null;
}
catch { return null; }
}
public static string? TryResolveHostname(IPAddress ip)
{
try { return Dns.GetHostEntry(ip).HostName; }
catch { return null; }
}
public static string LookupVendor(string? mac, Dictionary<string, string> oui)
{
if (string.IsNullOrWhiteSpace(mac)) return "-";
string prefix = mac.ToUpper().Substring(0, 8);
return oui.TryGetValue(prefix, out var vendor)
? vendor
: "Unknown Vendor";
}
public static readonly string OuiUrl = "https://standards-oui.ieee.org/oui/oui.txt";
public static readonly string OuiCacheFile = "oui.txt";
public static async Task<Dictionary<string, string>> LoadOuiAsync()
{
if (!File.Exists(OuiCacheFile))
{
Console.WriteLine("Loading OUI-Data from IEEE …");
using var http = new HttpClient();
await File.WriteAllTextAsync(OuiCacheFile, await http.GetStringAsync(OuiUrl));
}
return File.ReadLines(OuiCacheFile)
.Where(l => l.Contains("(hex)"))
.Select(l =>
{
var parts = l.Split("(hex)", StringSplitOptions.RemoveEmptyEntries);
return new
{
Prefix = parts[0].Trim().Replace(" ", "-").ToUpper(),
Vendor = parts[1].Trim()
};
})
.GroupBy(x => x.Prefix)
.ToDictionary(g => g.Key, g => g.First().Vendor);
}
public static string GetLocalSubnet()
{
var ipv4 = NetworkInterface.GetAllNetworkInterfaces()
.SelectMany(i => i.GetIPProperties().UnicastAddresses)
.FirstOrDefault(a => a.Address.AddressFamily == AddressFamily.InterNetwork)
?.Address;
if (ipv4 == null)
throw new Exception("No IPv4 found.");
var b = ipv4.GetAddressBytes();
return $"{b[0]}.{b[1]}.{b[2]}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment