Generate peer name / mac address in Go

This commit is contained in:
Bryan Boreham committed 2017-01-11 13:12:30 +00:00
1 parent d143470d77
commit 70a20b4d26
4 files changed
+101

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
package net
import (
"crypto/rand"
"crypto/sha256"
"net"
)
func RandomMAC() (net.HardwareAddr, error) {
mac := make([]byte, 6)
if _, err := rand.Read(mac); err != nil {
return nil, err
}
setUnicastAndLocal(mac)
return net.HardwareAddr(mac), nil
}
func MACfromUUID(uuid []byte) net.HardwareAddr {
hash := sha256.New()
// We salt the input just as a precaution to avoid clashes with
// other applications who might have had the bright idea of
// generating MACs in the same way.
hash.Write([]byte("9oBJ0Jmip-"))
hash.Write(uuid)
sum := hash.Sum(nil)
setUnicastAndLocal(sum)
return net.HardwareAddr(sum[:6])
}
// In the first byte of the MAC, the 'multicast' bit should be
// clear and 'locally administered' bit should be set.
func setUnicastAndLocal(mac []byte) {
mac[0] = (mac[0] & 0xFE) | 0x02
}
+42
View File
@@ -0,0 +1,42 @@
package net
import (
"fmt"
"io/ioutil"
"net"
"os"
)
func getSystemUUID(hostRoot string) ([]byte, error) {
machineid, err := ioutil.ReadFile(hostRoot + "/etc/machine-id")
if os.IsNotExist(err) {
machineid, _ = ioutil.ReadFile(hostRoot + "/var/lib/dbus/machine-id")
}
uuid, err := ioutil.ReadFile(hostRoot + "/sys/class/dmi/id/product_uuid")
if os.IsNotExist(err) {
uuid, _ = ioutil.ReadFile(hostRoot + "/sys/hypervisor/uuid")
}
if err != nil && !os.IsNotExist(err) {
return nil, err
}
if len(machineid)+len(uuid) == 0 {
return nil, fmt.Errorf("Empty system uuid")
}
return append(machineid, uuid...), nil
}
// GetSystemPeerName returns an ID derived from concatenated machine-id
// (either systemd or dbus), the system (aka bios) UUID and the
// hypervisor UUID. It is tweaked and formatted to be usable as a mac address
func GetSystemPeerName(hostRoot string) (string, error) {
var mac net.HardwareAddr
if uuid, err := getSystemUUID(hostRoot); err == nil {
mac = MACfromUUID(uuid)
} else {
mac, err = RandomMAC()
if err != nil {
return "", err
}
}
return mac.String(), nil
}
+1
View File
@@ -36,6 +36,7 @@ func init() {
"cni-ipam": cniIPAM,
"expose-nat": exposeNAT,
"bridge-ip": bridgeIP,
"unique-id": uniqueID,
}
}
+20
View File
@@ -0,0 +1,20 @@
package main
import (
"fmt"
weavenet "github.com/weaveworks/weave/net"
)
func uniqueID(args []string) error {
if len(args) != 1 {
cmdUsage("unique-id", "<host-root>")
}
hostRoot := args[0]
uid, err := weavenet.GetSystemPeerName(hostRoot)
if err != nil {
return err
}
fmt.Printf(uid)
return nil
}