예제 #1
0
        /// Obtains the best MAC address found on local network interfaces.
        /// Generally speaking, an active network interface used on public
        /// networks is better than a local network interface.
        /// <returns>byte array containing a MAC. null if no MAC can be found.</returns>
        public static byte[] GetBestAvailableMac()
        {
            // Find the best MAC address available.
            byte[]    bestMacAddr  = NotFound;
            IPAddress bestInetAddr = IPAddress.Loopback;

            // Retrieve the list of available network interfaces.
            Dictionary <NetworkInterface, IPAddress> ifaces = new Dictionary <NetworkInterface, IPAddress>();

            try
            {
                foreach (var iface in NetworkInterface.GetAllNetworkInterfaces())
                {
                    // Use the interface with proper INET addresses only.
                    var addrs = iface.GetIPProperties().UnicastAddresses;
                    if ((uint)addrs.Count > 0u)
                    {
                        var addressInfo = addrs.First();
                        if (!IPAddress.IsLoopback(addressInfo.Address))
                        {
                            ifaces.Add(iface, addressInfo.Address);
                        }
                    }
                }
            }
            catch (SocketException e)
            {
                logger.FailedToRetrieveTheListOfAvailableNetworkInterfaces(e);
            }

            foreach (var entry in ifaces)
            {
                NetworkInterface iface    = entry.Key;
                IPAddress        inetAddr = entry.Value;
                // todo: netty has a check for whether interface is virtual but it always returns false. There is no equivalent in .NET
                byte[] macAddr = iface.GetPhysicalAddress()?.GetAddressBytes();
                bool   replace = false;
                uint   res     = (uint)CompareAddresses(bestMacAddr, macAddr);
                if (res > SharedConstants.TooBigOrNegative) // res < 0
                {
                    // Found a better MAC address.
                    replace = true;
                }
                else if (0u >= res)
                {
                    // Two MAC addresses are of pretty much same quality.
                    res = (uint)CompareAddresses(bestInetAddr, inetAddr);
                    if (res > SharedConstants.TooBigOrNegative) // res < 0
                    {
                        // Found a MAC address with better INET address.
                        replace = true;
                    }
                    else if (0u >= res)
                    {
                        // Cannot tell the difference.  Choose the longer one.
                        if ((uint)bestMacAddr.Length < (uint)macAddr.Length)
                        {
                            replace = true;
                        }
                    }
                }

                if (replace)
                {
                    bestMacAddr  = macAddr;
                    bestInetAddr = inetAddr;
                }
            }

            if (bestMacAddr == NotFound)
            {
                return(null);
            }

            switch (bestMacAddr.Length)
            {
            case 6:     // EUI-48 - convert to EUI-64
                var newAddr = new byte[MacAddressLength];
                Array.Copy(bestMacAddr, 0, newAddr, 0, 3);
                newAddr[3] = 0xFF;
                newAddr[4] = 0xFE;
                Array.Copy(bestMacAddr, 3, newAddr, 5, 3);
                bestMacAddr = newAddr;
                break;

            default:     // Unknown
                bestMacAddr = bestMacAddr.Slice(0, Math.Min(bestMacAddr.Length, MacAddressLength));
                break;
            }

            return(bestMacAddr);
        }