如何区分虚拟 MAC 地址和物理 MAC 地址

huangapple go评论70阅读模式
英文:

How to distinguish virtual MAC address and physical MAC address

问题

我想使用MAC地址生成一个唯一的ID,但是通过net.Interfaces()在服务器上有虚拟MAC地址和物理MAC地址。我该如何区分它们?我不想使用虚拟的那些。

这是我使用net.Interfaces()得到的结果:

[
{1 65536 lo  up|loopback} 
{2 1450 eth0 fa:16:3e:12:39:9c up|broadcast|multicast} 
{3 1500 docker0 02:42:b4:9d:fb:54 up|broadcast|multicast} 
{4 1500 br-dbabe92ec60c 02:42:e3:7f:96:13 up|broadcast|multicast} 
{6 1500 veth4bb5809 e6:a3:38:2f:f7:e4 up|broadcast|multicast} 
{8 1500 vethcada9d2 16:8c:c9:37:8d:76 up|broadcast|multicast} 
{10 1500 veth1e10eaa da:37:f9:9a:1d:10 up|broadcast|multicast}
]

我找不到它们之间的区别。

英文:

I want to generate an unique id using MAC address, but there are virtual MAC addresses and physical MAC addresses in a server through net.Interfaces(). How can I distinguish them? I do not want to use the virtual ones.

Here is what I get using net.Interfaces()

[[
{1 65536 lo  up|loopback} 
{2 1450 eth0 fa:16:3e:12:39:9c up|broadcast|multicast} 
{3 1500 docker0 02:42:b4:9d:fb:54 up|broadcast|multicast} 
{4 1500 br-dbabe92ec60c 02:42:e3:7f:96:13 up|broadcast|multicast} 
{6 1500 veth4bb5809 e6:a3:38:2f:f7:e4 up|broadcast|multicast} 
{8 1500 vethcada9d2 16:8c:c9:37:8d:76 up|broadcast|multicast} 
{10 1500 veth1e10eaa da:37:f9:9a:1d:10 up|broadcast|multicast}
]]

I can not find the differences between them.

答案1

得分: 2

以下是翻译好的内容:

package main

import (
	"fmt"
	"net"
	"os"
)

func main(){

	ifaces, err := net.Interfaces()
	if err != nil {
		fmt.Println(err)
		os.Exit(0)
	}

	for _, iface := range ifaces {		
		// 如果MAC地址的第一个八位中的第二个最低有效位为1,
		// 则它是一个本地管理的地址,我们将其省略。
		// 如果HardwareAddr为nil,则是一个环回接口,所以省略。
		if (iface.HardwareAddr==nil) || (iface.HardwareAddr[0]&2 == 2) {
			continue
		}
		fmt.Println(iface)
	}

}

我确定你有使用MAC地址作为UUID的原因,但是如果我不提到的话,我会感到遗憾,你可能想考虑使用类似UUIDv4的方法。

英文:

Something like below should work. The comment in the code explains why as does this faq.

package main

import (
	"fmt"
	"net"
	"os"
)

func main(){

	ifaces, err := net.Interfaces()
	if err != nil {
		fmt.Println(err)
		os.Exit(0)
	}

	for _, iface := range ifaces {		
		// If the second least significant bit of the first octet of the MAC address is 1,
		// then it's a locally administered address so we omit it.
		// If HardwareAddr is nil, it's a loopbook, so omit.
		if (iface.HardwareAddr==nil) || (iface.HardwareAddr[0]&2 == 2) {
			continue
		}
		fmt.Println(iface)
	}

}

I'm sure you have a reason you want to use the MAC for a uuid, but I'd be remiss if I did not mention you may want to look at doing something like UUIDv4.

答案2

得分: 1

如果硬件设备已在https://macvendors.com/注册,则可以使用其API。

我已将另一个MAC地址添加到您的数据中,因为上述地址似乎都没有被识别为“真实”硬件。

package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
	"time"
)

type idata struct {
	index int
	mtu   int
	name  string
	mac   string
	flags string
}

func main() {

	data := []idata{
		{1, 65536, "lo", "", "up|loopback"},
		{2, 1450, "eth0", "", "up|broadcast|multicast"},
		{3, 1500, "docker0", "02:42:b4:9d:fb:54", "up|broadcast|multicast"},
		{4, 1500, "br-dbabe92ec60c", "02:42:e3:7f:96:13", "up|broadcast|multicast"},
		{6, 1500, "veth4bb5809", "e6:a3:38:2f:f7:e4", "up|broadcast|multicast"},
		{8, 1500, "vethcada9d2", "16:8c:c9:37:8d:76", "up|broadcast|multicast"},
		{10, 1500, "veth1e10eaa", "da:37:f9:9a:1d:10", "up|broadcast|multicast"},
		{11, 1500, "en8", "00:e0:4c:36:01:d4", "up|broadcast|multicast"},
	}

	for _, iv := range data {
		// 跳过没有MAC地址的项目(如localhost)
		if iv.mac == "" {
			continue
		}
		// 对MAC地址进行URL编码
		mac := url.QueryEscape(iv.mac)
		resp, err := http.Get("https://api.macvendors.com/" + mac)
		defer resp.Body.Close()
		if err != nil {
			panic(err)
		}

		body, err := io.ReadAll(resp.Body)
		fmt.Println(iv.mac)
		fmt.Println(string(body))
		fmt.Println("-----------------")
		// 休眠以防止超过API的速率限制
		time.Sleep(5 * time.Second)
	}
}

以上是您要翻译的内容。

英文:

If the hardware devices are registered with https://macvendors.com/ then you can use their API

I added another mac address to your data as none of the above seemed to be recognised as "real" hardware

package main
import (
"fmt"
"net/http"
"net/url"
"io"
"time"
)
type idata struct {
index int
mtu   int
name  string
mac   string
flags string
}
func main() {
data := []idata{
{1, 65536, "lo", "", "up|loopback"},
{2, 1450, "eth0", "", "up|broadcast|multicast"},
{3, 1500, "docker0", "02:42:b4:9d:fb:54", "up|broadcast|multicast"},
{4, 1500, "br-dbabe92ec60c", "02:42:e3:7f:96:13", "up|broadcast|multicast"},
{6, 1500, "veth4bb5809", "e6:a3:38:2f:f7:e4", "up|broadcast|multicast"},
{8, 1500, "vethcada9d2", "16:8c:c9:37:8d:76", "up|broadcast|multicast"},
{10, 1500, "veth1e10eaa", "da:37:f9:9a:1d:10", "up|broadcast|multicast"},
{11, 1500, "en8", "00:e0:4c:36:01:d4", "up|broadcast|multicast"},
}
for _, iv := range data {
// skip items (like localhost) with no mac address
if iv.mac == "" {
continue
}
// url encode the mac address
mac := url.QueryEscape(iv.mac)              
resp, err := http.Get("https://api.macvendors.com/" + mac)
defer resp.Body.Close()
if err != nil {
panic(err)
}
body, err := io.ReadAll(resp.Body)
fmt.Println(iv.mac)
fmt.Println(string(body))
fmt.Println("-----------------")
// sleep to stop the API rate limit being exceeded
time.Sleep( 5 * time.Second)
}
}

huangapple
  • 本文由 发表于 2021年8月5日 14:27:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/68661614.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定