From 07e6c919474aded70dcbf7c58b6b71d5c9bb9890 Mon Sep 17 00:00:00 2001 From: Aos Dabbagh Date: Tue, 22 Sep 2020 23:09:35 -0400 Subject: [PATCH 1/3] Added Get/SetMAC address, updated readme to include those 2 --- README.md | 13 +++++++++++-- go.mod | 3 +++ if.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ syscalls_linux.go | 3 ++- 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 go.mod diff --git a/README.md b/README.md index 00969a5..0ea2b41 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ See https://github.com/songgao/packets for functions for parsing various packets ## Installation ``` -go get -u github.com/songgao/water +go get -u github.com/aos/water go get -u github.com/songgao/water/waterutil ``` @@ -38,7 +38,7 @@ import ( "log" "github.com/songgao/packets/ethernet" - "github.com/songgao/water" + "github.com/aos/water" ) func main() { @@ -51,6 +51,15 @@ func main() { if err != nil { log.Fatal(err) } + + ifce.SetMAC("d6:db:b0:42:2c:7e") + + mac, err := ifce.GetMAC() + if err != nil { + log.Fatal(err) + } + fmt.Println("MAC address:", mac) + var frame ethernet.Frame for { diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..651cf79 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/aos/water + +go 1.14 diff --git a/if.go b/if.go index 4023a1a..b8d910e 100644 --- a/if.go +++ b/if.go @@ -3,6 +3,9 @@ package water import ( "errors" "io" + "net" + "syscall" + "unsafe" ) // Interface is a TUN/TAP interface. @@ -78,3 +81,47 @@ func (ifce *Interface) IsTAP() bool { func (ifce *Interface) Name() string { return ifce.name } + +// GetMAC returns the created interface's MAC address +func (ifce *Interface) GetMAC() (string, error) { + var req ifReq + req.Flags = syscall.AF_UNIX + copy(req.Name[:], ifce.name) + + fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) + if err != nil { + return "", err + } + defer syscall.Close(fd) + + err = ioctl(uintptr(fd), syscall.SIOCGIFHWADDR, uintptr(unsafe.Pointer(&req))) + if err != nil { + return "", err + } + return net.HardwareAddr(req.Mac[:]).String(), nil +} + +// SetMAC sets the MAC address for the interface +func (ifce *Interface) SetMAC(mac string) error { + var req ifReq + req.Flags = syscall.AF_UNIX + copy(req.Name[:], ifce.name) + + macBytes, err := net.ParseMAC(mac) + if err != nil { + return err + } + copy(req.Mac[:], macBytes) + + fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) + if err != nil { + return err + } + defer syscall.Close(fd) + + err = ioctl(uintptr(fd), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&req))) + if err != nil { + return err + } + return err +} diff --git a/syscalls_linux.go b/syscalls_linux.go index af382d1..dced6f2 100644 --- a/syscalls_linux.go +++ b/syscalls_linux.go @@ -17,7 +17,8 @@ const ( type ifReq struct { Name [0x10]byte Flags uint16 - pad [0x28 - 0x10 - 2]byte + Mac [6]byte + pad [0x28 - 0x10 - 8]byte } func ioctl(fd uintptr, request uintptr, argp uintptr) error { From 5b046bdc0199d83d506760ab25976671cac8b9ba Mon Sep 17 00:00:00 2001 From: Aos Dabbagh Date: Wed, 23 Sep 2020 21:40:05 -0400 Subject: [PATCH 2/3] Added SO_REUSEADDR to socket options, updated error message --- if.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/if.go b/if.go index b8d910e..1f80b80 100644 --- a/if.go +++ b/if.go @@ -4,6 +4,7 @@ import ( "errors" "io" "net" + "os" "syscall" "unsafe" ) @@ -90,10 +91,15 @@ func (ifce *Interface) GetMAC() (string, error) { fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) if err != nil { - return "", err + return "", os.NewSyscallError("socket", err) } defer syscall.Close(fd) + err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) + if err != nil { + return "", os.NewSyscallError("setsockopt", err) + } + err = ioctl(uintptr(fd), syscall.SIOCGIFHWADDR, uintptr(unsafe.Pointer(&req))) if err != nil { return "", err @@ -115,10 +121,15 @@ func (ifce *Interface) SetMAC(mac string) error { fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0) if err != nil { - return err + return os.NewSyscallError("socket", err) } defer syscall.Close(fd) + err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1) + if err != nil { + return os.NewSyscallError("setsockopt", err) + } + err = ioctl(uintptr(fd), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&req))) if err != nil { return err From 85bee66bb2d725f2ade76ba49865c2cf7323ac41 Mon Sep 17 00:00:00 2001 From: Aos Dabbagh Date: Wed, 30 Sep 2020 23:44:08 -0400 Subject: [PATCH 3/3] Add get/set mac addresses --- README.md | 4 ++-- go.mod | 3 --- if.go | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 go.mod diff --git a/README.md b/README.md index 0ea2b41..69563e7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ See https://github.com/songgao/packets for functions for parsing various packets ## Installation ``` -go get -u github.com/aos/water +go get -u github.com/songgao/water go get -u github.com/songgao/water/waterutil ``` @@ -38,7 +38,7 @@ import ( "log" "github.com/songgao/packets/ethernet" - "github.com/aos/water" + "github.com/songgao/water" ) func main() { diff --git a/go.mod b/go.mod deleted file mode 100644 index 651cf79..0000000 --- a/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module github.com/aos/water - -go 1.14 diff --git a/if.go b/if.go index 1f80b80..d2d87ee 100644 --- a/if.go +++ b/if.go @@ -134,5 +134,5 @@ func (ifce *Interface) SetMAC(mac string) error { if err != nil { return err } - return err + return nil }