Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/actions/setup-runner/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ runs:
- name: Set environment variables
shell: bash
run: |
echo "DOTNET_VERSION=10.x" >> $GITHUB_ENV
echo "DOTNET_NOLOGO=false" >> $GITHUB_ENV
echo "DOTNET_CLI_TELEMETRY_OPTOUT=true" >> $GITHUB_ENV
echo "NUKE_TELEMETRY_OPTOUT=true" >> $GITHUB_ENV

- name: Set up .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
global-json-file: global.json

- name: Restore .NET tools
shell: bash
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ on:
- 'detailed'
- 'diagnostic'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test-linux:
name: 🐧 Test
Expand Down
8 changes: 6 additions & 2 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:best-practices"],
"timezone": "Europe/Berlin",
"addLabels": [
"dependencies"
],
"minimumReleaseAge": "14 days",
"minimumReleaseAge": "7 days",
"internalChecksFilter": "strict",
"prCreation": "not-pending",
"dependencyDashboard": true,
"prConcurrentLimit": 5,
"prHourlyLimit": 0,
"vulnerabilityAlerts": {
"labels": ["security"],
"minimumReleaseAge": "1 day"
},
"automerge": false,
"dockerfile": {
//"pinDigests": true
Expand Down
25 changes: 15 additions & 10 deletions src/Scanning/Arp/LinuxArpTableProvider.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
using System.Diagnostics;
using System.Net;
using System.Runtime.Versioning;
using Drift.Domain.Device.Addresses;

namespace Drift.Scanning.Arp;

internal class LinuxArpTableProvider : ArpTableProviderBase {
// TODO read from /proc/net/arp instead of spawning processes
private const string ProcArpPath = "/proc/net/arp";

[SupportedOSPlatform( "linux" )]
protected override ArpTable ReadSystemArpCache() {
const string procArpPath = "/proc/net/arp";

if ( !File.Exists( procArpPath ) ) {
throw new FileNotFoundException( $"Path not found: {procArpPath}" );
if ( !File.Exists( ProcArpPath ) ) {
throw new FileNotFoundException( $"Path not found: {ProcArpPath}" );
}

using var streamReader = new StreamReader( procArpPath );
using var streamReader = new StreamReader( ProcArpPath );

return ParseArpOutput( streamReader );
}

/// <summary>
/// Parses the output of <c>/proc/net/arp</c> into an <see cref="ArpTable"/>.
/// Parses the contents of <c>/proc/net/arp</c> into an <see cref="ArpTable"/>.
/// </summary>
/// <remarks>
/// Format:
Expand All @@ -33,10 +31,17 @@ protected override ArpTable ReadSystemArpCache() {
internal static ArpTable ParseArpOutput( TextReader reader ) {
var map = new Dictionary<IPAddress, MacAddress>();

reader.ReadLine(); // Skip header

while ( reader.ReadLine() is { } line ) {
var parts = line.Split( (char[]?) null, StringSplitOptions.RemoveEmptyEntries );

if (
parts[0].Count( c => c == '.' ) != 3 && // Dots in an IPv4 address
parts[3].Count( c => c == ':' ) != 5 // Semicolons in a Linux-reported MAC. E.g., 00:11:22:33:44:55
) {
Console.Error.WriteLine( $"Skipping invalid ARP entry: {line}" );
continue;
}

var ip = IPAddress.Parse( parts[0] );
var mac = new MacAddress( parts[3] );
map[ip] = mac;
Expand Down
13 changes: 8 additions & 5 deletions src/Scanning/Arp/WindowsArpTableProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,17 @@ protected override ArpTable ReadSystemArpCache() {
internal static ArpTable ParseArpOutput( TextReader reader ) {
var map = new Dictionary<IPAddress, MacAddress>();

reader.ReadLine(); // Skip empty line
reader.ReadLine(); // Skip interface
reader.ReadLine(); // Skip header

while ( reader.ReadLine() is { } line ) {
if ( string.IsNullOrWhiteSpace( line ) ) {
continue;
}

var parts = line.Split( (char[]?) null, StringSplitOptions.RemoveEmptyEntries );

if ( parts[0].Count( c => c == '.' ) != 3 ) { // Should look like an IPv4 address
if (
parts[0].Count( c => c == '.' ) != 3 && // Dots in an IPv4 address
parts[1].Count( c => c == '-' ) != 5 // Hyphens in a Windows-reported MAC. E.g., 00-11-22-33-44-55
) {
Console.Error.WriteLine( $"Skipping invalid ARP entry: {line}" );
continue;
}
Expand Down
Loading