diff --git a/ipv6/sockopt_asmreq_unix.go b/ipv6/sockopt_asmreq_unix.go new file mode 100644 index 00000000..b7fd4fe6 --- /dev/null +++ b/ipv6/sockopt_asmreq_unix.go @@ -0,0 +1,22 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "net" + "os" + "unsafe" +) + +func setsockoptIPMreq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + var mreq sysIPv6Mreq + copy(mreq.Multiaddr[:], grp) + if ifi != nil { + mreq.setIfindex(ifi.Index) + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mreq), sysSizeofIPv6Mreq)) +} diff --git a/ipv6/sockopt_asmreq_windows.go b/ipv6/sockopt_asmreq_windows.go new file mode 100644 index 00000000..c03c7313 --- /dev/null +++ b/ipv6/sockopt_asmreq_windows.go @@ -0,0 +1,21 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ipv6 + +import ( + "net" + "os" + "syscall" + "unsafe" +) + +func setsockoptIPMreq(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + var mreq sysIPv6Mreq + copy(mreq.Multiaddr[:], grp) + if ifi != nil { + mreq.setIfindex(ifi.Index) + } + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&mreq)), sysSizeofIPv6Mreq)) +} diff --git a/ipv6/sockopt_rfc2292_unix.go b/ipv6/sockopt_rfc2292_unix.go deleted file mode 100644 index 851043a5..00000000 --- a/ipv6/sockopt_rfc2292_unix.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin - -package ipv6 - -import ( - "os" - "syscall" - "unsafe" -) - -func ipv6ReceiveTrafficClass(fd int) (bool, error) { - return false, errOpNoSupport -} - -func setIPv6ReceiveTrafficClass(fd int, v bool) error { - return errOpNoSupport -} - -func ipv6ReceiveHopLimit(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceiveHopLimit(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, boolint(v))) -} - -func ipv6ReceivePacketInfo(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceivePacketInfo(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, boolint(v))) -} - -func ipv6PathMTU(fd int) (int, error) { - return 0, errOpNoSupport -} - -func ipv6ReceivePathMTU(fd int) (bool, error) { - return false, errOpNoSupport -} - -func setIPv6ReceivePathMTU(fd int, v bool) error { - return errOpNoSupport -} - -func ipv6ICMPFilter(fd int) (*ICMPFilter, error) { - var v ICMPFilter - l := sysSockoptLen(sysSizeofICMPFilter) - if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, unsafe.Pointer(&v.sysICMPFilter), &l); err != nil { - return nil, os.NewSyscallError("getsockopt", err) - } - return &v, nil -} - -func setIPv6ICMPFilter(fd int, f *ICMPFilter) error { - return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, unsafe.Pointer(&f.sysICMPFilter), sysSizeofICMPFilter)) -} diff --git a/ipv6/sockopt_rfc3493_bsd.go b/ipv6/sockopt_rfc3493_bsd.go deleted file mode 100644 index 0542253a..00000000 --- a/ipv6/sockopt_rfc3493_bsd.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd netbsd openbsd - -package ipv6 - -import ( - "os" - "syscall" -) - -func setIPv6Checksum(fd int, on bool, offset int) error { - if !on { - offset = -1 - } - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptChecksum, offset)) -} diff --git a/ipv6/sockopt_rfc3493_linux.go b/ipv6/sockopt_rfc3493_linux.go deleted file mode 100644 index 0f4d2ba7..00000000 --- a/ipv6/sockopt_rfc3493_linux.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv6 - -import ( - "os" - "syscall" -) - -func setIPv6Checksum(fd int, on bool, offset int) error { - if !on { - offset = -1 - } - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolReserved, sysSockoptChecksum, offset)) -} diff --git a/ipv6/sockopt_rfc3493_unix.go b/ipv6/sockopt_rfc3493_unix.go deleted file mode 100644 index 710bacc2..00000000 --- a/ipv6/sockopt_rfc3493_unix.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build darwin dragonfly freebsd linux netbsd openbsd - -package ipv6 - -import ( - "net" - "os" - "syscall" - "unsafe" -) - -func ipv6TrafficClass(fd int) (int, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptTrafficClass) - if err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return v, nil -} - -func setIPv6TrafficClass(fd, v int) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, v)) -} - -func ipv6HopLimit(fd int) (int, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit) - if err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return v, nil -} - -func setIPv6HopLimit(fd, v int) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, v)) -} - -func ipv6Checksum(fd int) (bool, int, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptChecksum) - if err != nil { - return false, 0, os.NewSyscallError("getsockopt", err) - } - on := true - if v == -1 { - on = false - } - return on, v, nil -} - -func ipv6MulticastHopLimit(fd int) (int, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit) - if err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return v, nil -} - -func setIPv6MulticastHopLimit(fd, v int) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, v)) -} - -func ipv6MulticastInterface(fd int) (*net.Interface, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface) - if err != nil { - return nil, os.NewSyscallError("getsockopt", err) - } - if v == 0 { - return nil, nil - } - ifi, err := net.InterfaceByIndex(v) - if err != nil { - return nil, err - } - return ifi, nil -} - -func setIPv6MulticastInterface(fd int, ifi *net.Interface) error { - var v int - if ifi != nil { - v = ifi.Index - } - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, v)) -} - -func ipv6MulticastLoopback(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6MulticastLoopback(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, boolint(v))) -} - -func joinIPv6Group(fd int, ifi *net.Interface, grp net.IP) error { - mreq := sysMulticastReq{} - copy(mreq.IP[:], grp) - if ifi != nil { - mreq.IfIndex = uint32(ifi.Index) - } - return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, unsafe.Pointer(&mreq), sysSizeofMulticastReq)) -} - -func leaveIPv6Group(fd int, ifi *net.Interface, grp net.IP) error { - mreq := sysMulticastReq{} - copy(mreq.IP[:], grp) - if ifi != nil { - mreq.IfIndex = uint32(ifi.Index) - } - return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, unsafe.Pointer(&mreq), sysSizeofMulticastReq)) -} diff --git a/ipv6/sockopt_rfc3493_windows.go b/ipv6/sockopt_rfc3493_windows.go deleted file mode 100644 index aeac8b6a..00000000 --- a/ipv6/sockopt_rfc3493_windows.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv6 - -import ( - "net" - "os" - "syscall" - "unsafe" -) - -func ipv6TrafficClass(fd syscall.Handle) (int, error) { - // TODO(mikio): Implement this - return 0, syscall.EWINDOWS -} - -func setIPv6TrafficClass(fd syscall.Handle, v int) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} - -func ipv6HopLimit(fd syscall.Handle) (int, error) { - var v int32 - l := int32(4) - if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return int(v), nil -} - -func setIPv6HopLimit(fd syscall.Handle, v int) error { - vv := int32(v) - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4)) -} - -func ipv6Checksum(fd syscall.Handle) (bool, int, error) { - // TODO(mikio): Implement this - return false, 0, syscall.EWINDOWS -} - -func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) { - var v int32 - l := int32(4) - if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return int(v), nil -} - -func setIPv6MulticastHopLimit(fd syscall.Handle, v int) error { - vv := int32(v) - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4)) -} - -func ipv6MulticastInterface(fd syscall.Handle) (*net.Interface, error) { - var v int32 - l := int32(4) - if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), &l); err != nil { - return nil, os.NewSyscallError("getsockopt", err) - } - if v == 0 { - return nil, nil - } - ifi, err := net.InterfaceByIndex(int(v)) - if err != nil { - return nil, err - } - return ifi, nil -} - -func setIPv6MulticastInterface(fd syscall.Handle, ifi *net.Interface) error { - var v int32 - if ifi != nil { - v = int32(ifi.Index) - } - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), 4)) -} - -func ipv6MulticastLoopback(fd syscall.Handle) (bool, error) { - var v int32 - l := int32(4) - if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&v)), &l); err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6MulticastLoopback(fd syscall.Handle, v bool) error { - vv := int32(boolint(v)) - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&vv)), 4)) -} - -func joinIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { - mreq := sysMulticastReq{} - copy(mreq.IP[:], grp) - if ifi != nil { - mreq.IfIndex = uint32(ifi.Index) - } - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq))) -} - -func leaveIPv6Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { - mreq := sysMulticastReq{} - copy(mreq.IP[:], grp) - if ifi != nil { - mreq.IfIndex = uint32(ifi.Index) - } - return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofMulticastReq))) -} - -func setIPv6Checksum(fd syscall.Handle, on bool, offset int) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} diff --git a/ipv6/sockopt_rfc3542_stub.go b/ipv6/sockopt_rfc3542_stub.go deleted file mode 100644 index 03aa43b6..00000000 --- a/ipv6/sockopt_rfc3542_stub.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build nacl plan9 solaris - -package ipv6 - -func ipv6PathMTU(fd int) (int, error) { - // TODO(mikio): Implement this - return 0, errOpNoSupport -} diff --git a/ipv6/sockopt_rfc3542_unix.go b/ipv6/sockopt_rfc3542_unix.go deleted file mode 100644 index cf9d5263..00000000 --- a/ipv6/sockopt_rfc3542_unix.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build dragonfly freebsd linux netbsd openbsd - -package ipv6 - -import ( - "os" - "syscall" - "unsafe" -) - -func ipv6ReceiveTrafficClass(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceiveTrafficClass(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, boolint(v))) -} - -func ipv6ReceiveHopLimit(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceiveHopLimit(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, boolint(v))) -} - -func ipv6ReceivePacketInfo(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceivePacketInfo(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, boolint(v))) -} - -func ipv6PathMTU(fd int) (int, error) { - var v sysMTUInfo - l := sysSockoptLen(sysSizeofMTUInfo) - if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptPathMTU, unsafe.Pointer(&v), &l); err != nil { - return 0, os.NewSyscallError("getsockopt", err) - } - return int(v.MTU), nil -} - -func ipv6ReceivePathMTU(fd int) (bool, error) { - v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU) - if err != nil { - return false, os.NewSyscallError("getsockopt", err) - } - return v == 1, nil -} - -func setIPv6ReceivePathMTU(fd int, v bool) error { - return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, boolint(v))) -} - -func ipv6ICMPFilter(fd int) (*ICMPFilter, error) { - var v ICMPFilter - l := sysSockoptLen(sysSizeofICMPFilter) - if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, unsafe.Pointer(&v.sysICMPFilter), &l); err != nil { - return nil, os.NewSyscallError("getsockopt", err) - } - return &v, nil -} - -func setIPv6ICMPFilter(fd int, f *ICMPFilter) error { - return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, unsafe.Pointer(&f.sysICMPFilter), sysSizeofICMPFilter)) -} diff --git a/ipv6/sockopt_rfc3542_windows.go b/ipv6/sockopt_rfc3542_windows.go deleted file mode 100644 index 2bc22d9a..00000000 --- a/ipv6/sockopt_rfc3542_windows.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv6 - -import "syscall" - -func ipv6ReceiveTrafficClass(fd syscall.Handle) (bool, error) { - // TODO(mikio): Implement this - return false, syscall.EWINDOWS -} - -func setIPv6ReceiveTrafficClass(fd syscall.Handle, v bool) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} - -func ipv6ReceiveHopLimit(fd syscall.Handle) (bool, error) { - // TODO(mikio): Implement this - return false, syscall.EWINDOWS -} - -func setIPv6ReceiveHopLimit(fd syscall.Handle, v bool) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} - -func ipv6ReceivePacketInfo(fd syscall.Handle) (bool, error) { - // TODO(mikio): Implement this - return false, syscall.EWINDOWS -} - -func setIPv6ReceivePacketInfo(fd syscall.Handle, v bool) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} - -func ipv6PathMTU(fd syscall.Handle) (int, error) { - // TODO(mikio): Implement this - return 0, syscall.EWINDOWS -} - -func ipv6ReceivePathMTU(fd syscall.Handle) (bool, error) { - // TODO(mikio): Implement this - return false, syscall.EWINDOWS -} - -func setIPv6ReceivePathMTU(fd syscall.Handle, v bool) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} - -func ipv6ICMPFilter(fd syscall.Handle) (*ICMPFilter, error) { - // TODO(mikio): Implement this - return nil, syscall.EWINDOWS -} - -func setIPv6ICMPFilter(fd syscall.Handle, f *ICMPFilter) error { - // TODO(mikio): Implement this - return syscall.EWINDOWS -} diff --git a/ipv6/sockopt_stub.go b/ipv6/sockopt_stub.go new file mode 100644 index 00000000..3d6337c4 --- /dev/null +++ b/ipv6/sockopt_stub.go @@ -0,0 +1,41 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build nacl plan9 solaris + +package ipv6 + +import "net" + +func getInt(fd int, opt *sockOpt) (int, error) { + return 0, errOpNoSupport +} + +func setInt(fd int, opt *sockOpt, v int) error { + return errOpNoSupport +} + +func getInterface(fd int, opt *sockOpt) (*net.Interface, error) { + return nil, errOpNoSupport +} + +func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error { + return errOpNoSupport +} + +func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error { + return errOpNoSupport +} + +func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) { + return nil, 0, errOpNoSupport +} + +func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + return errOpNoSupport +} diff --git a/ipv6/sockopt_unix.go b/ipv6/sockopt_unix.go new file mode 100644 index 00000000..50bb414f --- /dev/null +++ b/ipv6/sockopt_unix.go @@ -0,0 +1,108 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "net" + "os" + "unsafe" +) + +func getInt(fd int, opt *sockOpt) (int, error) { + if opt.name < 1 || opt.typ != ssoTypeInt { + return 0, errOpNoSupport + } + var i int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(i), nil +} + +func setInt(fd int, opt *sockOpt, v int) error { + if opt.name < 1 || opt.typ != ssoTypeInt { + return errOpNoSupport + } + i := int32(v) + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4))) +} + +func getInterface(fd int, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return nil, errOpNoSupport + } + var i int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + if i == 0 { + return nil, nil + } + ifi, err := net.InterfaceByIndex(int(i)) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return errOpNoSupport + } + var i int32 + if ifi != nil { + i = int32(ifi.Index) + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4))) +} + +func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return nil, errOpNoSupport + } + var f ICMPFilter + l := sysSockoptLen(sysSizeofICMPv6Filter) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + return &f, nil +} + +func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return errOpNoSupport + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), sysSizeofICMPv6Filter)) +} + +func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) { + if opt.name < 1 || opt.typ != ssoTypeMTUInfo { + return nil, 0, errOpNoSupport + } + var mi sysIPv6Mtuinfo + l := sysSockoptLen(sysSizeofIPv6Mtuinfo) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mi), &l); err != nil { + return nil, 0, os.NewSyscallError("getsockopt", err) + } + if mi.Addr.Scope_id == 0 { + return nil, int(mi.Mtu), nil + } + ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id)) + if err != nil { + return nil, 0, err + } + return ifi, int(mi.Mtu), nil +} + +func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeIPMreq { + return errOpNoSupport + } + return setsockoptIPMreq(fd, opt, ifi, grp) +} diff --git a/ipv6/sockopt_windows.go b/ipv6/sockopt_windows.go new file mode 100644 index 00000000..91e90d0d --- /dev/null +++ b/ipv6/sockopt_windows.go @@ -0,0 +1,81 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ipv6 + +import ( + "net" + "os" + "syscall" + "unsafe" +) + +func getInt(fd syscall.Handle, opt *sockOpt) (int, error) { + if opt.name < 1 || opt.typ != ssoTypeInt { + return 0, errOpNoSupport + } + var i int32 + l := int32(4) + if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(i), nil +} + +func setInt(fd syscall.Handle, opt *sockOpt, v int) error { + if opt.name < 1 || opt.typ != ssoTypeInt { + return errOpNoSupport + } + i := int32(v) + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4)) +} + +func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return nil, errOpNoSupport + } + var i int32 + l := int32(4) + if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + if i == 0 { + return nil, nil + } + ifi, err := net.InterfaceByIndex(int(i)) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return errOpNoSupport + } + var i int32 + if ifi != nil { + i = int32(ifi.Index) + } + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4)) +} + +func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error { + return errOpNoSupport +} + +func getMTUInfo(fd syscall.Handle, opt *sockOpt) (*net.Interface, int, error) { + return nil, 0, errOpNoSupport +} + +func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeIPMreq { + return errOpNoSupport + } + return setsockoptIPMreq(fd, opt, ifi, grp) +}