【问题标题】:Vb.net : Get MAC Address of only internal DeviceVb.net:仅获取内部设备的 MAC 地址
【发布时间】:2015-05-28 17:15:03
【问题描述】:

我们正在使用以下方法获取 MAC 地址。

Imports System.Net.NetworkInformation
Dim nic As NetworkInterface = Nothing
Dim max() As String
Dim i As Integer
Dim nics() As NetworkInterface = NetworkInterface.GetAllNetworkInterfaces()
For Each nic In nics
    max(i) = nic.GetPhysicalAddress().ToString
    i = i + 1
Next

使用上述代码,我们可以成功获取所有 MAC 地址,包括加密狗的 MAC 地址[Plug & Play Device]。但我们想要的只是内部设备的 MAC 地址。

我们如何才能获得可以称为永久 MAC 地址的内部设备的 MAC 地址?

【问题讨论】:

  • 内部 LAN MAC 地址是什么意思?
  • 我的意思是,内部设备的 MAC 地址可能是永久的。而不是任何即插即用设备。
  • 你已经得到了各个系统的MAC地址知道吗?
  • 我们正在获取所有 MAC 地址,包括即插即用设备。我们只想获取更可能是永久性的内部设备的 MAC 地址。
  • MAC怎么变了?!

标签: vb.net lan mac-address


【解决方案1】:

我假设您 LAN 中的端点获得一个私有 IP(作为 DHCP 响应),而加密狗(一个外部 USB GSM 调制解调器)获得一个全局 IP 地址。

私有 IP 地址的标准范围:

  • A 类网络10.0.0.0 - 10.255.255.255
  • B 类网络172.16.0.0 - 172.31.255.255
  • C 类 网络192.168.0.0 - 192.168.255.255

您可以使用正则表达式来确定每个接口的当前 IP 地址是否为私有。

你可以辅助这个正则表达式(source):

(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)

例如,这是VB.net中上述的基本正则表达式匹配:

Imports System.Net.NetworkInformation
Imports System.Text.RegularExpressions

Module VBModule

    Sub Main()
        Dim nic As NetworkInterface = Nothing
        Dim max() As String
        Dim nics() As NetworkInterface = NetworkInterface.GetAllNetworkInterfaces()
        For Each nic In nics

            Dim ip = nic.GetIPProperties().UnicastAddresses(0).Address.ToString

            Dim regex As Regex = New Regex("(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)")
            Dim match As Match = regex.Match(ip)

            If match.Success Then
                Console.WriteLine(ip)
                Console.WriteLine(nic.GetPhysicalAddress().ToString)     
            End If

        Next

    End Sub

End Module

在行动中看到它http://goo.gl/i9N6T9:

【讨论】:

  • 没有一个 MAC 与 IP 匹配(如果匹配。成功)。事实上,每个事物的 IP 都是这样的 --> "fe80::e997:bc09:37a4:c67c%12"
  • 这没有回答问题。请记住,答案必须适用于其他用例,而不仅仅是该问题的用例。
  • 虽然这种方法每次需要为静态网络配置 NIC 时都可以使用......恕我直言,这非常麻烦
【解决方案2】:

下面的代码返回最常见的持久接口(LAN 或 WLAN)的 MAC 地址。这通常可以完成工作。您可以将不同的接口类型添加到比较数组中。

Public Function GetDurableMACAddresses() As IEnumerable(Of String)
    Return From nic In NetworkInterface.GetAllNetworkInterfaces()
           Where ({NetworkInterfaceType.Ethernet, NetworkInterfaceType.Wireless80211}).Contains(nic.NetworkInterfaceType)
           Select macaddress = nic.GetPhysicalAddress().ToString()
End Function

【讨论】:

    【解决方案3】:

    以下函数可用于获取内部MAC地址:

    Private Function getMacAddress() As String
        Try
            Dim adapters As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
            Dim adapter As NetworkInterface
            Dim myMac As String = String.Empty
    
            For Each adapter In adapters
                Select Case adapter.NetworkInterfaceType
                    'Exclude Tunnels, Loopbacks and PPP
                    Case NetworkInterfaceType.Tunnel, NetworkInterfaceType.Loopback, NetworkInterfaceType.Ppp
                    Case Else
                        If Not adapter.GetPhysicalAddress.ToString = String.Empty And Not adapter.GetPhysicalAddress.ToString = "00000000000000E0" Then
                            myMac = adapter.GetPhysicalAddress.ToString
                            Exit For
                        End If
    
                End Select
            Next adapter
    
            Return myMac
        Catch ex As Exception
            Return String.Empty
        End Try
    End Function
    

    它使用网络信息库,可以使用Imports System.Net.NetworkInformation 导入。上述代码还排除了 VPN、隧道、网桥等。

    为了测试这一点,我制作了一个示例项目 can be downloaded here,并给出了正确的 MAC 地址输出:

    系统的媒体访问控制 (MAC) 地址为 142D27B97FD6

    这是通过查看我的无线适配器属性测试的正确 MAC 地址:

    【讨论】:

    • 你如何确定 MAC 的 index(1) 是内部设备的 MAC?那么 index(0) 处的地址呢?
    • @SHREE 这是适配器编号。由于我提供的屏幕截图,我确定这是内部设备的 MAC 地址。更新了代码,修复了 MAC 地址中的小错误。
    • @cybermoneky 系统是否有可能没有 MAC?通常第 0 个索引会是什么?
    • @SHREE 如果系统有网络适配器,它将始终有一个 MAC 地址。如果没有,Try Catch 语句将捕获错误并返回一个空字符串。你总是可以有更多的错误处理,例如MsgBox,以通知用户他们没有安装网络适配器。
    • @cybermonkey 当我插入加密狗并运行程序时,我得到 MAC -“E89A8FA35AD0”,当我移除它时,我得到 MAC -“”D0DF9AC58E03”。但是加密狗的 MAC 是“001E101F0000”外部设备 MAC 始终位于第 0 位?
    【解决方案4】:

    如果没有关于 NIC 本身的其他信息,就无法识别“内部”的 - 但是:如果您构建一个 CLR (C++) - 库调用本机函数来检索必要的信息,例如“ NIC 位于哪条总线上”,您也许能够收集有关 NIC 的分组信息。

    提示:很容易在您的 VB.NET 应用程序中使用 CLR 库...只需添加项目,导入它的 namespace 就可以了:https://msdn.microsoft.com/en-us/library/ms235638%28v=vs.90%29.aspx

    首先,你需要通过SetupDiGetClassDevs查询所有网卡,参数GUID_DEVCLASS_NET,然后用SetupDiEnumDeviceInfo枚举该列表,属性DEVPKEY_Device_BusTypeGuid是你感兴趣的,你可以检索它通过SetupDiGetDeviceProperty - 在枚举完所有设备之后,您现在可以将它们分组为总线类型,其中至少一个是 USB 总线类型。

    可以通过here、here 和here 列出的所有其他属性进行附加过滤。

    嗯,这是相当昂贵的解决方案,但它将实际上使您能够过滤掉“内部”网卡,祝您好运 - 随时提出任何问题。

    edit :显然还有一个用于 USB 设备的 GUID,所以如果您只需检索属性 DEVPKEY_DeviceInterface_ClassGuid 并将其与 GUID_DEVINTERFACE_USB_DEVICE 进行比较,您就可以过滤掉 USB-NIC苍蝇,不需要额外的分组......这看起来很有希望

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-22
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多