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 {