Updated tests for iphlpapi

pull/60/head
David Hall 2019-04-24 08:37:46 -06:00
parent 27ab71a4f9
commit c68aca71ac
3 changed files with 1006 additions and 438 deletions

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -29,12 +30,14 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="IpHlpApiTests.cs" />
<Compile Include="NetIOApiTests.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NUnit">

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,545 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using static Vanara.PInvoke.IpHlpApi;
using static Vanara.PInvoke.Ws2_32;
#pragma warning disable CS0618 // Type or member is obsolete
namespace Vanara.PInvoke.Tests
{
public partial class IpHlpApiTests
{
[Test]
public void ConversionTests()
{
var luid = primaryAdapter.Luid;
const int sblen = 1024;
var sb = new StringBuilder(sblen, sblen);
Assert.That(ConvertInterfaceLuidToAlias(luid, sb, sblen), Is.Zero);
Assert.That(sb.ToString(), Is.EqualTo(primaryAdapter.FriendlyName));
var alias = sb.ToString();
TestContext.WriteLine($"LUID=>Alias = {alias}");
Assert.That(ConvertInterfaceLuidToGuid(luid, out var ifGuid), Is.Zero);
Assert.That(ifGuid, Is.EqualTo(Guid.Parse(primaryAdapter.AdapterName)));
TestContext.WriteLine($"LUID=>GUID = {ifGuid}");
Assert.That(ConvertInterfaceLuidToIndex(luid, out var ifIdx), Is.Zero);
Assert.That(ifIdx, Is.EqualTo(primaryAdapter.IfIndex));
TestContext.WriteLine($"LUID=>Idx = {ifIdx}");
sb.Clear();
Assert.That(ConvertInterfaceLuidToName(luid, sb, sblen), Is.Zero);
var name = sb.ToString();
TestContext.WriteLine($"LUID=>Name = {name}");
Assert.That(ConvertInterfaceAliasToLuid(alias, out var luid2), Is.Zero);
Assert.That(luid2, Is.EqualTo(luid));
Assert.That(ConvertInterfaceGuidToLuid(ifGuid, out luid2), Is.Zero);
Assert.That(luid2, Is.EqualTo(luid));
Assert.That(ConvertInterfaceIndexToLuid(ifIdx, out luid2), Is.Zero);
Assert.That(luid2, Is.EqualTo(luid));
Assert.That(ConvertInterfaceNameToLuid(name, out luid2), Is.Zero);
Assert.That(luid2, Is.EqualTo(luid));
uint mask = 0x00FFFFFF; // 255.255.255.0
Assert.That(ConvertIpv4MaskToLength(mask, out var maskLen), Is.Zero);
Assert.That(maskLen, Is.EqualTo(24));
Assert.That(ConvertLengthToIpv4Mask(maskLen, out var mask2), Is.Zero);
Assert.That(mask2, Is.EqualTo(mask));
}
[Test]
public void CreateGetDeleteAnycastIpAddressEntryTest()
{
var mibrow = new MIB_ANYCASTIPADDRESS_ROW(GetV6Addr(), primaryAdapter.Luid);
Assert.That(GetAnycastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t1), Is.Zero);
if (t1.Contains(mibrow))
Assert.That(DeleteAnycastIpAddressEntry(ref mibrow), Is.Zero);
Assert.That(CreateAnycastIpAddressEntry(ref mibrow), Is.Zero);
GetAnycastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t2);
Assert.That(t2, Has.Member(mibrow));
Assert.That(GetAnycastIpAddressEntry(ref mibrow), Is.Zero);
Assert.That(DeleteAnycastIpAddressEntry(ref mibrow), Is.Zero);
GetAnycastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t3);
Assert.That(t3, Has.No.Member(mibrow));
}
[Test]
public void CreateSetDeleteIpForwardEntry2Test()
{
var mibrow = new MIB_IPFORWARD_ROW2(new IP_ADDRESS_PREFIX((SOCKADDR_IN6)IN6_ADDR.Unspecified, 128), GetV6Addr(), primaryAdapter.Luid)
{
Protocol = MIB_IPFORWARD_PROTO.MIB_IPPROTO_NETMGMT,
Metric = 1
};
DeleteIpForwardEntry2(ref mibrow);
Assert.That(CreateIpForwardEntry2(ref mibrow), Is.Zero);
mibrow.PreferredLifetime = 500000;
Assert.That(SetIpForwardEntry2(mibrow), Is.Zero);
Assert.That(GetIpForwardEntry2(ref mibrow), Is.Zero);
Assert.That(DeleteIpForwardEntry2(ref mibrow), Is.Zero);
}
[Test]
public void CreateSetDeleteIpNetEntry2Test()
{
var target = new IN_ADDR(192, 168, 0, 202);
Assert.That(GetBestRoute(target, 0, out var fwdRow), Is.Zero);
var mibrow = new MIB_IPNET_ROW2(new SOCKADDR_IN(target), fwdRow.dwForwardIfIndex, SendARP(target));
Assert.That(GetIpNetTable2(ADDRESS_FAMILY.AF_INET, out var t1), Is.Zero);
if (HasVal(t1, mibrow))
Assert.That(DeleteIpNetEntry2(ref mibrow), Is.Zero);
Assert.That(CreateIpNetEntry2(ref mibrow), Is.Zero);
GetIpNetTable2(ADDRESS_FAMILY.AF_INET, out var t2);
Assert.That(HasVal(t2, mibrow), Is.True);
Assert.That(DeleteIpNetEntry2(ref mibrow), Is.Zero);
GetIpNetTable2(ADDRESS_FAMILY.AF_INET, out var t3);
Assert.That(HasVal(t3, mibrow), Is.False);
bool HasVal(IEnumerable<MIB_IPNET_ROW2> t, MIB_IPNET_ROW2 r) =>
t.Any(tr => tr.Address.Ipv4.sin_addr == r.Address.Ipv4.sin_addr && tr.InterfaceIndex == r.InterfaceIndex && tr.PhysicalAddress.SequenceEqual(r.PhysicalAddress));
}
[Test]
public void CreateSetGetDeleteUnicastIpAddressEntryTest()
{
Assert.That(GetUnicastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t1), Is.Zero);
var mibrow = t1.First();
Assert.That(DeleteUnicastIpAddressEntry(ref mibrow), Is.Zero);
Assert.That(CreateUnicastIpAddressEntry(ref mibrow), Is.Zero);
GetUnicastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t2);
Assert.That(t2, Has.Member(mibrow));
mibrow.PreferredLifetime = 500000;
Assert.That(SetUnicastIpAddressEntry(mibrow), Is.Zero);
Assert.That(GetUnicastIpAddressEntry(ref mibrow), Is.Zero);
Assert.That(DeleteUnicastIpAddressEntry(ref mibrow), Is.Zero);
GetUnicastIpAddressTable(ADDRESS_FAMILY.AF_INET6, out var t4);
Assert.That(t4, Has.No.Member(mibrow));
}
[Test]
public void CreateSortedAddressPairsTest()
{
var dest = primaryAdapter.MulticastAddresses.Select(ma => ma.Address.GetSOCKADDR().Ipv6).ToArray();
TestContext.WriteLine(string.Join("\r\n", dest));
SOCKADDR_IN6_PAIR_NATIVE[] result = null;
Assert.That(() => result = CreateSortedAddressPairs(dest), Throws.Nothing);
TestContext.WriteLine("\r\n" + string.Join("\r\n", result));
Assert.That(result, Has.Length.GreaterThan(0));
}
[Test]
public void FlushIpNetTable2Test()
{
Assert.That(FlushIpNetTable2(ADDRESS_FAMILY.AF_INET6, primaryAdapter.IfIndex), Is.Zero);
}
[Test]
public void FlushIpPathTableTest()
{
Assert.That(FlushIpPathTable(ADDRESS_FAMILY.AF_INET6), Is.Zero);
}
[Test]
public void GetAnycastIpAddressEntryTableTest()
{
Assert.That(GetAnycastIpAddressTable(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.Zero);
var row = new MIB_ANYCASTIPADDRESS_ROW();
Assert.That(GetAnycastIpAddressEntry(ref row), Is.Not.Zero);
}
[Test]
public void GetBestRoute2Test()
{
var addr = new SOCKADDR_INET { Ipv4 = new SOCKADDR_IN(new IN_ADDR(192, 168, 0, 202)) };
Assert.That(GetBestRoute2(IntPtr.Zero, primaryAdapter.IfIndex, IntPtr.Zero, addr, 0, out var rt, out var src), Is.Zero);
Assert.That(rt.InterfaceIndex, Is.EqualTo(primaryAdapter.IfIndex));
Assert.That(src.Ipv4.sin_addr, Is.EqualTo(new IN_ADDR(192, 168, 0, 203)));
}
[Test]
public void GetIfEntry2ExTest()
{
var row = new MIB_IF_ROW2(primaryAdapter.IfIndex);
Assert.That(GetIfEntry2Ex(MIB_IF_ENTRY_LEVEL.MibIfEntryNormalWithoutStatistics, ref row), Is.Zero);
Assert.That(row.InterfaceLuid, Is.EqualTo(primaryAdapter.Luid));
}
[Test]
public void GetIfEntry2Test()
{
var row = new MIB_IF_ROW2(primaryAdapter.IfIndex);
Assert.That(GetIfEntry2(ref row), Is.Zero);
Assert.That(row.InterfaceLuid, Is.EqualTo(primaryAdapter.Luid));
}
[Test]
public void GetIfStackTableTest()
{
Assert.That(GetIfStackTable(out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
}
[Test]
public void GetIfTable2ExTest()
{
var e = GetIfTable2Ex(MIB_IF_TABLE_LEVEL.MibIfTableNormal, out var itbl);
Assert.That(e.Succeeded);
Assert.That(itbl.Table, Is.Not.Empty);
itbl.Dispose();
Assert.That(itbl.IsInvalid);
}
[Test]
public void GetIfTable2Test()
{
var e = GetIfTable2(out var itbl);
Assert.That(e.Succeeded);
Assert.That(itbl.Table, Is.Not.Empty);
itbl.Dispose();
Assert.That(itbl.IsInvalid);
}
[Test]
public void GetInvertedIfStackTableTest()
{
Assert.That(GetInvertedIfStackTable(out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
}
[Test]
public void GetIpForwardEntryTable2Test()
{
Assert.That(GetIpForwardTable2(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_IPFORWARD_ROW2 { DestinationPrefix = goodRow.DestinationPrefix, NextHop = goodRow.NextHop, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetIpForwardEntry2(ref row), Is.Zero);
Assert.That(row.InterfaceIndex, Is.Not.Zero.And.EqualTo(goodRow.InterfaceIndex));
}
[Test]
public void GetIpInterfaceEntryTableTest()
{
Assert.That(GetIpInterfaceTable(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_IPINTERFACE_ROW { Family = goodRow.Family, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetIpInterfaceEntry(ref row), Is.Zero);
Assert.That(row.InterfaceIndex, Is.Not.Zero.And.EqualTo(goodRow.InterfaceIndex));
}
[Test]
public void GetIpNetworkConnectionBandwidthEstimatesTest()
{
Assert.That(GetIpNetworkConnectionBandwidthEstimates(primaryAdapter.IfIndex, ADDRESS_FAMILY.AF_INET, out var est), Is.Zero);
Assert.That(est.InboundBandwidthInformation.Bandwidth, Is.GreaterThan(0));
Assert.That(est.OutboundBandwidthInformation.Bandwidth, Is.GreaterThan(0));
}
[Test]
public void GetIpPathEntryTableTest()
{
Assert.That(GetIpPathTable(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_IPPATH_ROW { Destination = goodRow.Destination, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetIpPathEntry(ref row), Is.Zero);
Assert.That((int)row.Source.si_family, Is.Not.Zero);
}
[Test]
public void GetMulticastIpAddressEntryTableTest()
{
Assert.That(GetMulticastIpAddressTable(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_MULTICASTIPADDRESS_ROW { Address = goodRow.Address, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetMulticastIpAddressEntry(ref row), Is.Zero);
Assert.That(row.InterfaceIndex, Is.Not.Zero.And.EqualTo(goodRow.InterfaceIndex));
}
[Test]
public void GetSetIpInterfaceEntryTest()
{
var mibrow = new MIB_IPINTERFACE_ROW(ADDRESS_FAMILY.AF_INET, primaryAdapter.Luid);
Assert.That(GetIpInterfaceEntry(ref mibrow), Is.Zero);
var prev = mibrow.SitePrefixLength;
mibrow.SitePrefixLength = 0;
Assert.That(SetIpInterfaceEntry(mibrow), Is.Zero);
mibrow = new MIB_IPINTERFACE_ROW(ADDRESS_FAMILY.AF_INET, primaryAdapter.Luid);
Assert.That(GetIpInterfaceEntry(ref mibrow), Is.Zero);
Assert.That(mibrow.PathMtuDiscoveryTimeout, Is.EqualTo(600000));
mibrow.SitePrefixLength = prev;
Assert.That(SetIpInterfaceEntry(mibrow), Is.Zero);
}
[Test]
public void GetSetIpNetEntryTable2Test()
{
Assert.That(GetIpNetTable2(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_IPNET_ROW2 { Address = goodRow.Address, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetIpNetEntry2(ref row), Is.Zero);
Assert.That(row.InterfaceIndex, Is.Not.Zero.And.EqualTo(goodRow.InterfaceIndex));
row = new MIB_IPNET_ROW2 { Address = primaryAdapter.MulticastAddresses.First().Address.GetSOCKADDR(), InterfaceIndex = primaryAdapter.IfIndex };
Assert.That(() => SetIpNetEntry2(row), Throws.Nothing); // This call always fails w/ ERROR_NOT_FOUND, but it works
}
[Test]
public void GetTeredoPortTest()
{
Assert.That(GetTeredoPort(out var port), Is.Zero.Or.EqualTo(Win32Error.ERROR_NOT_READY));
}
[Test]
public void GetUnicastIpAddressEntryTableTest()
{
Assert.That(GetUnicastIpAddressTable(ADDRESS_FAMILY.AF_UNSPEC, out var table), Is.Zero);
Assert.That(table.NumEntries, Is.GreaterThan(0));
Assert.That(() => table.Table, Throws.Nothing);
var goodRow = table.Table[0];
var row = new MIB_UNICASTIPADDRESS_ROW { Address = goodRow.Address, InterfaceLuid = goodRow.InterfaceLuid };
Assert.That(GetUnicastIpAddressEntry(ref row), Is.Zero);
Assert.That(row.CreationTimeStamp, Is.Not.Zero.And.EqualTo(goodRow.CreationTimeStamp));
}
[Test]
public void if_indextonameANDif_nametoindexTest()
{
var sb = new StringBuilder(IF_MAX_STRING_SIZE, IF_MAX_STRING_SIZE);
Assert.That(if_indextoname(primaryAdapter.IfIndex, sb), Is.Not.EqualTo(IntPtr.Zero));
TestContext.WriteLine(sb);
Assert.That(if_nametoindex(sb.ToString()), Is.EqualTo(primaryAdapter.IfIndex));
}
[Test]
public void InitializeIpForwardEntryTest()
{
InitializeIpForwardEntry(out var entry);
Assert.That(entry.ValidLifetime, Is.Not.Zero);
Assert.That(entry.Loopback, Is.True);
}
[Test]
public void InitializeIpInterfaceEntryTest()
{
InitializeIpInterfaceEntry(out var entry);
Assert.That((int)entry.Family, Is.Zero);
Assert.That(entry.InterfaceIdentifier, Is.Not.Zero);
Assert.That(entry.SupportsNeighborDiscovery, Is.True);
}
[Test]
public void InitializeUnicastIpAddressEntryTest()
{
InitializeUnicastIpAddressEntry(out var entry);
Assert.That(entry.ValidLifetime, Is.Not.Zero);
Assert.That(entry.PrefixOrigin, Is.EqualTo(NL_PREFIX_ORIGIN.IpPrefixOriginUnchanged));
}
[Test]
public void NotifyIpInterfaceChangeTest()
{
var fired = new ManualResetEvent(false);
var done = new ManualResetEvent(false);
new Thread(() =>
{
try
{
Assert.That(NotifyIpInterfaceChange(ADDRESS_FAMILY.AF_UNSPEC, NotifyFunc, NotifyData, true, out var hNot), Is.Zero);
fired.WaitOne(3000);
Assert.That(CancelMibChangeNotify2(hNot), Is.Zero);
}
finally
{
done.Set();
}
}).Start();
Assert.That(done.WaitOne(5000), Is.True);
void NotifyFunc(IntPtr CallerContext, IntPtr Row, MIB_NOTIFICATION_TYPE NotificationType)
{
Assert.That(CallerContext, Is.EqualTo(NotifyData));
TestContext.WriteLine(Row.ToString());
Assert.That(NotificationType, Is.EqualTo(MIB_NOTIFICATION_TYPE.MibInitialNotification));
fired.Set();
}
}
[Test]
public void NotifyRouteChange2Test()
{
var fired = new ManualResetEvent(false);
var done = new ManualResetEvent(false);
new Thread(() =>
{
try
{
Assert.That(NotifyRouteChange2(ADDRESS_FAMILY.AF_UNSPEC, NotifyFunc, NotifyData, true, out var hNot), Is.Zero);
fired.WaitOne(3000);
Assert.That(CancelMibChangeNotify2(hNot), Is.Zero);
}
finally
{
done.Set();
}
}).Start();
Assert.That(done.WaitOne(5000), Is.True);
void NotifyFunc(IntPtr CallerContext, ref MIB_IPFORWARD_ROW2 Row, MIB_NOTIFICATION_TYPE NotificationType)
{
Assert.That(CallerContext, Is.EqualTo(NotifyData));
TestContext.WriteLine(Row.ToString());
Assert.That(NotificationType, Is.EqualTo(MIB_NOTIFICATION_TYPE.MibInitialNotification));
fired.Set();
}
}
[Test]
public void NotifyStableUnicastIpAddressTableTest()
{
var fired = new ManualResetEvent(false);
var done = new ManualResetEvent(false);
new Thread(() =>
{
try
{
Assert.That(NotifyStableUnicastIpAddressTable(ADDRESS_FAMILY.AF_UNSPEC, out var table, NotifyFunc, NotifyData, out var hNot), Is.Zero.Or.EqualTo(Win32Error.ERROR_IO_PENDING));
if (table == IntPtr.Zero)
{
fired.WaitOne(3000);
Assert.That(CancelMibChangeNotify2(hNot), Is.Zero);
}
}
finally
{
done.Set();
}
}).Start();
Assert.That(done.WaitOne(5000), Is.True);
void NotifyFunc(IntPtr CallerContext, IntPtr Table)
{
Assert.That(CallerContext, Is.EqualTo(NotifyData));
TestContext.WriteLine(Table.ToString());
fired.Set();
}
}
[Test]
public void NotifyTeredoPortChangeTest()
{
var fired = new ManualResetEvent(false);
var done = new ManualResetEvent(false);
new Thread(() =>
{
try
{
Assert.That(NotifyTeredoPortChange(NotifyFunc, NotifyData, true, out var hNot), Is.Zero);
fired.WaitOne(3000);
Assert.That(CancelMibChangeNotify2(hNot), Is.Zero);
}
finally
{
done.Set();
}
}).Start();
Assert.That(done.WaitOne(5000), Is.True);
void NotifyFunc(IntPtr CallerContext, ushort Port, MIB_NOTIFICATION_TYPE NotificationType)
{
Assert.That(CallerContext, Is.EqualTo(NotifyData));
TestContext.WriteLine(Port.ToString());
Assert.That(NotificationType, Is.EqualTo(MIB_NOTIFICATION_TYPE.MibInitialNotification));
fired.Set();
}
}
[Test]
public void NotifyUnicastIpAddressChangeTest()
{
var fired = new ManualResetEvent(false);
var done = new ManualResetEvent(false);
new Thread(() =>
{
try
{
Assert.That(NotifyUnicastIpAddressChange(ADDRESS_FAMILY.AF_UNSPEC, NotifyFunc, NotifyData, true, out var hNot), Is.Zero);
fired.WaitOne(3000);
Assert.That(CancelMibChangeNotify2(hNot), Is.Zero);
}
finally
{
done.Set();
}
}).Start();
Assert.That(done.WaitOne(5000), Is.True);
void NotifyFunc(IntPtr CallerContext, IntPtr Row, MIB_NOTIFICATION_TYPE NotificationType)
{
Assert.That(CallerContext, Is.EqualTo(NotifyData));
TestContext.WriteLine(Row.ToString());
Assert.That(NotificationType, Is.EqualTo(MIB_NOTIFICATION_TYPE.MibInitialNotification));
fired.Set();
}
}
[Test]
public void ResolveIpNetEntry2Test()
{
var e = new MIB_IPNET_ROW2(new SOCKADDR_IN(new IN_ADDR(192, 168, 0, 202)), primaryAdapter.IfIndex);
Assert.That(ResolveIpNetEntry2(ref e), Is.Zero);
Assert.That(e.State, Is.EqualTo(NL_NEIGHBOR_STATE.NlnsReachable));
}
[Test]
public void FutureUseTest()
{
Assert.That(SetCurrentThreadCompartmentId(1), Is.GreaterThanOrEqualTo(0));
Assert.That(SetNetworkInformation(Guid.NewGuid(), 1, "Fred"), Is.GreaterThanOrEqualTo(0));
Assert.That(SetSessionCompartmentId(1, 1), Is.GreaterThanOrEqualTo(0));
}
private SOCKADDR_IN6 GetV6Addr() => new SOCKADDR_IN6(new IN6_ADDR(new byte[] { 0xfe, 0x3f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x20, 0x00 }), 0);
}
}