Skip to content

Commit

Permalink
Merge pull request #31 from ewilliams0305/development
Browse files Browse the repository at this point in the history
Added single scanner and HTTP query
  • Loading branch information
ewilliams0305 authored Mar 10, 2024
2 parents 93f28dd + 7abe633 commit 223b923
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 73 deletions.
39 changes: 31 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ using var scanner = ScannerBuilder
.Build();
```

*single ip address*
``` csharp
var scanner = ScannerBuilder.Configure()
.WithAddress( IPAddress.Parse("10.0.0.111"))
.WithHttpScan()
.WithMaxTimeout(TimeSpan.FromSeconds(2))
.Build();
```

*subnetmask*
``` csharp
using var scanner = ScannerBuilder
Expand All @@ -90,15 +99,17 @@ using var scanner = ScannerBuilder
.Build();
```

## Parallel Configuration
## Web Server Query
An optional web server query can be enabled. Use the `WithHttpScan` option after configuring the addresses.
In order to prevent port or dns exhaustion the scan depends on a `Func<HttpClient>`. You can use this function to create an http client pool,
leverage the http client factory, or simply return a new client. Each query will request a client and dispose of the client afterwards.

After the ips are determined you can optionally execute the scans using the TPL, add the WithParallelism
method and provide a batch size. Each batch of IP addresses will be scanned in parellel. Each batch will contsin the number of IP addresses divided by the size of the provided addresses.
``` csharp
using var scanner = ScannerBuilder
.Configure()
.WithAddresses(ips)
.WithParallelism(numberOfBatches: 10) // of 254 addresses 25 batches of 10 addresses will be scanned.
A default factory is provided in the library if no function is provided.

```csharp
var scanner = config
.WithInterface(adapter)
.WithHttpScan(() => new HttpClient())
.Build();
```

Expand All @@ -119,6 +130,18 @@ using var scanner = ScannerBuilder.Configure()
.Build();
```

## Parallel Configuration

After the ips are determined you can optionally execute the scans using the TPL, add the WithParallelism
method and provide a batch size. Each batch of IP addresses will be scanned in parellel. Each batch will contsin the number of IP addresses divided by the size of the provided addresses.
``` csharp
using var scanner = ScannerBuilder
.Configure()
.WithAddresses(ips)
.WithParallelism(numberOfBatches: 10) // of 254 addresses 25 batches of 10 addresses will be scanned.
.Build();
```

## Logging Configuration
BYOL(Logger)

Expand Down
28 changes: 20 additions & 8 deletions source/Kangaroo.CLI/Commands/AdapterScanCommand.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System.Net.NetworkInformation;
using Cocona;
using Cocona;
using Dumpify;
using Microsoft.Extensions.Logging;
using System.Net.NetworkInformation;

namespace Kangaroo.CLI.Commands;

public sealed class AdapterScanCommand(ILogger logger, IScannerIpConfiguration config)
public sealed class AdapterScanCommand()
{

[Command("adapter", Aliases = ["a"],Description = "Scans IP address using the subnet on the provided adapter")]
public async ValueTask<int> QueryAdapter(
public static async ValueTask<int> QueryAdapter(
[Option(
shortName: 'a',
Description = "The network adapter to scan",
Expand Down Expand Up @@ -49,7 +49,7 @@ private static int QueryAdapters()
return 0;
}

public async Task<int> ScanAdapter(string adapterName, int? timeout)
public static async Task<int> ScanAdapter(string adapterName, int? timeout)
{
try
{
Expand All @@ -64,13 +64,25 @@ public async Task<int> ScanAdapter(string adapterName, int? timeout)
Console.WriteLine($"Invalid Network Adapter Specified {adapterName}");
return -1;
}
var scanner = config
var scanner = ScannerBuilder
.Configure()
.WithInterface(adapter)
.WithHttpScan(() => new HttpClient())
.WithHttpScan(() =>
{
return new HttpClient(new HttpClientHandler()
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) => true
});
})
.WithMaxTimeout(TimeSpan.FromMilliseconds(timeout ?? 1000))
.WithMaxHops(4)
.WithParallelism(10)
.WithLogging(logger)
.WithLogging(LoggerFactory.Create(ops =>
{
ops.AddConsole();
}))
.Build();

var results = await scanner.QueryNetwork();
Expand Down
23 changes: 17 additions & 6 deletions source/Kangaroo.CLI/Commands/RangeScanCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace Kangaroo.CLI.Commands;

public sealed class RangeScanCommand(ILogger logger, IScannerIpConfiguration config)
public sealed class RangeScanCommand()
{
[Command("range", Description = "Scans the configured range of IP addresses")]
public async Task<int> ScanNetwork(
public static async Task<int> ScanNetwork(
[Option(
shortName: 's',
Description = "Starting IP address to begin scan with",
Expand All @@ -23,14 +23,25 @@ public async Task<int> ScanNetwork(
{
try
{
var scanner = config

var scanner = ScannerBuilder
.Configure()
.WithRange(start, end)
.WithHttpScan(() => new HttpClient())
.WithHttpScan(() =>
{
return new HttpClient(new HttpClientHandler()
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) => true
});
})
.WithMaxTimeout(TimeSpan.FromMilliseconds(timeout ?? 1000))
.WithMaxHops(4)
.WithParallelism(10)
.WithLogging(logger)
.WithLogging(LoggerFactory.Create(ops =>
{
ops.AddConsole();
}))
.Build();

var results = await scanner.QueryNetwork();
Expand Down
23 changes: 17 additions & 6 deletions source/Kangaroo.CLI/Commands/SubnetScanCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace Kangaroo.CLI.Commands;

public sealed class SubnetScanCommand(ILogger logger, IScannerIpConfiguration config)
public sealed class SubnetScanCommand()
{
[Command("subnet", Description = "Scans the configured subnet, note only /16 - /24 is currently available")]
public async Task<int> ScanNetwork(
public static async Task<int> ScanNetwork(
[Option(
shortName: 'i',
Description = "IP Address matching the subnet mask provided",
Expand All @@ -24,14 +24,25 @@ public async Task<int> ScanNetwork(

try
{
var scanner = config

var scanner = ScannerBuilder
.Configure()
.WithSubnet(ip, mask)
.WithHttpScan(() => new HttpClient())
.WithHttpScan(() =>
{
return new HttpClient(new HttpClientHandler()
{
ClientCertificateOptions = ClientCertificateOption.Manual,
ServerCertificateCustomValidationCallback =
(httpRequestMessage, cert, cetChain, policyErrors) => true
});
})
.WithMaxTimeout(TimeSpan.FromMilliseconds(timeout ?? 1000))
.WithMaxHops(4)
.WithParallelism(10)
.WithLogging(logger)
.WithLogging(LoggerFactory.Create(ops =>
{
ops.AddConsole();
}))
.Build();

var results = await scanner.QueryNetwork();
Expand Down
4 changes: 3 additions & 1 deletion source/Kangaroo.CLI/Kangaroo.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Cocona" Version="2.2.0" />
<PackageReference Include="Cocona.Lite" Version="2.2.0" />
<PackageReference Include="Dumpify" Version="0.6.5" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
8 changes: 4 additions & 4 deletions source/Kangaroo.CLI/OutputExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Dumpify;
using Dumpify;
using Kangaroo;
using System.Net.NetworkInformation;

namespace Kangaroo.CLI;

Expand All @@ -17,6 +15,7 @@ public static void DumpNode(this IEnumerable<NetworkNode> nodes)
IPAddress = n.IpAddress.ToString(),
MacAddress = n.MacAddress.ToString(),
Hostname = n.HostName,
n.WebServer,
Latency = n.Latency.ToString(),
QueryTime = n.QueryTime.ToString(),
})
Expand All @@ -34,6 +33,7 @@ public static void DumpResults(this ScanResults results)
IPAddress = n.IpAddress.ToString(),
MacAddress = n.MacAddress.ToString(),
Hostname = n.HostName,
n.WebServer,
Latency = n.Latency.ToString(),
QueryTime = n.QueryTime.ToString(),
})
Expand Down
19 changes: 1 addition & 18 deletions source/Kangaroo.CLI/Program.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
using Cocona;
using Kangaroo;
using Kangaroo.CLI.Commands;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var builder = CoconaApp.CreateBuilder();

builder.Services.AddSingleton<ILogger>(x =>
{
return LoggerFactory.Create(ops =>
{
ops.AddConsole();
}).CreateLogger<Program>();
});

builder.Services.AddTransient(sp => ScannerBuilder.Configure());

var app = builder.Build();
var app = CoconaLiteApp.Create(args);

app.AddCommands<RangeScanCommand>();
app.AddCommands<AdapterScanCommand>();
app.AddCommands<SubnetScanCommand>();



app.Run();
3 changes: 3 additions & 0 deletions source/Kangaroo.CLI/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"Kangaroo Adapter": {
"commandName": "Project",
"commandLineArgs": "adapter -a Wi-Fi"
},
"No Args": {
"commandName": "Project"
}
}
}
1 change: 1 addition & 0 deletions source/Kangaroo/Builder/Options/ScannerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ internal sealed class ScannerOptions
public IEnumerable<IPAddress> IpAddresses { get; set; } = Enumerable.Empty<IPAddress>();

public bool Concurrent { get; set; } = false;

public bool ScanHttpServers { get; set; } = false;

public int ItemsPerBatch { get; set; } = 10;
Expand Down
19 changes: 19 additions & 0 deletions source/Kangaroo/Builder/Pipeline/IScannerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ namespace Kangaroo;

/// <summary>
/// The first step in the build pipeline configures the IP addresses used for the scans.
/// <exception cref="InvalidIpRangeException"></exception>
/// <exception cref="InvalidIpAddressException"></exception>
/// <exception cref="InvalidSubnetException"></exception>
/// <exception cref="InvalidNetworkAdapterException"></exception>
/// <exception cref="InvalidTimeoutException"></exception>
/// <exception cref="InvalidTtlException"></exception>
/// </summary>
public interface IScannerIpConfiguration : IScannerSubnet, IScannerRange, IScannerSpecific, IScannerInterface { }

Expand Down Expand Up @@ -83,6 +89,13 @@ public interface IScannerSpecific
/// </summary>
/// <returns>Next step in the pipeline</returns>
IScannerTasks WithAddresses(IEnumerable<IPAddress> addresses);

/// <summary>
/// Creates a new scanner that can only query a single network address.
/// </summary>
/// <param name="address">IP Address</param>
/// <returns>Next step in the pipeline</returns>
IScannerTasks WithAddress(IPAddress address);
}

#endregion
Expand Down Expand Up @@ -220,6 +233,12 @@ public interface IScannerLogging

/// <summary>
/// The file step in the pipeline builds a new scanner
/// <exception cref="InvalidIpRangeException"></exception>
/// <exception cref="InvalidIpAddressException"></exception>
/// <exception cref="InvalidSubnetException"></exception>
/// <exception cref="InvalidNetworkAdapterException"></exception>
/// <exception cref="InvalidTimeoutException"></exception>
/// <exception cref="InvalidTtlException"></exception>
/// </summary>
public interface IScannerBuilder
{
Expand Down
23 changes: 22 additions & 1 deletion source/Kangaroo/Builder/Pipeline/ScannerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ public IScannerTasks WithAddresses(IEnumerable<IPAddress> addresses)
_options.IpAddresses = addresses;
return this;
}

/// <inheritdoc />
public IScannerTasks WithAddress(IPAddress address)
{
_options.IpAddresses = new []{ address };
return this;
}

/// <inheritdoc />
public IScannerTasks WithInterface(NetworkInterface? @interface = null)
Expand Down Expand Up @@ -154,9 +161,15 @@ public IScanner Build()
logger: _options.Logger,
ping: _options.Concurrent
? new QueryPingResultsParallel(_options.Logger, queryOptions)
: new QueryPingResultsOrderly(_options.Logger, new Ping(), queryOptions))
: new QueryPingResultsOrderly(_options.Logger, new Ping(), queryOptions),
clientFactory: _options.ScanHttpServers ? _options.HttpFactory : null)
.CreateQuerier();

if (_options.IpAddresses.Count() == 1)
{
return CreateSingleScanner(querier, _options.IpAddresses);
}

return !_options.Concurrent
? CreateOrderlyScanner(querier, _options.IpAddresses)
: CreateParallelScanner(querier, _options.IpAddresses, _options.ItemsPerBatch);
Expand All @@ -179,4 +192,12 @@ private IScanner CreateOrderlyScanner(
_options.Logger,
querier,
addresses);

private IScanner CreateSingleScanner(
IQueryNetworkNode querier,
IEnumerable<IPAddress> addresses) =>
SingleScanner.CreateScanner(
_options.Logger,
querier,
addresses.First());
}
2 changes: 1 addition & 1 deletion source/Kangaroo/Queries/IQueryWebServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Kangaroo.Queries;

internal interface IQueryWebServer : IDisposable
internal interface IQueryWebServer
{
Task<string> Query(IPAddress ipAddress, CancellationToken token = default);
}
Loading

0 comments on commit 223b923

Please sign in to comment.