Update project to .NET 8 and auto update mac db

This commit is contained in:
Stone_Red
2024-05-01 01:36:31 +02:00
parent a4536f05d8
commit 6de6edbf48
8 changed files with 119 additions and 44624 deletions
+3 -3
View File
@@ -40,7 +40,7 @@ enclosed in quotation marks, you should use an editor that supports UTF-8, not t
<!-- Note that unstable versions like 0.0.1 can be considered a released version, but it's <!-- Note that unstable versions like 0.0.1 can be considered a released version, but it's
possible that one can release a 0.0.1-beta before you release a 0.0.1 version. If the version possible that one can release a 0.0.1-beta before you release a 0.0.1 version. If the version
number is final, that is considered a released version and not a prerelease. --> number is final, that is considered a released version and not a prerelease. -->
<version>0.2.0.20240103</version> <version>1.0.0.0</version>
<!-- <packageSourceUrl>Where is this Chocolatey package located (think GitHub)? packageSourceUrl <!-- <packageSourceUrl>Where is this Chocolatey package located (think GitHub)? packageSourceUrl
is highly recommended for the community feed</packageSourceUrl>--> is highly recommended for the community feed</packageSourceUrl>-->
<!-- owners is a poor name for maintainers of the package. It sticks around by this name for <!-- owners is a poor name for maintainers of the package. It sticks around by this name for
@@ -68,7 +68,7 @@ enclosed in quotation marks, you should use an editor that supports UTF-8, not t
what url are the software docs located?</docsUrl>--> what url are the software docs located?</docsUrl>-->
<!--<mailingListUrl></mailingListUrl>--> <!--<mailingListUrl></mailingListUrl>-->
<!--<bugTrackerUrl></bugTrackerUrl>--> <!--<bugTrackerUrl></bugTrackerUrl>-->
<tags>arp-scanner arp p2p fiel-transfer</tags> <tags>arp-scanner arp</tags>
<summary>A lightweight cross-platform IP scanner</summary> <summary>A lightweight cross-platform IP scanner</summary>
<description> <description>
**Usage** **Usage**
@@ -112,6 +112,6 @@ enclosed in quotation marks, you should use an editor that supports UTF-8, not t
<files> <files>
<!-- this section controls what actually gets packaged into the Chocolatey package --> <!-- this section controls what actually gets packaged into the Chocolatey package -->
<file src="tools\**" target="tools" /> <file src="tools\**" target="tools" />
<file src="..\src\ARP-Scanner\bin\Release\net6.0\**" target="tools" /> <file src="..\src\ARP-Scanner\bin\Release\net8.0\**" target="tools" />
</files> </files>
</package> </package>
+3 -3
View File
@@ -1,5 +1,5 @@
name: arp-scanner # you probably want to 'snapcraft register <name>' name: arp-scanner # you probably want to 'snapcraft register <name>'
version: "0.2.0.20240103" # just for humans, typically '1.2+git' or '1.3.2' version: "1.0.0.0" # just for humans, typically '1.2+git' or '1.3.2'
grade: stable # must be 'stable' to release into candidate/stable channels grade: stable # must be 'stable' to release into candidate/stable channels
summary: A lightweight cross-platform IP scanner # 79 char long summary summary: A lightweight cross-platform IP scanner # 79 char long summary
description: | description: |
@@ -18,7 +18,7 @@ description: |
- ArpLookup (https://github.com/georg-jung/ArpLookup) - MIT (https://github.com/georg-jung/ArpLookup/blob/master/LICENSE.txt) - ArpLookup (https://github.com/georg-jung/ArpLookup) - MIT (https://github.com/georg-jung/ArpLookup/blob/master/LICENSE.txt)
- IPAddressRange (https://github.com/jsakamoto/ipaddressrange) - MPL-2.0 (https://github.com/jsakamoto/ipaddressrange/blob/master/LICENSE) - IPAddressRange (https://github.com/jsakamoto/ipaddressrange) - MPL-2.0 (https://github.com/jsakamoto/ipaddressrange/blob/master/LICENSE)
base: core22 # the base snap is the execution environment for this snap base: core24 # the base snap is the execution environment for this snap
architectures: architectures:
- build-on: amd64 - build-on: amd64
@@ -34,7 +34,7 @@ parts:
dotnet-self-contained-runtime-identifier: linux-x64 dotnet-self-contained-runtime-identifier: linux-x64
source: ./src/ARP-Scanner source: ./src/ARP-Scanner
build-packages: build-packages:
- dotnet-sdk-6.0 - dotnet-sdk-8.0
stage-packages: stage-packages:
- libicu70 - libicu70
+2 -8
View File
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<RootNamespace>ARP_Scanner</RootNamespace> <RootNamespace>ARP_Scanner</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@@ -10,14 +10,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="ArpLookup" Version="2.0.3" /> <PackageReference Include="ArpLookup" Version="2.0.3" />
<PackageReference Include="CuteUtils" Version="1.0.0" />
<PackageReference Include="IPAddressRange" Version="6.0.0" /> <PackageReference Include="IPAddressRange" Version="6.0.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> </ItemGroup>
</Project> </Project>
+7
View File
@@ -0,0 +1,7 @@
namespace ARP_Scanner;
internal class MacDatabase
{
public DateTime LastUpdate { get; set; }
public List<MacInformation> MacInformations { get; set; } = [];
}
+21
View File
@@ -0,0 +1,21 @@
using System.Text.Json.Serialization;
namespace ARP_Scanner;
internal class MacInformation
{
[JsonPropertyName("macPrefix")]
public required string MacPrefix { get; set; }
[JsonPropertyName("vendorName")]
public required string VendorName { get; set; }
[JsonPropertyName("private")]
public bool? Private { get; set; }
[JsonPropertyName("blockType")]
public required string BlockType { get; set; }
[JsonPropertyName("lastUpdate")]
public required string LastUpdate { get; set; }
}
+69 -31
View File
@@ -1,57 +1,95 @@
using System.Text.RegularExpressions; using CuteUtils.Misc;
using System.Net.Http.Json;
using System.Text.Json;
namespace ARP_Scanner; namespace ARP_Scanner;
internal class MacVendorLookup internal partial class MacVendorLookup
{ {
public readonly string[] header; private const string macLookupUrl = "https://maclookup.app/downloads/json-database/get-db";
private readonly string[][] fields; private readonly HttpClient httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(20) };
public MacVendorLookup(string csvPath) private MacDatabase macDatabase = new MacDatabase();
public async Task Initialize()
{ {
if (!File.Exists(csvPath)) string cachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "macDatabase.json");
// Snap support
string? snapUserCommon = Environment.GetEnvironmentVariable("SNAP_USER_COMMON");
if (snapUserCommon is not null)
{ {
header = Array.Empty<string>(); cachePath = Path.Combine(snapUserCommon, "macDatabase.json");
fields = Array.Empty<string[]>(); }
if (File.Exists(cachePath))
{
try
{
macDatabase = JsonSerializer.Deserialize<MacDatabase>(File.ReadAllText(cachePath)) ?? new MacDatabase();
}
catch (Exception ex)
{
ConsoleExt.WriteLine($"Failed to read MAC database cache: {ex.Message}", ConsoleColor.Red);
}
}
// Update MAC database if it's older than a week
if (macDatabase.LastUpdate > DateTime.Now.AddDays(-7))
{
ConsoleExt.WriteLine("Using cached MAC database...", ConsoleColor.DarkYellow);
return; return;
} }
string[] lines = File.ReadAllLines(csvPath); ConsoleExt.WriteLine("Downloading MAC database from maclookup.app...", ConsoleColor.DarkYellow);
header = lines[0].Split(','); List<MacInformation>? newMacInformations = null;
fields = lines.Skip(1).Select(l => Regex.Split(l, ",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))")).ToArray();
}
public string[] GetInformation(string macAdress) try
{
string[]? data = Array.Find(fields, f => macAdress.StartsWith(f[0]));
if (fields.Length == 0 || header.Length == 0)
{ {
return Array.Empty<string>(); newMacInformations = await httpClient.GetFromJsonAsync<List<MacInformation>>(macLookupUrl);
} }
else if (data is null) catch (Exception ex)
{ {
string[] result = new string[header.Length - 1]; ConsoleExt.WriteLine($"Failed to download MAC database: {ex.Message}", ConsoleColor.Red);
for (int i = 0; i < result.Length; i++) }
if (newMacInformations is null)
{
if (macDatabase.MacInformations.Count != 0)
{ {
result[i] = "Unknown"; ConsoleExt.WriteLine("Failed to download MAC database, using cache...", ConsoleColor.DarkYellow);
}
else
{
ConsoleExt.WriteLine("Failed to download MAC database and no cache found, using empty database...", ConsoleColor.Red);
} }
return result;
} }
else else
{ {
List<string> result = new List<string>(); ConsoleExt.WriteLine("MAC database downloaded successfully!", ConsoleColor.Green);
for (int i = 1; i < header.Length; i++)
{ _ = Directory.CreateDirectory(Path.GetDirectoryName(cachePath)!);
result.Add($"{data[i]}");
} macDatabase.MacInformations = newMacInformations;
return result.ToArray(); macDatabase.LastUpdate = DateTime.Now;
File.WriteAllText(cachePath, JsonSerializer.Serialize(macDatabase));
} }
} }
public string[] GetHeader() public MacInformation GetInformation(string macAdress)
{ {
return header!.Skip(1).ToArray(); macAdress = macAdress.Replace("-", ":")[..8].ToUpper();
return macDatabase.MacInformations.Find(m => m.MacPrefix == macAdress) ?? new MacInformation()
{
MacPrefix = macAdress,
VendorName = "Unknown",
BlockType = "Unknown",
Private = false,
LastUpdate = "Unknown"
};
} }
} }
+14 -12
View File
@@ -1,9 +1,8 @@
using ArpLookup; using ArpLookup;
using NetTools; using CuteUtils.Misc;
using Stone_Red_Utilities.CollectionExtentions; using NetTools;
using Stone_Red_Utilities.ConsoleExtentions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Net; using System.Net;
@@ -15,7 +14,7 @@ internal static class Program
{ {
private static async Task Main(string[] args) private static async Task Main(string[] args)
{ {
MacVendorLookup macVendorLookup = new MacVendorLookup("mac-vendors.csv"); MacVendorLookup macVendorLookup = new MacVendorLookup();
if (!Arp.IsSupported) if (!Arp.IsSupported)
{ {
@@ -29,14 +28,16 @@ internal static class Program
return; return;
} }
await macVendorLookup.Initialize();
long ipAddressesCount = ipAddressRange.Count(); long ipAddressesCount = ipAddressRange.Count();
long processedIpAddressesCount = 0; long processedIpAddressesCount = 0;
int numberOfDigits = ipAddressesCount.ToString().Length; int numberOfDigits = ipAddressesCount.ToString().Length;
List<string> header = new List<string>() { "IP", "MAC" }; List<string> header = ["IP", "MAC"];
ConcurrentBag<string[]> activeHosts = new ConcurrentBag<string[]>(); ConcurrentBag<string[]> activeHosts = [];
header.AddRange(macVendorLookup.GetHeader()); header.AddRange([nameof(MacInformation.VendorName), nameof(MacInformation.BlockType), nameof(MacInformation.Private), nameof(MacInformation.LastUpdate)]);
ConsoleExt.WriteLine("Starting scan...", ConsoleColor.DarkYellow); ConsoleExt.WriteLine("Starting scan...", ConsoleColor.DarkYellow);
@@ -60,10 +61,11 @@ internal static class Program
{ {
string formattedMac = BitConverter.ToString(mac.GetAddressBytes()); string formattedMac = BitConverter.ToString(mac.GetAddressBytes());
List<string> info = new List<string> { ipAddress.ToString(), formattedMac }; MacInformation macInformation = macVendorLookup.GetInformation(formattedMac);
info.AddRange(macVendorLookup.GetInformation(formattedMac));
List<string> info = [ipAddress.ToString(), formattedMac, macInformation.VendorName, macInformation.BlockType, macInformation.Private.ToString() ?? "Unknown", macInformation.LastUpdate];
ConsoleExt.WriteLine($"Progress: {localProcessedIpAddressesCount.ToString().PadLeft(numberOfDigits)}/{ipAddressesCount} [{100d / ipAddressesCount * localProcessedIpAddressesCount,6:##0.00}%] | Active: {ipAddress}", ConsoleColor.Green); ConsoleExt.WriteLine($"Progress: {localProcessedIpAddressesCount.ToString().PadLeft(numberOfDigits)}/{ipAddressesCount} [{100d / ipAddressesCount * localProcessedIpAddressesCount,6:##0.00}%] | Active: {ipAddress}", ConsoleColor.Green);
activeHosts.Add(info.ToArray()); activeHosts.Add([.. info]);
} }
else if (fail) else if (fail)
{ {
@@ -79,9 +81,9 @@ internal static class Program
{ {
Console.WriteLine(Environment.NewLine + "Active hosts:"); Console.WriteLine(Environment.NewLine + "Active hosts:");
List<string[]>? activeHostsTable = activeHosts.ToList(); List<string[]>? activeHostsTable = [.. activeHosts];
activeHostsTable.Insert(0, header.ToArray()); activeHostsTable.Insert(0, [.. header]);
activeHostsTable.ToArray().To2D().PrintTable(TableStyle.List); activeHostsTable.ToArray().To2D().PrintTable(TableStyle.List);
File diff suppressed because it is too large Load Diff