ipv4: plumb in the standard library of Go 1.9 by using internal/socket package
This change uses the internal/socket package to ensure that the ipv4
package works with all supported versions of the Go standard library.
Fixes golang/go#19051.
Change-Id: If0256007c749c319970533823a10afdc1ffbce31
Reviewed-on: https://go-review.googlesource.com/37036
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/ipv4/bpfopt_linux.go b/ipv4/bpfopt_linux.go
deleted file mode 100644
index 2d626d9..0000000
--- a/ipv4/bpfopt_linux.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 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 ipv4
-
-import (
- "os"
- "unsafe"
-
- "golang.org/x/net/bpf"
- "golang.org/x/net/internal/netreflect"
-)
-
-// SetBPF attaches a BPF program to the connection.
-//
-// Only supported on Linux.
-func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
- }
- prog := sockFProg{
- Len: uint16(len(filter)),
- Filter: (*sockFilter)(unsafe.Pointer(&filter[0])),
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, sysSOL_SOCKET, sysSO_ATTACH_FILTER, unsafe.Pointer(&prog), uint32(unsafe.Sizeof(prog))))
-}
diff --git a/ipv4/bpfopt_stub.go b/ipv4/bpfopt_stub.go
deleted file mode 100644
index c4a8481..0000000
--- a/ipv4/bpfopt_stub.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 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 !linux
-
-package ipv4
-
-import "golang.org/x/net/bpf"
-
-// SetBPF attaches a BPF program to the connection.
-//
-// Only supported on Linux.
-func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
- return errOpNoSupport
-}
diff --git a/ipv4/control_stub.go b/ipv4/control_stub.go
index 27e618b..de9b1a0 100644
--- a/ipv4/control_stub.go
+++ b/ipv4/control_stub.go
@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build nacl plan9
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv4
-func setControlMessage(s uintptr, opt *rawOpt, cf ControlFlags, on bool) error {
+import "golang.org/x/net/internal/socket"
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
return errOpNoSupport
}
diff --git a/ipv4/control_unix.go b/ipv4/control_unix.go
index 25ef661..9111520 100644
--- a/ipv4/control_unix.go
+++ b/ipv4/control_unix.go
@@ -12,13 +12,14 @@
"unsafe"
"golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
-func setControlMessage(s uintptr, opt *rawOpt, cf ControlFlags, on bool) error {
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
opt.Lock()
defer opt.Unlock()
- if cf&FlagTTL != 0 && sockOpts[ssoReceiveTTL].name > 0 {
- if err := setInt(s, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil {
+ if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
return err
}
if on {
@@ -27,9 +28,9 @@
opt.clear(FlagTTL)
}
}
- if sockOpts[ssoPacketInfo].name > 0 {
+ if so, ok := sockOpts[ssoPacketInfo]; ok {
if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
- if err := setInt(s, &sockOpts[ssoPacketInfo], boolint(on)); err != nil {
+ if err := so.SetInt(c, boolint(on)); err != nil {
return err
}
if on {
@@ -39,8 +40,8 @@
}
}
} else {
- if cf&FlagDst != 0 && sockOpts[ssoReceiveDst].name > 0 {
- if err := setInt(s, &sockOpts[ssoReceiveDst], boolint(on)); err != nil {
+ if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
return err
}
if on {
@@ -49,8 +50,8 @@
opt.clear(FlagDst)
}
}
- if cf&FlagInterface != 0 && sockOpts[ssoReceiveInterface].name > 0 {
- if err := setInt(s, &sockOpts[ssoReceiveInterface], boolint(on)); err != nil {
+ if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
+ if err := so.SetInt(c, boolint(on)); err != nil {
return err
}
if on {
diff --git a/ipv4/control_windows.go b/ipv4/control_windows.go
index b27407d..5560fcf 100644
--- a/ipv4/control_windows.go
+++ b/ipv4/control_windows.go
@@ -4,9 +4,13 @@
package ipv4
-import "syscall"
+import (
+ "syscall"
-func setControlMessage(s uintptr, opt *rawOpt, cf ControlFlags, on bool) error {
+ "golang.org/x/net/internal/socket"
+)
+
+func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
// TODO(mikio): implement this
return syscall.EWINDOWS
}
diff --git a/ipv4/defs_linux.go b/ipv4/defs_linux.go
index 31dfa09..beb1107 100644
--- a/ipv4/defs_linux.go
+++ b/ipv4/defs_linux.go
@@ -93,6 +93,8 @@
sizeofGroupSourceReq = C.sizeof_struct_group_source_req
sizeofICMPFilter = C.sizeof_struct_icmp_filter
+
+ sizeofSockFprog = C.sizeof_struct_sock_fprog
)
type kernelSockaddrStorage C.struct___kernel_sockaddr_storage
diff --git a/ipv4/dgramopt_posix.go b/ipv4/dgramopt.go
similarity index 69%
rename from ipv4/dgramopt_posix.go
rename to ipv4/dgramopt.go
index fbc5df1..54d77d5 100644
--- a/ipv4/dgramopt_posix.go
+++ b/ipv4/dgramopt.go
@@ -2,15 +2,13 @@
// 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 solaris windows
-
package ipv4
import (
"net"
"syscall"
- "golang.org/x/net/internal/netreflect"
+ "golang.org/x/net/bpf"
)
// MulticastTTL returns the time-to-live field value for outgoing
@@ -19,11 +17,11 @@
if !c.ok() {
return 0, syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return 0, err
+ so, ok := sockOpts[ssoMulticastTTL]
+ if !ok {
+ return 0, errOpNoSupport
}
- return getInt(s, &sockOpts[ssoMulticastTTL])
+ return so.GetInt(c.Conn)
}
// SetMulticastTTL sets the time-to-live field value for future
@@ -32,11 +30,11 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoMulticastTTL]
+ if !ok {
+ return errOpNoSupport
}
- return setInt(s, &sockOpts[ssoMulticastTTL], ttl)
+ return so.SetInt(c.Conn, ttl)
}
// MulticastInterface returns the default interface for multicast
@@ -45,11 +43,11 @@
if !c.ok() {
return nil, syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return nil, err
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return nil, errOpNoSupport
}
- return getInterface(s, &sockOpts[ssoMulticastInterface])
+ return so.getMulticastInterface(c.Conn)
}
// SetMulticastInterface sets the default interface for future
@@ -58,11 +56,11 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoMulticastInterface]
+ if !ok {
+ return errOpNoSupport
}
- return setInterface(s, &sockOpts[ssoMulticastInterface], ifi)
+ return so.setMulticastInterface(c.Conn, ifi)
}
// MulticastLoopback reports whether transmitted multicast packets
@@ -71,11 +69,11 @@
if !c.ok() {
return false, syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return false, err
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return false, errOpNoSupport
}
- on, err := getInt(s, &sockOpts[ssoMulticastLoopback])
+ on, err := so.GetInt(c.Conn)
if err != nil {
return false, err
}
@@ -88,11 +86,11 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoMulticastLoopback]
+ if !ok {
+ return errOpNoSupport
}
- return setInt(s, &sockOpts[ssoMulticastLoopback], boolint(on))
+ return so.SetInt(c.Conn, boolint(on))
}
// JoinGroup joins the group address group on the interface ifi.
@@ -108,15 +106,15 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoJoinGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
return errMissingAddress
}
- return setGroup(s, &sockOpts[ssoJoinGroup], ifi, grp)
+ return so.setGroup(c.Conn, ifi, grp)
}
// LeaveGroup leaves the group address group on the interface ifi
@@ -126,15 +124,15 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoLeaveGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
return errMissingAddress
}
- return setGroup(s, &sockOpts[ssoLeaveGroup], ifi, grp)
+ return so.setGroup(c.Conn, ifi, grp)
}
// JoinSourceSpecificGroup joins the source-specific group comprising
@@ -147,9 +145,9 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoJoinSourceGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
@@ -159,7 +157,7 @@
if src == nil {
return errMissingAddress
}
- return setSourceGroup(s, &sockOpts[ssoJoinSourceGroup], ifi, grp, src)
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
}
// LeaveSourceSpecificGroup leaves the source-specific group on the
@@ -168,9 +166,9 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoLeaveSourceGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
@@ -180,7 +178,7 @@
if src == nil {
return errMissingAddress
}
- return setSourceGroup(s, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src)
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
}
// ExcludeSourceSpecificGroup excludes the source-specific group from
@@ -190,9 +188,9 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoBlockSourceGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
@@ -202,7 +200,7 @@
if src == nil {
return errMissingAddress
}
- return setSourceGroup(s, &sockOpts[ssoBlockSourceGroup], ifi, grp, src)
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
}
// IncludeSourceSpecificGroup includes the excluded source-specific
@@ -211,9 +209,9 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoUnblockSourceGroup]
+ if !ok {
+ return errOpNoSupport
}
grp := netAddrToIP4(group)
if grp == nil {
@@ -223,7 +221,7 @@
if src == nil {
return errMissingAddress
}
- return setSourceGroup(s, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src)
+ return so.setSourceGroup(c.Conn, ifi, grp, src)
}
// ICMPFilter returns an ICMP filter.
@@ -232,11 +230,11 @@
if !c.ok() {
return nil, syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return nil, err
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return nil, errOpNoSupport
}
- return getICMPFilter(s, &sockOpts[ssoICMPFilter])
+ return so.getICMPFilter(c.Conn)
}
// SetICMPFilter deploys the ICMP filter.
@@ -245,9 +243,23 @@
if !c.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.PacketConn)
- if err != nil {
- return err
+ so, ok := sockOpts[ssoICMPFilter]
+ if !ok {
+ return errOpNoSupport
}
- return setICMPFilter(s, &sockOpts[ssoICMPFilter], f)
+ return so.setICMPFilter(c.Conn, f)
+}
+
+// SetBPF attaches a BPF program to the connection.
+//
+// Only supported on Linux.
+func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ so, ok := sockOpts[ssoAttachFilter]
+ if !ok {
+ return errOpNoSupport
+ }
+ return so.setBPF(c.Conn, filter)
}
diff --git a/ipv4/dgramopt_stub.go b/ipv4/dgramopt_stub.go
deleted file mode 100644
index f6b867f..0000000
--- a/ipv4/dgramopt_stub.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2012 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
-
-package ipv4
-
-import "net"
-
-// MulticastTTL returns the time-to-live field value for outgoing
-// multicast packets.
-func (c *dgramOpt) MulticastTTL() (int, error) {
- return 0, errOpNoSupport
-}
-
-// SetMulticastTTL sets the time-to-live field value for future
-// outgoing multicast packets.
-func (c *dgramOpt) SetMulticastTTL(ttl int) error {
- return errOpNoSupport
-}
-
-// MulticastInterface returns the default interface for multicast
-// packet transmissions.
-func (c *dgramOpt) MulticastInterface() (*net.Interface, error) {
- return nil, errOpNoSupport
-}
-
-// SetMulticastInterface sets the default interface for future
-// multicast packet transmissions.
-func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error {
- return errOpNoSupport
-}
-
-// MulticastLoopback reports whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) MulticastLoopback() (bool, error) {
- return false, errOpNoSupport
-}
-
-// SetMulticastLoopback sets whether transmitted multicast packets
-// should be copied and send back to the originator.
-func (c *dgramOpt) SetMulticastLoopback(on bool) error {
- return errOpNoSupport
-}
-
-// JoinGroup joins the group address group on the interface ifi.
-// By default all sources that can cast data to group are accepted.
-// It's possible to mute and unmute data transmission from a specific
-// source by using ExcludeSourceSpecificGroup and
-// IncludeSourceSpecificGroup.
-// JoinGroup uses the system assigned multicast interface when ifi is
-// nil, although this is not recommended because the assignment
-// depends on platforms and sometimes it might require routing
-// configuration.
-func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error {
- return errOpNoSupport
-}
-
-// LeaveGroup leaves the group address group on the interface ifi
-// regardless of whether the group is any-source group or
-// source-specific group.
-func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error {
- return errOpNoSupport
-}
-
-// JoinSourceSpecificGroup joins the source-specific group comprising
-// group and source on the interface ifi.
-// JoinSourceSpecificGroup uses the system assigned multicast
-// interface when ifi is nil, although this is not recommended because
-// the assignment depends on platforms and sometimes it might require
-// routing configuration.
-func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
- return errOpNoSupport
-}
-
-// LeaveSourceSpecificGroup leaves the source-specific group on the
-// interface ifi.
-func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
- return errOpNoSupport
-}
-
-// ExcludeSourceSpecificGroup excludes the source-specific group from
-// the already joined any-source groups by JoinGroup on the interface
-// ifi.
-func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
- return errOpNoSupport
-}
-
-// IncludeSourceSpecificGroup includes the excluded source-specific
-// group by ExcludeSourceSpecificGroup again on the interface ifi.
-func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error {
- return errOpNoSupport
-}
-
-// ICMPFilter returns an ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) {
- return nil, errOpNoSupport
-}
-
-// SetICMPFilter deploys the ICMP filter.
-// Currently only Linux supports this.
-func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error {
- return errOpNoSupport
-}
diff --git a/ipv4/endpoint.go b/ipv4/endpoint.go
index 8f7e07a..f173ed4 100644
--- a/ipv4/endpoint.go
+++ b/ipv4/endpoint.go
@@ -9,7 +9,7 @@
"syscall"
"time"
- "golang.org/x/net/internal/netreflect"
+ "golang.org/x/net/internal/socket"
)
// BUG(mikio): On Windows, the JoinSourceSpecificGroup,
@@ -25,15 +25,16 @@
}
type genericOpt struct {
- net.Conn
+ *socket.Conn
}
func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
// NewConn returns a new Conn.
func NewConn(c net.Conn) *Conn {
+ cc, _ := socket.NewConn(c)
return &Conn{
- genericOpt: genericOpt{Conn: c},
+ genericOpt: genericOpt{Conn: cc},
}
}
@@ -49,21 +50,17 @@
}
type dgramOpt struct {
- net.PacketConn
+ *socket.Conn
}
-func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil }
+func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
// SetControlMessage sets the per packet IP-level socket options.
func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
if !c.payloadHandler.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.dgramOpt.PacketConn)
- if err != nil {
- return err
- }
- return setControlMessage(s, &c.payloadHandler.rawOpt, cf, on)
+ return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
}
// SetDeadline sets the read and write deadlines associated with the
@@ -104,14 +101,15 @@
// NewPacketConn returns a new PacketConn using c as its underlying
// transport.
func NewPacketConn(c net.PacketConn) *PacketConn {
+ cc, _ := socket.NewConn(c.(net.Conn))
p := &PacketConn{
- genericOpt: genericOpt{Conn: c.(net.Conn)},
- dgramOpt: dgramOpt{PacketConn: c},
+ genericOpt: genericOpt{Conn: cc},
+ dgramOpt: dgramOpt{Conn: cc},
payloadHandler: payloadHandler{PacketConn: c},
}
- if _, ok := c.(*net.IPConn); ok && sockOpts[ssoStripHeader].name > 0 {
- if s, err := netreflect.PacketSocketOf(c); err == nil {
- setInt(s, &sockOpts[ssoStripHeader], boolint(true))
+ if _, ok := c.(*net.IPConn); ok {
+ if so, ok := sockOpts[ssoStripHeader]; ok {
+ so.SetInt(p.dgramOpt.Conn, boolint(true))
}
}
return p
@@ -133,11 +131,7 @@
if !c.packetHandler.ok() {
return syscall.EINVAL
}
- s, err := netreflect.PacketSocketOf(c.dgramOpt.PacketConn)
- if err != nil {
- return err
- }
- return setControlMessage(s, &c.packetHandler.rawOpt, cf, on)
+ return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
}
// SetDeadline sets the read and write deadlines associated with the
@@ -178,16 +172,20 @@
// NewRawConn returns a new RawConn using c as its underlying
// transport.
func NewRawConn(c net.PacketConn) (*RawConn, error) {
- r := &RawConn{
- genericOpt: genericOpt{Conn: c.(net.Conn)},
- dgramOpt: dgramOpt{PacketConn: c},
- packetHandler: packetHandler{c: c.(*net.IPConn)},
- }
- s, err := netreflect.PacketSocketOf(c)
+ cc, err := socket.NewConn(c.(net.Conn))
if err != nil {
return nil, err
}
- if err := setInt(s, &sockOpts[ssoHeaderPrepend], boolint(true)); err != nil {
+ r := &RawConn{
+ genericOpt: genericOpt{Conn: cc},
+ dgramOpt: dgramOpt{Conn: cc},
+ packetHandler: packetHandler{c: c.(*net.IPConn)},
+ }
+ so, ok := sockOpts[ssoHeaderPrepend]
+ if !ok {
+ return nil, errOpNoSupport
+ }
+ if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
return nil, err
}
return r, nil
diff --git a/ipv4/genericopt.go b/ipv4/genericopt.go
new file mode 100644
index 0000000..119bf84
--- /dev/null
+++ b/ipv4/genericopt.go
@@ -0,0 +1,57 @@
+// Copyright 2012 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 ipv4
+
+import "syscall"
+
+// TOS returns the type-of-service field value for outgoing packets.
+func (c *genericOpt) TOS() (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ so, ok := sockOpts[ssoTOS]
+ if !ok {
+ return 0, errOpNoSupport
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetTOS sets the type-of-service field value for future outgoing
+// packets.
+func (c *genericOpt) SetTOS(tos int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ so, ok := sockOpts[ssoTOS]
+ if !ok {
+ return errOpNoSupport
+ }
+ return so.SetInt(c.Conn, tos)
+}
+
+// TTL returns the time-to-live field value for outgoing packets.
+func (c *genericOpt) TTL() (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ so, ok := sockOpts[ssoTTL]
+ if !ok {
+ return 0, errOpNoSupport
+ }
+ return so.GetInt(c.Conn)
+}
+
+// SetTTL sets the time-to-live field value for future outgoing
+// packets.
+func (c *genericOpt) SetTTL(ttl int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ so, ok := sockOpts[ssoTTL]
+ if !ok {
+ return errOpNoSupport
+ }
+ return so.SetInt(c.Conn, ttl)
+}
diff --git a/ipv4/genericopt_posix.go b/ipv4/genericopt_posix.go
deleted file mode 100644
index 58168b7..0000000
--- a/ipv4/genericopt_posix.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012 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 solaris windows
-
-package ipv4
-
-import (
- "syscall"
-
- "golang.org/x/net/internal/netreflect"
-)
-
-// TOS returns the type-of-service field value for outgoing packets.
-func (c *genericOpt) TOS() (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- s, err := netreflect.SocketOf(c.Conn)
- if err != nil {
- return 0, err
- }
- return getInt(s, &sockOpts[ssoTOS])
-}
-
-// SetTOS sets the type-of-service field value for future outgoing
-// packets.
-func (c *genericOpt) SetTOS(tos int) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- s, err := netreflect.SocketOf(c.Conn)
- if err != nil {
- return err
- }
- return setInt(s, &sockOpts[ssoTOS], tos)
-}
-
-// TTL returns the time-to-live field value for outgoing packets.
-func (c *genericOpt) TTL() (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- s, err := netreflect.SocketOf(c.Conn)
- if err != nil {
- return 0, err
- }
- return getInt(s, &sockOpts[ssoTTL])
-}
-
-// SetTTL sets the time-to-live field value for future outgoing
-// packets.
-func (c *genericOpt) SetTTL(ttl int) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- s, err := netreflect.SocketOf(c.Conn)
- if err != nil {
- return err
- }
- return setInt(s, &sockOpts[ssoTTL], ttl)
-}
diff --git a/ipv4/genericopt_stub.go b/ipv4/genericopt_stub.go
deleted file mode 100644
index 661a4d1..0000000
--- a/ipv4/genericopt_stub.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 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
-
-package ipv4
-
-// TOS returns the type-of-service field value for outgoing packets.
-func (c *genericOpt) TOS() (int, error) {
- return 0, errOpNoSupport
-}
-
-// SetTOS sets the type-of-service field value for future outgoing
-// packets.
-func (c *genericOpt) SetTOS(tos int) error {
- return errOpNoSupport
-}
-
-// TTL returns the time-to-live field value for outgoing packets.
-func (c *genericOpt) TTL() (int, error) {
- return 0, errOpNoSupport
-}
-
-// SetTTL sets the time-to-live field value for future outgoing
-// packets.
-func (c *genericOpt) SetTTL(ttl int) error {
- return errOpNoSupport
-}
diff --git a/ipv4/header.go b/ipv4/header.go
index 6dc26d4..6480597 100644
--- a/ipv4/header.go
+++ b/ipv4/header.go
@@ -10,6 +10,8 @@
"net"
"runtime"
"syscall"
+
+ "golang.org/x/net/internal/socket"
)
const (
@@ -64,12 +66,12 @@
flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13)
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
- nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
- nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
case "freebsd":
if freebsdVersion < 1100000 {
- nativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
- nativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
+ socket.NativeEndian.PutUint16(b[2:4], uint16(h.TotalLen))
+ socket.NativeEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
} else {
binary.BigEndian.PutUint16(b[2:4], uint16(h.TotalLen))
binary.BigEndian.PutUint16(b[6:8], uint16(flagsAndFragOff))
@@ -118,15 +120,15 @@
}
switch runtime.GOOS {
case "darwin", "dragonfly", "netbsd":
- h.TotalLen = int(nativeEndian.Uint16(b[2:4])) + hdrlen
- h.FragOff = int(nativeEndian.Uint16(b[6:8]))
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen
+ h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
case "freebsd":
if freebsdVersion < 1100000 {
- h.TotalLen = int(nativeEndian.Uint16(b[2:4]))
+ h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4]))
if freebsdVersion < 1000000 {
h.TotalLen += hdrlen
}
- h.FragOff = int(nativeEndian.Uint16(b[6:8]))
+ h.FragOff = int(socket.NativeEndian.Uint16(b[6:8]))
} else {
h.TotalLen = int(binary.BigEndian.Uint16(b[2:4]))
h.FragOff = int(binary.BigEndian.Uint16(b[6:8]))
diff --git a/ipv4/header_test.go b/ipv4/header_test.go
index cdf27fd..8dd6fc6 100644
--- a/ipv4/header_test.go
+++ b/ipv4/header_test.go
@@ -12,6 +12,8 @@
"runtime"
"strings"
"testing"
+
+ "golang.org/x/net/internal/socket"
)
type headerTest struct {
@@ -87,7 +89,7 @@
func TestMarshalHeader(t *testing.T) {
tt := &headerLittleEndianTest
- if nativeEndian != binary.LittleEndian {
+ if socket.NativeEndian != binary.LittleEndian {
t.Skip("no test for non-little endian machine yet")
}
@@ -118,7 +120,7 @@
func TestParseHeader(t *testing.T) {
tt := &headerLittleEndianTest
- if nativeEndian != binary.LittleEndian {
+ if socket.NativeEndian != binary.LittleEndian {
t.Skip("no test for big endian machine yet")
}
diff --git a/ipv4/helper.go b/ipv4/helper.go
index 0838979..5f747a4 100644
--- a/ipv4/helper.go
+++ b/ipv4/helper.go
@@ -5,10 +5,8 @@
package ipv4
import (
- "encoding/binary"
"errors"
"net"
- "unsafe"
)
var (
@@ -23,20 +21,8 @@
// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html.
freebsdVersion uint32
-
- nativeEndian binary.ByteOrder
)
-func init() {
- i := uint32(1)
- b := (*[4]byte)(unsafe.Pointer(&i))
- if b[0] == 1 {
- nativeEndian = binary.LittleEndian
- } else {
- nativeEndian = binary.BigEndian
- }
-}
-
func boolint(b bool) int {
if b {
return 1
diff --git a/ipv4/payload_cmsg.go b/ipv4/payload_cmsg.go
index 5e6e55c..9a155d2 100644
--- a/ipv4/payload_cmsg.go
+++ b/ipv4/payload_cmsg.go
@@ -27,7 +27,7 @@
return 0, nil, nil, err
}
case *net.IPConn:
- if sockOpts[ssoStripHeader].name > 0 {
+ if _, ok := sockOpts[ssoStripHeader]; ok {
if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
return 0, nil, nil, err
}
diff --git a/ipv4/sockopt.go b/ipv4/sockopt.go
index ace37d3..22e90c0 100644
--- a/ipv4/sockopt.go
+++ b/ipv4/sockopt.go
@@ -4,6 +4,8 @@
package ipv4
+import "golang.org/x/net/internal/socket"
+
// Sticky socket options
const (
ssoTOS = iota // header field for unicast packet
@@ -24,16 +26,12 @@
ssoLeaveSourceGroup // source-specific multicast
ssoBlockSourceGroup // any-source or source-specific multicast
ssoUnblockSourceGroup // any-source or source-specific multicast
- ssoMax
+ ssoAttachFilter // attach BPF for filtering inbound traffic
)
// Sticky socket option value types
const (
- ssoTypeByte = iota + 1
- ssoTypeInt
- ssoTypeInterface
- ssoTypeICMPFilter
- ssoTypeIPMreq
+ ssoTypeIPMreq = iota + 1
ssoTypeIPMreqn
ssoTypeGroupReq
ssoTypeGroupSourceReq
@@ -41,6 +39,6 @@
// A sockOpt represents a binding for sticky socket option.
type sockOpt struct {
- name int // option name, must be equal or greater than 1
- typ int // option value type, must be equal or greater than 1
+ socket.Option
+ typ int // hint for option value type; optional
}
diff --git a/ipv4/sockopt_asmreq_posix.go b/ipv4/sockopt_asmreq_posix.go
deleted file mode 100644
index 2259a39..0000000
--- a/ipv4/sockopt_asmreq_posix.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2012 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 solaris windows
-
-package ipv4
-
-import (
- "net"
- "os"
- "unsafe"
-
- "golang.org/x/net/internal/iana"
-)
-
-func setsockoptIPMreq(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- mreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
- if err := setIPMreqInterface(&mreq, ifi); err != nil {
- return err
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&mreq), sizeofIPMreq))
-}
-
-func getsockoptInterface(s uintptr, name int) (*net.Interface, error) {
- var b [4]byte
- l := uint32(4)
- if err := getsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), &l); err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
- if err != nil {
- return nil, err
- }
- return ifi, nil
-}
-
-func setsockoptInterface(s uintptr, name int, ifi *net.Interface) error {
- ip, err := netInterfaceToIP4(ifi)
- if err != nil {
- return err
- }
- var b [4]byte
- copy(b[:], ip)
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), uint32(4)))
-}
diff --git a/ipv4/sockopt_asmreq_stub.go b/ipv4/sockopt_asmreq_stub.go
deleted file mode 100644
index e655635..0000000
--- a/ipv4/sockopt_asmreq_stub.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 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,!solaris,!windows
-
-package ipv4
-
-import "net"
-
-func setsockoptIPMreq(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- return errOpNoSupport
-}
-
-func getsockoptInterface(s uintptr, name int) (*net.Interface, error) {
- return nil, errOpNoSupport
-}
-
-func setsockoptInterface(s uintptr, name int, ifi *net.Interface) error {
- return errOpNoSupport
-}
diff --git a/ipv4/sockopt_asmreqn_stub.go b/ipv4/sockopt_asmreqn_stub.go
deleted file mode 100644
index 0c7f0f8..0000000
--- a/ipv4/sockopt_asmreqn_stub.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 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,!freebsd,!linux
-
-package ipv4
-
-import "net"
-
-func getsockoptIPMreqn(s uintptr, name int) (*net.Interface, error) {
- return nil, errOpNoSupport
-}
-
-func setsockoptIPMreqn(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- return errOpNoSupport
-}
diff --git a/ipv4/sockopt_asmreqn_unix.go b/ipv4/sockopt_asmreqn_unix.go
deleted file mode 100644
index 92daffb..0000000
--- a/ipv4/sockopt_asmreqn_unix.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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 freebsd linux
-
-package ipv4
-
-import (
- "net"
- "os"
- "unsafe"
-
- "golang.org/x/net/internal/iana"
-)
-
-func getsockoptIPMreqn(s uintptr, name int) (*net.Interface, error) {
- var mreqn ipMreqn
- l := uint32(sizeofIPMreqn)
- if err := getsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- if mreqn.Ifindex == 0 {
- return nil, nil
- }
- ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))
- if err != nil {
- return nil, err
- }
- return ifi, nil
-}
-
-func setsockoptIPMreqn(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- var mreqn ipMreqn
- if ifi != nil {
- mreqn.Ifindex = int32(ifi.Index)
- }
- if grp != nil {
- mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), sizeofIPMreqn))
-}
diff --git a/ipv4/sockopt_posix.go b/ipv4/sockopt_posix.go
index d806803..e96955b 100644
--- a/ipv4/sockopt_posix.go
+++ b/ipv4/sockopt_posix.go
@@ -8,115 +8,64 @@
import (
"net"
- "os"
"unsafe"
- "golang.org/x/net/internal/iana"
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
)
-func getInt(s uintptr, opt *sockOpt) (int, error) {
- if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) {
- return 0, errOpNoSupport
- }
- var i int32
- var b byte
- p := unsafe.Pointer(&i)
- l := uint32(4)
- if opt.typ == ssoTypeByte {
- p = unsafe.Pointer(&b)
- l = 1
- }
- if err := getsockopt(s, iana.ProtocolIP, opt.name, p, &l); err != nil {
- return 0, os.NewSyscallError("getsockopt", err)
- }
- if opt.typ == ssoTypeByte {
- return int(b), nil
- }
- return int(i), nil
-}
-
-func setInt(s uintptr, opt *sockOpt, v int) error {
- if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) {
- return errOpNoSupport
- }
- i := int32(v)
- var b byte
- p := unsafe.Pointer(&i)
- l := uint32(4)
- if opt.typ == ssoTypeByte {
- b = byte(v)
- p = unsafe.Pointer(&b)
- l = 1
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, opt.name, p, l))
-}
-
-func getInterface(s uintptr, opt *sockOpt) (*net.Interface, error) {
- if opt.name < 1 {
- return nil, errOpNoSupport
- }
- switch opt.typ {
- case ssoTypeInterface:
- return getsockoptInterface(s, opt.name)
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ switch so.typ {
case ssoTypeIPMreqn:
- return getsockoptIPMreqn(s, opt.name)
+ return so.getIPMreqn(c)
default:
- return nil, errOpNoSupport
+ return so.getMulticastIf(c)
}
}
-func setInterface(s uintptr, opt *sockOpt, ifi *net.Interface) error {
- if opt.name < 1 {
- return errOpNoSupport
- }
- switch opt.typ {
- case ssoTypeInterface:
- return setsockoptInterface(s, opt.name, ifi)
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ switch so.typ {
case ssoTypeIPMreqn:
- return setsockoptIPMreqn(s, opt.name, ifi, nil)
+ return so.setIPMreqn(c, ifi, nil)
default:
- return errOpNoSupport
+ return so.setMulticastIf(c, ifi)
}
}
-func getICMPFilter(s uintptr, opt *sockOpt) (*ICMPFilter, error) {
- if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ b := make([]byte, so.Len)
+ n, err := so.Get(c, b)
+ if err != nil {
+ return nil, err
+ }
+ if n != sizeofICMPFilter {
return nil, errOpNoSupport
}
- var f ICMPFilter
- l := uint32(sizeofICMPFilter)
- if err := getsockopt(s, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.icmpFilter), &l); err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- return &f, nil
+ return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil
}
-func setICMPFilter(s uintptr, opt *sockOpt, f *ICMPFilter) error {
- if opt.name < 1 || opt.typ != ssoTypeICMPFilter {
- return errOpNoSupport
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.icmpFilter), sizeofICMPFilter))
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ b := (*[sizeofICMPFilter]byte)(unsafe.Pointer(f))[:sizeofICMPFilter]
+ return so.Set(c, b)
}
-func setGroup(s uintptr, opt *sockOpt, ifi *net.Interface, grp net.IP) error {
- if opt.name < 1 {
- return errOpNoSupport
- }
- switch opt.typ {
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ switch so.typ {
case ssoTypeIPMreq:
- return setsockoptIPMreq(s, opt.name, ifi, grp)
+ return so.setIPMreq(c, ifi, grp)
case ssoTypeIPMreqn:
- return setsockoptIPMreqn(s, opt.name, ifi, grp)
+ return so.setIPMreqn(c, ifi, grp)
case ssoTypeGroupReq:
- return setsockoptGroupReq(s, opt.name, ifi, grp)
+ return so.setGroupReq(c, ifi, grp)
default:
return errOpNoSupport
}
}
-func setSourceGroup(s uintptr, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error {
- if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq {
- return errOpNoSupport
- }
- return setsockoptGroupSourceReq(s, opt.name, ifi, grp, src)
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return so.setGroupSourceReq(c, ifi, grp, src)
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
+ return so.setAttachFilter(c, f)
}
diff --git a/ipv4/sockopt_ssmreq_stub.go b/ipv4/sockopt_ssmreq_stub.go
deleted file mode 100644
index 0287396..0000000
--- a/ipv4/sockopt_ssmreq_stub.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 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,!freebsd,!linux,!solaris
-
-package ipv4
-
-import "net"
-
-func setsockoptGroupReq(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- return errOpNoSupport
-}
-
-func setsockoptGroupSourceReq(s uintptr, name int, ifi *net.Interface, grp, src net.IP) error {
- return errOpNoSupport
-}
diff --git a/ipv4/sockopt_ssmreq_unix.go b/ipv4/sockopt_ssmreq_unix.go
deleted file mode 100644
index c9af55b..0000000
--- a/ipv4/sockopt_ssmreq_unix.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2014 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 freebsd linux solaris
-
-package ipv4
-
-import (
- "net"
- "os"
- "unsafe"
-
- "golang.org/x/net/internal/iana"
-)
-
-var freebsd32o64 bool
-
-func setsockoptGroupReq(s uintptr, name int, ifi *net.Interface, grp net.IP) error {
- var gr groupReq
- if ifi != nil {
- gr.Interface = uint32(ifi.Index)
- }
- gr.setGroup(grp)
- var p unsafe.Pointer
- var l uint32
- if freebsd32o64 {
- var d [sizeofGroupReq + 4]byte
- s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))
- copy(d[:4], s[:4])
- copy(d[8:], s[4:])
- p = unsafe.Pointer(&d[0])
- l = sizeofGroupReq + 4
- } else {
- p = unsafe.Pointer(&gr)
- l = sizeofGroupReq
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, name, p, l))
-}
-
-func setsockoptGroupSourceReq(s uintptr, name int, ifi *net.Interface, grp, src net.IP) error {
- var gsr groupSourceReq
- if ifi != nil {
- gsr.Interface = uint32(ifi.Index)
- }
- gsr.setSourceGroup(grp, src)
- var p unsafe.Pointer
- var l uint32
- if freebsd32o64 {
- var d [sizeofGroupSourceReq + 4]byte
- s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
- copy(d[:4], s[:4])
- copy(d[8:], s[4:])
- p = unsafe.Pointer(&d[0])
- l = sizeofGroupSourceReq + 4
- } else {
- p = unsafe.Pointer(&gsr)
- l = sizeofGroupSourceReq
- }
- return os.NewSyscallError("setsockopt", setsockopt(s, iana.ProtocolIP, name, p, l))
-}
diff --git a/ipv4/sockopt_stub.go b/ipv4/sockopt_stub.go
index 4ff6099..23249b7 100644
--- a/ipv4/sockopt_stub.go
+++ b/ipv4/sockopt_stub.go
@@ -2,10 +2,41 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build nacl plan9
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv4
-func setInt(s uintptr, opt *sockOpt, v int) error {
+import (
+ "net"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
+ return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
+ return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
return errOpNoSupport
}
diff --git a/ipv4/sockopt_asmreq.go b/ipv4/sys_asmreq.go
similarity index 65%
rename from ipv4/sockopt_asmreq.go
rename to ipv4/sys_asmreq.go
index 8092f1d..0388cba 100644
--- a/ipv4/sockopt_asmreq.go
+++ b/ipv4/sys_asmreq.go
@@ -6,7 +6,43 @@
package ipv4
-import "net"
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ mreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
+ if err := setIPMreqInterface(&mreq, ifi); err != nil {
+ return err
+ }
+ b := (*[sizeofIPMreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPMreq]
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {
+ var b [4]byte
+ if _, err := so.Get(c, b[:]); err != nil {
+ return nil, err
+ }
+ ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3]))
+ if err != nil {
+ return nil, err
+ }
+ return ifi, nil
+}
+
+func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {
+ ip, err := netInterfaceToIP4(ifi)
+ if err != nil {
+ return err
+ }
+ var b [4]byte
+ copy(b[:], ip)
+ return so.Set(c, b[:])
+}
func setIPMreqInterface(mreq *ipMreq, ifi *net.Interface) error {
if ifi == nil {
diff --git a/ipv4/sys_asmreq_stub.go b/ipv4/sys_asmreq_stub.go
new file mode 100644
index 0000000..f391920
--- /dev/null
+++ b/ipv4/sys_asmreq_stub.go
@@ -0,0 +1,25 @@
+// Copyright 2017 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,!solaris,!windows
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) {
+ return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error {
+ return errOpNoSupport
+}
diff --git a/ipv4/sys_asmreqn.go b/ipv4/sys_asmreqn.go
new file mode 100644
index 0000000..1f24f69
--- /dev/null
+++ b/ipv4/sys_asmreqn.go
@@ -0,0 +1,42 @@
+// Copyright 2014 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 freebsd linux
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
+ b := make([]byte, so.Len)
+ if _, err := so.Get(c, b); err != nil {
+ return nil, err
+ }
+ mreqn := (*ipMreqn)(unsafe.Pointer(&b[0]))
+ if mreqn.Ifindex == 0 {
+ return nil, nil
+ }
+ ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))
+ if err != nil {
+ return nil, err
+ }
+ return ifi, nil
+}
+
+func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var mreqn ipMreqn
+ if ifi != nil {
+ mreqn.Ifindex = int32(ifi.Index)
+ }
+ if grp != nil {
+ mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]}
+ }
+ b := (*[sizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:sizeofIPMreqn]
+ return so.Set(c, b)
+}
diff --git a/ipv4/sys_asmreqn_stub.go b/ipv4/sys_asmreqn_stub.go
new file mode 100644
index 0000000..0711d3d
--- /dev/null
+++ b/ipv4/sys_asmreqn_stub.go
@@ -0,0 +1,21 @@
+// Copyright 2014 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,!freebsd,!linux
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) {
+ return nil, errOpNoSupport
+}
+
+func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errOpNoSupport
+}
diff --git a/ipv4/sys_bpf.go b/ipv4/sys_bpf.go
new file mode 100644
index 0000000..9f30b73
--- /dev/null
+++ b/ipv4/sys_bpf.go
@@ -0,0 +1,23 @@
+// Copyright 2017 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 linux
+
+package ipv4
+
+import (
+ "unsafe"
+
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ prog := sockFProg{
+ Len: uint16(len(f)),
+ Filter: (*sockFilter)(unsafe.Pointer(&f[0])),
+ }
+ b := (*[sizeofSockFprog]byte)(unsafe.Pointer(&prog))[:sizeofSockFprog]
+ return so.Set(c, b)
+}
diff --git a/ipv4/sys_bpf_stub.go b/ipv4/sys_bpf_stub.go
new file mode 100644
index 0000000..9a21320
--- /dev/null
+++ b/ipv4/sys_bpf_stub.go
@@ -0,0 +1,16 @@
+// Copyright 2017 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 !linux
+
+package ipv4
+
+import (
+ "golang.org/x/net/bpf"
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
+ return errOpNoSupport
+}
diff --git a/ipv4/sys_bsd.go b/ipv4/sys_bsd.go
index 203033d..58256dd 100644
--- a/ipv4/sys_bsd.go
+++ b/ipv4/sys_bsd.go
@@ -2,13 +2,16 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build dragonfly netbsd
+// +build netbsd openbsd
package ipv4
import (
"net"
"syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
var (
@@ -18,17 +21,17 @@
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt},
- ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
- ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/ipv4/sys_darwin.go b/ipv4/sys_darwin.go
index abfffca..e8fb191 100644
--- a/ipv4/sys_darwin.go
+++ b/ipv4/sys_darwin.go
@@ -10,6 +10,9 @@
"strings"
"syscall"
"unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
var (
@@ -19,19 +22,19 @@
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt},
- ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoStripHeader: {sysIP_STRIPHDR, ssoTypeInt},
- ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
- ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_STRIPHDR, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
@@ -57,21 +60,14 @@
ctlOpts[ctlPacketInfo].length = sizeofInetPktinfo
ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo
ctlOpts[ctlPacketInfo].parse = parsePacketInfo
- sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO
- sockOpts[ssoPacketInfo].typ = ssoTypeInt
- sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
- sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP
- sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq
- sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP
- sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq
- sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP
- sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP
- sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE
- sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq
- sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE
- sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq
+ sockOpts[ssoPacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}}
+ sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
+ sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+ sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
+ sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+ sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+ sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
+ sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
}
func (pi *inetPktinfo) setIfindex(i int) {
diff --git a/ipv4/sys_dragonfly.go b/ipv4/sys_dragonfly.go
new file mode 100644
index 0000000..859764f
--- /dev/null
+++ b/ipv4/sys_dragonfly.go
@@ -0,0 +1,35 @@
+// Copyright 2017 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 ipv4
+
+import (
+ "net"
+ "syscall"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
+var (
+ ctlOpts = [ctlMax]ctlOpt{
+ ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
+ ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
+ ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
+ }
+
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ }
+)
diff --git a/ipv4/sys_freebsd.go b/ipv4/sys_freebsd.go
index fceffe9..b800324 100644
--- a/ipv4/sys_freebsd.go
+++ b/ipv4/sys_freebsd.go
@@ -10,6 +10,9 @@
"strings"
"syscall"
"unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
var (
@@ -19,29 +22,29 @@
ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt},
- ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoJoinGroup: {sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
- ssoLeaveGroup: {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
- ssoJoinSourceGroup: {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVDSTADDR, Len: 4}},
+ ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVIF, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
func init() {
freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate")
if freebsdVersion >= 1000000 {
- sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn
+ sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn}
}
if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" {
archs, _ := syscall.Sysctl("kern.supported_archs")
diff --git a/ipv4/sys_linux.go b/ipv4/sys_linux.go
index c6c2a50..60defe1 100644
--- a/ipv4/sys_linux.go
+++ b/ipv4/sys_linux.go
@@ -8,6 +8,9 @@
"net"
"syscall"
"unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
var (
@@ -16,22 +19,23 @@
ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeInt},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeIPMreqn},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoPacketInfo: {sysIP_PKTINFO, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoICMPFilter: {sysICMP_FILTER, ssoTypeICMPFilter},
- ssoJoinGroup: {sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
- ssoLeaveGroup: {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
- ssoJoinSourceGroup: {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: sizeofIPMreqn}, typ: ssoTypeIPMreqn},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_PKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolReserved, Name: sysICMP_FILTER, Len: sizeofICMPFilter}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoAttachFilter: {Option: socket.Option{Level: sysSOL_SOCKET, Name: sysSO_ATTACH_FILTER, Len: sizeofSockFprog}},
}
)
diff --git a/ipv4/sys_linux_386.s b/ipv4/sys_linux_386.s
deleted file mode 100644
index b85551a..0000000
--- a/ipv4/sys_linux_386.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2014 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.
-
-#include "textflag.h"
-
-TEXT ·socketcall(SB),NOSPLIT,$0-36
- JMP syscall·socketcall(SB)
diff --git a/ipv4/sys_openbsd.go b/ipv4/sys_openbsd.go
deleted file mode 100644
index d78083a..0000000
--- a/ipv4/sys_openbsd.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 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 ipv4
-
-import (
- "net"
- "syscall"
-)
-
-var (
- ctlOpts = [ctlMax]ctlOpt{
- ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL},
- ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst},
- ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface},
- }
-
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeByte},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt},
- ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
- ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
- }
-)
diff --git a/ipv4/sys_solaris.go b/ipv4/sys_solaris.go
index 879f39e..832fef1 100644
--- a/ipv4/sys_solaris.go
+++ b/ipv4/sys_solaris.go
@@ -8,6 +8,9 @@
"net"
"syscall"
"unsafe"
+
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
)
var (
@@ -16,21 +19,21 @@
ctlPacketInfo: {sysIP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo},
}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeByte},
- ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt},
- ssoPacketInfo: {sysIP_RECVPKTINFO, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoJoinGroup: {sysMCAST_JOIN_GROUP, ssoTypeGroupReq},
- ssoLeaveGroup: {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq},
- ssoJoinSourceGroup: {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoLeaveSourceGroup: {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq},
- ssoBlockSourceGroup: {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq},
- ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq},
+ sockOpts = map[int]sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 1}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 1}},
+ ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVTTL, Len: 4}},
+ ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_RECVPKTINFO, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq},
+ ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
+ ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq},
}
)
diff --git a/ipv4/sys_solaris_amd64.s b/ipv4/sys_solaris_amd64.s
deleted file mode 100644
index 39d76af..0000000
--- a/ipv4/sys_solaris_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2016 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.
-
-#include "textflag.h"
-
-TEXT ·sysvicall6(SB),NOSPLIT,$0-88
- JMP syscall·sysvicall6(SB)
diff --git a/ipv4/sys_ssmreq.go b/ipv4/sys_ssmreq.go
new file mode 100644
index 0000000..ae5704e
--- /dev/null
+++ b/ipv4/sys_ssmreq.go
@@ -0,0 +1,54 @@
+// Copyright 2014 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 freebsd linux solaris
+
+package ipv4
+
+import (
+ "net"
+ "unsafe"
+
+ "golang.org/x/net/internal/socket"
+)
+
+var freebsd32o64 bool
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ var gr groupReq
+ if ifi != nil {
+ gr.Interface = uint32(ifi.Index)
+ }
+ gr.setGroup(grp)
+ var b []byte
+ if freebsd32o64 {
+ var d [sizeofGroupReq + 4]byte
+ s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq]
+ }
+ return so.Set(c, b)
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ var gsr groupSourceReq
+ if ifi != nil {
+ gsr.Interface = uint32(ifi.Index)
+ }
+ gsr.setSourceGroup(grp, src)
+ var b []byte
+ if freebsd32o64 {
+ var d [sizeofGroupSourceReq + 4]byte
+ s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))
+ copy(d[:4], s[:4])
+ copy(d[8:], s[4:])
+ b = d[:]
+ } else {
+ b = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq]
+ }
+ return so.Set(c, b)
+}
diff --git a/ipv4/sys_ssmreq_stub.go b/ipv4/sys_ssmreq_stub.go
new file mode 100644
index 0000000..e6b7623
--- /dev/null
+++ b/ipv4/sys_ssmreq_stub.go
@@ -0,0 +1,21 @@
+// Copyright 2014 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,!freebsd,!linux,!solaris
+
+package ipv4
+
+import (
+ "net"
+
+ "golang.org/x/net/internal/socket"
+)
+
+func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
+ return errOpNoSupport
+}
+
+func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
+ return errOpNoSupport
+}
diff --git a/ipv4/sys_stub.go b/ipv4/sys_stub.go
index d6dd812..4f07647 100644
--- a/ipv4/sys_stub.go
+++ b/ipv4/sys_stub.go
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build nacl plan9
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
package ipv4
var (
ctlOpts = [ctlMax]ctlOpt{}
- sockOpts = [ssoMax]sockOpt{}
+ sockOpts = map[int]*sockOpt{}
)
diff --git a/ipv4/sys_windows.go b/ipv4/sys_windows.go
index fac00bd..b0913d5 100644
--- a/ipv4/sys_windows.go
+++ b/ipv4/sys_windows.go
@@ -4,6 +4,11 @@
package ipv4
+import (
+ "golang.org/x/net/internal/iana"
+ "golang.org/x/net/internal/socket"
+)
+
const (
// See ws2tcpip.h.
sysIP_OPTIONS = 0x1
@@ -45,15 +50,15 @@
var (
ctlOpts = [ctlMax]ctlOpt{}
- sockOpts = [ssoMax]sockOpt{
- ssoTOS: {sysIP_TOS, ssoTypeInt},
- ssoTTL: {sysIP_TTL, ssoTypeInt},
- ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeInt},
- ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface},
- ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt},
- ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt},
- ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq},
- ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq},
+ sockOpts = map[int]*sockOpt{
+ ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TOS, Len: 4}},
+ ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_TTL, Len: 4}},
+ ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_TTL, Len: 4}},
+ ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_IF, Len: 4}},
+ ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_MULTICAST_LOOP, Len: 4}},
+ ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_HDRINCL, Len: 4}},
+ ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
+ ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: sysIP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq},
}
)
diff --git a/ipv4/syscall_linux_386.go b/ipv4/syscall_linux_386.go
deleted file mode 100644
index 84f60bf..0000000
--- a/ipv4/syscall_linux_386.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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 ipv4
-
-import (
- "syscall"
- "unsafe"
-)
-
-const (
- sysGETSOCKOPT = 0xf
- sysSETSOCKOPT = 0xe
-)
-
-func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno)
-
-func getsockopt(s uintptr, level, name int, v unsafe.Pointer, l *uint32) error {
- if _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
- return error(errno)
- }
- return nil
-}
-
-func setsockopt(s uintptr, level, name int, v unsafe.Pointer, l uint32) error {
- if _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
- return error(errno)
- }
- return nil
-}
diff --git a/ipv4/syscall_solaris.go b/ipv4/syscall_solaris.go
deleted file mode 100644
index 8b0e1e4..0000000
--- a/ipv4/syscall_solaris.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 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 ipv4
-
-import (
- "syscall"
- "unsafe"
-)
-
-//go:cgo_import_dynamic libc___xnet_getsockopt __xnet_getsockopt "libsocket.so"
-//go:cgo_import_dynamic libc_setsockopt setsockopt "libsocket.so"
-
-//go:linkname procGetsockopt libc___xnet_getsockopt
-//go:linkname procSetsockopt libc_setsockopt
-
-var (
- procGetsockopt uintptr
- procSetsockopt uintptr
-)
-
-func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno)
-
-func getsockopt(s uintptr, level, name int, v unsafe.Pointer, l *uint32) error {
- _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procGetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0)
- if errno != 0 {
- return error(errno)
- }
- return nil
-}
-
-func setsockopt(s uintptr, level, name int, v unsafe.Pointer, l uint32) error {
- if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procSetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
- return error(errno)
- }
- return nil
-}
diff --git a/ipv4/syscall_unix.go b/ipv4/syscall_unix.go
deleted file mode 100644
index d952763..0000000
--- a/ipv4/syscall_unix.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2014 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,!386 netbsd openbsd
-
-package ipv4
-
-import (
- "syscall"
- "unsafe"
-)
-
-func getsockopt(s uintptr, level, name int, v unsafe.Pointer, l *uint32) error {
- if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 {
- return error(errno)
- }
- return nil
-}
-
-func setsockopt(s uintptr, level, name int, v unsafe.Pointer, l uint32) error {
- if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 {
- return error(errno)
- }
- return nil
-}
diff --git a/ipv4/syscall_windows.go b/ipv4/syscall_windows.go
deleted file mode 100644
index 0f42d22..0000000
--- a/ipv4/syscall_windows.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2016 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 ipv4
-
-import (
- "syscall"
- "unsafe"
-)
-
-func getsockopt(s uintptr, level, name int, v unsafe.Pointer, l *uint32) error {
- return syscall.Getsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(v), (*int32)(unsafe.Pointer(l)))
-}
-
-func setsockopt(s uintptr, level, name int, v unsafe.Pointer, l uint32) error {
- return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(v), int32(l))
-}
diff --git a/ipv4/zsys_linux_386.go b/ipv4/zsys_linux_386.go
index 4da6720..c0260f0 100644
--- a/ipv4/zsys_linux_386.go
+++ b/ipv4/zsys_linux_386.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x104
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x8
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_amd64.go b/ipv4/zsys_linux_amd64.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_amd64.go
+++ b/ipv4/zsys_linux_amd64.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_arm.go b/ipv4/zsys_linux_arm.go
index 4da6720..c0260f0 100644
--- a/ipv4/zsys_linux_arm.go
+++ b/ipv4/zsys_linux_arm.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x104
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x8
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_arm64.go b/ipv4/zsys_linux_arm64.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_arm64.go
+++ b/ipv4/zsys_linux_arm64.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_mips.go b/ipv4/zsys_linux_mips.go
index 4da6720..c0260f0 100644
--- a/ipv4/zsys_linux_mips.go
+++ b/ipv4/zsys_linux_mips.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x104
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x8
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_mips64.go b/ipv4/zsys_linux_mips64.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_mips64.go
+++ b/ipv4/zsys_linux_mips64.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_mips64le.go b/ipv4/zsys_linux_mips64le.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_mips64le.go
+++ b/ipv4/zsys_linux_mips64le.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_mipsle.go b/ipv4/zsys_linux_mipsle.go
index 4da6720..c0260f0 100644
--- a/ipv4/zsys_linux_mipsle.go
+++ b/ipv4/zsys_linux_mipsle.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x104
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x8
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_ppc.go b/ipv4/zsys_linux_ppc.go
index b825a18..f65bd9a 100644
--- a/ipv4/zsys_linux_ppc.go
+++ b/ipv4/zsys_linux_ppc.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x104
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x8
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_ppc64.go b/ipv4/zsys_linux_ppc64.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_ppc64.go
+++ b/ipv4/zsys_linux_ppc64.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_ppc64le.go b/ipv4/zsys_linux_ppc64le.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_ppc64le.go
+++ b/ipv4/zsys_linux_ppc64le.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {
diff --git a/ipv4/zsys_linux_s390x.go b/ipv4/zsys_linux_s390x.go
index 65945bb..9c967ea 100644
--- a/ipv4/zsys_linux_s390x.go
+++ b/ipv4/zsys_linux_s390x.go
@@ -70,6 +70,8 @@
sizeofGroupSourceReq = 0x108
sizeofICMPFilter = 0x4
+
+ sizeofSockFprog = 0x10
)
type kernelSockaddrStorage struct {