mirror of https://github.com/dahall/Vanara.git
Addition of over 20 methods and corresponding structures and enums and tests for IpHlpApi
parent
79ba7668c8
commit
112356f305
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,308 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vanara.Extensions;
|
||||
using Vanara.InteropServices;
|
||||
|
||||
namespace Vanara.PInvoke
|
||||
{
|
||||
public static partial class IpHlpApi
|
||||
{
|
||||
[PInvokeData("winsock2.h")]
|
||||
public enum ADDRESS_FAMILY : ushort
|
||||
{
|
||||
AF_UNSPEC = 0, // unspecified
|
||||
AF_UNIX = 1, // local to host (pipes, portals)
|
||||
AF_INET = 2, // internetwork: UDP, TCP, etc.
|
||||
AF_IMPLINK = 3, // arpanet imp addresses
|
||||
AF_PUP = 4, // pup protocols: e.g. BSP
|
||||
AF_CHAOS = 5, // mit CHAOS protocols
|
||||
AF_NS = 6, // XEROX NS protocols
|
||||
AF_IPX = AF_NS, // IPX protocols: IPX, SPX, etc.
|
||||
AF_ISO = 7, // ISO protocols
|
||||
AF_OSI = AF_ISO, // OSI is ISO
|
||||
AF_ECMA = 8, // european computer manufacturers
|
||||
AF_DATAKIT = 9, // datakit protocols
|
||||
AF_CCITT = 10, // CCITT protocols, X.25 etc
|
||||
AF_SNA = 11, // IBM SNA
|
||||
AF_DECnet = 12, // DECnet
|
||||
AF_DLI = 13, // Direct data link interface
|
||||
AF_LAT = 14, // LAT
|
||||
AF_HYLINK = 15, // NSC Hyperchannel
|
||||
AF_APPLETALK = 16, // AppleTalk
|
||||
AF_NETBIOS = 17, // NetBios-style addresses
|
||||
AF_VOICEVIEW = 18, // VoiceView
|
||||
AF_FIREFOX = 19, // Protocols from Firefox
|
||||
AF_UNKNOWN1 = 20, // Somebody is using this!
|
||||
AF_BAN = 21, // Banyan
|
||||
AF_ATM = 22, // Native ATM Services
|
||||
AF_INET6 = 23, // Internetwork Version 6
|
||||
AF_CLUSTER = 24, // Microsoft Wolfpack
|
||||
AF_12844 = 25, // IEEE 1284.4 WG AF
|
||||
AF_IRDA = 26, // IrDA
|
||||
AF_NETDES = 28, // Network Designers OSI & gateway
|
||||
AF_TCNPROCESS = 29,
|
||||
AF_TCNMESSAGE = 30,
|
||||
AF_ICLFXBM = 31,
|
||||
AF_BTH = 32, // Bluetooth RFCOMM/L2CAP protocols
|
||||
AF_LINK = 33,
|
||||
AF_HYPERV = 34,
|
||||
}
|
||||
|
||||
/// <summary>The IN_ADDR structure represents an IPv4 address.</summary>
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct IN_ADDR
|
||||
{
|
||||
/// <summary>An IPv4 address formatted as a u_long.</summary>
|
||||
public uint S_addr;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="IN_ADDR"/> struct.</summary>
|
||||
/// <param name="v4addr">An IPv4 address.</param>
|
||||
public IN_ADDR(uint v4addr) { S_addr = v4addr; }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="IN_ADDR"/> struct.</summary>
|
||||
/// <param name="v4addr">An IPv4 address</param>
|
||||
/// <exception cref="ArgumentException">Byte array must have 4 items. - v4addr</exception>
|
||||
public IN_ADDR(byte[] v4addr)
|
||||
{
|
||||
if (v4addr == null && v4addr.Length != 4)
|
||||
throw new ArgumentException("Byte array must have 4 items.", nameof(v4addr));
|
||||
S_addr = BitConverter.ToUInt32(v4addr, 0);
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="IN_ADDR"/> struct.</summary>
|
||||
/// <param name="b1">The first byte.</param>
|
||||
/// <param name="b2">The second byte.</param>
|
||||
/// <param name="b3">The third byte.</param>
|
||||
/// <param name="b4">The fourth byte.</param>
|
||||
public IN_ADDR(byte b1, byte b2, byte b3, byte b4)
|
||||
{
|
||||
S_addr = b1 | (uint)b2 << 8 | (uint)b3 << 16 | (uint)b4 << 24;
|
||||
}
|
||||
|
||||
/// <summary>Gets the address represented as four bytes.</summary>
|
||||
/// <value>An IPv4 address formatted as four u_chars.</value>
|
||||
public byte[] S_un_b => BitConverter.GetBytes(S_addr);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="IN_ADDR"/> to <see cref="System.UInt32"/>.</summary>
|
||||
/// <param name="a">An IN_ADDR value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator uint(IN_ADDR a) => a.S_addr;
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="IN_ADDR"/> to <see cref="System.Int64"/>.</summary>
|
||||
/// <param name="a">An IN_ADDR value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator long(IN_ADDR a) => (long)a.S_addr;
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="IN_ADDR"/> to <see cref="System.Byte[]"/>.</summary>
|
||||
/// <param name="a">An IN_ADDR value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator byte[](IN_ADDR a) => BitConverter.GetBytes(a.S_addr);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="System.UInt32"/> to <see cref="IN_ADDR"/>.</summary>
|
||||
/// <param name="a">A UInt32 value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator IN_ADDR(uint a) => new IN_ADDR(a);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="System.Int64"/> to <see cref="IN_ADDR"/>.</summary>
|
||||
/// <param name="a">An Int64 value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator IN_ADDR(long a) => new IN_ADDR((uint)a);
|
||||
|
||||
/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
|
||||
/// <returns>A <see cref="System.String" /> that represents this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var b = S_un_b;
|
||||
return $"{b[0]}.{b[1]}.{b[2]}.{b[3]}";
|
||||
}
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential, Size = IN6_ADDR_SIZE)]
|
||||
public unsafe struct IN6_ADDR
|
||||
{
|
||||
private const int IN6_ADDR_SIZE = 16;
|
||||
|
||||
private fixed byte _u_bytes[IN6_ADDR_SIZE];
|
||||
|
||||
public IN6_ADDR(byte[] v6addr)
|
||||
{
|
||||
u_bytes = v6addr;
|
||||
}
|
||||
|
||||
public byte[] u_bytes
|
||||
{
|
||||
get
|
||||
{
|
||||
var v6addr = new byte[IN6_ADDR_SIZE];
|
||||
fixed (byte* src = _u_bytes, dest = v6addr)
|
||||
{
|
||||
for (var i = 0; i < IN6_ADDR_SIZE; i++)
|
||||
*(dest + i) = *(src + i);
|
||||
}
|
||||
return v6addr;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null) value = new byte[IN6_ADDR_SIZE];
|
||||
if (value.Length != IN6_ADDR_SIZE)
|
||||
throw new ArgumentException("Byte array must have 16 items.", nameof(value));
|
||||
fixed (byte* src = value, dest = _u_bytes)
|
||||
{
|
||||
for (var i = 0; i < IN6_ADDR_SIZE; i++)
|
||||
*(dest + i) = *(src + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ushort[] u_words
|
||||
{
|
||||
get
|
||||
{
|
||||
var v6addr = new ushort[IN6_ADDR_SIZE / 2];
|
||||
fixed (byte* pbytes = _u_bytes)
|
||||
fixed (ushort* dest = v6addr)
|
||||
{
|
||||
var src = (ushort*)pbytes;
|
||||
for (var i = 0; i < IN6_ADDR_SIZE / 2; i++)
|
||||
*(dest + i) = *(src + i);
|
||||
}
|
||||
return v6addr;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null) value = new ushort[IN6_ADDR_SIZE / 2];
|
||||
if (value.Length != IN6_ADDR_SIZE / 2)
|
||||
throw new ArgumentException("UInt16 array must have 8 items.", nameof(value));
|
||||
fixed (ushort* src = value)
|
||||
fixed (byte* pbytes = _u_bytes)
|
||||
{
|
||||
var dest = (ushort*)pbytes;
|
||||
for (var i = 0; i < IN6_ADDR_SIZE / 2; i++)
|
||||
*(dest + i) = *(src + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator IN6_ADDR(byte[] a) => new IN6_ADDR(a);
|
||||
|
||||
public static implicit operator byte[] (IN6_ADDR a) => a.u_bytes;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
const string numberFormat = "{0:x4}:{1:x4}:{2:x4}:{3:x4}:{4:x4}:{5:x4}:{6}.{7}.{8}.{9}";
|
||||
var m_Numbers = u_words;
|
||||
return string.Format(System.Globalization.CultureInfo.InvariantCulture, numberFormat,
|
||||
m_Numbers[0], m_Numbers[1], m_Numbers[2], m_Numbers[3], m_Numbers[4], m_Numbers[5],
|
||||
((m_Numbers[6] >> 8) & 0xFF), (m_Numbers[6] & 0xFF), ((m_Numbers[7] >> 8) & 0xFF), (m_Numbers[7] & 0xFF));
|
||||
}
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct SOCKADDR_IN
|
||||
{
|
||||
public ADDRESS_FAMILY sin_family;
|
||||
public ushort sin_port;
|
||||
public IN_ADDR sin_addr;
|
||||
public ulong sin_zero;
|
||||
|
||||
public SOCKADDR_IN(IN_ADDR addr, ushort port = 0)
|
||||
{
|
||||
sin_family = ADDRESS_FAMILY.AF_INET;
|
||||
sin_port = port;
|
||||
sin_addr = addr;
|
||||
sin_zero = 0;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{sin_addr}:{sin_port}";
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct SOCKADDR_IN6
|
||||
{
|
||||
public ADDRESS_FAMILY sin6_family;
|
||||
public ushort sin6_port;
|
||||
public uint sin6_flowinfo;
|
||||
public IN6_ADDR sin6_addr;
|
||||
public uint sin6_scope_id;
|
||||
|
||||
public SOCKADDR_IN6(IN6_ADDR addr, uint scope_id, ushort port = 0) : this(addr.u_bytes, scope_id, port) { }
|
||||
|
||||
public SOCKADDR_IN6(byte[] addr, uint scope_id, ushort port = 0)
|
||||
{
|
||||
if (addr.Length != 16) throw new ArgumentException();
|
||||
sin6_family = ADDRESS_FAMILY.AF_INET6;
|
||||
sin6_port = port;
|
||||
sin6_flowinfo = 0;
|
||||
sin6_addr = new byte[16];
|
||||
Array.ConstrainedCopy(addr, 0, sin6_addr, 0, addr.Length);
|
||||
sin6_scope_id = scope_id;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{sin6_addr}" + (sin6_scope_id == 0 ? "" : "%" + sin6_scope_id.ToString()) + $":{sin6_port}";
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct SOCKADDR_INET
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public SOCKADDR_IN Ipv4;
|
||||
[FieldOffset(0)]
|
||||
public SOCKADDR_IN6 Ipv6;
|
||||
[FieldOffset(0)]
|
||||
public ADDRESS_FAMILY si_family;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder($"{si_family}");
|
||||
if (si_family == ADDRESS_FAMILY.AF_INET)
|
||||
sb.Append(":").Append(Ipv4);
|
||||
else if (si_family == ADDRESS_FAMILY.AF_INET6)
|
||||
sb.Append(":").Append(Ipv6);
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SOCKET_ADDRESS
|
||||
{
|
||||
public IntPtr lpSockAddr;
|
||||
public int iSockaddrLength;
|
||||
|
||||
public SOCKADDR_INET GetSOCKADDR() => lpSockAddr.ToStructure<SOCKADDR_INET>();
|
||||
|
||||
public override string ToString() => GetSOCKADDR().ToString();
|
||||
}
|
||||
|
||||
[PInvokeData("winsock2.h")]
|
||||
public class SOCKADDR : SafeMemoryHandle<CoTaskMemoryMethods>
|
||||
{
|
||||
public SOCKADDR(uint addr, ushort port = 0) : this(BitConverter.GetBytes(addr), port) { }
|
||||
|
||||
public SOCKADDR(byte[] addr, ushort port = 0, uint scopeId = 0) :
|
||||
base(addr.Length == 4 ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6)))
|
||||
{
|
||||
if (addr.Length == 4)
|
||||
{
|
||||
var in4 = new SOCKADDR_IN(new IN_ADDR(addr), port);
|
||||
Marshal.StructureToPtr(in4, handle, false);
|
||||
}
|
||||
else if (addr.Length == 16)
|
||||
{
|
||||
var in6 = new SOCKADDR_IN6(addr, scopeId, port);
|
||||
Marshal.StructureToPtr(in6, handle, false);
|
||||
}
|
||||
else
|
||||
throw new ArgumentOutOfRangeException(nameof(addr));
|
||||
}
|
||||
|
||||
public byte[] sa_data => GetBytes(2, 14);
|
||||
public ushort sa_family => handle.ToStructure<ushort>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,356 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vanara.Extensions;
|
||||
using Vanara.InteropServices;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
|
||||
namespace Vanara.PInvoke.Tests
|
||||
{
|
||||
public static class IPAddressExt
|
||||
{
|
||||
public static System.Net.IPAddress Convert(this SOCKET_ADDRESS sockAddr)
|
||||
{
|
||||
switch ((ADDRESS_FAMILY)Marshal.ReadInt16(sockAddr.lpSockAddr))
|
||||
{
|
||||
case ADDRESS_FAMILY.AF_INET:
|
||||
return new System.Net.IPAddress((long)sockAddr.lpSockAddr.ToStructure<SOCKADDR_IN>().sin_addr);
|
||||
case ADDRESS_FAMILY.AF_INET6:
|
||||
return new System.Net.IPAddress(sockAddr.lpSockAddr.ToStructure<SOCKADDR_IN6>().sin6_addr);
|
||||
default:
|
||||
throw new Exception("Non-IP address family");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestFixture()]
|
||||
public class IpHlpApiTests
|
||||
{
|
||||
private static IP_ADAPTER_ADDRESSES primaryAdapter;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
primaryAdapter = GetAdaptersAddresses(GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_GATEWAYS).FirstOrDefault(r => r.OperStatus == IF_OPER_STATUS.IfOperStatusUp && r.TunnelType == TUNNEL_TYPE.TUNNEL_TYPE_NONE);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AddDeleteIPAddressTest()
|
||||
{
|
||||
var newIp = new IN_ADDR(192, 168, 0, 252);
|
||||
var mask = new IN_ADDR(255, 255, 255, 0);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Assert.That(AddIPAddress(newIp, mask, primaryAdapter.IfIndex, out var ctx, out var inst), Is.Zero);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
Assert.That(DeleteIPAddress(ctx), Is.Zero);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateSetDeleteIpNetEntryTest()
|
||||
{
|
||||
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 MIB_IPNET_TABLE2 t1), Is.Zero);
|
||||
foreach (var r in t1) Debug.WriteLine(r);
|
||||
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 EnableUnenableRouterTest()
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAdapterIndexTest()
|
||||
{
|
||||
const string prefix = "\\DEVICE\\TCPIP_";
|
||||
Assert.That(GetAdapterIndex(prefix + primaryAdapter.AdapterName, out var idx), Is.Zero);
|
||||
Assert.That(idx, Is.EqualTo(primaryAdapter.IfIndex));
|
||||
Assert.That(GetAdapterIndex(primaryAdapter.AdapterName, out idx), Is.EqualTo(Win32Error.ERROR_FILE_NOT_FOUND));
|
||||
Assert.That(GetAdapterIndex("__Bogus**__", out idx), Is.EqualTo(Win32Error.ERROR_INVALID_PARAMETER));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAdaptersAddressesTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
foreach (var addrs in GetAdaptersAddresses(GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_PREFIX, ADDRESS_FAMILY.AF_UNSPEC))
|
||||
{
|
||||
Debug.WriteLine($"{addrs.IfIndex}) {addrs.AdapterName} ({addrs.FriendlyName});{addrs.Description};MAC:{PhysicalAddressToString(addrs.PhysicalAddress)}");
|
||||
Debug.WriteLine(" Uni:" + string.Join(";", addrs.UnicastAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" Any:" + string.Join(";", addrs.AnycastAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" MCS:" + string.Join(";", addrs.MulticastAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" DNS:" + string.Join(";", addrs.DnsServerAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" Prfx:" + string.Join(";", addrs.Prefixes.Select(a => a.Address)));
|
||||
Debug.WriteLine(" WINS:" + string.Join(";", addrs.WinsServerAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" GTWY:" + string.Join(";", addrs.GatewayAddresses.Select(a => a.Address)));
|
||||
Debug.WriteLine(" Sufx:" + string.Join(";", addrs.DnsSuffixes.Select(a => a.String)));
|
||||
}
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetAdaptersInfoTest()
|
||||
{
|
||||
uint len = 15000;
|
||||
var mem = new SafeCoTaskMemHandle((int)len);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Assert.That(GetAdaptersInfo((IntPtr)mem, ref len), Is.Zero);
|
||||
Assert.That(((IntPtr)mem).LinkedListToIEnum<IP_ADAPTER_INFO>(i => i.Next), Is.Not.Empty);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBestInterfaceTest()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var gw = (uint)primaryAdapter.GatewayAddresses.Select(a => a.Address.Convert()).FirstOrDefault().Address;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
Assert.That(gw, Is.Not.Zero);
|
||||
Assert.That(GetBestInterface(gw, out var idx), Is.Zero);
|
||||
Assert.That(idx, Is.EqualTo(primaryAdapter.IfIndex));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBestInterfaceExTest()
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var gw = primaryAdapter.GatewayAddresses.Select(a => a.Address.Convert()).FirstOrDefault();
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
var sa = new SOCKADDR(gw.GetAddressBytes(), 0, gw.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? 0 : (uint)gw.ScopeId);
|
||||
Assert.That(GetBestInterfaceEx(sa, out var idx), Is.Zero);
|
||||
Assert.That(idx, Is.EqualTo(primaryAdapter.IfIndex));
|
||||
}
|
||||
|
||||
[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, ref 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,113)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetExtendedTcpTableTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t1 = GetExtendedTcpTable<MIB_TCPTABLE>(TCP_TABLE_CLASS.TCP_TABLE_BASIC_ALL);
|
||||
Assert.That(t1.dwNumEntries, Is.GreaterThan(0));
|
||||
var t2 = GetExtendedTcpTable<MIB_TCPTABLE>(TCP_TABLE_CLASS.TCP_TABLE_BASIC_CONNECTIONS);
|
||||
Assert.That(t2.dwNumEntries, Is.GreaterThan(0));
|
||||
var t3 = GetExtendedTcpTable<MIB_TCPTABLE>(TCP_TABLE_CLASS.TCP_TABLE_BASIC_LISTENER);
|
||||
Assert.That(t3.dwNumEntries, Is.GreaterThan(0));
|
||||
var t4 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_ALL);
|
||||
Assert.That(t4.dwNumEntries, Is.GreaterThan(0));
|
||||
var t5 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_ALL, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t5.dwNumEntries, Is.GreaterThan(0));
|
||||
var t6 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_CONNECTIONS);
|
||||
Assert.That(t6.dwNumEntries, Is.GreaterThan(0));
|
||||
var t7 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_CONNECTIONS, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t7.dwNumEntries, Is.GreaterThan(0));
|
||||
var t8 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_LISTENER);
|
||||
Assert.That(t8.dwNumEntries, Is.GreaterThan(0));
|
||||
var t9 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_LISTENER, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t9.dwNumEntries, Is.GreaterThan(0));
|
||||
var t10 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
|
||||
Assert.That(t10.dwNumEntries, Is.GreaterThan(0));
|
||||
var t11 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t11.dwNumEntries, Is.GreaterThan(0));
|
||||
var t12 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_CONNECTIONS);
|
||||
Assert.That(t12.dwNumEntries, Is.GreaterThan(0));
|
||||
var t13 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_CONNECTIONS, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t13.dwNumEntries, Is.GreaterThan(0));
|
||||
var t14 = GetExtendedTcpTable<MIB_TCPTABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_LISTENER);
|
||||
Assert.That(t14.dwNumEntries, Is.GreaterThan(0));
|
||||
var t15 = GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_PID>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_LISTENER, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t15.dwNumEntries, Is.GreaterThan(0));
|
||||
}, Throws.Nothing);
|
||||
Assert.That(() => GetExtendedTcpTable<MIB_TCPTABLE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_ALL), Throws.InvalidOperationException);
|
||||
Assert.That(() => GetExtendedTcpTable<MIB_TCP6TABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_ALL), Throws.InvalidOperationException);
|
||||
Assert.That(() => GetExtendedTcpTable<MIB_TCPTABLE_OWNER_MODULE>(TCP_TABLE_CLASS.TCP_TABLE_OWNER_MODULE_ALL, ADDRESS_FAMILY.AF_INET6), Throws.InvalidOperationException);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetExtendedUdpTableTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t1 = GetExtendedUdpTable<MIB_UDPTABLE>(UDP_TABLE_CLASS.UDP_TABLE_BASIC);
|
||||
Assert.That(t1.dwNumEntries, Is.GreaterThan(0));
|
||||
var t4 = GetExtendedUdpTable<MIB_UDPTABLE_OWNER_MODULE>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_MODULE);
|
||||
Assert.That(t4.dwNumEntries, Is.GreaterThan(0));
|
||||
var t5 = GetExtendedUdpTable<MIB_UDP6TABLE_OWNER_MODULE>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_MODULE, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t5.dwNumEntries, Is.GreaterThan(0));
|
||||
var t10 = GetExtendedUdpTable<MIB_UDPTABLE_OWNER_PID>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
|
||||
Assert.That(t10.dwNumEntries, Is.GreaterThan(0));
|
||||
var t11 = GetExtendedUdpTable<MIB_UDP6TABLE_OWNER_PID>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID, ADDRESS_FAMILY.AF_INET6);
|
||||
Assert.That(t11.dwNumEntries, Is.GreaterThan(0));
|
||||
}, Throws.Nothing);
|
||||
Assert.That(() => GetExtendedUdpTable<MIB_UDPTABLE>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_MODULE), Throws.InvalidOperationException);
|
||||
Assert.That(() => GetExtendedUdpTable<MIB_UDP6TABLE_OWNER_MODULE>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_MODULE), Throws.InvalidOperationException);
|
||||
Assert.That(() => GetExtendedUdpTable<MIB_UDPTABLE_OWNER_MODULE>(UDP_TABLE_CLASS.UDP_TABLE_OWNER_MODULE, ADDRESS_FAMILY.AF_INET6), Throws.InvalidOperationException);
|
||||
}
|
||||
|
||||
[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 GetIfEntry2ExTest()
|
||||
{
|
||||
return;
|
||||
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 GetIfTableTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t = GetIfTable();
|
||||
Assert.That(t.dwNumEntries, Is.GreaterThan(0));
|
||||
foreach (var r in t) ;
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIfTable2Test()
|
||||
{
|
||||
var e = GetIfTable2(out var itbl);
|
||||
Assert.That(e.Succeeded);
|
||||
Assert.That(itbl.Elements, Is.Not.Empty);
|
||||
itbl.Dispose();
|
||||
Assert.That(itbl.IsInvalid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIfTable2ExTest()
|
||||
{
|
||||
var e = GetIfTable2Ex(MIB_IF_TABLE_LEVEL.MibIfTableNormal, out var itbl);
|
||||
Assert.That(e.Succeeded);
|
||||
Assert.That(itbl.Elements, Is.Not.Empty);
|
||||
itbl.Dispose();
|
||||
Assert.That(itbl.IsInvalid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetInterfaceInfoTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t = GetInterfaceInfo();
|
||||
Assert.That(t.NumAdapters, Is.GreaterThan(0));
|
||||
foreach (var r in t) ;
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIpAddrTableTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t = GetIpAddrTable();
|
||||
Assert.That(t.dwNumEntries, Is.GreaterThan(0));
|
||||
foreach (var r in t) ;
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetNetworkParamsTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var t = GetNetworkParams();
|
||||
Assert.That(t.HostName, Is.Not.Null);
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPerAdapterInfoTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var info = GetPerAdapterInfo(primaryAdapter.IfIndex);
|
||||
Assert.That(info.DnsServerList, Is.Not.Empty);
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetUniDirectionalAdapterInfoTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var info = GetUniDirectionalAdapterInfo();
|
||||
Assert.That(info.Address.Length, Is.GreaterThanOrEqualTo(0));
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NotifyAddrChangeTest()
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NotifyRouteChangeTest()
|
||||
{
|
||||
Assert.Fail();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IpReleaseRenewAddressTest()
|
||||
{
|
||||
var i = GetInterfaceInfo().First();
|
||||
Assert.That(IpReleaseAddress(ref i), Is.Zero);
|
||||
Assert.That(IpRenewAddress(ref i), Is.Zero);
|
||||
var x = new IP_ADAPTER_INDEX_MAP() { Name = "Bogus" };
|
||||
Assert.That(IpReleaseAddress(ref x), Is.EqualTo(Win32Error.ERROR_INVALID_PARAMETER));
|
||||
Assert.That(IpRenewAddress(ref x), Is.EqualTo(Win32Error.ERROR_INVALID_PARAMETER));
|
||||
}
|
||||
|
||||
[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 SendARPTest()
|
||||
{
|
||||
Assert.That(() =>
|
||||
{
|
||||
var gw = primaryAdapter.GatewayAddresses.Select(a => a.Address.Convert().GetAddressBytes()).FirstOrDefault();
|
||||
var mac = SendARP(new IN_ADDR(gw));
|
||||
Assert.That(mac.Length, Is.EqualTo(6));
|
||||
Assert.That(mac, Has.Some.Not.EqualTo(0));
|
||||
}, Throws.Nothing);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,6 +41,10 @@
|
|||
<Reference Include="Microsoft.Pex.Framework, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.VisualStudio.QualityTools.UnitTestFramework.Updated.15.0.26228\lib\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.2.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -82,6 +86,7 @@
|
|||
<Compile Include="PInvoke\DwmApi\DwmApiTests.cs" />
|
||||
<Compile Include="PInvoke\Gdi32\Gdi32Tests.cs" />
|
||||
<Compile Include="PInvoke\InteropServices\SafeLocalHandleTests.cs" />
|
||||
<Compile Include="PInvoke\IpHlpApi\IpHlpApiTests.cs" />
|
||||
<Compile Include="PInvoke\Kernel32\Kernel32Tests.cs" />
|
||||
<Compile Include="PInvoke\NetApi\NetApi32Tests.cs" />
|
||||
<Compile Include="PInvoke\NetApi\NetListMgrTests.cs" />
|
||||
|
@ -142,6 +147,10 @@
|
|||
<Project>{e186aff0-bc70-4776-8bee-9fdae108f4eb}</Project>
|
||||
<Name>Vanara.PInvoke.Gdi32</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PInvoke\IpHlpApi\Vanara.PInvoke.IpHlpApi.csproj">
|
||||
<Project>{bbd8ce8d-31d2-4dfb-8d96-46825c09c7f1}</Project>
|
||||
<Name>Vanara.PInvoke.IpHlpApi</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\PInvoke\Kernel32\Vanara.PInvoke.Kernel32.csproj">
|
||||
<Project>{842d436f-598c-47d7-b5aa-12399f8ccfe9}</Project>
|
||||
<Name>Vanara.PInvoke.Kernel32</Name>
|
||||
|
@ -226,6 +235,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.VisualStudio.QualityTools.UnitTestFramework.Updated" version="15.0.26228" targetFramework="net461" />
|
||||
<package id="MSTest.TestAdapter" version="1.2.0" targetFramework="net461" />
|
||||
<package id="MSTest.TestFramework" version="1.2.0" targetFramework="net461" />
|
||||
</packages>
|
Loading…
Reference in New Issue