netlink: Add NetworkSetMacAddress
Signed-off-by: Lewis Marshall <lewis@lmars.net>
This commit is contained in:
parent
e1d882b523
commit
80a574ab49
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
@ -932,7 +933,7 @@ func CreateBridge(name string, setMacAddr bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if setMacAddr {
|
if setMacAddr {
|
||||||
return setBridgeMacAddress(s, name)
|
return NetworkSetMacAddress(name, randMacAddr())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -988,22 +989,40 @@ func AddToBridge(iface, master *net.Interface) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBridgeMacAddress(s int, name string) error {
|
func randMacAddr() string {
|
||||||
|
hw := make(net.HardwareAddr, 6)
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
hw[i] = byte(rand.Intn(255))
|
||||||
|
}
|
||||||
|
hw[0] &^= 0x1 // clear multicast bit
|
||||||
|
hw[0] |= 0x2 // set local assignment bit (IEEE802)
|
||||||
|
return hw.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NetworkSetMacAddress(name, addr string) error {
|
||||||
if len(name) >= IFNAMSIZ {
|
if len(name) >= IFNAMSIZ {
|
||||||
return fmt.Errorf("Interface name %s too long", name)
|
return fmt.Errorf("Interface name %s too long", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hw, err := net.ParseMAC(addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := getIfSocket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer syscall.Close(s)
|
||||||
|
|
||||||
ifr := ifreqHwaddr{}
|
ifr := ifreqHwaddr{}
|
||||||
ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
|
ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER
|
||||||
copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
|
copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name)
|
||||||
|
|
||||||
for i := 0; i < 6; i++ {
|
for i := 0; i < 6; i++ {
|
||||||
ifr.IfruHwaddr.Data[i] = randIfrDataByte()
|
ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
ifr.IfruHwaddr.Data[0] &^= 0x1 // clear multicast bit
|
|
||||||
ifr.IfruHwaddr.Data[0] |= 0x2 // set local assignment bit (IEEE802)
|
|
||||||
|
|
||||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
|
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import (
|
func ifrDataByte(b byte) uint8 {
|
||||||
"math/rand"
|
return uint8(b)
|
||||||
)
|
|
||||||
|
|
||||||
func randIfrDataByte() uint8 {
|
|
||||||
return uint8(rand.Intn(255))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
|
|
||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import (
|
func ifrDataByte(b byte) int8 {
|
||||||
"math/rand"
|
return int8(b)
|
||||||
)
|
|
||||||
|
|
||||||
func randIfrDataByte() int8 {
|
|
||||||
return int8(rand.Intn(255))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,3 +125,30 @@ func TestCreateVethPair(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetMACAddress(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "testmac"
|
||||||
|
mac := randMacAddr()
|
||||||
|
|
||||||
|
if err := NetworkLinkAdd(name, "bridge"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer NetworkLinkDel(name)
|
||||||
|
|
||||||
|
if err := NetworkSetMacAddress(name, mac); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
iface, err := net.InterfaceByName(name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface.HardwareAddr.String() != mac {
|
||||||
|
t.Fatalf("mac address %q does not match %q", iface.HardwareAddr, mac)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue