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)); }
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)); }
static bool HasVal(MIB_IPNET_ROW2_Unmanaged *tr, MIB_IPNET_ROW2 r, uint numEntries) { for (uint i = 0; i < numEntries; i++, tr++) { if (tr->Address.Ipv4.sin_addr == r.Address.Ipv4.sin_addr && tr->InterfaceIndex == r.InterfaceIndex && CompareArrays(tr->PhysicalAddress, r.PhysicalAddress)) { return(true); } } return(false); }
public void GetIpNetEntryTable2Test() { 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)); }
static bool IsMatchingRow(IPAddress remoteAddress, MIB_IPNET_ROW2 row) { byte[] addressBytes; switch (row.Address.si_family) { case AF_INET: addressBytes = row.Address.Ipv4.Address; break; case AF_INET6: addressBytes = row.Address.Ipv6.Address; break; default: return(false); } return(remoteAddress.Equals(new IPAddress(addressBytes))); }
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 }
public unsafe void CreateSetDeleteIpNetEntry2UnmanagedPointerTest() { var target = new IN_ADDR(192, 168, 0, 202); Assert.That(GetBestRoute(target, 0, out var fwdRow), ResultIs.Successful); var mibrow = new MIB_IPNET_ROW2(new SOCKADDR_IN(target), fwdRow.dwForwardIfIndex, SendARP(target)); Assert.That(GetIpNetTable2_Unmanaged(ADDRESS_FAMILY.AF_INET, out var t1), ResultIs.Successful); if (HasVal(t1.AsUnmanagedArrayPointer(), mibrow, t1.NumEntries)) { Assert.That(DeleteIpNetEntry2(ref mibrow), ResultIs.Successful); } Assert.That(CreateIpNetEntry2(ref mibrow), ResultIs.Successful); GetIpNetTable2_Unmanaged(ADDRESS_FAMILY.AF_INET, out var t2); Assert.That(HasVal(t2.AsUnmanagedArrayPointer(), mibrow, t1.NumEntries), Is.True); Assert.That(DeleteIpNetEntry2(ref mibrow), ResultIs.Successful); GetIpNetTable2_Unmanaged(ADDRESS_FAMILY.AF_INET, out var t3); Assert.That(HasVal(t3.AsUnmanagedArrayPointer(), mibrow, t1.NumEntries), Is.False);
/// <summary> /// Tries to find a matching row in the IP neighbor table for the <paramref name="remoteAddress"/>. /// </summary> /// <param name="remoteAddress">The romote IP address.</param> /// <param name="entry">If successful, the matching row in the neighbor table for the <paramref name="remoteAddress"/>.</param> /// <returns><c>true</c> if a matching row was found.</returns> static bool TryGetEntryFromNetTable(IPAddress remoteAddress, out MIB_IPNET_ROW2 entry) { //LogRows(); ushort family = remoteAddress.AddressFamily == AddressFamily.InterNetworkV6 ? AF_INET6 : AF_INET; var rows = GetIPNetTableRows(family); if (rows != null) { foreach (var row in rows) { if (HasPhysicalAddress(row) && IsMatchingRow(remoteAddress, row)) { entry = row; return(true); } } } entry = default(MIB_IPNET_ROW2); return(false); }
/// <summary> /// Tries to resolve the hardware address for the <paramref name="remoteAddress"/>. /// </summary> /// <param name="localAddress">The address of the local endpoint to use to send the resolution request.</param> /// <param name="remoteAddress">The romote IP address to resolve.</param> /// <param name="entry">If successful, an <see cref="MIB_IPNET_ROW2"/> for the <paramref name="remoteAddress"/>.</param> /// <returns></returns> static bool TryResolveIPNetEntry(IPAddress localAddress, IPAddress remoteAddress, out MIB_IPNET_ROW2 entry) { //Set up target address entry = new MIB_IPNET_ROW2(); entry.PhysicalAddress = new byte[32]; entry.State = NL_NEIGHBOR_STATE.NlnsReachable; //Either InterfaceLuid or InterfaceIndex must be filled entry.InterfaceIndex = (uint)GetAdapterIndex(localAddress); //Populate the IP address depending on whether the address is IPv4 or IPv6 if (remoteAddress.AddressFamily == AddressFamily.InterNetwork) { entry.Address.Ipv4.sin_family = AF_INET; entry.Address.Ipv4.Address = remoteAddress.GetAddressBytes(); } else { entry.Address.Ipv6.sin6_family = AF_INET6; entry.Address.Ipv6.Address = remoteAddress.GetAddressBytes(); } //Set up the local address to use to resolve the remote address byte[] localAddressBytes = localAddress.GetAddressBytes(); SOCKADDR_INET sourceAddress = new SOCKADDR_INET(); if (localAddress.AddressFamily == AddressFamily.InterNetworkV6) { sourceAddress.Ipv6.Address = localAddressBytes; } else { sourceAddress.Ipv4.Address = localAddressBytes; } //Try and resolve the address int hr = NativeMethods.ResolveIpNetEntry2(ref entry, ref sourceAddress); Marshal.ThrowExceptionForHR(hr); return(hr == 0 && HasPhysicalAddress(entry)); }
static bool HasPhysicalAddress(MIB_IPNET_ROW2 row) { return(row.PhysicalAddressLength == PHYSICAL_ADDRESS_LENGTH && row.PhysicalAddress.Any(b => b != 0)); }
public static byte[] GetMacFromIPv6Address(IPAddress ipv6Address) { if (ipv6Address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6) { throw new ArgumentException( "The IPAddress provided was not an IPv6 address."); } //set up target address MIB_IPNET_ROW2 row2 = new MIB_IPNET_ROW2(); row2.PhysicalAddress = new byte[32]; row2.State = NL_NEIGHBOR_STATE.NlnsReachable; row2.Address.Ipv6.sin6_addr.Byte = new byte[16]; row2.Address.Ipv6.sin6_family = AF_INET6; row2.Address.Ipv6.sin6_flowinfo = 0; row2.Address.Ipv6.sin6_port = 0; row2.Address.Ipv6.sin6_scope_id = Convert.ToUInt32(ipv6Address.ScopeId); byte[] ipv6AddressBytes = ipv6Address.GetAddressBytes(); System.Buffer.BlockCopy(ipv6AddressBytes, 0, row2.Address.Ipv6.sin6_addr.Byte, 0, ipv6AddressBytes.Length); //get this machine's local IPv6 address SOCKADDR_INET sock = new SOCKADDR_INET(); sock.Ipv6.sin6_family = AF_INET6; sock.Ipv6.sin6_flowinfo = 0; sock.Ipv6.sin6_port = 0; sock.Ipv6.sin6_addr.Byte = new byte[16]; IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName()); foreach (IPAddress address in addresses) { if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { sock.Ipv6.sin6_addr.Byte = address.GetAddressBytes(); break; } } foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces()) { if (netInterface.OperationalStatus == OperationalStatus.Up) { row2.InterfaceIndex = (uint)clsNetworkStats.GetInterfaceIndex( netInterface.Description); break; } } int result = ResolveIpNetEntry2(ref row2, ref sock); if (result != 0) { throw new ApplicationException( "The call to ResolveIpNetEntry2 failed; error number: " + result.ToString()); } byte[] macAddress = new byte[6]; System.Buffer.BlockCopy(row2.PhysicalAddress, 0, macAddress, 0, 6); return(macAddress); }
private static extern int ResolveIpNetEntry2(ref MIB_IPNET_ROW2 Row, ref SOCKADDR_INET SourceAddress);