Example #1
0
        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));
        }
Example #2
0
        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));
        }
Example #3
0
            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);
            }
Example #4
0
        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));
        }
Example #5
0
        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)));
        }
Example #6
0
        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
        }
Example #7
0
        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);
Example #8
0
        /// <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);
        }
Example #9
0
        /// <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));
        }
Example #10
0
 static bool HasPhysicalAddress(MIB_IPNET_ROW2 row)
 {
     return(row.PhysicalAddressLength == PHYSICAL_ADDRESS_LENGTH && row.PhysicalAddress.Any(b => b != 0));
 }
Example #11
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);
    }
Example #12
0
 private static extern int ResolveIpNetEntry2(ref MIB_IPNET_ROW2 Row,
                                              ref SOCKADDR_INET SourceAddress);