aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikio Hara <mikioh.mikioh@gmail.com>2015-06-18 12:02:03 +0900
committerMikio Hara <mikioh.mikioh@gmail.com>2015-06-19 01:28:42 +0000
commitd375fa34084fb5703fbe4ee98e64108f3d2235ca (patch)
treeff087045a6c6bafc0842e10a9e6ee90a08c16fb6
parent4d302b6b446f7a5d2b73cad083959f7bf27b4181 (diff)
downloadnet-d375fa34084fb5703fbe4ee98e64108f3d2235ca.tar.gz
ipv6: fix multicast socket options on freebsd/386 on amd64
Change-Id: Ifdd525f27a8ed35bda240c08f379014d03fd2201 Reviewed-on: https://go-review.googlesource.com/11226 Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--ipv6/sockopt_ssmreq_unix.go32
-rw-r--r--ipv6/sys_freebsd.go14
2 files changed, 44 insertions, 2 deletions
diff --git a/ipv6/sockopt_ssmreq_unix.go b/ipv6/sockopt_ssmreq_unix.go
index 8e1dcef..c64d6d5 100644
--- a/ipv6/sockopt_ssmreq_unix.go
+++ b/ipv6/sockopt_ssmreq_unix.go
@@ -12,13 +12,28 @@ import (
"unsafe"
)
+var freebsd32o64 bool
+
func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
var gr sysGroupReq
if ifi != nil {
gr.Interface = uint32(ifi.Index)
}
gr.setGroup(grp)
- return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&gr), sysSizeofGroupReq))
+ var p unsafe.Pointer
+ var l sysSockoptLen
+ if freebsd32o64 {
+ var d [sysSizeofGroupReq + 4]byte
+ s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ p = unsafe.Pointer(&d[0])
+ l = sysSizeofGroupReq + 4
+ } else {
+ p = unsafe.Pointer(&gr)
+ l = sysSizeofGroupReq
+ }
+ return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
}
func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
@@ -27,5 +42,18 @@ func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src
gsr.Interface = uint32(ifi.Index)
}
gsr.setSourceGroup(grp, src)
- return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&gsr), sysSizeofGroupSourceReq))
+ var p unsafe.Pointer
+ var l sysSockoptLen
+ if freebsd32o64 {
+ var d [sysSizeofGroupSourceReq + 4]byte
+ s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ p = unsafe.Pointer(&d[0])
+ l = sysSizeofGroupSourceReq + 4
+ } else {
+ p = unsafe.Pointer(&gsr)
+ l = sysSizeofGroupSourceReq
+ }
+ return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l))
}
diff --git a/ipv6/sys_freebsd.go b/ipv6/sys_freebsd.go
index abf3bb9..feedab0 100644
--- a/ipv6/sys_freebsd.go
+++ b/ipv6/sys_freebsd.go
@@ -6,6 +6,8 @@ package ipv6
import (
"net"
+ "runtime"
+ "strings"
"syscall"
"unsafe"
@@ -45,6 +47,18 @@ var (
}
)
+func init() {
+ if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
+ archs, _ := syscall.Sysctl("kern.supported_archs")
+ for _, s := range strings.Split(archs, " ") {
+ if strings.TrimSpace(s) == "amd64" {
+ freebsd32o64 = true
+ break
+ }
+ }
+ }
+}
+
func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) {
sa.Len = sysSizeofSockaddrInet6
sa.Family = syscall.AF_INET6