Skip to content

Smdn.Net.AddressResolution version 1.2.0

Latest
Compare
Choose a tag to compare
@smdn smdn released this 11 Apr 12:33
· 2 commits to main since this release
810c4a5

Released package

Release notes

The full release notes are available at gist.

Change log

Change log in this release:

API changes

API changes in this release:
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs
deleted file mode 100644
index cd0a785..0000000
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net6.0.apilist.cs
+++ /dev/null
@@ -1,299 +0,0 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.1.0)
-//   Name: Smdn.Net.AddressResolution
-//   AssemblyVersion: 1.1.0.0
-//   InformationalVersion: 1.1.0+fe88b9191dd60b0f5dc1e1881193ccd376b9795c
-//   TargetFramework: .NETCoreApp,Version=v6.0
-//   Configuration: Release
-//   Referenced assemblies:
-//     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
-//     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
-//     System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Collections.Concurrent, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.ComponentModel, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.ComponentModel.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Diagnostics.Process, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Linq, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Memory, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
-//     System.Net.NetworkInformation, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Net.Ping, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Net.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Runtime.InteropServices, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Runtime.InteropServices.RuntimeInformation, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     System.Threading, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     Vanara.PInvoke.IpHlpApi, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Shared, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Ws2_32, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-#nullable enable annotations
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Net;
-using System.Net.NetworkInformation;
-using System.Runtime.CompilerServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
-using Smdn.Net;
-using Smdn.Net.AddressResolution;
-using Smdn.Net.AddressTables;
-using Smdn.Net.NetworkScanning;
-
-namespace Smdn.Net {
-  public abstract class IPNetworkProfile {
-    public static IPNetworkProfile Create() {}
-    public static IPNetworkProfile Create(Func<IEnumerable<IPAddress>?> addressRangeGenerator, NetworkInterface? networkInterface = null) {}
-    public static IPNetworkProfile Create(IPAddress baseAddress, IPAddress subnetMask, NetworkInterface? networkInterface = null) {}
-    public static IPNetworkProfile Create(IPAddress baseAddress, int prefixLength, NetworkInterface? networkInterface = null) {}
-    public static IPNetworkProfile Create(NetworkInterface networkInterface) {}
-    public static IPNetworkProfile Create(Predicate<NetworkInterface> predicateForNetworkInterface) {}
-    public static IPNetworkProfile CreateFromNetworkInterface(Guid id) {}
-    public static IPNetworkProfile CreateFromNetworkInterface(PhysicalAddress physicalAddress) {}
-    public static IPNetworkProfile CreateFromNetworkInterface(string id) {}
-    public static IPNetworkProfile CreateFromNetworkInterfaceName(string name) {}
-
-    protected IPNetworkProfile(NetworkInterface? networkInterface) {}
-
-    public NetworkInterface? NetworkInterface { get; }
-
-    public abstract IEnumerable<IPAddress>? GetAddressRange();
-  }
-
-  public static class PhysicalAddressExtensions {
-    public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
-  }
-}
-
-namespace Smdn.Net.AddressResolution {
-  public interface IAddressResolver<TAddress, TResolvedAddress> where TAddress : notnull where TResolvedAddress : notnull {
-    void Invalidate(TAddress address);
-    ValueTask<TResolvedAddress?> ResolveAsync(TAddress address, CancellationToken cancellationToken);
-  }
-
-  public class MacAddressResolver : MacAddressResolverBase {
-    protected MacAddressResolver(IAddressTable addressTable, bool shouldDisposeAddressTable, INetworkScanner? networkScanner, bool shouldDisposeNetworkScanner, NetworkInterface? networkInterface, int maxParallelCountForRefreshInvalidatedAddresses, ILogger? logger) {}
-    public MacAddressResolver() {}
-    public MacAddressResolver(IAddressTable? addressTable, INetworkScanner? networkScanner, bool shouldDisposeAddressTable = false, bool shouldDisposeNetworkScanner = false, NetworkInterface? networkInterface = null, int maxParallelCountForRefreshInvalidatedAddresses = 3, IServiceProvider? serviceProvider = null) {}
-    public MacAddressResolver(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    public bool CanPerformNetworkScan { get; }
-    public override bool HasInvalidated { get; }
-    public TimeSpan NetworkScanInterval { get; set; }
-    public TimeSpan NetworkScanMinInterval { get; set; }
-
-    protected override void Dispose(bool disposing) {}
-    public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(CancellationToken cancellationToken = default) {}
-    public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken = default) {}
-    protected override void InvalidateCore(IPAddress ipAddress) {}
-    protected override void InvalidateCore(PhysicalAddress macAddress) {}
-    protected override ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken = default) {}
-    protected override ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken = default) {}
-    protected override async ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken) {}
-    protected override async ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken) {}
-    protected virtual async ValueTask<AddressTableEntry> SelectAddressTableEntryAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken) {}
-  }
-
-  public abstract class MacAddressResolverBase :
-    IAddressResolver<IPAddress, PhysicalAddress>,
-    IAddressResolver<PhysicalAddress, IPAddress>,
-    IDisposable
-  {
-    protected static PhysicalAddress AllZeroMacAddress { get; }
-    public static MacAddressResolverBase Null { get; }
-
-    protected MacAddressResolverBase(ILogger? logger = null) {}
-
-    public abstract bool HasInvalidated { get; }
-    protected ILogger? Logger { get; }
-
-    protected virtual void Dispose(bool disposing) {}
-    public void Dispose() {}
-    public void Invalidate(IPAddress ipAddress) {}
-    public void Invalidate(PhysicalAddress macAddress) {}
-    protected abstract void InvalidateCore(IPAddress ipAddress);
-    protected abstract void InvalidateCore(PhysicalAddress macAddress);
-    public ValueTask RefreshAddressTableAsync(CancellationToken cancellationToken = default) {}
-    protected virtual ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken) {}
-    public ValueTask RefreshInvalidatedAddressesAsync(CancellationToken cancellationToken = default) {}
-    protected virtual ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken) {}
-    public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
-    protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
-    public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
-    protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
-    void IAddressResolver<IPAddress, PhysicalAddress>.Invalidate(IPAddress address) {}
-    ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
-    void IAddressResolver<PhysicalAddress, IPAddress>.Invalidate(PhysicalAddress address) {}
-    ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
-    protected void ThrowIfDisposed() {}
-  }
-}
-
-namespace Smdn.Net.AddressTables {
-  public interface IAddressTable : IDisposable {
-    IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken);
-  }
-
-  public enum AddressTableEntryState : int {
-    Delay = 4,
-    Incomplete = 1,
-    None = 0,
-    Probe = 5,
-    Reachable = 2,
-    Stale = 3,
-  }
-
-  public abstract class AddressTable : IAddressTable {
-    public static IAddressTable Null { get; }
-
-    public static IAddressTable Create(IServiceProvider? serviceProvider = null) {}
-
-    protected AddressTable(ILogger? logger = null) {}
-
-    protected ILogger? Logger { get; }
-
-    protected virtual void Dispose(bool disposing) {}
-    public void Dispose() {}
-    public IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken = default) {}
-    protected abstract IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore(CancellationToken cancellationToken);
-    protected void ThrowIfDisposed() {}
-  }
-
-  public sealed class IpHlpApiAddressTable : AddressTable {
-    public static bool IsSupported { get; }
-
-    public IpHlpApiAddressTable(IServiceProvider? serviceProvider = null) {}
-
-    [AsyncIteratorStateMachine(typeof(IpHlpApiAddressTable.<EnumerateEntriesAsyncCore>d__4))]
-    protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
-  }
-
-  public sealed class ProcfsArpAddressTable : AddressTable {
-    public static bool IsSupported { get; }
-
-    public ProcfsArpAddressTable(IServiceProvider? serviceProvider = null) {}
-
-    [AsyncIteratorStateMachine(typeof(ProcfsArpAddressTable.<EnumerateEntriesAsyncCore>d__5))]
-    protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
-  }
-
-  public readonly struct AddressTableEntry :
-    IEquatable<AddressTableEntry>,
-    IEquatable<IPAddress>,
-    IEquatable<PhysicalAddress>
-  {
-    public static readonly AddressTableEntry Empty; // = "{IP=, MAC=(null), IsPermanent=False, State=None, Iface=}"
-
-    public static IEqualityComparer<AddressTableEntry> DefaultEqualityComparer { get; }
-    public static IEqualityComparer<AddressTableEntry> ExceptStateEqualityComparer { get; }
-
-    public AddressTableEntry(IPAddress ipAddress, PhysicalAddress? physicalAddress, bool isPermanent, AddressTableEntryState state, string? interfaceId) {}
-
-    public IPAddress? IPAddress { get; }
-    public string? InterfaceId { get; }
-    [MemberNotNullWhen(false, "IPAddress")]
-    public bool IsEmpty { [MemberNotNullWhen(false, "IPAddress")] get; }
-    public bool IsPermanent { get; }
-    public PhysicalAddress? PhysicalAddress { get; }
-    public AddressTableEntryState State { get; }
-
-    public bool Equals(AddressTableEntry other) {}
-    public bool Equals(IPAddress? other) {}
-    public bool Equals(PhysicalAddress? other) {}
-    public override bool Equals(object? obj) {}
-    public override int GetHashCode() {}
-    public override string ToString() {}
-  }
-}
-
-namespace Smdn.Net.NetworkScanning {
-  public interface INetworkScanner : IDisposable {
-    ValueTask ScanAsync(CancellationToken cancellationToken);
-    ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken);
-  }
-
-  public sealed class ArpScanCommandNetworkScanner : CommandNetworkScanner {
-    public static bool IsSupported { get; }
-
-    public ArpScanCommandNetworkScanner(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
-    protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
-  }
-
-  public abstract class CommandNetworkScanner : INetworkScanner {
-    public interface IProcessFactory {
-      Process CreateProcess(ProcessStartInfo processStartInfo);
-    }
-
-    protected readonly struct Command {
-      public Command(string name, string? executablePath) {}
-
-      public bool IsAvailable { get; }
-      public string Name { get; }
-
-      public string GetExecutablePathOrThrow() {}
-    }
-
-    protected static IReadOnlyCollection<string> DefaultCommandPaths { get; }
-
-    protected static CommandNetworkScanner.Command FindCommand(string command, IEnumerable<string> paths) {}
-
-    protected CommandNetworkScanner(ILogger? logger, IServiceProvider? serviceProvider) {}
-
-    protected virtual void Dispose(bool disposing) {}
-    public void Dispose() {}
-    protected abstract bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string? arguments);
-    protected abstract bool GetCommandLineArguments(out string executable, out string? arguments);
-    public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
-    public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
-    protected void ThrowIfDisposed() {}
-  }
-
-  public sealed class IpHlpApiNetworkScanner : NetworkScanner {
-    public static bool IsSupported { get; }
-
-    public IpHlpApiNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
-  }
-
-  public abstract class NetworkScanner : INetworkScanner {
-    public static INetworkScanner Null { get; }
-
-    public static INetworkScanner Create(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    protected NetworkScanner(IPNetworkProfile networkProfile, ILogger? logger = null) {}
-
-    protected ILogger? Logger { get; }
-    protected IPNetworkProfile NetworkProfile { get; }
-
-    protected virtual void Dispose(bool disposing) {}
-    public void Dispose() {}
-    public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
-    public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
-    protected virtual ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken) {}
-    protected void ThrowIfDisposed() {}
-  }
-
-  public sealed class NmapCommandNetworkScanner : CommandNetworkScanner {
-    public static bool IsSupported { get; }
-
-    public NmapCommandNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
-    protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
-  }
-
-  public sealed class PingNetworkScanner : NetworkScanner {
-    public static bool IsSupported { get; }
-
-    public PingNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
-
-    protected override void Dispose(bool disposing) {}
-    protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
-  }
-}
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.3.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net8.0.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net8.0.apilist.cs
index 8133b50..f47a14a 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net8.0.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-net8.0.apilist.cs
@@ -1,299 +1,304 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.1.0)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.2.0)
 //   Name: Smdn.Net.AddressResolution
-//   AssemblyVersion: 1.1.0.0
-//   InformationalVersion: 1.1.0+fe88b9191dd60b0f5dc1e1881193ccd376b9795c
+//   AssemblyVersion: 1.2.0.0
+//   InformationalVersion: 1.2.0+c05b71d8cee9f9e5f62130f20bb3eb25e8a79614
 //   TargetFramework: .NETCoreApp,Version=v8.0
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     System.Collections, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Collections.Concurrent, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.ComponentModel, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.ComponentModel.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Diagnostics.Process, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Memory, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     System.Net.NetworkInformation, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Net.Ping, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Runtime.InteropServices, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
 //     System.Threading, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
-//     Vanara.PInvoke.IpHlpApi, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Shared, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Ws2_32, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.Core, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.IpHlpApi, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Shared, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Ws2_32, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
 #nullable enable annotations
 
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net;
 using Smdn.Net.AddressResolution;
 using Smdn.Net.AddressTables;
 using Smdn.Net.NetworkScanning;
 
 namespace Smdn.Net {
   public abstract class IPNetworkProfile {
     public static IPNetworkProfile Create() {}
     public static IPNetworkProfile Create(Func<IEnumerable<IPAddress>?> addressRangeGenerator, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, IPAddress subnetMask, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, int prefixLength, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPNetwork network, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(NetworkInterface networkInterface) {}
     public static IPNetworkProfile Create(Predicate<NetworkInterface> predicateForNetworkInterface) {}
     public static IPNetworkProfile CreateFromNetworkInterface(Guid id) {}
     public static IPNetworkProfile CreateFromNetworkInterface(PhysicalAddress physicalAddress) {}
     public static IPNetworkProfile CreateFromNetworkInterface(string id) {}
     public static IPNetworkProfile CreateFromNetworkInterfaceName(string name) {}
 
     protected IPNetworkProfile(NetworkInterface? networkInterface) {}
 
     public NetworkInterface? NetworkInterface { get; }
 
     public abstract IEnumerable<IPAddress>? GetAddressRange();
   }
 
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> where TAddress : notnull where TResolvedAddress : notnull {
     void Invalidate(TAddress address);
     ValueTask<TResolvedAddress?> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public class MacAddressResolver : MacAddressResolverBase {
     protected MacAddressResolver(IAddressTable addressTable, bool shouldDisposeAddressTable, INetworkScanner? networkScanner, bool shouldDisposeNetworkScanner, NetworkInterface? networkInterface, int maxParallelCountForRefreshInvalidatedAddresses, ILogger? logger) {}
     public MacAddressResolver() {}
     public MacAddressResolver(IAddressTable? addressTable, INetworkScanner? networkScanner, bool shouldDisposeAddressTable = false, bool shouldDisposeNetworkScanner = false, NetworkInterface? networkInterface = null, int maxParallelCountForRefreshInvalidatedAddresses = 3, IServiceProvider? serviceProvider = null) {}
     public MacAddressResolver(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     public bool CanPerformNetworkScan { get; }
     public override bool HasInvalidated { get; }
     public TimeSpan NetworkScanInterval { get; set; }
     public TimeSpan NetworkScanMinInterval { get; set; }
+    public bool ShouldResolveIPv4MappedIPv6Address { get; set; }
 
     protected override void Dispose(bool disposing) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(CancellationToken cancellationToken = default) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken = default) {}
     protected override void InvalidateCore(IPAddress ipAddress) {}
     protected override void InvalidateCore(PhysicalAddress macAddress) {}
     protected override ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken = default) {}
     protected override ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken = default) {}
     protected override async ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken) {}
     protected override async ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken) {}
     protected virtual async ValueTask<AddressTableEntry> SelectAddressTableEntryAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken) {}
   }
 
   public abstract class MacAddressResolverBase :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static PhysicalAddress AllZeroMacAddress { get; }
     public static MacAddressResolverBase Null { get; }
 
     protected MacAddressResolverBase(ILogger? logger = null) {}
 
     public abstract bool HasInvalidated { get; }
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public void Invalidate(IPAddress ipAddress) {}
     public void Invalidate(PhysicalAddress macAddress) {}
     protected abstract void InvalidateCore(IPAddress ipAddress);
     protected abstract void InvalidateCore(PhysicalAddress macAddress);
     public ValueTask RefreshAddressTableAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask RefreshInvalidatedAddressesAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     void IAddressResolver<IPAddress, PhysicalAddress>.Invalidate(IPAddress address) {}
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     void IAddressResolver<PhysicalAddress, IPAddress>.Invalidate(PhysicalAddress address) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 }
 
 namespace Smdn.Net.AddressTables {
   public interface IAddressTable : IDisposable {
     IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken);
   }
 
   public enum AddressTableEntryState : int {
     Delay = 4,
     Incomplete = 1,
     None = 0,
     Probe = 5,
     Reachable = 2,
     Stale = 3,
   }
 
   public abstract class AddressTable : IAddressTable {
     public static IAddressTable Null { get; }
 
     public static IAddressTable Create(IServiceProvider? serviceProvider = null) {}
 
     protected AddressTable(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken = default) {}
     protected abstract IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore(CancellationToken cancellationToken);
     protected void ThrowIfDisposed() {}
   }
 
+  [SupportedOSPlatform("windows")]
   public sealed class IpHlpApiAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public IpHlpApiAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(IpHlpApiAddressTable.<EnumerateEntriesAsyncCore>d__4))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public sealed class ProcfsArpAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public ProcfsArpAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(ProcfsArpAddressTable.<EnumerateEntriesAsyncCore>d__5))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public readonly struct AddressTableEntry :
     IEquatable<AddressTableEntry>,
     IEquatable<IPAddress>,
     IEquatable<PhysicalAddress>
   {
     public static readonly AddressTableEntry Empty; // = "{IP=, MAC=(null), IsPermanent=False, State=None, Iface=}"
 
     public static IEqualityComparer<AddressTableEntry> DefaultEqualityComparer { get; }
     public static IEqualityComparer<AddressTableEntry> ExceptStateEqualityComparer { get; }
 
     public AddressTableEntry(IPAddress ipAddress, PhysicalAddress? physicalAddress, bool isPermanent, AddressTableEntryState state, string? interfaceId) {}
 
     public IPAddress? IPAddress { get; }
     public string? InterfaceId { get; }
     [MemberNotNullWhen(false, "IPAddress")]
     public bool IsEmpty { [MemberNotNullWhen(false, "IPAddress")] get; }
     public bool IsPermanent { get; }
     public PhysicalAddress? PhysicalAddress { get; }
     public AddressTableEntryState State { get; }
 
     public bool Equals(AddressTableEntry other) {}
     public bool Equals(IPAddress? other) {}
+    public bool Equals(IPAddress? other, bool shouldConsiderIPv4MappedIPv6Address) {}
     public bool Equals(PhysicalAddress? other) {}
     public override bool Equals(object? obj) {}
     public override int GetHashCode() {}
     public override string ToString() {}
   }
 }
 
 namespace Smdn.Net.NetworkScanning {
   public interface INetworkScanner : IDisposable {
     ValueTask ScanAsync(CancellationToken cancellationToken);
     ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken);
   }
 
   public sealed class ArpScanCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public ArpScanCommandNetworkScanner(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public abstract class CommandNetworkScanner : INetworkScanner {
     public interface IProcessFactory {
       Process CreateProcess(ProcessStartInfo processStartInfo);
     }
 
     protected readonly struct Command {
       public Command(string name, string? executablePath) {}
 
       public bool IsAvailable { get; }
       public string Name { get; }
 
       public string GetExecutablePathOrThrow() {}
     }
 
     protected static IReadOnlyCollection<string> DefaultCommandPaths { get; }
 
     protected static CommandNetworkScanner.Command FindCommand(string command, IEnumerable<string> paths) {}
 
     protected CommandNetworkScanner(ILogger? logger, IServiceProvider? serviceProvider) {}
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     protected abstract bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string? arguments);
     protected abstract bool GetCommandLineArguments(out string executable, out string? arguments);
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected void ThrowIfDisposed() {}
   }
 
+  [SupportedOSPlatform("windows")]
   public sealed class IpHlpApiNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public IpHlpApiNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 
   public abstract class NetworkScanner : INetworkScanner {
     public static INetworkScanner Null { get; }
 
     public static INetworkScanner Create(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected NetworkScanner(IPNetworkProfile networkProfile, ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
     protected IPNetworkProfile NetworkProfile { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected virtual ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class NmapCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public NmapCommandNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public sealed class PingNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public PingNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override void Dispose(bool disposing) {}
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 }
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.3.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.5.0.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
index 36ef88d..9e5ffa5 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.0.apilist.cs
@@ -1,288 +1,291 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.1.0)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.2.0)
 //   Name: Smdn.Net.AddressResolution
-//   AssemblyVersion: 1.1.0.0
-//   InformationalVersion: 1.1.0+fe88b9191dd60b0f5dc1e1881193ccd376b9795c
+//   AssemblyVersion: 1.2.0.0
+//   InformationalVersion: 1.2.0+c05b71d8cee9f9e5f62130f20bb3eb25e8a79614
 //   TargetFramework: .NETStandard,Version=v2.0
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Bcl.AsyncInterfaces, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     Microsoft.Bcl.HashCode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 //     System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
-//     Vanara.PInvoke.IpHlpApi, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Shared, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Ws2_32, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.Core, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.IpHlpApi, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Shared, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Ws2_32, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
 //     netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 #nullable enable annotations
 
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net;
 using Smdn.Net.AddressResolution;
 using Smdn.Net.AddressTables;
 using Smdn.Net.NetworkScanning;
 
 namespace Smdn.Net {
   public abstract class IPNetworkProfile {
     public static IPNetworkProfile Create() {}
     public static IPNetworkProfile Create(Func<IEnumerable<IPAddress>?> addressRangeGenerator, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, IPAddress subnetMask, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, int prefixLength, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(NetworkInterface networkInterface) {}
     public static IPNetworkProfile Create(Predicate<NetworkInterface> predicateForNetworkInterface) {}
     public static IPNetworkProfile CreateFromNetworkInterface(Guid id) {}
     public static IPNetworkProfile CreateFromNetworkInterface(PhysicalAddress physicalAddress) {}
     public static IPNetworkProfile CreateFromNetworkInterface(string id) {}
     public static IPNetworkProfile CreateFromNetworkInterfaceName(string name) {}
 
     protected IPNetworkProfile(NetworkInterface? networkInterface) {}
 
     public NetworkInterface? NetworkInterface { get; }
 
     public abstract IEnumerable<IPAddress>? GetAddressRange();
   }
 
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> where TAddress : notnull where TResolvedAddress : notnull {
     void Invalidate(TAddress address);
     ValueTask<TResolvedAddress?> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public class MacAddressResolver : MacAddressResolverBase {
     protected MacAddressResolver(IAddressTable addressTable, bool shouldDisposeAddressTable, INetworkScanner? networkScanner, bool shouldDisposeNetworkScanner, NetworkInterface? networkInterface, int maxParallelCountForRefreshInvalidatedAddresses, ILogger? logger) {}
     public MacAddressResolver() {}
     public MacAddressResolver(IAddressTable? addressTable, INetworkScanner? networkScanner, bool shouldDisposeAddressTable = false, bool shouldDisposeNetworkScanner = false, NetworkInterface? networkInterface = null, int maxParallelCountForRefreshInvalidatedAddresses = 3, IServiceProvider? serviceProvider = null) {}
     public MacAddressResolver(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     public bool CanPerformNetworkScan { get; }
     public override bool HasInvalidated { get; }
     public TimeSpan NetworkScanInterval { get; set; }
     public TimeSpan NetworkScanMinInterval { get; set; }
+    public bool ShouldResolveIPv4MappedIPv6Address { get; set; }
 
     protected override void Dispose(bool disposing) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(CancellationToken cancellationToken = default) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken = default) {}
     protected override void InvalidateCore(IPAddress ipAddress) {}
     protected override void InvalidateCore(PhysicalAddress macAddress) {}
     protected override ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken = default) {}
     protected override ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken = default) {}
     protected override async ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken) {}
     protected override async ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken) {}
     protected virtual async ValueTask<AddressTableEntry> SelectAddressTableEntryAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken) {}
   }
 
   public abstract class MacAddressResolverBase :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static PhysicalAddress AllZeroMacAddress { get; }
     public static MacAddressResolverBase Null { get; }
 
     protected MacAddressResolverBase(ILogger? logger = null) {}
 
     public abstract bool HasInvalidated { get; }
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public void Invalidate(IPAddress ipAddress) {}
     public void Invalidate(PhysicalAddress macAddress) {}
     protected abstract void InvalidateCore(IPAddress ipAddress);
     protected abstract void InvalidateCore(PhysicalAddress macAddress);
     public ValueTask RefreshAddressTableAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask RefreshInvalidatedAddressesAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     void IAddressResolver<IPAddress, PhysicalAddress>.Invalidate(IPAddress address) {}
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     void IAddressResolver<PhysicalAddress, IPAddress>.Invalidate(PhysicalAddress address) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 }
 
 namespace Smdn.Net.AddressTables {
   public interface IAddressTable : IDisposable {
     IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken);
   }
 
   public enum AddressTableEntryState : int {
     Delay = 4,
     Incomplete = 1,
     None = 0,
     Probe = 5,
     Reachable = 2,
     Stale = 3,
   }
 
   public abstract class AddressTable : IAddressTable {
     public static IAddressTable Null { get; }
 
     public static IAddressTable Create(IServiceProvider? serviceProvider = null) {}
 
     protected AddressTable(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken = default) {}
     protected abstract IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore(CancellationToken cancellationToken);
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class IpHlpApiAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public IpHlpApiAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(IpHlpApiAddressTable.<EnumerateEntriesAsyncCore>d__4))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public sealed class ProcfsArpAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public ProcfsArpAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(ProcfsArpAddressTable.<EnumerateEntriesAsyncCore>d__5))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public readonly struct AddressTableEntry :
     IEquatable<AddressTableEntry>,
     IEquatable<IPAddress>,
     IEquatable<PhysicalAddress>
   {
     public static readonly AddressTableEntry Empty; // = "{IP=, MAC=(null), IsPermanent=False, State=None, Iface=}"
 
     public static IEqualityComparer<AddressTableEntry> DefaultEqualityComparer { get; }
     public static IEqualityComparer<AddressTableEntry> ExceptStateEqualityComparer { get; }
 
     public AddressTableEntry(IPAddress ipAddress, PhysicalAddress? physicalAddress, bool isPermanent, AddressTableEntryState state, string? interfaceId) {}
 
     public IPAddress? IPAddress { get; }
     public string? InterfaceId { get; }
     public bool IsEmpty { get; }
     public bool IsPermanent { get; }
     public PhysicalAddress? PhysicalAddress { get; }
     public AddressTableEntryState State { get; }
 
     public bool Equals(AddressTableEntry other) {}
     public bool Equals(IPAddress? other) {}
+    public bool Equals(IPAddress? other, bool shouldConsiderIPv4MappedIPv6Address) {}
     public bool Equals(PhysicalAddress? other) {}
     public override bool Equals(object? obj) {}
     public override int GetHashCode() {}
     public override string ToString() {}
   }
 }
 
 namespace Smdn.Net.NetworkScanning {
   public interface INetworkScanner : IDisposable {
     ValueTask ScanAsync(CancellationToken cancellationToken);
     ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken);
   }
 
   public sealed class ArpScanCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public ArpScanCommandNetworkScanner(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public abstract class CommandNetworkScanner : INetworkScanner {
     public interface IProcessFactory {
       Process CreateProcess(ProcessStartInfo processStartInfo);
     }
 
     protected readonly struct Command {
       public Command(string name, string? executablePath) {}
 
       public bool IsAvailable { get; }
       public string Name { get; }
 
       public string GetExecutablePathOrThrow() {}
     }
 
     protected static IReadOnlyCollection<string> DefaultCommandPaths { get; }
 
     protected static CommandNetworkScanner.Command FindCommand(string command, IEnumerable<string> paths) {}
 
     protected CommandNetworkScanner(ILogger? logger, IServiceProvider? serviceProvider) {}
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     protected abstract bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string? arguments);
     protected abstract bool GetCommandLineArguments(out string executable, out string? arguments);
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class IpHlpApiNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public IpHlpApiNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 
   public abstract class NetworkScanner : INetworkScanner {
     public static INetworkScanner Null { get; }
 
     public static INetworkScanner Create(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected NetworkScanner(IPNetworkProfile networkProfile, ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
     protected IPNetworkProfile NetworkProfile { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected virtual ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class NmapCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public NmapCommandNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public sealed class PingNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public PingNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override void Dispose(bool disposing) {}
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 }
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.3.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.5.0.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
index 39aa175..22572ba 100644
--- a/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
+++ b/doc/api-list/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution-netstandard2.1.apilist.cs
@@ -1,284 +1,287 @@
-// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.1.0)
+// Smdn.Net.AddressResolution.dll (Smdn.Net.AddressResolution-1.2.0)
 //   Name: Smdn.Net.AddressResolution
-//   AssemblyVersion: 1.1.0.0
-//   InformationalVersion: 1.1.0+fe88b9191dd60b0f5dc1e1881193ccd376b9795c
+//   AssemblyVersion: 1.2.0.0
+//   InformationalVersion: 1.2.0+c05b71d8cee9f9e5f62130f20bb3eb25e8a79614
 //   TargetFramework: .NETStandard,Version=v2.1
 //   Configuration: Release
 //   Referenced assemblies:
 //     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
 //     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
-//     Vanara.PInvoke.IpHlpApi, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Shared, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
-//     Vanara.PInvoke.Ws2_32, Version=3.4.13.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.Core, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.IpHlpApi, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Shared, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
+//     Vanara.PInvoke.Ws2_32, Version=4.1.1.0, Culture=neutral, PublicKeyToken=c37e4080322237fa
 //     netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
 #nullable enable annotations
 
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Runtime.CompilerServices;
 using System.Threading;
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Smdn.Net;
 using Smdn.Net.AddressResolution;
 using Smdn.Net.AddressTables;
 using Smdn.Net.NetworkScanning;
 
 namespace Smdn.Net {
   public abstract class IPNetworkProfile {
     public static IPNetworkProfile Create() {}
     public static IPNetworkProfile Create(Func<IEnumerable<IPAddress>?> addressRangeGenerator, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, IPAddress subnetMask, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(IPAddress baseAddress, int prefixLength, NetworkInterface? networkInterface = null) {}
     public static IPNetworkProfile Create(NetworkInterface networkInterface) {}
     public static IPNetworkProfile Create(Predicate<NetworkInterface> predicateForNetworkInterface) {}
     public static IPNetworkProfile CreateFromNetworkInterface(Guid id) {}
     public static IPNetworkProfile CreateFromNetworkInterface(PhysicalAddress physicalAddress) {}
     public static IPNetworkProfile CreateFromNetworkInterface(string id) {}
     public static IPNetworkProfile CreateFromNetworkInterfaceName(string name) {}
 
     protected IPNetworkProfile(NetworkInterface? networkInterface) {}
 
     public NetworkInterface? NetworkInterface { get; }
 
     public abstract IEnumerable<IPAddress>? GetAddressRange();
   }
 
   public static class PhysicalAddressExtensions {
     public static string ToMacAddressString(this PhysicalAddress hardwareAddress, char delimiter = ':') {}
   }
 }
 
 namespace Smdn.Net.AddressResolution {
   public interface IAddressResolver<TAddress, TResolvedAddress> where TAddress : notnull where TResolvedAddress : notnull {
     void Invalidate(TAddress address);
     ValueTask<TResolvedAddress?> ResolveAsync(TAddress address, CancellationToken cancellationToken);
   }
 
   public class MacAddressResolver : MacAddressResolverBase {
     protected MacAddressResolver(IAddressTable addressTable, bool shouldDisposeAddressTable, INetworkScanner? networkScanner, bool shouldDisposeNetworkScanner, NetworkInterface? networkInterface, int maxParallelCountForRefreshInvalidatedAddresses, ILogger? logger) {}
     public MacAddressResolver() {}
     public MacAddressResolver(IAddressTable? addressTable, INetworkScanner? networkScanner, bool shouldDisposeAddressTable = false, bool shouldDisposeNetworkScanner = false, NetworkInterface? networkInterface = null, int maxParallelCountForRefreshInvalidatedAddresses = 3, IServiceProvider? serviceProvider = null) {}
     public MacAddressResolver(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     public bool CanPerformNetworkScan { get; }
     public override bool HasInvalidated { get; }
     public TimeSpan NetworkScanInterval { get; set; }
     public TimeSpan NetworkScanMinInterval { get; set; }
+    public bool ShouldResolveIPv4MappedIPv6Address { get; set; }
 
     protected override void Dispose(bool disposing) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(CancellationToken cancellationToken = default) {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateAddressTableEntriesAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken = default) {}
     protected override void InvalidateCore(IPAddress ipAddress) {}
     protected override void InvalidateCore(PhysicalAddress macAddress) {}
     protected override ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken = default) {}
     protected override ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken = default) {}
     protected override async ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken) {}
     protected override async ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken) {}
     protected virtual async ValueTask<AddressTableEntry> SelectAddressTableEntryAsync(Predicate<AddressTableEntry> predicate, CancellationToken cancellationToken) {}
   }
 
   public abstract class MacAddressResolverBase :
     IAddressResolver<IPAddress, PhysicalAddress>,
     IAddressResolver<PhysicalAddress, IPAddress>,
     IDisposable
   {
     protected static PhysicalAddress AllZeroMacAddress { get; }
     public static MacAddressResolverBase Null { get; }
 
     protected MacAddressResolverBase(ILogger? logger = null) {}
 
     public abstract bool HasInvalidated { get; }
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public void Invalidate(IPAddress ipAddress) {}
     public void Invalidate(PhysicalAddress macAddress) {}
     protected abstract void InvalidateCore(IPAddress ipAddress);
     protected abstract void InvalidateCore(PhysicalAddress macAddress);
     public ValueTask RefreshAddressTableAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshAddressTableAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask RefreshInvalidatedAddressesAsync(CancellationToken cancellationToken = default) {}
     protected virtual ValueTask RefreshInvalidatedAddressesAsyncCore(CancellationToken cancellationToken) {}
     public ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsync(IPAddress ipAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<PhysicalAddress?> ResolveIPAddressToMacAddressAsyncCore(IPAddress ipAddress, CancellationToken cancellationToken);
     public ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsync(PhysicalAddress macAddress, CancellationToken cancellationToken = default) {}
     protected abstract ValueTask<IPAddress?> ResolveMacAddressToIPAddressAsyncCore(PhysicalAddress macAddress, CancellationToken cancellationToken);
     void IAddressResolver<IPAddress, PhysicalAddress>.Invalidate(IPAddress address) {}
     ValueTask<PhysicalAddress?> IAddressResolver<IPAddress, PhysicalAddress>.ResolveAsync(IPAddress address, CancellationToken cancellationToken) {}
     void IAddressResolver<PhysicalAddress, IPAddress>.Invalidate(PhysicalAddress address) {}
     ValueTask<IPAddress?> IAddressResolver<PhysicalAddress, IPAddress>.ResolveAsync(PhysicalAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 }
 
 namespace Smdn.Net.AddressTables {
   public interface IAddressTable : IDisposable {
     IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken);
   }
 
   public enum AddressTableEntryState : int {
     Delay = 4,
     Incomplete = 1,
     None = 0,
     Probe = 5,
     Reachable = 2,
     Stale = 3,
   }
 
   public abstract class AddressTable : IAddressTable {
     public static IAddressTable Null { get; }
 
     public static IAddressTable Create(IServiceProvider? serviceProvider = null) {}
 
     protected AddressTable(ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsync(CancellationToken cancellationToken = default) {}
     protected abstract IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore(CancellationToken cancellationToken);
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class IpHlpApiAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public IpHlpApiAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(IpHlpApiAddressTable.<EnumerateEntriesAsyncCore>d__4))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public sealed class ProcfsArpAddressTable : AddressTable {
     public static bool IsSupported { get; }
 
     public ProcfsArpAddressTable(IServiceProvider? serviceProvider = null) {}
 
     [AsyncIteratorStateMachine(typeof(ProcfsArpAddressTable.<EnumerateEntriesAsyncCore>d__5))]
     protected override IAsyncEnumerable<AddressTableEntry> EnumerateEntriesAsyncCore([EnumeratorCancellation] CancellationToken cancellationToken) {}
   }
 
   public readonly struct AddressTableEntry :
     IEquatable<AddressTableEntry>,
     IEquatable<IPAddress>,
     IEquatable<PhysicalAddress>
   {
     public static readonly AddressTableEntry Empty; // = "{IP=, MAC=(null), IsPermanent=False, State=None, Iface=}"
 
     public static IEqualityComparer<AddressTableEntry> DefaultEqualityComparer { get; }
     public static IEqualityComparer<AddressTableEntry> ExceptStateEqualityComparer { get; }
 
     public AddressTableEntry(IPAddress ipAddress, PhysicalAddress? physicalAddress, bool isPermanent, AddressTableEntryState state, string? interfaceId) {}
 
     public IPAddress? IPAddress { get; }
     public string? InterfaceId { get; }
     public bool IsEmpty { get; }
     public bool IsPermanent { get; }
     public PhysicalAddress? PhysicalAddress { get; }
     public AddressTableEntryState State { get; }
 
     public bool Equals(AddressTableEntry other) {}
     public bool Equals(IPAddress? other) {}
+    public bool Equals(IPAddress? other, bool shouldConsiderIPv4MappedIPv6Address) {}
     public bool Equals(PhysicalAddress? other) {}
     public override bool Equals(object? obj) {}
     public override int GetHashCode() {}
     public override string ToString() {}
   }
 }
 
 namespace Smdn.Net.NetworkScanning {
   public interface INetworkScanner : IDisposable {
     ValueTask ScanAsync(CancellationToken cancellationToken);
     ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken);
   }
 
   public sealed class ArpScanCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public ArpScanCommandNetworkScanner(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public abstract class CommandNetworkScanner : INetworkScanner {
     public interface IProcessFactory {
       Process CreateProcess(ProcessStartInfo processStartInfo);
     }
 
     protected readonly struct Command {
       public Command(string name, string? executablePath) {}
 
       public bool IsAvailable { get; }
       public string Name { get; }
 
       public string GetExecutablePathOrThrow() {}
     }
 
     protected static IReadOnlyCollection<string> DefaultCommandPaths { get; }
 
     protected static CommandNetworkScanner.Command FindCommand(string command, IEnumerable<string> paths) {}
 
     protected CommandNetworkScanner(ILogger? logger, IServiceProvider? serviceProvider) {}
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     protected abstract bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string? arguments);
     protected abstract bool GetCommandLineArguments(out string executable, out string? arguments);
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class IpHlpApiNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public IpHlpApiNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 
   public abstract class NetworkScanner : INetworkScanner {
     public static INetworkScanner Null { get; }
 
     public static INetworkScanner Create(IPNetworkProfile? networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected NetworkScanner(IPNetworkProfile networkProfile, ILogger? logger = null) {}
 
     protected ILogger? Logger { get; }
     protected IPNetworkProfile NetworkProfile { get; }
 
     protected virtual void Dispose(bool disposing) {}
     public void Dispose() {}
     public virtual ValueTask ScanAsync(CancellationToken cancellationToken = default) {}
     public virtual ValueTask ScanAsync(IEnumerable<IPAddress> addresses, CancellationToken cancellationToken = default) {}
     protected virtual ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken) {}
     protected void ThrowIfDisposed() {}
   }
 
   public sealed class NmapCommandNetworkScanner : CommandNetworkScanner {
     public static bool IsSupported { get; }
 
     public NmapCommandNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override bool GetCommandLineArguments(IEnumerable<IPAddress> addressesToScan, out string executable, out string arguments) {}
     protected override bool GetCommandLineArguments(out string executable, out string arguments) {}
   }
 
   public sealed class PingNetworkScanner : NetworkScanner {
     public static bool IsSupported { get; }
 
     public PingNetworkScanner(IPNetworkProfile networkProfile, IServiceProvider? serviceProvider = null) {}
 
     protected override void Dispose(bool disposing) {}
     protected override async ValueTask ScanAsyncCore(IPAddress address, CancellationToken cancellationToken = default) {}
   }
 }
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.3.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.5.0.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)

Full changes

Full changes in this release:
diff --git a/src/Smdn.Net.AddressResolution/CompatibilitySuppressions.xml b/src/Smdn.Net.AddressResolution/CompatibilitySuppressions.xml
index f6af1d0..f2e3423 100644
--- a/src/Smdn.Net.AddressResolution/CompatibilitySuppressions.xml
+++ b/src/Smdn.Net.AddressResolution/CompatibilitySuppressions.xml
@@ -1,12 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids -->
 <Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
-  <!-- 1.0.2 vs 1.1.0 -->
+  <!-- 1.0.2 vs 1.2.0 -->
+  <Suppression>
+    <DiagnosticId>CP0008</DiagnosticId>
+    <Target>T:Smdn.Net.AddressTables.AddressTableEntryState</Target>
+    <Left>lib/net6.0/Smdn.Net.AddressResolution.dll</Left>
+    <Right>lib/netstandard2.1/Smdn.Net.AddressResolution.dll</Right>
+    <IsBaselineSuppression>true</IsBaselineSuppression>
+  </Suppression>
   <Suppression>
     <DiagnosticId>CP0008</DiagnosticId>
     <Target>T:Smdn.Net.AddressTables.AddressTableEntryState</Target>
     <Left>lib/net7.0/Smdn.Net.AddressResolution.dll</Left>
-    <Right>lib/net6.0/Smdn.Net.AddressResolution.dll</Right>
+    <Right>lib/netstandard2.1/Smdn.Net.AddressResolution.dll</Right>
     <IsBaselineSuppression>true</IsBaselineSuppression>
   </Suppression>
 </Suppressions>
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
index 86d31f1..fa89375 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution.csproj
@@ -4,8 +4,8 @@ SPDX-License-Identifier: MIT
 -->
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFrameworks>net8.0;net6.0;netstandard2.1;netstandard2.0</TargetFrameworks>
-    <VersionPrefix>1.1.0</VersionPrefix>
+    <TargetFrameworks>net8.0;netstandard2.1;netstandard2.0</TargetFrameworks>
+    <VersionPrefix>1.2.0</VersionPrefix>
     <VersionSuffix></VersionSuffix>
     <PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
     <RootNamespace/> <!-- empty the root namespace so that the namespace is determined only by the directory name, for code style rule IDE0030 -->
@@ -40,7 +40,17 @@ This library also provides a functionality for referencing the system's address
     <PackageReference Include="Microsoft.Bcl.HashCode" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
-    <PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.4.13" />
+    <PackageReference Include="Vanara.Core" Version="4.1.1">
+      <!--
+        `Vanara.Core` imports code analysis attributes such as `NotNullWhenAttributes` for backward compatibility.
+        Therefore, depending on the configuration of <TargetFramework>s, this may conflict with
+        type names imported from the assembly `netstandard`.
+        So, define separate namespaces with the Aliases property, and allow names imported from each
+        assembly to be referenced separately by using `extern aliases`.
+      -->
+      <Aliases>VanaraCore</Aliases>
+    </PackageReference>
+    <PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="4.1.1" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.AddressResolution.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.AddressResolution.cs
index 1abfcfb..bc69f5c 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.AddressResolution.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.AddressResolution.cs
@@ -33,7 +33,7 @@ partial class MacAddressResolver {
         if (!FilterAddressTableEntryForAddressResolution(entry))
           return false;
 
-        if (!entry.Equals(ipAddress))
+        if (!entry.Equals(ipAddress, shouldConsiderIPv4MappedIPv6Address: ShouldResolveIPv4MappedIPv6Address))
           return false;
 
         // ignore the entry that is marked as invalidated
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.cs
index f795c03..635afd6 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressResolution/MacAddressResolver.cs
@@ -161,6 +161,14 @@ public partial class MacAddressResolver : MacAddressResolverBase {
   private const int DefaultParallelCountForRefreshInvalidatedAddresses = 3;
   private SemaphoreSlim partialScanSemaphore;
 
+  /// <summary>
+  /// Gets or sets a value indicating whether the address resolution to be aware or not to be aware that
+  /// the IP address is an IPv4-mapped IPv6 address when resolving IP address to MAC address.
+  /// </summary>
+  /// <seealso cref="MacAddressResolverBase.ResolveIPAddressToMacAddressAsync(IPAddress, CancellationToken)" />
+  /// <seealso cref="AddressTableEntry.Equals(IPAddress?, bool)" />
+  public bool ShouldResolveIPv4MappedIPv6Address { get; set; }
+
   /// <summary>
   /// Initializes a new instance of the <see cref="MacAddressResolver"/> class.
   /// </summary>
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTable.Create.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTable.Create.cs
index e0430db..0ac99a2 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTable.Create.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTable.Create.cs
@@ -1,6 +1,7 @@
 // SPDX-FileCopyrightText: 2023 smdn <smdn@smdn.jp>
 // SPDX-License-Identifier: MIT
 using System;
+using System.Runtime.InteropServices;
 
 namespace Smdn.Net.AddressTables;
 
@@ -11,7 +12,7 @@ partial class AddressTable {
     IServiceProvider? serviceProvider = null
   )
   {
-    if (IpHlpApiAddressTable.IsSupported)
+    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && IpHlpApiAddressTable.IsSupported)
       return new IpHlpApiAddressTable(serviceProvider);
 
     if (ProcfsArpAddressTable.IsSupported)
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTableEntry.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTableEntry.cs
index d1bd402..d39330d 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTableEntry.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/AddressTableEntry.cs
@@ -73,11 +73,31 @@ public readonly struct AddressTableEntry : IEquatable<AddressTableEntry>, IEquat
     => DefaultEqualityComparer.Equals(this, other);
 
   public bool Equals(IPAddress? other)
+    => Equals(other, shouldConsiderIPv4MappedIPv6Address: false);
+
+  /// <summary>
+  /// Indicates whether the member <see cref="AddressTableEntry.IPAddress"/> is equal to the IP address passed to the parameter.
+  /// </summary>
+  /// <param name="other">The <see cref="System.Net.IPAddress"/> to be compared with the <see cref="AddressTableEntry.IPAddress"/>.</param>
+  /// <param name="shouldConsiderIPv4MappedIPv6Address">
+  /// Specifies whether or not to be aware that the IP address to be an IPv4-mapped IPv6 address or not when comparing IP addresses.
+  /// </param>
+  /// <returns>
+  /// <see langword="true"/> if the <see cref="AddressTableEntry.IPAddress"/> is equal to the <paramref name="other"/> parameter; otherwise, <see langword="false"/>.
+  /// </returns>
+  public bool Equals(IPAddress? other, bool shouldConsiderIPv4MappedIPv6Address)
   {
-    if (IPAddress is null)
-      return other is null;
+    if (other is null)
+      return IPAddress is null;
+
+    if (shouldConsiderIPv4MappedIPv6Address) {
+      if (other.IsIPv4MappedToIPv6 && other.MapToIPv4().Equals(IPAddress))
+        return true;
+      if (IPAddress is not null && IPAddress.IsIPv4MappedToIPv6 && other.Equals(IPAddress.MapToIPv4()))
+        return true;
+    }
 
-    return IPAddress.Equals(other);
+    return other.Equals(IPAddress);
   }
 
   public bool Equals(PhysicalAddress? other)
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/IpHlpApiAddressTable.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/IpHlpApiAddressTable.cs
index bd7601d..599c0ee 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/IpHlpApiAddressTable.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/IpHlpApiAddressTable.cs
@@ -6,6 +6,9 @@ using System.Runtime.CompilerServices;
 #if SYSTEM_RUNTIME_EXCEPTIONSERVICES_EXCEPTIONDISPATCHINFO_SETCURRENTSTACKTRACE
 using System.Runtime.ExceptionServices;
 #endif
+#if SYSTEM_RUNTIME_VERSIONING_SUPPORTEDOSPLATFORMATTRIBUTE
+using System.Runtime.Versioning;
+#endif
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -17,6 +20,9 @@ using static Vanara.PInvoke.Ws2_32;
 
 namespace Smdn.Net.AddressTables;
 
+#if SYSTEM_RUNTIME_VERSIONING_SUPPORTEDOSPLATFORMATTRIBUTE
+[SupportedOSPlatform("windows")]
+#endif
 public sealed class IpHlpApiAddressTable : AddressTable {
   public static bool IsSupported => LazyIsSupported.Value;
 
@@ -50,6 +56,9 @@ public sealed class IpHlpApiAddressTable : AddressTable {
   {
     using var table = await GetIpNetTable2Async().ConfigureAwait(false);
 
+    if (table.Table is null)
+      yield break;
+
     foreach (var ipnetRow2 in table.Table) {
       cancellationToken.ThrowIfCancellationRequested();
 
@@ -82,7 +91,7 @@ public sealed class IpHlpApiAddressTable : AddressTable {
 
         table.Dispose();
 
-        var ex = ret.GetException();
+        var ex = ret.GetException() ?? new InvalidOperationException($"GetIpNetTable2 failed: {ret}");
 
 #if SYSTEM_RUNTIME_EXCEPTIONSERVICES_EXCEPTIONDISPATCHINFO_SETCURRENTSTACKTRACE
         ex = ExceptionDispatchInfo.SetCurrentStackTrace(ex);
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/ProcfsArpAddressTable.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/ProcfsArpAddressTable.cs
index b1ecd40..de61b07 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/ProcfsArpAddressTable.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.AddressTables/ProcfsArpAddressTable.cs
@@ -2,9 +2,6 @@
 // SPDX-License-Identifier: MIT
 using System;
 using System.Collections.Generic;
-#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
-using System.Diagnostics.CodeAnalysis;
-#endif
 using System.Globalization;
 using System.IO;
 using System.Net;
@@ -15,6 +12,13 @@ using System.Threading;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 
+#if NULL_STATE_STATIC_ANALYSIS_ATTRIBUTES
+// `Vanara.Core` imports code analysis attributes such as `NotNullWhenAttributes`.
+// Since there is a name conflict between `Vanara.Core` and `netstandard`, assign a different
+// alias to `Vanara.Core` in csproj and refer to the netstandard name by the global alias here.
+using NotNullWhenAttribute = global::System.Diagnostics.CodeAnalysis.NotNullWhenAttribute;
+#endif
+
 namespace Smdn.Net.AddressTables;
 
 public sealed class ProcfsArpAddressTable : AddressTable {
diff --git a/src/Smdn.Net.AddressResolution/Smdn.Net.NetworkScanning/IpHlpApiNetworkScanner.cs b/src/Smdn.Net.AddressResolution/Smdn.Net.NetworkScanning/IpHlpApiNetworkScanner.cs
index d991671..cea9771 100644
--- a/src/Smdn.Net.AddressResolution/Smdn.Net.NetworkScanning/IpHlpApiNetworkScanner.cs
+++ b/src/Smdn.Net.AddressResolution/Smdn.Net.NetworkScanning/IpHlpApiNetworkScanner.cs
@@ -6,6 +6,9 @@ using System.Net.Sockets;
 #if SYSTEM_RUNTIME_EXCEPTIONSERVICES_EXCEPTIONDISPATCHINFO_SETCURRENTSTACKTRACE
 using System.Runtime.ExceptionServices;
 #endif
+#if SYSTEM_RUNTIME_VERSIONING_SUPPORTEDOSPLATFORMATTRIBUTE
+using System.Runtime.Versioning;
+#endif
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -19,6 +22,9 @@ using static Vanara.PInvoke.Ws2_32;
 
 namespace Smdn.Net.NetworkScanning;
 
+#if SYSTEM_RUNTIME_VERSIONING_SUPPORTEDOSPLATFORMATTRIBUTE
+[SupportedOSPlatform("windows")]
+#endif
 public sealed class IpHlpApiNetworkScanner : NetworkScanner {
   // ref:
   //   https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/wpd_sdk/error-constants.md
@@ -125,7 +131,7 @@ public sealed class IpHlpApiNetworkScanner : NetworkScanner {
 
     Logger?.LogWarning("ResolveIpNetEntry2({Address}) {Result}", address, ret.ToString());
 
-    var ex = ret.GetException();
+    var ex = ret.GetException() ?? new InvalidOperationException($"ResolveIpNetEntry2({address}) failed: {ret}");
 
 #if SYSTEM_RUNTIME_EXCEPTIONSERVICES_EXCEPTIONDISPATCHINFO_SETCURRENTSTACKTRACE
     ex = ExceptionDispatchInfo.SetCurrentStackTrace(ex);

Notes

Full Changelog: releases/Smdn.Net.AddressResolution-1.1.0...releases/Smdn.Net.AddressResolution-1.2.0