go.net/ipv6: make it work with Go 1.1
This CL makes use of built-in syscall stuff to allow go.net/ipv6
to work together with Go 1.1. Also it's able to improve the package
without churning the Go standard library.
Fixes golang/go#6548.
R=golang-dev, dave
CC=golang-dev
https://golang.org/cl/15040044
diff --git a/ipv6/control_rfc2292_darwin.go b/ipv6/control_rfc2292_unix.go
similarity index 78%
rename from ipv6/control_rfc2292_darwin.go
rename to ipv6/control_rfc2292_unix.go
index f09ad7b..eef3968 100644
--- a/ipv6/control_rfc2292_darwin.go
+++ b/ipv6/control_rfc2292_unix.go
@@ -2,6 +2,8 @@
// 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 (
@@ -47,23 +49,23 @@
l += syscall.CmsgSpace(4)
}
if opt.isset(pktinfo) {
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ l += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if l > 0 {
oob = make([]byte, l)
if opt.isset(FlagHopLimit) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_2292HOPLIMIT
+ m.Type = sysSockopt2292HopLimit
m.SetLen(syscall.CmsgLen(4))
off += syscall.CmsgSpace(4)
}
if opt.isset(pktinfo) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_2292PKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ m.Type = sysSockopt2292PacketInfo
+ m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+ off += syscall.CmsgSpace(sysSizeofPacketInfo)
}
}
return
@@ -83,12 +85,12 @@
continue
}
switch m.Header.Type {
- case syscall.IPV6_2292HOPLIMIT:
+ case sysSockopt2292HopLimit:
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
- case syscall.IPV6_2292PKTINFO:
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
- cm.IfIndex = int(pi.Ifindex)
- cm.Dst = pi.Addr[:]
+ case sysSockopt2292PacketInfo:
+ pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
+ cm.IfIndex = int(pi.IfIndex)
+ cm.Dst = pi.IP[:]
}
}
return cm, nil
@@ -105,7 +107,7 @@
pion := false
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
pion = true
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ l += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if len(cm.NextHop) == net.IPv6len {
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
@@ -115,7 +117,7 @@
if cm.HopLimit > 0 {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_2292HOPLIMIT
+ m.Type = sysSockopt2292HopLimit
m.SetLen(syscall.CmsgLen(4))
data := oob[off+syscall.CmsgLen(0):]
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
@@ -124,21 +126,21 @@
if pion {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_2292PKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+ m.Type = sysSockopt2292PacketInfo
+ m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+ pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
- copy(pi.Addr[:], ip)
+ copy(pi.IP[:], ip)
}
if cm.IfIndex != 0 {
- pi.Ifindex = uint32(cm.IfIndex)
+ pi.IfIndex = uint32(cm.IfIndex)
}
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ off += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if len(cm.NextHop) == net.IPv6len {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_2292NEXTHOP
+ m.Type = sysSockopt2292NextHop
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
sa.Len = syscall.SizeofSockaddrInet6
diff --git a/ipv6/control_rfc3542_linux.go b/ipv6/control_rfc3542_linux.go
deleted file mode 100644
index 3e73f3b..0000000
--- a/ipv6/control_rfc3542_linux.go
+++ /dev/null
@@ -1,217 +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"
-)
-
-const (
- // See /usr/include/linux/in6.h.
- syscall_IPV6_RECVPATHMTU = syscall.IPV6_DSTOPTS + 1 + iota
- syscall_IPV6_PATHMTU
- syscall_IPV6_DONTFRAG
-)
-
-const pktinfo = FlagDst | FlagInterface
-
-func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
- opt.Lock()
- defer opt.Unlock()
- if cf&FlagTrafficClass != 0 {
- if err := setIPv6ReceiveTrafficClass(fd, on); err != nil {
- return err
- }
- if on {
- opt.set(FlagTrafficClass)
- } else {
- opt.clear(FlagTrafficClass)
- }
- }
- if cf&FlagHopLimit != 0 {
- if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
- return err
- }
- if on {
- opt.set(FlagHopLimit)
- } else {
- opt.clear(FlagHopLimit)
- }
- }
- if cf&pktinfo != 0 {
- if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
- return err
- }
- if on {
- opt.set(cf & pktinfo)
- } else {
- opt.clear(cf & pktinfo)
- }
- }
- if cf&FlagPathMTU != 0 {
- if err := setIPv6ReceivePathMTU(fd, on); err != nil {
- return err
- }
- if on {
- opt.set(FlagPathMTU)
- } else {
- opt.clear(FlagPathMTU)
- }
- }
- return nil
-}
-
-func newControlMessage(opt *rawOpt) (oob []byte) {
- opt.Lock()
- defer opt.Unlock()
- l, off := 0, 0
- if opt.isset(FlagTrafficClass) {
- l += syscall.CmsgSpace(4)
- }
- if opt.isset(FlagHopLimit) {
- l += syscall.CmsgSpace(4)
- }
- if opt.isset(pktinfo) {
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
- }
- if opt.isset(FlagPathMTU) {
- l += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
- }
- if l > 0 {
- oob = make([]byte, l)
- if opt.isset(FlagTrafficClass) {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVTCLASS
- m.SetLen(syscall.CmsgLen(4))
- off += syscall.CmsgSpace(4)
- }
- if opt.isset(FlagHopLimit) {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVHOPLIMIT
- m.SetLen(syscall.CmsgLen(4))
- off += syscall.CmsgSpace(4)
- }
- if opt.isset(pktinfo) {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVPKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
- }
- if opt.isset(FlagPathMTU) {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall_IPV6_RECVPATHMTU
- m.SetLen(syscall.CmsgLen(syscall.SizeofIPv6MTUInfo))
- off += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
- }
- }
- return
-}
-
-func parseControlMessage(b []byte) (*ControlMessage, error) {
- if len(b) == 0 {
- return nil, nil
- }
- cmsgs, err := syscall.ParseSocketControlMessage(b)
- if err != nil {
- return nil, os.NewSyscallError("parse socket control message", err)
- }
- cm := &ControlMessage{}
- for _, m := range cmsgs {
- if m.Header.Level != ianaProtocolIPv6 {
- continue
- }
- switch m.Header.Type {
- case syscall.IPV6_TCLASS:
- cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
- case syscall.IPV6_HOPLIMIT:
- cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
- case syscall.IPV6_PKTINFO:
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
- cm.Dst = pi.Addr[:]
- cm.IfIndex = int(pi.Ifindex)
- case syscall_IPV6_PATHMTU:
- mi := (*syscall.IPv6MTUInfo)(unsafe.Pointer(&m.Data[0]))
- cm.Dst = mi.Addr.Addr[:]
- cm.IfIndex = int(mi.Addr.Scope_id)
- cm.MTU = int(mi.Mtu)
- }
- }
- return cm, nil
-}
-
-func marshalControlMessage(cm *ControlMessage) (oob []byte) {
- if cm == nil {
- return
- }
- l, off := 0, 0
- if cm.TrafficClass > 0 {
- l += syscall.CmsgSpace(4)
- }
- if cm.HopLimit > 0 {
- l += syscall.CmsgSpace(4)
- }
- pion := false
- if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
- pion = true
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
- }
- if len(cm.NextHop) == net.IPv6len {
- l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
- }
- if l > 0 {
- oob = make([]byte, l)
- if cm.TrafficClass > 0 {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_TCLASS
- m.SetLen(syscall.CmsgLen(4))
- data := oob[off+syscall.CmsgLen(0):]
- *(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
- off += syscall.CmsgSpace(4)
- }
- if cm.HopLimit > 0 {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_HOPLIMIT
- m.SetLen(syscall.CmsgLen(4))
- data := oob[off+syscall.CmsgLen(0):]
- *(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
- off += syscall.CmsgSpace(4)
- }
- if pion {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_PKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
- if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
- copy(pi.Addr[:], ip)
- }
- if cm.IfIndex != 0 {
- pi.Ifindex = uint32(cm.IfIndex)
- }
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
- }
- if len(cm.NextHop) == net.IPv6len {
- m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
- m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_NEXTHOP
- m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
- sa.Family = syscall.AF_INET6
- copy(sa.Addr[:], cm.NextHop)
- sa.Scope_id = uint32(cm.IfIndex)
- off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
- }
- }
- return
-}
diff --git a/ipv6/control_rfc3542_bsd.go b/ipv6/control_rfc3542_unix.go
similarity index 74%
rename from ipv6/control_rfc3542_bsd.go
rename to ipv6/control_rfc3542_unix.go
index 0b42c0b..882a77b 100644
--- a/ipv6/control_rfc3542_bsd.go
+++ b/ipv6/control_rfc3542_unix.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build freebsd netbsd openbsd
+// +build freebsd linux netbsd openbsd
package ipv6
@@ -72,40 +72,40 @@
l += syscall.CmsgSpace(4)
}
if opt.isset(pktinfo) {
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ l += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if opt.isset(FlagPathMTU) {
- l += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
+ l += syscall.CmsgSpace(sysSizeofMTUInfo)
}
if l > 0 {
oob = make([]byte, l)
if opt.isset(FlagTrafficClass) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVTCLASS
+ m.Type = sysSockoptReceiveTrafficClass
m.SetLen(syscall.CmsgLen(4))
off += syscall.CmsgSpace(4)
}
if opt.isset(FlagHopLimit) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVHOPLIMIT
+ m.Type = sysSockoptReceiveHopLimit
m.SetLen(syscall.CmsgLen(4))
off += syscall.CmsgSpace(4)
}
if opt.isset(pktinfo) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVPKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ m.Type = sysSockoptReceivePacketInfo
+ m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+ off += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if opt.isset(FlagPathMTU) {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_RECVPATHMTU
- m.SetLen(syscall.CmsgLen(syscall.SizeofIPv6MTUInfo))
- off += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
+ m.Type = sysSockoptReceivePathMTU
+ m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
+ off += syscall.CmsgSpace(sysSizeofMTUInfo)
}
}
return
@@ -125,19 +125,19 @@
continue
}
switch m.Header.Type {
- case syscall.IPV6_TCLASS:
+ case sysSockoptTrafficClass:
cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
- case syscall.IPV6_HOPLIMIT:
+ case sysSockoptHopLimit:
cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
- case syscall.IPV6_PKTINFO:
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&m.Data[0]))
- cm.Dst = pi.Addr[:]
- cm.IfIndex = int(pi.Ifindex)
- case syscall.IPV6_PATHMTU:
- mi := (*syscall.IPv6MTUInfo)(unsafe.Pointer(&m.Data[0]))
+ case sysSockoptPacketInfo:
+ pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
+ cm.Dst = pi.IP[:]
+ cm.IfIndex = int(pi.IfIndex)
+ case sysSockoptPathMTU:
+ mi := (*sysMTUInfo)(unsafe.Pointer(&m.Data[0]))
cm.Dst = mi.Addr.Addr[:]
cm.IfIndex = int(mi.Addr.Scope_id)
- cm.MTU = int(mi.Mtu)
+ cm.MTU = int(mi.MTU)
}
}
return cm, nil
@@ -157,7 +157,7 @@
pion := false
if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
pion = true
- l += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ l += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if len(cm.NextHop) == net.IPv6len {
l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
@@ -167,7 +167,7 @@
if cm.TrafficClass > 0 {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_TCLASS
+ m.Type = sysSockoptTrafficClass
m.SetLen(syscall.CmsgLen(4))
data := oob[off+syscall.CmsgLen(0):]
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
@@ -176,7 +176,7 @@
if cm.HopLimit > 0 {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_HOPLIMIT
+ m.Type = sysSockoptHopLimit
m.SetLen(syscall.CmsgLen(4))
data := oob[off+syscall.CmsgLen(0):]
*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
@@ -185,27 +185,24 @@
if pion {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_PKTINFO
- m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
- pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
+ m.Type = sysSockoptPacketInfo
+ m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
+ pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
- copy(pi.Addr[:], ip)
+ copy(pi.IP[:], ip)
}
if cm.IfIndex != 0 {
- pi.Ifindex = uint32(cm.IfIndex)
+ pi.IfIndex = uint32(cm.IfIndex)
}
- off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
+ off += syscall.CmsgSpace(sysSizeofPacketInfo)
}
if len(cm.NextHop) == net.IPv6len {
m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
m.Level = ianaProtocolIPv6
- m.Type = syscall.IPV6_NEXTHOP
+ m.Type = sysSockoptNextHop
m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
- sa.Len = syscall.SizeofSockaddrInet6
- sa.Family = syscall.AF_INET6
- copy(sa.Addr[:], cm.NextHop)
- sa.Scope_id = uint32(cm.IfIndex)
+ setSockaddr(sa, cm.NextHop, cm.IfIndex)
off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
}
}
diff --git a/ipv6/icmp.go b/ipv6/icmp.go
index 9fb6a48..b45486f 100644
--- a/ipv6/icmp.go
+++ b/ipv6/icmp.go
@@ -21,26 +21,27 @@
// packets.
type ICMPFilter struct {
mu sync.RWMutex
- rawICMPFilter
+ sysICMPFilter
}
// Set sets the ICMP type and filter action to the filter.
func (f *ICMPFilter) Set(typ ICMPType, block bool) {
f.mu.Lock()
- defer f.mu.Unlock()
f.set(typ, block)
+ f.mu.Unlock()
}
// SetAll sets the filter action to the filter.
func (f *ICMPFilter) SetAll(block bool) {
f.mu.Lock()
- defer f.mu.Unlock()
f.setAll(block)
+ f.mu.Unlock()
}
// WillBlock reports whether the ICMP type will be blocked.
func (f *ICMPFilter) WillBlock(typ ICMPType) bool {
f.mu.RLock()
- defer f.mu.RUnlock()
- return f.willBlock(typ)
+ ok := f.willBlock(typ)
+ f.mu.RUnlock()
+ return ok
}
diff --git a/ipv6/icmp_bsd.go b/ipv6/icmp_bsd.go
index fd5f83e..b92e0d9 100644
--- a/ipv6/icmp_bsd.go
+++ b/ipv6/icmp_bsd.go
@@ -6,13 +6,11 @@
package ipv6
-import "syscall"
-
-type rawICMPFilter struct {
- syscall.ICMPv6Filter
+type sysICMPFilter struct {
+ Filt [8]uint32
}
-func (f *rawICMPFilter) set(typ ICMPType, block bool) {
+func (f *sysICMPFilter) set(typ ICMPType, block bool) {
if block {
f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
} else {
@@ -20,7 +18,7 @@
}
}
-func (f *rawICMPFilter) setAll(block bool) {
+func (f *sysICMPFilter) setAll(block bool) {
for i := range f.Filt {
if block {
f.Filt[i] = 0
@@ -30,6 +28,6 @@
}
}
-func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
+func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
}
diff --git a/ipv6/icmp_linux.go b/ipv6/icmp_linux.go
index 0a70f5f..7b3e2bd 100644
--- a/ipv6/icmp_linux.go
+++ b/ipv6/icmp_linux.go
@@ -4,13 +4,11 @@
package ipv6
-import "syscall"
-
-type rawICMPFilter struct {
- syscall.ICMPv6Filter
+type sysICMPFilter struct {
+ Data [8]uint32
}
-func (f *rawICMPFilter) set(typ ICMPType, block bool) {
+func (f *sysICMPFilter) set(typ ICMPType, block bool) {
if block {
f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
} else {
@@ -18,7 +16,7 @@
}
}
-func (f *rawICMPFilter) setAll(block bool) {
+func (f *sysICMPFilter) setAll(block bool) {
for i := range f.Data {
if block {
f.Data[i] = 1<<32 - 1
@@ -28,6 +26,6 @@
}
}
-func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
+func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
}
diff --git a/ipv6/icmp_plan9.go b/ipv6/icmp_plan9.go
index b97c828..cf4ea4c 100644
--- a/ipv6/icmp_plan9.go
+++ b/ipv6/icmp_plan9.go
@@ -4,19 +4,19 @@
package ipv6
-type rawICMPFilter struct {
+type sysICMPFilter struct {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) set(typ ICMPType, block bool) {
+func (f *sysICMPFilter) set(typ ICMPType, block bool) {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) setAll(block bool) {
+func (f *sysICMPFilter) setAll(block bool) {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
+func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
// TODO(mikio): Implement this
return false
}
diff --git a/ipv6/icmp_windows.go b/ipv6/icmp_windows.go
index b97c828..cf4ea4c 100644
--- a/ipv6/icmp_windows.go
+++ b/ipv6/icmp_windows.go
@@ -4,19 +4,19 @@
package ipv6
-type rawICMPFilter struct {
+type sysICMPFilter struct {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) set(typ ICMPType, block bool) {
+func (f *sysICMPFilter) set(typ ICMPType, block bool) {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) setAll(block bool) {
+func (f *sysICMPFilter) setAll(block bool) {
// TODO(mikio): Implement this
}
-func (f *rawICMPFilter) willBlock(typ ICMPType) bool {
+func (f *sysICMPFilter) willBlock(typ ICMPType) bool {
// TODO(mikio): Implement this
return false
}
diff --git a/ipv6/sockopt_rfc2292_darwin.go b/ipv6/sockopt_rfc2292_darwin.go
deleted file mode 100644
index f21802c..0000000
--- a/ipv6/sockopt_rfc2292_darwin.go
+++ /dev/null
@@ -1,66 +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 ipv6ReceiveTrafficClass(fd int) (bool, error) {
- return false, errNotSupported
-}
-
-func setIPv6ReceiveTrafficClass(fd int, v bool) error {
- return errNotSupported
-}
-
-func ipv6ReceiveHopLimit(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292HOPLIMIT)
- 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, syscall.IPV6_2292HOPLIMIT, boolint(v)))
-}
-
-func ipv6ReceivePacketInfo(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_2292PKTINFO)
- 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, syscall.IPV6_2292PKTINFO, boolint(v)))
-}
-
-func ipv6PathMTU(fd int) (int, error) {
- return 0, errNotSupported
-}
-
-func ipv6ReceivePathMTU(fd int) (bool, error) {
- return false, errNotSupported
-}
-
-func setIPv6ReceivePathMTU(fd int, v bool) error {
- return errNotSupported
-}
-
-func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
- v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER)
- if err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
-}
-
-func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
-}
diff --git a/ipv6/sockopt_rfc2292_unix.go b/ipv6/sockopt_rfc2292_unix.go
new file mode 100644
index 0000000..827e943
--- /dev/null
+++ b/ipv6/sockopt_rfc2292_unix.go
@@ -0,0 +1,73 @@
+// 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"
+ "unsafe"
+)
+
+func ipv6ReceiveTrafficClass(fd int) (bool, error) {
+ return false, errNotSupported
+}
+
+func setIPv6ReceiveTrafficClass(fd int, v bool) error {
+ return errNotSupported
+}
+
+func ipv6ReceiveHopLimit(fd int) (bool, error) {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+ return false, os.NewSyscallError("getsockopt", err)
+ }
+ return v == 1, nil
+}
+
+func setIPv6ReceiveHopLimit(fd int, v bool) error {
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292HopLimit, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6ReceivePacketInfo(fd int) (bool, error) {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+ return false, os.NewSyscallError("getsockopt", err)
+ }
+ return v == 1, nil
+}
+
+func setIPv6ReceivePacketInfo(fd int, v bool) error {
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockopt2292PacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6PathMTU(fd int) (int, error) {
+ return 0, errNotSupported
+}
+
+func ipv6ReceivePathMTU(fd int) (bool, error) {
+ return false, errNotSupported
+}
+
+func setIPv6ReceivePathMTU(fd int, v bool) error {
+ return errNotSupported
+}
+
+func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
+ var v ICMPFilter
+ l := sysSockoptLen(sysSizeofICMPFilter)
+ if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(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, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
+}
diff --git a/ipv6/sockopt_rfc3493_bsd.go b/ipv6/sockopt_rfc3493_bsd.go
index aa5e6e3..352a161 100644
--- a/ipv6/sockopt_rfc3493_bsd.go
+++ b/ipv6/sockopt_rfc3493_bsd.go
@@ -8,12 +8,13 @@
import (
"os"
- "syscall"
+ "unsafe"
)
func setIPv6Checksum(fd int, on bool, offset int) error {
if !on {
offset = -1
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_CHECKSUM, offset))
+ v := int32(offset)
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
}
diff --git a/ipv6/sockopt_rfc3493_linux.go b/ipv6/sockopt_rfc3493_linux.go
index b2557e8..f13a28f 100644
--- a/ipv6/sockopt_rfc3493_linux.go
+++ b/ipv6/sockopt_rfc3493_linux.go
@@ -6,12 +6,13 @@
import (
"os"
- "syscall"
+ "unsafe"
)
func setIPv6Checksum(fd int, on bool, offset int) error {
if !on {
offset = -1
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolReserved, syscall.IPV6_CHECKSUM, offset))
+ v := int32(offset)
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolReserved, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), 4))
}
diff --git a/ipv6/sockopt_rfc3493_unix.go b/ipv6/sockopt_rfc3493_unix.go
index b055cf0..a9f5e11 100644
--- a/ipv6/sockopt_rfc3493_unix.go
+++ b/ipv6/sockopt_rfc3493_unix.go
@@ -9,66 +9,74 @@
import (
"net"
"os"
- "syscall"
+ "unsafe"
)
func ipv6TrafficClass(fd int) (int, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_TCLASS)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&v)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
- return v, nil
+ return int(v), nil
}
func setIPv6TrafficClass(fd, v int) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_TCLASS, v))
+ vv := int32(v)
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
}
func ipv6HopLimit(fd int) (int, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
- return v, nil
+ return int(v), nil
}
func setIPv6HopLimit(fd, v int) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, v))
+ vv := int32(v)
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
}
func ipv6Checksum(fd int) (bool, int, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_CHECKSUM)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptChecksum, uintptr(unsafe.Pointer(&v)), &l); err != nil {
return false, 0, os.NewSyscallError("getsockopt", err)
}
on := true
if v == -1 {
on = false
}
- return on, v, nil
+ return on, int(v), nil
}
func ipv6MulticastHopLimit(fd int) (int, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&v)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
- return v, nil
+ return int(v), nil
}
func setIPv6MulticastHopLimit(fd, v int) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, v))
+ vv := int32(v)
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
}
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), &l); err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
if v == 0 {
return nil, nil
}
- ifi, err := net.InterfaceByIndex(v)
+ ifi, err := net.InterfaceByIndex(int(v))
if err != nil {
return nil, err
}
@@ -76,39 +84,41 @@
}
func setIPv6MulticastInterface(fd int, ifi *net.Interface) error {
- var v int
+ var v int32
if ifi != nil {
- v = ifi.Index
+ v = int32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF, v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, uintptr(unsafe.Pointer(&v)), 4))
}
func ipv6MulticastLoopback(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&v)), &l); 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, syscall.IPV6_MULTICAST_LOOP, boolint(v)))
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, uintptr(unsafe.Pointer(&vv)), 4))
}
func joinIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
- mreq := syscall.IPv6Mreq{}
- copy(mreq.Multiaddr[:], grp)
+ mreq := sysMulticastReq{}
+ copy(mreq.IP[:], grp)
if ifi != nil {
- mreq.Interface = uint32(ifi.Index)
+ mreq.IfIndex = uint32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd, ianaProtocolIPv6, syscall.IPV6_JOIN_GROUP, &mreq))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptJoinGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
}
func leaveIPv6Group(fd int, ifi *net.Interface, grp net.IP) error {
- mreq := syscall.IPv6Mreq{}
- copy(mreq.Multiaddr[:], grp)
+ mreq := sysMulticastReq{}
+ copy(mreq.IP[:], grp)
if ifi != nil {
- mreq.Interface = uint32(ifi.Index)
+ mreq.IfIndex = uint32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd, ianaProtocolIPv6, syscall.IPV6_LEAVE_GROUP, &mreq))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptLeaveGroup, uintptr(unsafe.Pointer(&mreq)), sysSizeofMulticastReq))
}
diff --git a/ipv6/sockopt_rfc3493_windows.go b/ipv6/sockopt_rfc3493_windows.go
index 04d4526..aeac8b6 100644
--- a/ipv6/sockopt_rfc3493_windows.go
+++ b/ipv6/sockopt_rfc3493_windows.go
@@ -24,7 +24,7 @@
func ipv6HopLimit(fd syscall.Handle) (int, error) {
var v int32
l := int32(4)
- if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
+ if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
return int(v), nil
@@ -32,7 +32,7 @@
func setIPv6HopLimit(fd syscall.Handle, v int) error {
vv := int32(v)
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_UNICAST_HOPS, (*byte)(unsafe.Pointer(&vv)), 4))
+ return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, sysSockoptUnicastHopLimit, (*byte)(unsafe.Pointer(&vv)), 4))
}
func ipv6Checksum(fd syscall.Handle) (bool, int, error) {
@@ -43,7 +43,7 @@
func ipv6MulticastHopLimit(fd syscall.Handle) (int, error) {
var v int32
l := int32(4)
- if err := syscall.Getsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
+ if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastHopLimit, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
return 0, os.NewSyscallError("getsockopt", err)
}
return int(v), nil
@@ -51,13 +51,13 @@
func setIPv6MulticastHopLimit(fd syscall.Handle, v int) error {
vv := int32(v)
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_HOPS, (*byte)(unsafe.Pointer(&vv)), 4))
+ 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, syscall.IPV6_MULTICAST_IF, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
+ if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
return nil, os.NewSyscallError("getsockopt", err)
}
if v == 0 {
@@ -75,13 +75,13 @@
if ifi != nil {
v = int32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF, (*byte)(unsafe.Pointer(&v)), 4))
+ 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, syscall.IPV6_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
+ if err := syscall.Getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastLoopback, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
return false, os.NewSyscallError("getsockopt", err)
}
return v == 1, nil
@@ -89,25 +89,25 @@
func setIPv6MulticastLoopback(fd syscall.Handle, v bool) error {
vv := int32(boolint(v))
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&vv)), 4))
+ 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 := syscall.IPv6Mreq{}
- copy(mreq.Multiaddr[:], grp)
+ mreq := sysMulticastReq{}
+ copy(mreq.IP[:], grp)
if ifi != nil {
- mreq.Interface = uint32(ifi.Index)
+ mreq.IfIndex = uint32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_JOIN_GROUP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
+ 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 := syscall.IPv6Mreq{}
- copy(mreq.Multiaddr[:], grp)
+ mreq := sysMulticastReq{}
+ copy(mreq.IP[:], grp)
if ifi != nil {
- mreq.Interface = uint32(ifi.Index)
+ mreq.IfIndex = uint32(ifi.Index)
}
- return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIPv6, syscall.IPV6_LEAVE_GROUP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
+ 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 {
diff --git a/ipv6/sockopt_rfc3542_bsd.go b/ipv6/sockopt_rfc3542_bsd.go
deleted file mode 100644
index 61073b1..0000000
--- a/ipv6/sockopt_rfc3542_bsd.go
+++ /dev/null
@@ -1,44 +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 freebsd netbsd openbsd
-
-package ipv6
-
-import (
- "os"
- "syscall"
-)
-
-func ipv6PathMTU(fd int) (int, error) {
- v, err := syscall.GetsockoptIPv6MTUInfo(fd, ianaProtocolIPv6, syscall.IPV6_PATHMTU)
- if 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, syscall.IPV6_RECVPATHMTU)
- 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, syscall.IPV6_RECVPATHMTU, boolint(v)))
-}
-
-func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
- v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER)
- if err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
-}
-
-func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMP6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
-}
diff --git a/ipv6/sockopt_rfc3542_linux.go b/ipv6/sockopt_rfc3542_linux.go
deleted file mode 100644
index 9cea683..0000000
--- a/ipv6/sockopt_rfc3542_linux.go
+++ /dev/null
@@ -1,42 +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 ipv6PathMTU(fd int) (int, error) {
- v, err := syscall.GetsockoptIPv6MTUInfo(fd, ianaProtocolIPv6, syscall_IPV6_PATHMTU)
- if 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, syscall_IPV6_RECVPATHMTU)
- 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, syscall_IPV6_RECVPATHMTU, boolint(v)))
-}
-
-func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
- v, err := syscall.GetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMPV6_FILTER)
- if err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- return &ICMPFilter{rawICMPFilter: rawICMPFilter{*v}}, nil
-}
-
-func setIPv6ICMPFilter(fd int, f *ICMPFilter) error {
- return os.NewSyscallError("setsockopt", syscall.SetsockoptICMPv6Filter(fd, ianaProtocolIPv6ICMP, syscall.ICMPV6_FILTER, &f.rawICMPFilter.ICMPv6Filter))
-}
diff --git a/ipv6/sockopt_rfc3542_unix.go b/ipv6/sockopt_rfc3542_unix.go
index 463f426..da9111c 100644
--- a/ipv6/sockopt_rfc3542_unix.go
+++ b/ipv6/sockopt_rfc3542_unix.go
@@ -8,41 +8,83 @@
import (
"os"
- "syscall"
+ "unsafe"
)
func ipv6ReceiveTrafficClass(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVTCLASS)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&v)), &l); 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, syscall.IPV6_RECVTCLASS, boolint(v)))
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveTrafficClass, uintptr(unsafe.Pointer(&vv)), 4))
}
func ipv6ReceiveHopLimit(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVHOPLIMIT)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&v)), &l); 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, syscall.IPV6_RECVHOPLIMIT, boolint(v)))
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceiveHopLimit, uintptr(unsafe.Pointer(&vv)), 4))
}
func ipv6ReceivePacketInfo(fd int) (bool, error) {
- v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_RECVPKTINFO)
- if err != nil {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&v)), &l); 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, syscall.IPV6_RECVPKTINFO, boolint(v)))
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePacketInfo, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6PathMTU(fd int) (int, error) {
+ var v sysMTUInfo
+ l := sysSockoptLen(sysSizeofMTUInfo)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptPathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+ return 0, os.NewSyscallError("getsockopt", err)
+ }
+ return int(v.MTU), nil
+}
+
+func ipv6ReceivePathMTU(fd int) (bool, error) {
+ var v int32
+ l := sysSockoptLen(4)
+ if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&v)), &l); err != nil {
+ return false, os.NewSyscallError("getsockopt", err)
+ }
+ return v == 1, nil
+}
+
+func setIPv6ReceivePathMTU(fd int, v bool) error {
+ vv := int32(boolint(v))
+ return os.NewSyscallError("setsockopt", setsockopt(fd, ianaProtocolIPv6, sysSockoptReceivePathMTU, uintptr(unsafe.Pointer(&vv)), 4))
+}
+
+func ipv6ICMPFilter(fd int) (*ICMPFilter, error) {
+ var v ICMPFilter
+ l := sysSockoptLen(sysSizeofICMPFilter)
+ if err := getsockopt(fd, ianaProtocolIPv6ICMP, sysSockoptICMPFilter, uintptr(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, uintptr(unsafe.Pointer(&f.sysICMPFilter)), sysSizeofICMPFilter))
}