Initial commit

This commit is contained in:
Stone_Red
2021-12-12 17:44:06 +01:00
commit 730264efc8
11 changed files with 45177 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>ARP_Scanner</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="IPAddressRange" Version="4.2.0" />
<PackageReference Include="Stone_Red-C-Sharp-Utilities" Version="1.0.3.1" />
</ItemGroup>
<ItemGroup>
<None Update="mac-vendors.csv">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+39
View File
@@ -0,0 +1,39 @@
using Stone_Red_Utilities.ConsoleExtentions;
using System.Net;
using System.Runtime.InteropServices;
namespace ARP_Scanner;
internal class ArpUtilities
{
[DllImport("iphlpapi.dll", ExactSpelling = true)]
private static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);
private uint macAddrLen = (uint)new byte[6].Length;
public string? SendArpRequest(IPAddress ipAddress)
{
byte[] macAddr = new byte[6];
try
{
_ = SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen);
if (MacAddresstoString(macAddr) != "00-00-00-00-00-00")
{
return MacAddresstoString(macAddr);
}
}
catch (Exception e)
{
ConsoleExt.WriteLine(e.Message, ConsoleColor.Red);
}
return null;
}
public static string MacAddresstoString(byte[] macAdrr)
{
string macString = BitConverter.ToString(macAdrr);
return macString.ToUpper();
}
}
+57
View File
@@ -0,0 +1,57 @@
using System.Text.RegularExpressions;
namespace ARP_Scanner;
internal class MacVendorLookup
{
public readonly string[] header;
private readonly string[][] fields;
public MacVendorLookup(string csvPath)
{
if (!File.Exists(csvPath))
{
header = Array.Empty<string>();
fields = Array.Empty<string[]>();
return;
}
string[] lines = File.ReadAllLines(csvPath);
header = lines[0].Split(',');
fields = lines.Skip(1).Select(l => Regex.Split(l, ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))")).ToArray();
}
public string[] GetInformation(string macAdress)
{
string[]? data = fields.FirstOrDefault(f => macAdress.StartsWith(f[0]))?.ToArray();
if (fields.Length == 0 || header.Length == 0)
{
return Array.Empty<string>();
}
else if (data is null)
{
string[] result = new string[header.Length - 1];
for (int i = 0; i < result.Length; i++)
{
result[i] = "Unknown";
}
return result;
}
else
{
List<string> result = new List<string>();
for (int i = 1; i < header.Length; i++)
{
result.Add($"{data[i]}");
}
return result.ToArray();
}
}
public string[] GetHeader()
{
return header!.Skip(1).ToArray();
}
}
+100
View File
@@ -0,0 +1,100 @@
using ARP_Scanner;
using NetTools;
using Stone_Red_Utilities.CollectionExtentions;
using Stone_Red_Utilities.ConsoleExtentions;
using System.Collections.Concurrent;
using System.Net;
internal class Program
{
private static void Main(string[] args)
{
bool success = false;
IPAddress[]? ipAddresses = null;
MacVendorLookup macVendorLookup = new MacVendorLookup("mac-vendors.csv");
if (args.Length >= 1)
{
success = IPAddressRange.TryParse(string.Join("", args), out IPAddressRange iPAddressRange);
ipAddresses = iPAddressRange.AsEnumerable().ToArray();
}
if (!success || ipAddresses is null)
{
ConsoleExt.WriteLine("Invalid IP range!", ConsoleColor.Red);
return;
}
int ipAddressesCount = ipAddresses.Length;
int processedIpAddressesCount = 0;
List<string> header = new List<string>() { "IP", "MAC" };
ConcurrentBag<string[]> activeHosts = new ConcurrentBag<string[]>();
header.AddRange(macVendorLookup.GetHeader());
ConsoleExt.WriteLine("Starting scan...", ConsoleColor.DarkYellow);
Parallel.ForEach(ipAddresses, ipAddress =>
{
string? mac = new ArpUtilities().SendArpRequest(ipAddress);
Interlocked.Increment(ref processedIpAddressesCount);
if (mac is not null)
{
List<string> info = new List<string> { ipAddress.ToString(), mac };
info.AddRange(macVendorLookup.GetInformation(mac));
ConsoleExt.WriteLine($"Progress: {processedIpAddressesCount}/{ipAddressesCount} [{100d / ipAddressesCount * processedIpAddressesCount:0.00}%] | Active: {ipAddress}", ConsoleColor.Green);
activeHosts.Add(info.ToArray());
}
else
{
ConsoleExt.WriteLine($"Progress: {processedIpAddressesCount}/{ipAddressesCount} [{100d / ipAddressesCount * processedIpAddressesCount:0.00}%] | Inactive: {ipAddress}", ConsoleColor.Red);
}
});
if (!activeHosts.IsEmpty)
{
Console.WriteLine(Environment.NewLine + "Active hosts:");
List<string[]>? activeHostsTable = activeHosts.ToList();
activeHostsTable.Insert(0, header.ToArray());
To2D(activeHostsTable.ToArray()).PrintTable(TableStyle.List);
ConsoleExt.WriteLine($"{Environment.NewLine}Found {activeHosts.Count} active hosts", ConsoleColor.Green);
}
else
{
ConsoleExt.WriteLine($"{Environment.NewLine}No active hosts found", ConsoleColor.Red);
}
}
private static T[,] To2D<T>(T[][] source)
{
try
{
int FirstDim = source.Length;
int SecondDim = source.GroupBy(row => row.Length).Single().Key; // throws InvalidOperationException if source is not rectangular
T[,]? result = new T[FirstDim, SecondDim];
for (int i = 0; i < FirstDim; ++i)
{
for (int j = 0; j < SecondDim; ++j)
{
result[i, j] = source[i][j];
}
}
return result;
}
catch (InvalidOperationException)
{
throw new InvalidOperationException("The given jagged array is not rectangular.");
}
}
}
@@ -0,0 +1,8 @@
{
"profiles": {
"ARP-Scanner": {
"commandName": "Project",
"commandLineArgs": "192.168.1.0 - 192.168.1.255"
}
}
}
File diff suppressed because it is too large Load Diff